feat: infinity months date picker, texts from translate v2, prices from chosen
This commit is contained in:
parent
87eba58d0e
commit
64bdc08452
@ -34,7 +34,7 @@ function App(): JSX.Element {
|
|||||||
const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState<boolean>(false)
|
const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState<boolean>(false)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const closeSpecialOffer = () => {
|
const closeSpecialOfferAttention = () => {
|
||||||
setIsSpecialOfferOpen(false)
|
setIsSpecialOfferOpen(false)
|
||||||
navigate(routes.client.emailEnter())
|
navigate(routes.client.emailEnter())
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ function App(): JSX.Element {
|
|||||||
<Route path={routes.client.birthday()} element={<BirthdayPage />} />
|
<Route path={routes.client.birthday()} element={<BirthdayPage />} />
|
||||||
<Route path={routes.client.didYouKnow()} element={<DidYouKnowPage />} />
|
<Route path={routes.client.didYouKnow()} element={<DidYouKnowPage />} />
|
||||||
<Route path={routes.client.freePeriodInfo()} element={<FreePeriodInfoPage />} />
|
<Route path={routes.client.freePeriodInfo()} element={<FreePeriodInfoPage />} />
|
||||||
<Route path={routes.client.attention()} element={<AttentionPage isOpenModal={isSpecialOfferOpen} onCloseSpecialOffer={closeSpecialOffer} />} />
|
<Route path={routes.client.attention()} element={<AttentionPage isOpenModal={isSpecialOfferOpen} onCloseSpecialOffer={closeSpecialOfferAttention} />} />
|
||||||
<Route path={routes.client.feedback()} element={<FeedbackPage />} />
|
<Route path={routes.client.feedback()} element={<FeedbackPage />} />
|
||||||
<Route path={routes.client.birthtime()} element={<BirthtimePage />} />
|
<Route path={routes.client.birthtime()} element={<BirthtimePage />} />
|
||||||
<Route path={routes.client.createProfile()} element={<SkipStep />} />
|
<Route path={routes.client.createProfile()} element={<SkipStep />} />
|
||||||
|
|||||||
@ -3,11 +3,13 @@ import Title from "../Title";
|
|||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { actions, selectors } from "@/store";
|
import { actions, selectors } from "@/store";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { AICompats, AIRequests, useApi, useApiCall } from "@/api";
|
import { AICompats, AIRequests, useApi, useApiCall } from "@/api";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import routes from "@/routes";
|
import routes from "@/routes";
|
||||||
import { EPathsFromHome } from "@/store/siteConfig";
|
import { EPathsFromHome } from "@/store/siteConfig";
|
||||||
|
import FullScreenModal from "../FullScreenModal";
|
||||||
|
import CompatibilityLoading from "../CompatibilityLoading";
|
||||||
|
|
||||||
function CompatResultPage(): JSX.Element {
|
function CompatResultPage(): JSX.Element {
|
||||||
const token =
|
const token =
|
||||||
@ -21,6 +23,18 @@ function CompatResultPage(): JSX.Element {
|
|||||||
const categoryId = useSelector(selectors.selectCategoryId);
|
const categoryId = useSelector(selectors.selectCategoryId);
|
||||||
const homeConfig = useSelector(selectors.selectHome);
|
const homeConfig = useSelector(selectors.selectHome);
|
||||||
const [text, setText] = useState("Loading...");
|
const [text, setText] = useState("Loading...");
|
||||||
|
const [isOpenModal, setIsOpenModal] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timeOut = setTimeout(() => {
|
||||||
|
setIsOpenModal(false)
|
||||||
|
}, 5000)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeOut)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
const handleNext = () => {
|
const handleNext = () => {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -75,6 +89,9 @@ function CompatResultPage(): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`}>
|
||||||
|
<FullScreenModal isOpen={isOpenModal}>
|
||||||
|
<CompatibilityLoading />
|
||||||
|
</FullScreenModal>
|
||||||
{text !== "Loading..." && (
|
{text !== "Loading..." && (
|
||||||
<div className={styles.cross} onClick={handleNext}></div>
|
<div className={styles.cross} onClick={handleNext}></div>
|
||||||
)}
|
)}
|
||||||
@ -103,7 +120,7 @@ function CompatResultPage(): JSX.Element {
|
|||||||
)}
|
)}
|
||||||
{text !== "Loading..." &&
|
{text !== "Loading..." &&
|
||||||
homeConfig.pathFromHome === EPathsFromHome.breath && (
|
homeConfig.pathFromHome === EPathsFromHome.breath && (
|
||||||
<button className={styles['button-green']} onClick={handleNext}>
|
<button className={styles["button-green"]} onClick={handleNext}>
|
||||||
{t("use-all-power")}
|
{t("use-all-power")}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -79,7 +79,8 @@
|
|||||||
color: #a09b9b;
|
color: #a09b9b;
|
||||||
}
|
}
|
||||||
.date-picker-item.selected {
|
.date-picker-item.selected {
|
||||||
color: white;
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header and confirm button */
|
/* Header and confirm button */
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const DatePicker: React.FC<DatePickerProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const days = Array.from({ length: 31 }, (_, index) => (index + 1).toString());
|
const days = Array.from({ length: 31 }, (_, index) => (index + 1).toString());
|
||||||
const months = Array.from({ length: 12 }, (_, index) =>
|
const months = Array.from({ length: 36 }, (_, index) =>
|
||||||
new Date(0, index).toLocaleDateString(undefined, { month: "long" })
|
new Date(0, index).toLocaleDateString(undefined, { month: "long" })
|
||||||
);
|
);
|
||||||
const years = Array.from({ length: 81 }, (_, index) =>
|
const years = Array.from({ length: 81 }, (_, index) =>
|
||||||
@ -27,19 +27,19 @@ const DatePicker: React.FC<DatePickerProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleDaySelect = (day: string) => {
|
const handleDaySelect = (day: string) => {
|
||||||
const newDate = new Date(getDateAsString(selectedDate));
|
const newDate = new Date(getDateAsString(selectedDate).replace(/-/g, "/"));
|
||||||
newDate.setDate(parseInt(day));
|
newDate.setDate(parseInt(day));
|
||||||
setSelectedDate(getDateAsString(newDate));
|
setSelectedDate(getDateAsString(newDate));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMonthSelect = (month: string) => {
|
const handleMonthSelect = (month: string) => {
|
||||||
const newDate = new Date(getDateAsString(selectedDate));
|
const newDate = new Date(getDateAsString(selectedDate).replace(/-/g, "/"));
|
||||||
newDate.setMonth(months.indexOf(month));
|
newDate.setMonth(months.indexOf(month));
|
||||||
setSelectedDate(getDateAsString(newDate));
|
setSelectedDate(getDateAsString(newDate));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleYearSelect = (year: string) => {
|
const handleYearSelect = (year: string) => {
|
||||||
const newDate = new Date(getDateAsString(selectedDate));
|
const newDate = new Date(getDateAsString(selectedDate).replace(/-/g, "/"));
|
||||||
newDate.setFullYear(parseInt(year));
|
newDate.setFullYear(parseInt(year));
|
||||||
setSelectedDate(getDateAsString(newDate));
|
setSelectedDate(getDateAsString(newDate));
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,17 +24,14 @@ const DatePickerItem: React.FC<DatePickerItemProps> = ({
|
|||||||
data,
|
data,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
onSelect,
|
onSelect,
|
||||||
unit
|
unit,
|
||||||
}) => {
|
}) => {
|
||||||
console.log(selectedValue);
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const scrollRef = useRef<HTMLDivElement | null>(null);
|
const scrollRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
const [touchY, setTouchY] = useState<number>(0);
|
const [touchY, setTouchY] = useState<number>(0);
|
||||||
const [translateY, setTranslateY] = useState<number>(
|
const [translateY, setTranslateY] = useState<number>(
|
||||||
data.indexOf(selectedValue) * -ITEM_HEIGHT
|
(data.indexOf(selectedValue) + (unit === "month" ? 12 : 0)) * -ITEM_HEIGHT
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {
|
const handleTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {
|
||||||
@ -45,10 +42,26 @@ const DatePickerItem: React.FC<DatePickerItemProps> = ({
|
|||||||
if (isMobile && touchY !== null) {
|
if (isMobile && touchY !== null) {
|
||||||
const deltaY = event.touches[0].clientY - touchY;
|
const deltaY = event.touches[0].clientY - touchY;
|
||||||
wheelScroll(deltaY);
|
wheelScroll(deltaY);
|
||||||
|
|
||||||
setTouchY(event.touches[0].clientY);
|
setTouchY(event.touches[0].clientY);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTranslateY((data.indexOf(selectedValue) + (unit === "month" ? 12 : 0)) * -ITEM_HEIGHT)
|
||||||
|
}, [selectedValue, data, unit])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (unit === "month") {
|
||||||
|
if (
|
||||||
|
data.indexOf(selectedValue) < 12 ||
|
||||||
|
data.indexOf(selectedValue) > 23
|
||||||
|
) {
|
||||||
|
setTranslateY((data.indexOf(selectedValue) + 12) * -ITEM_HEIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [unit, data, selectedValue]);
|
||||||
|
|
||||||
const handleTouchEnd = () => {
|
const handleTouchEnd = () => {
|
||||||
if (isMobile && scrollRef.current) {
|
if (isMobile && scrollRef.current) {
|
||||||
const selectedIndex = Math.round(-translateY / ITEM_HEIGHT);
|
const selectedIndex = Math.round(-translateY / ITEM_HEIGHT);
|
||||||
|
|||||||
@ -53,7 +53,7 @@ function CompatibilityPage(): JSX.Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleValidDate = (date: string | IDate) => {
|
const handleValidDate = (date: string | IDate) => {
|
||||||
setIsDisabledDate(date === '');
|
setIsDisabledDate(date === "");
|
||||||
setSelectedDate(date);
|
setSelectedDate(date);
|
||||||
checkAllDisabled();
|
checkAllDisabled();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -127,7 +127,7 @@
|
|||||||
.compatibility-categories {
|
.compatibility-categories {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 32px;
|
gap: 16px;
|
||||||
margin-top: 72px;
|
margin-top: 72px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/components/CompatibilityLoading/index.tsx
Normal file
18
src/components/CompatibilityLoading/index.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Title from "../Title";
|
||||||
|
import styles from "./styles.module.css";
|
||||||
|
|
||||||
|
// interface ICompatibilityLoadingProps {
|
||||||
|
// onEndLoading: () => void;
|
||||||
|
// }
|
||||||
|
|
||||||
|
function CompatibilityLoading(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<section className={`${styles.container}`}>
|
||||||
|
<Title variant="h3" className={styles.title}>
|
||||||
|
Analysis of you with Viktor Ershov
|
||||||
|
</Title>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CompatibilityLoading;
|
||||||
12
src/components/CompatibilityLoading/styles.module.css
Normal file
12
src/components/CompatibilityLoading/styles.module.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.container {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #fd3761;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
@ -7,24 +7,24 @@ import styles from './styles.module.css'
|
|||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { selectors } from '@/store'
|
import { selectors } from '@/store'
|
||||||
import { getZodiacSignByDate } from '@/services/zodiac-sign'
|
import { getZodiacSignByDate } from '@/services/zodiac-sign'
|
||||||
import SpecialWelcomeOffer from '../SpecialWelcomeOffer'
|
// import SpecialWelcomeOffer from '../SpecialWelcomeOffer'
|
||||||
import { useState } from 'react'
|
// import { useState } from 'react'
|
||||||
|
|
||||||
function DidYouKnowPage(): JSX.Element {
|
function DidYouKnowPage(): JSX.Element {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const handleNext = () => navigate(routes.client.freePeriodInfo())
|
const handleNext = () => navigate(routes.client.freePeriodInfo())
|
||||||
const [isOpenModal, setIsOpenModal] = useState(false)
|
// const [isOpenModal, setIsOpenModal] = useState(false)
|
||||||
const handleSpecialOffer = () => {
|
// const handleSpecialOffer = () => {
|
||||||
setIsOpenModal(true)
|
// setIsOpenModal(true)
|
||||||
}
|
// }
|
||||||
const birthdate = useSelector(selectors.selectBirthdate)
|
const birthdate = useSelector(selectors.selectBirthdate)
|
||||||
const zodiacSign = getZodiacSignByDate(birthdate)
|
const zodiacSign = getZodiacSignByDate(birthdate)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`}>
|
||||||
<SpecialWelcomeOffer open={isOpenModal} />
|
{/* <SpecialWelcomeOffer open={isOpenModal} /> */}
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Title variant='h1'>{t('did_you_know')}</Title>
|
<Title variant='h1'>{t('did_you_know')}</Title>
|
||||||
<p className={styles.zodiacInfo}>
|
<p className={styles.zodiacInfo}>
|
||||||
@ -35,7 +35,7 @@ function DidYouKnowPage(): JSX.Element {
|
|||||||
<MainButton onClick={handleNext}>
|
<MainButton onClick={handleNext}>
|
||||||
{t('learn_about_my_energy')}
|
{t('learn_about_my_energy')}
|
||||||
</MainButton>
|
</MainButton>
|
||||||
<span className={styles.skip} onClick={handleSpecialOffer}>{t('skip_for_now')}</span>
|
<span className={styles.skip} onClick={handleNext}>{t('skip_for_now')}</span>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -61,7 +61,7 @@ function EmailEnterPage(): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className='page'>
|
<section className='page'>
|
||||||
<Title variant='h2' className='mt-24'>{t('we_will_email_you')}</Title>
|
<Title variant='h2' className='mt-24'>{t('aura.web.email_title')}</Title>
|
||||||
<EmailInput
|
<EmailInput
|
||||||
name="email"
|
name="email"
|
||||||
value={email}
|
value={email}
|
||||||
@ -69,16 +69,16 @@ function EmailEnterPage(): JSX.Element {
|
|||||||
onValid={handleValidEmail}
|
onValid={handleValidEmail}
|
||||||
onInvalid={() => setIsDisabled(true)}
|
onInvalid={() => setIsDisabled(true)}
|
||||||
/>
|
/>
|
||||||
<p>{t('we_dont_share')}</p>
|
<p style={{ marginBottom: '8px' }}>{t('we_dont_share')}</p>
|
||||||
|
<MainButton onClick={handleClick} disabled={isDisabled}>
|
||||||
|
{isLoading ? <Loader color={LoaderColor.White} /> : t('_continue')}
|
||||||
|
</MainButton>
|
||||||
<Policy sizing='medium'>
|
<Policy sizing='medium'>
|
||||||
{t('_continue_agree', {
|
{t('_continue_agree', {
|
||||||
eulaLink: <a href='https://aura.wit.life/terms' target='_blank' rel='noopener noreferrer'>{t('eula')}</a>,
|
eulaLink: <a href='https://aura.wit.life/terms' target='_blank' rel='noopener noreferrer'>{t('eula')}</a>,
|
||||||
privacyLink: <a href='https://aura.wit.life/privacy' target='_blank' rel='noopener noreferrer'>{t('privacy_policy')}</a>,
|
privacyLink: <a href='https://aura.wit.life/privacy' target='_blank' rel='noopener noreferrer'>{t('privacy_policy')}</a>,
|
||||||
})}
|
})}
|
||||||
</Policy>
|
</Policy>
|
||||||
<MainButton onClick={handleClick} disabled={isDisabled}>
|
|
||||||
{isLoading ? <Loader color={LoaderColor.White} /> : t('_continue')}
|
|
||||||
</MainButton>
|
|
||||||
<ErrorText size='medium' isShown={Boolean(error)} message={error ? extractErrorMessage(error) : null} />
|
<ErrorText size='medium' isShown={Boolean(error)} message={error ? extractErrorMessage(error) : null} />
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -162,7 +162,7 @@ function HomePage(): JSX.Element {
|
|||||||
{/* <a href={asset?.url.replace('http://', 'https://')} download></a> */}
|
{/* <a href={asset?.url.replace('http://', 'https://')} download></a> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.content}>
|
<div className={styles.content} style={{ marginTop: isShowNavbar ? "calc(100vh - 570px)" : "calc(100vh - 500px)"}}>
|
||||||
<div className={styles["content__buttons"]}>
|
<div className={styles["content__buttons"]}>
|
||||||
<BlurringSubstrate
|
<BlurringSubstrate
|
||||||
style={{ color: "#fa71ea" }}
|
style={{ color: "#fa71ea" }}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ function PaymentTable({ currency, locale, items }: PaymentTableProps): JSX.Eleme
|
|||||||
</div>
|
</div>
|
||||||
<div className='payment__item-description'>
|
<div className='payment__item-description'>
|
||||||
<p>{item.description}</p>
|
<p>{item.description}</p>
|
||||||
<p>One dollar thirty six cents per day</p>
|
{/* <p>One dollar thirty six cents per day</p> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -44,7 +44,7 @@ function PaymentTable({ currency, locale, items }: PaymentTableProps): JSX.Eleme
|
|||||||
{items.map(toItem)}
|
{items.map(toItem)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='payment__information'>{t('charged_only')}</div>
|
<div className='payment__information'>{t('charged_only', {price: totalPrice.format()})}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 20px;
|
margin-top: 8px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ const removeAfterDot = (value: string): string => {
|
|||||||
|
|
||||||
interface PriceItemProps {
|
interface PriceItemProps {
|
||||||
active: boolean;
|
active: boolean;
|
||||||
click: () => void;
|
click: (id: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function PriceItem({
|
function PriceItem({
|
||||||
@ -38,12 +38,16 @@ function PriceItem({
|
|||||||
|
|
||||||
const compatClassName = () => {
|
const compatClassName = () => {
|
||||||
const isPopular = id === 3;
|
const isPopular = id === 3;
|
||||||
// const isActive = active;
|
const isActive = active;
|
||||||
return `${styles.container} ${isPopular ? styles.popular : ""}`;
|
return `${styles.container} ${isPopular ? styles.popular : ""} ${isActive ? styles.active : ""}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const itemClick = () => {
|
||||||
|
click(id);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onClick={click} className={compatClassName()}>
|
<div onClick={itemClick} className={compatClassName()}>
|
||||||
{removeAfterDot(_price.format())}
|
{removeAfterDot(_price.format())}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,11 +10,12 @@
|
|||||||
border: solid #d6d2d2 2px;
|
border: solid #d6d2d2 2px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s, color 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background-color: #30bf52;
|
background-color: #d6d2d2;
|
||||||
border-color: #30bf52;
|
border-color: #d6d2d2 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
import PriceItem from '../PriceItem'
|
import PriceItem from '../PriceItem'
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
import { actions } from '@/store'
|
||||||
|
|
||||||
export interface IPrice {
|
export interface IPrice {
|
||||||
id: number
|
id: number
|
||||||
@ -31,11 +34,29 @@ interface PriceListProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function PriceList({click, activeItem}: PriceListProps): JSX.Element {
|
function PriceList({click, activeItem}: PriceListProps): JSX.Element {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [activePriceItem, setActivePriceItem] = useState<number | null>(activeItem)
|
||||||
|
|
||||||
|
const priceItemClick = (id: number) => {
|
||||||
|
console.log(id);
|
||||||
|
setActivePriceItem(id)
|
||||||
|
const activePriceItem = prices.find((item) => item.id === Number(id))
|
||||||
|
if (activePriceItem) {
|
||||||
|
dispatch(
|
||||||
|
actions.payment.update({
|
||||||
|
selectedPrice: activePriceItem.value
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
click()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.container}`}>
|
<div className={`${styles.container}`}>
|
||||||
{prices.map((price, idx) => (
|
{prices.map((price, idx) => (
|
||||||
<PriceItem active={price.id === activeItem} key={idx} value={price.value} id={price.id} click={click} />
|
<PriceItem active={price.id === activePriceItem} key={idx} value={price.value} id={price.id} click={priceItemClick} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -31,7 +31,7 @@ function PriceListPage(): JSX.Element {
|
|||||||
<UserHeader email={email} />
|
<UserHeader email={email} />
|
||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`}>
|
||||||
<Title className={styles.title} variant='h2'>{t('choose_your_own_fee')}</Title>
|
<Title className={styles.title} variant='h2'>{t('choose_your_own_fee')}</Title>
|
||||||
<p className={styles.slogan}>{t('should_not_get', { strongText: <strong>{t('money')}</strong> })}</p>
|
<p className={styles.slogan}>{t('should_not_get', { strongText: <strong>{t('aura.web.price_selection')}</strong> })}</p>
|
||||||
<div className={styles['emails-list-container']}>
|
<div className={styles['emails-list-container']}>
|
||||||
<EmailsList />
|
<EmailsList />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import CallToAction from "../CallToAction";
|
|||||||
import routes from "@/routes";
|
import routes from "@/routes";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import Header from "../Header";
|
import Header from "../Header";
|
||||||
|
import SpecialWelcomeOffer from "../SpecialWelcomeOffer";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
const currency = Currency.USD;
|
const currency = Currency.USD;
|
||||||
const locale = Locale.EN;
|
const locale = Locale.EN;
|
||||||
@ -24,12 +26,17 @@ const paymentItems = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
function SubscriptionPage(): JSX.Element {
|
function SubscriptionPage(): JSX.Element {
|
||||||
|
const [isOpenModal, setIsOpenModal] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const email = useSelector(selectors.selectEmail);
|
const email = useSelector(selectors.selectEmail);
|
||||||
const itemPrice = useSelector(selectors.selectPlanById(itemPriceId));
|
const itemPrice = useSelector(selectors.selectPlanById(itemPriceId));
|
||||||
|
const selectedPrice = useSelector(selectors.selectSelectedPrice);
|
||||||
|
if (selectedPrice || selectedPrice === 0) {
|
||||||
|
paymentItems[0].price = selectedPrice;
|
||||||
|
}
|
||||||
const handleClick = () => navigate(routes.client.paymentMethod());
|
const handleClick = () => navigate(routes.client.paymentMethod());
|
||||||
const handleCross = () => navigate(routes.client.home());
|
const handleCross = () => setIsOpenModal(true);
|
||||||
const policyLink = (
|
const policyLink = (
|
||||||
<a href="https://aura.wit.life/" target="_blank" rel="noopener noreferrer">
|
<a href="https://aura.wit.life/" target="_blank" rel="noopener noreferrer">
|
||||||
{t("subscription_policy")}
|
{t("subscription_policy")}
|
||||||
@ -38,6 +45,7 @@ function SubscriptionPage(): JSX.Element {
|
|||||||
console.log({ itemPrice });
|
console.log({ itemPrice });
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<SpecialWelcomeOffer open={isOpenModal} onClose={handleClick} />
|
||||||
<Header classCross={styles.cross} clickCross={handleCross} />
|
<Header classCross={styles.cross} clickCross={handleCross} />
|
||||||
<UserHeader email={email} />
|
<UserHeader email={email} />
|
||||||
<section className="page">
|
<section className="page">
|
||||||
|
|||||||
@ -32,12 +32,12 @@ export default {
|
|||||||
unexpected_error: 'Sorry, an unexpected error has occurred.',
|
unexpected_error: 'Sorry, an unexpected error has occurred.',
|
||||||
oops: "Oops!",
|
oops: "Oops!",
|
||||||
total_today: "Total today",
|
total_today: "Total today",
|
||||||
charged_only: "You will be charged only $1 for your 7-day trial. We'll email you a reminder before your trial period ends. Cancel anytime.",
|
charged_only: "You will be charged only <price> for your 7-day trial. We'll email you a reminder before your trial period ends. Cancel anytime.",
|
||||||
purposes: "For entertaiment purposes only.",
|
purposes: "For entertaiment purposes only.",
|
||||||
get_access: "Get access",
|
get_access: "Get access",
|
||||||
subscription_text: "By proceeding, you agree that if you do not cancel your subscription before the end of the 7-day trial period, you will be automatically charged nineteen US dollars zero cents every 2 weeks until you cancel the subscription in the settings. Learn more about cancellation and refund policy in <policyLink>",
|
subscription_text: "By proceeding, you agree that if you do not cancel your subscription before the end of the 7-day trial period, you will be automatically charged nineteen US dollars zero cents every 2 weeks until you cancel the subscription in the settings. Learn more about cancellation and refund policy in <policyLink>",
|
||||||
subscription_policy: "Subscription policy",
|
subscription_policy: "Subscription policy",
|
||||||
company_name: "Wit LLC, California, US",
|
company_name: "Wit Apps LLC, California, US",
|
||||||
choose_payment: "Choose Payment Method",
|
choose_payment: "Choose Payment Method",
|
||||||
or: "OR",
|
or: "OR",
|
||||||
card: "Credit / Debit Card",
|
card: "Credit / Debit Card",
|
||||||
|
|||||||
@ -93,7 +93,7 @@ export const hasNavigation = (path: string) =>
|
|||||||
export const hasNoNavigation = (path: string) => !hasNavigation(path);
|
export const hasNoNavigation = (path: string) => !hasNavigation(path);
|
||||||
|
|
||||||
export const withCrossButtonRoutes = [
|
export const withCrossButtonRoutes = [
|
||||||
routes.client.attention(),
|
// routes.client.attention(),
|
||||||
routes.client.subscription(),
|
routes.client.subscription(),
|
||||||
];
|
];
|
||||||
export const hasCrossButton = (path: string) =>
|
export const hasCrossButton = (path: string) =>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user