AW-483-484-485-fix-bugs
This commit is contained in:
parent
4b7332f4d5
commit
5cc17824f3
@ -664,6 +664,12 @@
|
|||||||
"title": "Bought today: <count>",
|
"title": "Bought today: <count>",
|
||||||
"description": "<count> people are buying now:"
|
"description": "<count> people are buying now:"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"price-descriptions": {
|
||||||
|
"1": "Basic",
|
||||||
|
"2": "Standard",
|
||||||
|
"3": "Popular",
|
||||||
|
"4": "Premium"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/scan-hand": {
|
"/scan-hand": {
|
||||||
|
|||||||
@ -7,6 +7,20 @@
|
|||||||
"day": "Day",
|
"day": "Day",
|
||||||
"year": "Year",
|
"year": "Year",
|
||||||
"month": "Month",
|
"month": "Month",
|
||||||
|
"months": {
|
||||||
|
"january": "January",
|
||||||
|
"february": "February",
|
||||||
|
"march": "March",
|
||||||
|
"april": "April",
|
||||||
|
"may": "May",
|
||||||
|
"june": "June",
|
||||||
|
"july": "July",
|
||||||
|
"august": "August",
|
||||||
|
"september": "September",
|
||||||
|
"october": "October",
|
||||||
|
"november": "November",
|
||||||
|
"december": "December"
|
||||||
|
},
|
||||||
"aura_paywall_redesign_main": {
|
"aura_paywall_redesign_main": {
|
||||||
"text_0": "We've helped millions of people to have happier lives and better relationships, and we want to help you too.",
|
"text_0": "We've helped millions of people to have happier lives and better relationships, and we want to help you too.",
|
||||||
"text_0_color": "millions",
|
"text_0_color": "millions",
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { useSession } from "@/hooks/session/useSession";
|
|||||||
import { ESourceAuthorization } from "@/api/resources/User";
|
import { ESourceAuthorization } from "@/api/resources/User";
|
||||||
import { usePreloadImages } from "@/hooks/preload/images";
|
import { usePreloadImages } from "@/hooks/preload/images";
|
||||||
import { getZodiacSignByDate, ZODIACS } from "@/services/zodiac-sign";
|
import { getZodiacSignByDate, ZODIACS } from "@/services/zodiac-sign";
|
||||||
|
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||||
|
|
||||||
function Birthdate() {
|
function Birthdate() {
|
||||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||||
@ -26,14 +27,19 @@ function Birthdate() {
|
|||||||
const { gender } = useSelector(selectors.selectQuestionnaire);
|
const { gender } = useSelector(selectors.selectQuestionnaire);
|
||||||
const zodiacSign = getZodiacSignByDate(birthdate);
|
const zodiacSign = getZodiacSignByDate(birthdate);
|
||||||
|
|
||||||
|
const { variant: dateMonth = "v0" } = useUnleash({
|
||||||
|
flag: EUnleashFlags.v2CompatibilityDateMonth,
|
||||||
|
});
|
||||||
|
|
||||||
usePreloadImages(
|
usePreloadImages(
|
||||||
!!zodiacSign?.length ?
|
zodiacSign?.length
|
||||||
[
|
? [
|
||||||
`/zodiac-signs/${gender?.toLowerCase()}/${zodiacSign?.toLowerCase()}.svg`
|
`/zodiac-signs/${gender?.toLowerCase()}/${zodiacSign?.toLowerCase()}.svg`,
|
||||||
] :
|
]
|
||||||
ZODIACS.map(
|
: ZODIACS.map(
|
||||||
(zodiac) => `/zodiac-signs/${gender?.toLowerCase()}/${zodiac?.toLowerCase()}.svg`
|
(zodiac) =>
|
||||||
)
|
`/zodiac-signs/${gender?.toLowerCase()}/${zodiac?.toLowerCase()}.svg`
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleValid = (_birthdate: string) => {
|
const handleValid = (_birthdate: string) => {
|
||||||
@ -82,6 +88,7 @@ function Birthdate() {
|
|||||||
onValid={handleValid}
|
onValid={handleValid}
|
||||||
onInvalid={() => setIsDisabled(true)}
|
onInvalid={() => setIsDisabled(true)}
|
||||||
inputClassName="date-picker-input"
|
inputClassName="date-picker-input"
|
||||||
|
monthsDisplay={dateMonth === "v1" ? "name" : "number"}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { useSession } from "@/hooks/session/useSession";
|
|||||||
import { ESourceAuthorization } from "@/api/resources/User";
|
import { ESourceAuthorization } from "@/api/resources/User";
|
||||||
import { usePreloadImages } from "@/hooks/preload/images";
|
import { usePreloadImages } from "@/hooks/preload/images";
|
||||||
import { getZodiacSignByDate, ZODIACS } from "@/services/zodiac-sign";
|
import { getZodiacSignByDate, ZODIACS } from "@/services/zodiac-sign";
|
||||||
|
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||||
|
|
||||||
function BirthdatePartner() {
|
function BirthdatePartner() {
|
||||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||||
@ -24,6 +25,10 @@ function BirthdatePartner() {
|
|||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
const zodiacSign = getZodiacSignByDate(birthdate);
|
const zodiacSign = getZodiacSignByDate(birthdate);
|
||||||
|
|
||||||
|
const { variant: dateMonth = "v0" } = useUnleash({
|
||||||
|
flag: EUnleashFlags.v2CompatibilityDateMonth,
|
||||||
|
});
|
||||||
|
|
||||||
usePreloadImages(
|
usePreloadImages(
|
||||||
!!zodiacSign?.length ?
|
!!zodiacSign?.length ?
|
||||||
[
|
[
|
||||||
@ -64,6 +69,7 @@ function BirthdatePartner() {
|
|||||||
onValid={handleValid}
|
onValid={handleValid}
|
||||||
onInvalid={() => setIsDisabled(true)}
|
onInvalid={() => setIsDisabled(true)}
|
||||||
inputClassName="date-picker-input"
|
inputClassName="date-picker-input"
|
||||||
|
monthsDisplay={dateMonth === "v1" ? "name" : "number"}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { useTranslations } from "@/hooks/translations";
|
|||||||
import { ELocalesPlacement } from "@/locales";
|
import { ELocalesPlacement } from "@/locales";
|
||||||
import { useSession } from "@/hooks/session/useSession";
|
import { useSession } from "@/hooks/session/useSession";
|
||||||
import { ESourceAuthorization } from "@/api/resources/User";
|
import { ESourceAuthorization } from "@/api/resources/User";
|
||||||
|
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||||
|
|
||||||
function DateEvent() {
|
function DateEvent() {
|
||||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||||
@ -23,6 +24,10 @@ function DateEvent() {
|
|||||||
const [dateEvent, setDateEvent] = useState(dateEventFromStore);
|
const [dateEvent, setDateEvent] = useState(dateEventFromStore);
|
||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
|
|
||||||
|
const { variant: dateMonth = "v0" } = useUnleash({
|
||||||
|
flag: EUnleashFlags.v2CompatibilityDateMonth,
|
||||||
|
});
|
||||||
|
|
||||||
const handleValid = (_birthdate: string) => {
|
const handleValid = (_birthdate: string) => {
|
||||||
setDateEvent(_birthdate);
|
setDateEvent(_birthdate);
|
||||||
setIsDisabled(_birthdate === "");
|
setIsDisabled(_birthdate === "");
|
||||||
@ -54,6 +59,7 @@ function DateEvent() {
|
|||||||
onInvalid={() => setIsDisabled(true)}
|
onInvalid={() => setIsDisabled(true)}
|
||||||
inputClassName="date-picker-input"
|
inputClassName="date-picker-input"
|
||||||
differenceOfMaximumAndCurrentYear={0}
|
differenceOfMaximumAndCurrentYear={0}
|
||||||
|
monthsDisplay={dateMonth === "v1" ? "name" : "number"}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
|
|||||||
@ -116,7 +116,7 @@ function TrialChoice() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleNext = () => {
|
const handleNext = () => {
|
||||||
if (isDisabled && trialButtonVariant === "v1") {
|
if (isDisabled && ["v1", "v2", "v3", "v4"].includes(trialButtonVariant)) {
|
||||||
setIsDisabledButtonClicked(true);
|
setIsDisabledButtonClicked(true);
|
||||||
|
|
||||||
bottomRef.current?.scrollIntoView({
|
bottomRef.current?.scrollIntoView({
|
||||||
@ -203,37 +203,48 @@ function TrialChoice() {
|
|||||||
<div className={`${styles["price-container"]}`}>
|
<div className={`${styles["price-container"]}`}>
|
||||||
<div
|
<div
|
||||||
className={`${styles.priceListContainer} ${
|
className={`${styles.priceListContainer} ${
|
||||||
isDisabledButtonClicked && isDisabled
|
isDisabledButtonClicked &&
|
||||||
|
isDisabled &&
|
||||||
|
["v1", "v2"].includes(trialButtonVariant)
|
||||||
? styles.priceListContainerDisabled
|
? styles.priceListContainerDisabled
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{isDisabledButtonClicked && isDisabled && (
|
{isDisabledButtonClicked &&
|
||||||
<div className={styles.priceListContainerDisabledText}>
|
isDisabled &&
|
||||||
<svg
|
["v1", "v2"].includes(trialButtonVariant) && (
|
||||||
width="16"
|
<div className={styles.priceListContainerDisabledText}>
|
||||||
height="16"
|
<svg
|
||||||
viewBox="0 0 16 16"
|
width="16"
|
||||||
fill="none"
|
height="16"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
viewBox="0 0 16 16"
|
||||||
>
|
fill="none"
|
||||||
<rect width="16" height="16" rx="8" fill="#EF4444" />
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<path
|
>
|
||||||
d="M8.75 3C8.75 2.58516 8.41484 2.25 8 2.25C7.58516 2.25 7.25 2.58516 7.25 3V9C7.25 9.41484 7.58516 9.75 8 9.75C8.41484 9.75 8.75 9.41484 8.75 9V3ZM8 12.75C8.24864 12.75 8.4871 12.6512 8.66291 12.4754C8.83873 12.2996 8.9375 12.0611 8.9375 11.8125C8.9375 11.5639 8.83873 11.3254 8.66291 11.1496C8.4871 10.9738 8.24864 10.875 8 10.875C7.75136 10.875 7.5129 10.9738 7.33709 11.1496C7.16127 11.3254 7.0625 11.5639 7.0625 11.8125C7.0625 12.0611 7.16127 12.2996 7.33709 12.4754C7.5129 12.6512 7.75136 12.75 8 12.75Z"
|
<rect width="16" height="16" rx="8" fill="#EF4444" />
|
||||||
fill="white"
|
<path
|
||||||
/>
|
d="M8.75 3C8.75 2.58516 8.41484 2.25 8 2.25C7.58516 2.25 7.25 2.58516 7.25 3V9C7.25 9.41484 7.58516 9.75 8 9.75C8.41484 9.75 8.75 9.41484 8.75 9V3ZM8 12.75C8.24864 12.75 8.4871 12.6512 8.66291 12.4754C8.83873 12.2996 8.9375 12.0611 8.9375 11.8125C8.9375 11.5639 8.83873 11.3254 8.66291 11.1496C8.4871 10.9738 8.24864 10.875 8 10.875C7.75136 10.875 7.5129 10.9738 7.33709 11.1496C7.16127 11.3254 7.0625 11.5639 7.0625 11.8125C7.0625 12.0611 7.16127 12.2996 7.33709 12.4754C7.5129 12.6512 7.75136 12.75 8 12.75Z"
|
||||||
</svg>
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
{translate("/trial-choice.please-select")}
|
{translate("/trial-choice.please-select")}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PriceList
|
<PriceList
|
||||||
products={products}
|
products={products}
|
||||||
activeItem={selectedPrice}
|
activeItem={selectedPrice}
|
||||||
classNameItem={styles["price-item"]}
|
classNameItem={`${styles["price-item"]} ${
|
||||||
|
styles[trialButtonVariant]
|
||||||
|
} ${
|
||||||
|
isDisabledButtonClicked && isDisabled
|
||||||
|
? styles.priceItemDisabled
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
classNameItemActive={`${styles["price-item-active"]}`}
|
classNameItemActive={`${styles["price-item-active"]}`}
|
||||||
classNamePricesContainer={styles["prices-container"]}
|
classNamePricesContainer={styles["prices-container"]}
|
||||||
|
classNameDescription={styles["price-item-description"]}
|
||||||
currency={currency}
|
currency={currency}
|
||||||
showArrow={true}
|
showArrow={true}
|
||||||
productWidthArrow={products[products.length - 1]}
|
productWidthArrow={products[products.length - 1]}
|
||||||
@ -253,6 +264,17 @@ function TrialChoice() {
|
|||||||
</svg>
|
</svg>
|
||||||
}
|
}
|
||||||
click={handlePriceItem}
|
click={handlePriceItem}
|
||||||
|
displayMode={["v2", "v4"].includes(trialButtonVariant) ? "grid" : "row"}
|
||||||
|
pricesDescription={
|
||||||
|
["v2", "v4"].includes(trialButtonVariant)
|
||||||
|
? [
|
||||||
|
translate("/trial-choice.price-descriptions.1"),
|
||||||
|
translate("/trial-choice.price-descriptions.2"),
|
||||||
|
translate("/trial-choice.price-descriptions.3"),
|
||||||
|
translate("/trial-choice.price-descriptions.4"),
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className={styles["auxiliary-text"]}>
|
<p className={styles["auxiliary-text"]}>
|
||||||
@ -268,13 +290,17 @@ function TrialChoice() {
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
className={`${styles.button} ${
|
className={`${styles.button} ${
|
||||||
trialButtonVariant === "v1" ? styles["button-v1"] : ""
|
["v1", "v2", "v3", "v4"].includes(trialButtonVariant)
|
||||||
|
? styles["button-v1"]
|
||||||
|
: ""
|
||||||
} ${
|
} ${
|
||||||
isDisabled && trialButtonVariant === "v1"
|
isDisabled && ["v1", "v2", "v3", "v4"].includes(trialButtonVariant)
|
||||||
? styles["button-v1-disabled"]
|
? styles["button-v1-disabled"]
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
disabled={isDisabled && trialButtonVariant !== "v1"}
|
disabled={
|
||||||
|
isDisabled && !["v1", "v2", "v3", "v4"].includes(trialButtonVariant)
|
||||||
|
}
|
||||||
onClick={handleNext}
|
onClick={handleNext}
|
||||||
>
|
>
|
||||||
{translate("next")}
|
{translate("next")}
|
||||||
|
|||||||
@ -65,6 +65,54 @@
|
|||||||
color: #fb6c6c;
|
color: #fb6c6c;
|
||||||
border-color: #fb6c6c;
|
border-color: #fb6c6c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.v1,
|
||||||
|
&.v3 {
|
||||||
|
border: 1px solid #9ca3af;
|
||||||
|
|
||||||
|
&.price-item-active {
|
||||||
|
background: linear-gradient(90deg, #5393de 0%, #3a70b2 100%);
|
||||||
|
color: #fff !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v2,
|
||||||
|
&.v4 {
|
||||||
|
font-weight: 700;
|
||||||
|
border: 2px solid #d1d5db;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
&.price-item-active {
|
||||||
|
background: linear-gradient(90deg, #5393de 0%, #3a70b2 100%);
|
||||||
|
color: #fff !important;
|
||||||
|
border: 2px solid #3a70b2;
|
||||||
|
|
||||||
|
& > .price-item-description {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-width: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v3,
|
||||||
|
&.v4 {
|
||||||
|
&.priceItemDisabled {
|
||||||
|
color: #fb6c6c;
|
||||||
|
border-color: #fb6c6c;
|
||||||
|
|
||||||
|
& > .price-item-description {
|
||||||
|
color: #fb6c6c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark-theme) .price-item {
|
:global(.dark-theme) .price-item {
|
||||||
@ -79,6 +127,52 @@
|
|||||||
color: #fb6c6c;
|
color: #fb6c6c;
|
||||||
border-color: #fb6c6c;
|
border-color: #fb6c6c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.v1,
|
||||||
|
&.v3 {
|
||||||
|
border: 1px solid #9ca3af;
|
||||||
|
|
||||||
|
&.price-item-active {
|
||||||
|
background: linear-gradient(90deg, #5393de 0%, #3a70b2 100%);
|
||||||
|
color: #fff !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v2,
|
||||||
|
&.v4 {
|
||||||
|
border: 2px solid #d1d5db;
|
||||||
|
|
||||||
|
&.price-item-active {
|
||||||
|
background: linear-gradient(90deg, #5393de 0%, #3a70b2 100%);
|
||||||
|
color: #fff !important;
|
||||||
|
border: 2px solid #3a70b2;
|
||||||
|
|
||||||
|
& > .price-item-description {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-width: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v3,
|
||||||
|
&.v4 {
|
||||||
|
&.priceItemDisabled {
|
||||||
|
color: #fb6c6c;
|
||||||
|
border-color: #fb6c6c;
|
||||||
|
|
||||||
|
& > .price-item-description {
|
||||||
|
color: #fb6c6c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-container {
|
.price-container {
|
||||||
@ -118,15 +212,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
& .price-item {
|
& .price-item {
|
||||||
border: 1px solid rgba(156, 163, 175, 1);
|
// border: 1px solid rgba(156, 163, 175, 1);
|
||||||
color: #000;
|
color: #000;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.1),
|
box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.1),
|
||||||
0px 2px 4px 0px rgba(0, 0, 0, 0.1);
|
0px 2px 4px 0px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-width: 3px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { FormField } from "@/types";
|
import { FormField } from "@/types";
|
||||||
|
import { MonthOption } from "@/utils/monthNames";
|
||||||
|
|
||||||
type DatePartValue = string | undefined;
|
type DatePartValue = string | undefined;
|
||||||
|
|
||||||
@ -6,7 +7,7 @@ type DateInputProps = Omit<
|
|||||||
FormField<DatePartValue>,
|
FormField<DatePartValue>,
|
||||||
"onValid" | "onInvalid"
|
"onValid" | "onInvalid"
|
||||||
> & {
|
> & {
|
||||||
values: number[] | string[];
|
values: (number | string | MonthOption)[];
|
||||||
onChange: (part: string) => void;
|
onChange: (part: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,8 +22,8 @@ function DateInput(props: DateInputProps): JSX.Element {
|
|||||||
onChange,
|
onChange,
|
||||||
} = props;
|
} = props;
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const datePart = e.target.value ? parseInt(e.target.value, 10) : 0;
|
const selectedValue = e.target.value;
|
||||||
onChange(String(datePart));
|
onChange(selectedValue);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className={`date-picker__field ${inputClassName ?? ""}`}>
|
<div className={`date-picker__field ${inputClassName ?? ""}`}>
|
||||||
@ -37,11 +38,15 @@ function DateInput(props: DateInputProps): JSX.Element {
|
|||||||
<option value="" hidden>
|
<option value="" hidden>
|
||||||
{placeholder}
|
{placeholder}
|
||||||
</option>
|
</option>
|
||||||
{values.map((_value, index) => (
|
{values.map((_value, index) => {
|
||||||
<option key={`${_value}_${index}`} value={_value}>
|
const optionValue = typeof _value === 'object' ? _value.value : _value;
|
||||||
{_value}
|
const optionLabel = typeof _value === 'object' ? _value.label : _value;
|
||||||
</option>
|
return (
|
||||||
))}
|
<option key={`${optionValue}_${index}`} value={optionValue}>
|
||||||
|
{optionLabel}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,14 +7,24 @@ import { stringify, getCurrentYear } from "./utils";
|
|||||||
import { IDate, getDateAsString } from "@/services/date";
|
import { IDate, getDateAsString } from "@/services/date";
|
||||||
import { ELocalesPlacement, language } from "@/locales";
|
import { ELocalesPlacement, language } from "@/locales";
|
||||||
import { getDateInputLocaleFormat } from "@/locales/localFormats";
|
import { getDateInputLocaleFormat } from "@/locales/localFormats";
|
||||||
|
import { getMonthOptions } from "@/utils/monthNames";
|
||||||
|
|
||||||
export function DatePicker(
|
export function DatePicker(
|
||||||
props: FormField<Date | IDate | string> & {
|
props: FormField<Date | IDate | string> & {
|
||||||
differenceOfMaximumAndCurrentYear?: number;
|
differenceOfMaximumAndCurrentYear?: number;
|
||||||
|
monthsDisplay?: "number" | "name";
|
||||||
}
|
}
|
||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
const { translate } = useTranslations(ELocalesPlacement.V1);
|
const { translate } = useTranslations(ELocalesPlacement.V1);
|
||||||
const { name, value, inputClassName, differenceOfMaximumAndCurrentYear = 11, onValid, onInvalid } = props;
|
const {
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
inputClassName,
|
||||||
|
differenceOfMaximumAndCurrentYear = 11,
|
||||||
|
onValid,
|
||||||
|
onInvalid,
|
||||||
|
monthsDisplay = "number",
|
||||||
|
} = props;
|
||||||
const date = getDateAsString(value);
|
const date = getDateAsString(value);
|
||||||
const [initYear, initMonth, initDay] = date.split("-");
|
const [initYear, initMonth, initDay] = date.split("-");
|
||||||
const [year, setYear] = useState(initYear);
|
const [year, setYear] = useState(initYear);
|
||||||
@ -31,12 +41,15 @@ export function DatePicker(
|
|||||||
return Array.from({ length: 66 }, (_, index) => {
|
return Array.from({ length: 66 }, (_, index) => {
|
||||||
return currentYear - differenceOfMaximumAndCurrentYear - index;
|
return currentYear - differenceOfMaximumAndCurrentYear - index;
|
||||||
});
|
});
|
||||||
}, []);
|
}, [differenceOfMaximumAndCurrentYear]);
|
||||||
const months = useMemo(() => {
|
const months = useMemo(() => {
|
||||||
|
if (monthsDisplay === "name") {
|
||||||
|
return getMonthOptions(translate);
|
||||||
|
}
|
||||||
return Array.from({ length: 12 }, (_, index) => {
|
return Array.from({ length: 12 }, (_, index) => {
|
||||||
return index + 1;
|
return index + 1;
|
||||||
});
|
});
|
||||||
}, []);
|
}, [translate, monthsDisplay]);
|
||||||
|
|
||||||
const days = useMemo(() => {
|
const days = useMemo(() => {
|
||||||
return Array.from(
|
return Array.from(
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { removeAfterDot, roundToWhole } from "@/services/price";
|
import { removeAfterDot, roundToWhole } from "@/services/price";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.scss";
|
||||||
import Price, { Currency, Locale } from "@/components/PaymentTable/Price";
|
import Price, { Currency, Locale } from "@/components/PaymentTable/Price";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
@ -11,8 +11,10 @@ interface PriceItemProps {
|
|||||||
active: boolean;
|
active: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
classNameActive?: string;
|
classNameActive?: string;
|
||||||
|
classNameDescription?: string;
|
||||||
currency: Currency;
|
currency: Currency;
|
||||||
arrowElement?: React.ReactNode;
|
arrowElement?: React.ReactNode;
|
||||||
|
description?: string;
|
||||||
click: (id: string) => void;
|
click: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,8 +24,10 @@ function PriceItem({
|
|||||||
active,
|
active,
|
||||||
className = "",
|
className = "",
|
||||||
classNameActive = "",
|
classNameActive = "",
|
||||||
|
classNameDescription = "",
|
||||||
currency = Currency.USD,
|
currency = Currency.USD,
|
||||||
arrowElement,
|
arrowElement,
|
||||||
|
description,
|
||||||
click,
|
click,
|
||||||
}: PriceItemProps): JSX.Element {
|
}: PriceItemProps): JSX.Element {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -65,6 +69,11 @@ function PriceItem({
|
|||||||
className={compatClassName()}
|
className={compatClassName()}
|
||||||
>
|
>
|
||||||
{removeAfterDot(_price.format())}
|
{removeAfterDot(_price.format())}
|
||||||
|
{!!description?.length && (
|
||||||
|
<p className={`${styles.description} ${classNameDescription}`}>
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
{arrowElement}
|
{arrowElement}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
.container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s, color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background-color: #D1ACF2;
|
|
||||||
border-color: #D1ACF2 !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popular {
|
|
||||||
border-color: #30bf52;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popular:after {
|
|
||||||
content: 'Most Popular';
|
|
||||||
position: absolute;
|
|
||||||
width: 80px;
|
|
||||||
height: 20px;
|
|
||||||
left: -10px;
|
|
||||||
bottom: -25px;
|
|
||||||
background-color: #30bf52;
|
|
||||||
font-size: 9px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #fff;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s, color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
background-color: #d1acf2;
|
||||||
|
border-color: #d1acf2 !important;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popular {
|
||||||
|
border-color: #30bf52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popular:after {
|
||||||
|
content: "Most Popular";
|
||||||
|
position: absolute;
|
||||||
|
width: 80px;
|
||||||
|
height: 20px;
|
||||||
|
left: -10px;
|
||||||
|
bottom: -25px;
|
||||||
|
background-color: #30bf52;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.dark-theme) {
|
||||||
|
.description {
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
& > .description {
|
||||||
|
color: #4f8de5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,11 +12,14 @@ interface PriceListProps {
|
|||||||
classNameItem?: string;
|
classNameItem?: string;
|
||||||
classNameItemActive?: string;
|
classNameItemActive?: string;
|
||||||
classNamePricesContainer?: string;
|
classNamePricesContainer?: string;
|
||||||
|
classNameDescription?: string;
|
||||||
currency?: Currency;
|
currency?: Currency;
|
||||||
preActiveItems?: string[];
|
preActiveItems?: string[];
|
||||||
showArrow?: boolean;
|
showArrow?: boolean;
|
||||||
productWidthArrow?: IFunnelPaymentVariant;
|
productWidthArrow?: IFunnelPaymentVariant;
|
||||||
arrowElement?: React.ReactNode;
|
arrowElement?: React.ReactNode;
|
||||||
|
displayMode?: "row" | "grid";
|
||||||
|
pricesDescription?: string[];
|
||||||
click: () => void;
|
click: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,11 +33,14 @@ function PriceList({
|
|||||||
classNameItem = "",
|
classNameItem = "",
|
||||||
classNameItemActive = "",
|
classNameItemActive = "",
|
||||||
classNamePricesContainer = "",
|
classNamePricesContainer = "",
|
||||||
|
classNameDescription = "",
|
||||||
preActiveItems = [],
|
preActiveItems = [],
|
||||||
currency = Currency.USD,
|
currency = Currency.USD,
|
||||||
showArrow = false,
|
showArrow = false,
|
||||||
productWidthArrow,
|
productWidthArrow,
|
||||||
arrowElement,
|
arrowElement,
|
||||||
|
displayMode = "row",
|
||||||
|
pricesDescription = [],
|
||||||
}: PriceListProps): JSX.Element {
|
}: PriceListProps): JSX.Element {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [activeProductItem, setActiveProductItem] =
|
const [activeProductItem, setActiveProductItem] =
|
||||||
@ -54,7 +60,9 @@ function PriceList({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.container} ${classNamePricesContainer}`}>
|
<div
|
||||||
|
className={`${styles.container} ${classNamePricesContainer} ${styles[displayMode]}`}
|
||||||
|
>
|
||||||
{products.map((product, idx) => (
|
{products.map((product, idx) => (
|
||||||
<PriceItem
|
<PriceItem
|
||||||
active={
|
active={
|
||||||
@ -64,8 +72,9 @@ function PriceList({
|
|||||||
key={idx}
|
key={idx}
|
||||||
value={getPrice(product)}
|
value={getPrice(product)}
|
||||||
id={product.id}
|
id={product.id}
|
||||||
className={classNameItem}
|
className={`${classNameItem} ${styles.item} ${styles[displayMode]}`}
|
||||||
classNameActive={classNameItemActive}
|
classNameActive={`${classNameItemActive} ${styles.itemActive} ${styles[displayMode]}`}
|
||||||
|
classNameDescription={classNameDescription}
|
||||||
click={priceItemClick}
|
click={priceItemClick}
|
||||||
currency={currency}
|
currency={currency}
|
||||||
arrowElement={
|
arrowElement={
|
||||||
@ -73,6 +82,7 @@ function PriceList({
|
|||||||
? arrowElement
|
? arrowElement
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
description={pricesDescription[idx]}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,4 +4,36 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
|
&.grid {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
&.grid {
|
||||||
|
width: 162px;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
height: 76px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 380px) {
|
||||||
|
.item {
|
||||||
|
&.grid {
|
||||||
|
width: 142px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 340px) {
|
||||||
|
.item {
|
||||||
|
&.grid {
|
||||||
|
width: 102px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ export enum EUnleashFlags {
|
|||||||
"v2CompatibilityReviewPage" = "v2-compatibility-review-page",
|
"v2CompatibilityReviewPage" = "v2-compatibility-review-page",
|
||||||
"v2CompatibilityPathToEnteringBirthdate" = "v2-compatibility-path-to-entering-birthdate",
|
"v2CompatibilityPathToEnteringBirthdate" = "v2-compatibility-path-to-entering-birthdate",
|
||||||
"v2CompatibilityTrialChoicePath" = "v2-compatibility-trial-choice-path",
|
"v2CompatibilityTrialChoicePath" = "v2-compatibility-trial-choice-path",
|
||||||
|
"v2CompatibilityDateMonth" = "v2-compatibility-date-month",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IUseUnleashProps<T extends EUnleashFlags> {
|
interface IUseUnleashProps<T extends EUnleashFlags> {
|
||||||
@ -73,7 +74,7 @@ interface IVariants {
|
|||||||
[EUnleashFlags.compatibilityV2TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
[EUnleashFlags.compatibilityV2TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||||||
[EUnleashFlags.compatibilityV3TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
[EUnleashFlags.compatibilityV3TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||||||
[EUnleashFlags.compatibilityV4TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
[EUnleashFlags.compatibilityV4TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||||||
[EUnleashFlags.compatibilityV2TrialButton]: "v0" | "v1";
|
[EUnleashFlags.compatibilityV2TrialButton]: "v0" | "v1" | "v2" | "v3" | "v4";
|
||||||
[EUnleashFlags.palmistryV1TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
[EUnleashFlags.palmistryV1TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||||||
[EUnleashFlags.v2CompatibilityScanResultNumbers]: 'off' | 'on';
|
[EUnleashFlags.v2CompatibilityScanResultNumbers]: 'off' | 'on';
|
||||||
[EUnleashFlags.v2CompatibilityScanInstructionImage]: 'v0' | 'v1';
|
[EUnleashFlags.v2CompatibilityScanInstructionImage]: 'v0' | 'v1';
|
||||||
@ -82,6 +83,7 @@ interface IVariants {
|
|||||||
[EUnleashFlags.v2CompatibilityReviewPage]: 'v0' | 'v1' | 'v2' | 'v3' | 'v4';
|
[EUnleashFlags.v2CompatibilityReviewPage]: 'v0' | 'v1' | 'v2' | 'v3' | 'v4';
|
||||||
[EUnleashFlags.v2CompatibilityPathToEnteringBirthdate]: 'hide' | 'show';
|
[EUnleashFlags.v2CompatibilityPathToEnteringBirthdate]: 'hide' | 'show';
|
||||||
[EUnleashFlags.v2CompatibilityTrialChoicePath]: 'v0' | 'v1' | 'v2' | 'v3';
|
[EUnleashFlags.v2CompatibilityTrialChoicePath]: 'v0' | 'v1' | 'v2' | 'v3';
|
||||||
|
[EUnleashFlags.v2CompatibilityDateMonth]: 'v0' | 'v1';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
49
src/utils/monthNames.ts
Normal file
49
src/utils/monthNames.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
export interface MonthOption {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const monthKeys = [
|
||||||
|
"january",
|
||||||
|
"february",
|
||||||
|
"march",
|
||||||
|
"april",
|
||||||
|
"may",
|
||||||
|
"june",
|
||||||
|
"july",
|
||||||
|
"august",
|
||||||
|
"september",
|
||||||
|
"october",
|
||||||
|
"november",
|
||||||
|
"december",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const getMonthOptions = (
|
||||||
|
translate: (key: string) => string
|
||||||
|
): MonthOption[] => {
|
||||||
|
return monthKeys.map((monthKey, index) => ({
|
||||||
|
value: String(index + 1),
|
||||||
|
label: translate(`months.${monthKey}`),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMonthName = (
|
||||||
|
monthNumber: string | number,
|
||||||
|
translate: (key: string) => string
|
||||||
|
): string => {
|
||||||
|
const index = Number(monthNumber) - 1;
|
||||||
|
const monthKey = monthKeys[index];
|
||||||
|
|
||||||
|
return monthKey ? translate(`months.${monthKey}`) : String(monthNumber);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMonthNumber = (
|
||||||
|
monthName: string,
|
||||||
|
translate: (key: string) => string
|
||||||
|
): string => {
|
||||||
|
const index = monthKeys.findIndex(
|
||||||
|
(monthKey) => translate(`months.${monthKey}`) === monthName
|
||||||
|
);
|
||||||
|
|
||||||
|
return index !== -1 ? String(index + 1) : monthName;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user