diff --git a/public/your-friends.png b/public/your-friends.png new file mode 100644 index 0000000..c979408 Binary files /dev/null and b/public/your-friends.png differ diff --git a/src/components/AttentionPage/index.tsx b/src/components/AttentionPage/index.tsx index 1ffda06..1b69440 100644 --- a/src/components/AttentionPage/index.tsx +++ b/src/components/AttentionPage/index.tsx @@ -5,6 +5,7 @@ import routes from '@/routes' import styles from './styles.module.css' // import CheckboxWithText from '../CheckboxWithText' import SpecialWelcomeOffer from '../SpecialWelcomeOffer' +import MainButton from '../MainButton' // import MainButton from '../MainButton' interface AttentionPageProps { @@ -29,9 +30,11 @@ function AttentionPage({ isOpenModal, onCloseSpecialOffer }: AttentionPageProps) stop {t('aura.attention.title')}

{t('aura.warming_up.body')}

-
+
{/* */} - {t('aura.warming_up.button')} + {/* {t('aura.warming_up.button')} */} + {t('aura.warmin_good.button')} + {t('aura.warmin_bad.button')}
) diff --git a/src/components/AttentionPage/styles.module.css b/src/components/AttentionPage/styles.module.css index e815fc1..4185856 100644 --- a/src/components/AttentionPage/styles.module.css +++ b/src/components/AttentionPage/styles.module.css @@ -17,9 +17,12 @@ font-weight: 700; } -.checkbox-container { - width: 80%; +.buttons-container { + width: 100%; margin: 64px auto 0; + display: flex; + flex-direction: column; + gap: 13px; } .button { diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index bbdba66..f9172a9 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,60 +1,84 @@ -import { useState, useEffect } from 'react' -import { useNavigate, useLocation } from 'react-router-dom' -import { useTranslation } from 'react-i18next' -import routes, { hasCrossButton, hasNavigation, isNotEntrypoint } from '@/routes' -import BackButton from './BackButton' -import iconUrl from './icon.png' -import menuUrl from './menu.png' -import styles from './styles.module.css' +import { useState, useEffect } from "react"; +import { useNavigate, useLocation } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import routes, { + hasCrossButton, + hasNavigation, + isNotEntrypoint, +} from "@/routes"; +import BackButton from "./BackButton"; +import iconUrl from "./icon.png"; +import menuUrl from "./menu.png"; +import styles from "./styles.module.css"; type HeaderProps = { - openMenu?: () => void - showBack?: boolean - showCross?: boolean - classCross?: CSSModuleClasses | string - clickCross?: () => void -} + openMenu?: () => void; + showBack?: boolean; + showCross?: boolean; + classCross?: CSSModuleClasses | string; + clickCross?: () => void; +}; -function Header({ openMenu, showBack, showCross, classCross, clickCross = () => {undefined}, ...props }: HeaderProps & React.HTMLAttributes): JSX.Element { - const { t } = useTranslation() - const navigate = useNavigate() - const location = useLocation() +function Header({ + openMenu, + showBack, + showCross = true, + classCross, + clickCross = () => { + undefined; + }, + ...props +}: HeaderProps & React.HTMLAttributes): JSX.Element { + const { t } = useTranslation(); + const navigate = useNavigate(); + const location = useLocation(); const [initialPath, setInitialPath] = useState(null); const [isNavigated, setIsNavigated] = useState(false); - const showBackButton = isNotEntrypoint(location.pathname) - const showMenuButton = hasNavigation(location.pathname) - const showCrossButton = hasCrossButton(location.pathname) + const showBackButton = isNotEntrypoint(location.pathname); + const showMenuButton = hasNavigation(location.pathname); + const showCrossButton = hasCrossButton(location.pathname); useEffect(() => { if (!initialPath) { - setInitialPath(location.pathname) + setInitialPath(location.pathname); } if (initialPath && location.pathname !== initialPath && !isNavigated) { - setIsNavigated(true) + setIsNavigated(true); } - }, [location.pathname, initialPath, isNavigated]) + }, [location.pathname, initialPath, isNavigated]); const goBack = () => { if (initialPath && isNotEntrypoint(initialPath) && !isNavigated) { - navigate(routes.client.root()) + navigate(routes.client.root()); } else { - navigate(-1) + navigate(-1); } - } + }; return (
- { (showBackButton || showBack) ? : null } -
+ {showBackButton || showBack ? ( + + ) : null} +
logo - {t('app_name')} + {t("app_name")}
- {(showCrossButton || showCross) ? Cross : null} - {showMenuButton ?
- menu -
: null} + {showCrossButton && showCross ? ( + Cross + ) : null} + {showMenuButton ? ( +
+ menu +
+ ) : null}
- ) + ); } -export default Header +export default Header; diff --git a/src/components/SpecialWelcomeOffer/index.tsx b/src/components/SpecialWelcomeOffer/index.tsx index 35c178c..eea012e 100644 --- a/src/components/SpecialWelcomeOffer/index.tsx +++ b/src/components/SpecialWelcomeOffer/index.tsx @@ -1,52 +1,86 @@ -import { useNavigate } from 'react-router-dom' -import { useTranslation } from 'react-i18next' -import Title from '../Title' -import routes from '@/routes' -import styles from './styles.module.css' -import ModalTop from '../ModalTop' -import Header from '../Header' -import { useCallback } from 'react' -import { useDispatch } from 'react-redux' -import { actions } from '@/store' +import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import Title from "../Title"; +import routes from "@/routes"; +import styles from "./styles.module.css"; +import ModalTop from "../ModalTop"; +import Header from "../Header"; +import { useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import MainButton from "../MainButton"; interface ModalTopProps { - open: boolean - onClose?: () => void + open: boolean; + onClose?: () => void; } function SpecialWelcomeOffer({ open, onClose }: ModalTopProps): JSX.Element { - const { t } = useTranslation() - const navigate = useNavigate() - const dispatch = useDispatch() - const updateSelectedPrice = useCallback((selectedPrice: number | null) => { - dispatch(actions.payment.update({ - selectedPrice - })) - }, [dispatch]) + const { t } = useTranslation(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const selectedPrice = useSelector(selectors.selectSelectedPrice); + const halfPrice = (Math.round(selectedPrice || 0) / 2).toFixed(2); + const updateIsDiscount = useCallback((isDiscount: boolean) => { + dispatch( + actions.payment.update({ + isDiscount + }) + ); + }, [dispatch]); const handleNext = () => { - updateSelectedPrice(1) - navigate(routes.client.emailEnter()) - } - + updateIsDiscount(true); + navigate(routes.client.paymentMethod()); + }; return ( <> {open ? ( -
+
- {t('special_welcome_offer')} - {t('get_100_off')} -
- $9.99 - $0.00 + {/* {t('special_welcome_offer')} */} + Your friends + + {t("au.friends.window")} + + + {t("au.get50.only")} + +
+ {Number(halfPrice) > 0 && + <> + ${selectedPrice}{" "} + –${halfPrice} + + } + {!Number(halfPrice) && {t('au.free_trial_web.7_14')}}
- + + $ {halfPrice} – {t("au.try_for.button")} + + { + console.log("click"); + }} + > + Leo + {t("au.more_llc.button")} +
- ): null} + ) : null} - ) + ); } -export default SpecialWelcomeOffer +export default SpecialWelcomeOffer; diff --git a/src/components/SpecialWelcomeOffer/styles.module.css b/src/components/SpecialWelcomeOffer/styles.module.css index 7f26c9c..c52c4e2 100644 --- a/src/components/SpecialWelcomeOffer/styles.module.css +++ b/src/components/SpecialWelcomeOffer/styles.module.css @@ -1,40 +1,73 @@ - - .content { - padding: 0 24px 64px 24px; - display: flex; - flex-direction: column; - align-items: center; - gap: 12px; - padding-top: 28px; + padding: 0 24px 64px 24px; + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + padding-top: 28px; } .welcome-offer { - color: #717171; - font-weight: 500; + color: #717171; + font-weight: 500; } .discount-container { - display: flex; - flex-direction: row; - gap: 16px; - font-size: 24px; - font-weight: 600; + display: flex; + flex-direction: row; + gap: 16px; + font-size: 32px; + font-weight: 600; + margin-bottom: 32px; } .red-price { - color: red; - text-decoration: line-through; + color: red; + text-decoration: line-through; } -.button { - background-color: #69e573; - color: #fff; +.button-green { + background-color: #18d136; + font-weight: 600; + font-size: 21px; + /* color: #fff; border-radius: 26px; width: 100%; max-width: 300px; padding: 12px 0; border: none; font-size: 14px; - margin-top: 16px; -} \ No newline at end of file + margin-top: 16px; */ +} + +.button-black { + font-weight: 600; + font-size: 21px; + position: relative; +} + +.your-friends { + width: 80%; + font-weight: 600; + margin-bottom: 8px; +} + +.get-50-only { + margin-bottom: 0; + font-weight: 700; + color: #ff003d; +} + +.button-icon { + position: absolute; + width: 48px; + top: 50%; + left: 13px; + transform: translateY(-50%); + +} + +.free-trial { + font-size: 22px; + font-weight: 600; +} diff --git a/src/store/index.ts b/src/store/index.ts index 7ca2fcf..56f127e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -4,7 +4,7 @@ import user, { actions as userActions, selectUser } from './user' import form, { actions as formActions, selectors as formSelectors } from './form' import aura, { actions as auraActions } from './aura' import siteConfig, { selectHome, actions as siteConfigActions } from './siteConfig' -import payment, { actions as paymentActions } from './payment' +import payment, { actions as paymentActions, selectIsDiscount } from './payment' import subscriptionPlans, { actions as subscriptionPlasActions, selectPlanById } from './subscriptionPlan' import status, { actions as userStatusActions, selectStatus } from './status' import compatibility, { actions as compatibilityActions } from './compatibility' @@ -44,6 +44,7 @@ export const selectors = { selectUserCallbacksDescription, selectUserCallbacksPrevStat, selectHome, + selectIsDiscount, ...formSelectors, } export type RootState = ReturnType diff --git a/src/store/payment.ts b/src/store/payment.ts index 8cf8135..c4d7de4 100644 --- a/src/store/payment.ts +++ b/src/store/payment.ts @@ -1,28 +1,34 @@ -import { createSlice, createSelector } from '@reduxjs/toolkit' -import type { PayloadAction } from '@reduxjs/toolkit' +import { createSlice, createSelector } from "@reduxjs/toolkit"; +import type { PayloadAction } from "@reduxjs/toolkit"; interface IPayment { - selectedPrice: number | null + selectedPrice: number | null; + isDiscount: boolean; } const initialState: IPayment = { - selectedPrice: null -} + selectedPrice: null, + isDiscount: false, +}; const paymentSlice = createSlice({ - name: 'payment', + name: "payment", initialState, reducers: { update(state, action: PayloadAction>) { - return { ...state, ...action.payload } + return { ...state, ...action.payload }; }, }, - extraReducers: (builder) => builder.addCase('reset', () => initialState), -}) + extraReducers: (builder) => builder.addCase("reset", () => initialState), +}); -export const { actions } = paymentSlice +export const { actions } = paymentSlice; export const selectSelectedPrice = createSelector( (state: { payment: IPayment }) => state.payment.selectedPrice, (payment) => payment -) -export default paymentSlice.reducer +); +export const selectIsDiscount = createSelector( + (state: { payment: IPayment }) => state.payment.isDiscount, + (payment) => payment +); +export default paymentSlice.reducer;