Merge branch 'preview/discount-pages' into 'main'
Preview/discount pages See merge request witapp/aura-webapp!50
This commit is contained in:
commit
bd995211c5
@ -1,37 +1,43 @@
|
|||||||
import routes from "@/routes"
|
import routes from "@/routes";
|
||||||
import { AuthToken } from "../types"
|
import { AuthToken } from "../types";
|
||||||
import { User } from "./User"
|
import { User } from "./User";
|
||||||
import { getBaseHeaders } from "../utils"
|
import { getBaseHeaders } from "../utils";
|
||||||
|
|
||||||
export interface Payload {
|
export interface PayloadRegisterByEmail {
|
||||||
email: string
|
email: string;
|
||||||
timezone: string
|
timezone: string;
|
||||||
locale: string
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PayloadAuthWithJWT {
|
||||||
|
jwt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Payload = PayloadRegisterByEmail | PayloadAuthWithJWT;
|
||||||
|
|
||||||
export interface Response {
|
export interface Response {
|
||||||
auth: {
|
auth: {
|
||||||
token: AuthToken
|
token: AuthToken;
|
||||||
payload: JwtPayload
|
payload: JwtPayload;
|
||||||
user: User
|
user: User;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JwtPayload {
|
export interface JwtPayload {
|
||||||
sub: number
|
sub: number;
|
||||||
email: string
|
email: string;
|
||||||
loc: string
|
loc: string;
|
||||||
tz: number
|
tz: number;
|
||||||
state: string
|
state: string;
|
||||||
iat: number
|
iat: number;
|
||||||
exp: number
|
exp: number;
|
||||||
jti: string
|
jti: string;
|
||||||
type: string
|
type: string;
|
||||||
iss: string
|
iss: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createRequest = ({ locale, timezone, email }: Payload): Request => {
|
export const createRequest = (payload: Payload): Request => {
|
||||||
const url = new URL(routes.server.token())
|
const url = new URL(routes.server.token());
|
||||||
const body = JSON.stringify({ auth: { locale, timezone, email }})
|
const body = JSON.stringify({ auth: { ...payload } });
|
||||||
return new Request(url, { method: 'POST', headers: getBaseHeaders(), body })
|
return new Request(url, { method: "POST", headers: getBaseHeaders(), body });
|
||||||
}
|
};
|
||||||
|
|||||||
@ -1,28 +1,41 @@
|
|||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo } from "react";
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { actions, selectors } from '../store'
|
import { actions, selectors } from "../store";
|
||||||
import { AuthToken, User } from '../api'
|
import { AuthToken, User } from "../api";
|
||||||
import { AuthContext } from './AuthContext'
|
import { AuthContext } from "./AuthContext";
|
||||||
|
|
||||||
export function AuthProvider({ children }: React.PropsWithChildren<unknown>): JSX.Element {
|
export function AuthProvider({
|
||||||
const dispatch = useDispatch()
|
children,
|
||||||
const token = useSelector(selectors.selectToken)
|
}: React.PropsWithChildren<unknown>): JSX.Element {
|
||||||
const user = useSelector(selectors.selectUser)
|
const dispatch = useDispatch();
|
||||||
const signUp = useCallback((token: AuthToken, user: User.User): AuthToken => {
|
const token = useSelector(selectors.selectToken);
|
||||||
dispatch(actions.token.update(token))
|
const user = useSelector(selectors.selectUser);
|
||||||
dispatch(actions.user.update(user))
|
const signUp = useCallback(
|
||||||
return token
|
(token: AuthToken, user: User.User): AuthToken => {
|
||||||
}, [dispatch])
|
dispatch(actions.token.update(token));
|
||||||
const logout = useCallback(() => dispatch(actions.reset()), [dispatch])
|
dispatch(actions.user.update(user));
|
||||||
const auth = useMemo(() => ({
|
dispatch(actions.form.addEmail(user.email));
|
||||||
signUp,
|
if (user.profile.birthday?.length) {
|
||||||
logout,
|
dispatch(actions.form.addDate(user.profile.birthday.split(" ")[0]));
|
||||||
token,
|
dispatch(
|
||||||
user: user.id ? user : null
|
actions.form.addTime(
|
||||||
}), [token, user, signUp, logout])
|
new Date(user.profile.birthday).toLocaleTimeString()
|
||||||
return (
|
)
|
||||||
<AuthContext.Provider value={auth}>
|
);
|
||||||
{children}
|
}
|
||||||
</AuthContext.Provider>
|
return token;
|
||||||
)
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
const logout = useCallback(() => dispatch(actions.reset()), [dispatch]);
|
||||||
|
const auth = useMemo(
|
||||||
|
() => ({
|
||||||
|
signUp,
|
||||||
|
logout,
|
||||||
|
token,
|
||||||
|
user: user.id ? user : null,
|
||||||
|
}),
|
||||||
|
[token, user, signUp, logout]
|
||||||
|
);
|
||||||
|
return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
Outlet,
|
Outlet,
|
||||||
useLocation,
|
useLocation,
|
||||||
useNavigate,
|
useNavigate,
|
||||||
|
useSearchParams,
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import { useAuth } from "@/auth";
|
import { useAuth } from "@/auth";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
@ -112,7 +113,9 @@ function App(): JSX.Element {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { token, user } = useAuth();
|
const { token, user, signUp } = useAuth();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const jwtToken = searchParams.get("token");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isProduction) return;
|
if (!isProduction) return;
|
||||||
@ -137,6 +140,18 @@ function App(): JSX.Element {
|
|||||||
|
|
||||||
const { data } = useApiCall<Asset[]>(assetsData);
|
const { data } = useApiCall<Asset[]>(assetsData);
|
||||||
|
|
||||||
|
// jwt auth
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
if (!jwtToken) return;
|
||||||
|
const auth = await api.auth({ jwt: jwtToken });
|
||||||
|
const {
|
||||||
|
auth: { token, user },
|
||||||
|
} = auth;
|
||||||
|
signUp(token, user);
|
||||||
|
})();
|
||||||
|
}, [api, jwtToken, signUp]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!token.length || !user) return;
|
if (!token.length || !user) return;
|
||||||
@ -185,8 +200,11 @@ function App(): JSX.Element {
|
|||||||
|
|
||||||
// set user device type
|
// set user device type
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
|
const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
||||||
|
if (isIOS) {
|
||||||
dispatch(actions.userConfig.addDeviceType(EUserDeviceType.ios));
|
dispatch(actions.userConfig.addDeviceType(EUserDeviceType.ios));
|
||||||
|
} else {
|
||||||
|
dispatch(actions.userConfig.addDeviceType(EUserDeviceType.android));
|
||||||
}
|
}
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
@ -473,7 +491,6 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element {
|
|||||||
}, [dataItems]);
|
}, [dataItems]);
|
||||||
|
|
||||||
const onCloseFullDataModal = (_birthDate: string) => {
|
const onCloseFullDataModal = (_birthDate: string) => {
|
||||||
console.log("onCloseFullDataModal", _birthDate);
|
|
||||||
dispatch(actions.form.addDate(_birthDate));
|
dispatch(actions.form.addDate(_birthDate));
|
||||||
setIsShowFullDataModal(getIsShowFullDataModal(dataItems));
|
setIsShowFullDataModal(getIsShowFullDataModal(dataItems));
|
||||||
};
|
};
|
||||||
@ -584,8 +601,7 @@ function PrivateOutlet(): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function PrivateSubscriptionOutlet(): JSX.Element {
|
function PrivateSubscriptionOutlet(): JSX.Element {
|
||||||
// const isProduction = import.meta.env.MODE === "production";
|
const isProduction = import.meta.env.MODE === "production";
|
||||||
const isProduction = false;
|
|
||||||
const status = useSelector(selectors.selectStatus);
|
const status = useSelector(selectors.selectStatus);
|
||||||
return status === "subscribed" || !isProduction ? (
|
return status === "subscribed" || !isProduction ? (
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
|||||||
@ -41,6 +41,9 @@ function EmailEnterPage(): JSX.Element {
|
|||||||
const timezone = getClientTimezone();
|
const timezone = getClientTimezone();
|
||||||
const locale = i18n.language;
|
const locale = i18n.language;
|
||||||
const { subPlan } = useParams();
|
const { subPlan } = useParams();
|
||||||
|
const { gender, flowChoice, birthPlace } = useSelector(
|
||||||
|
selectors.selectQuestionnaire
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (subPlan) {
|
if (subPlan) {
|
||||||
@ -111,7 +114,15 @@ function EmailEnterPage(): JSX.Element {
|
|||||||
} = auth;
|
} = auth;
|
||||||
signUp(token, user);
|
signUp(token, user);
|
||||||
const payload = {
|
const payload = {
|
||||||
user: { profile_attributes: { birthday } },
|
user: {
|
||||||
|
profile_attributes: {
|
||||||
|
birthday,
|
||||||
|
gender,
|
||||||
|
full_name: name,
|
||||||
|
relationship_status: flowChoice,
|
||||||
|
},
|
||||||
|
birthplace_attributes: { address: birthPlace },
|
||||||
|
},
|
||||||
token,
|
token,
|
||||||
};
|
};
|
||||||
const updatedUser = await api.updateUser(payload).catch((error) => {
|
const updatedUser = await api.updateUser(payload).catch((error) => {
|
||||||
|
|||||||
@ -15,23 +15,23 @@ import {
|
|||||||
} from "@/services/zodiac-sign";
|
} from "@/services/zodiac-sign";
|
||||||
import { actions, selectors } from "@/store";
|
import { actions, selectors } from "@/store";
|
||||||
import { getRandomArbitrary } from "@/services/random-value";
|
import { getRandomArbitrary } from "@/services/random-value";
|
||||||
import Title from "../Title";
|
// import Title from "../Title";
|
||||||
// import { UserDailyForecast } from "@/api/resources/UserDailyForecasts";
|
// import { UserDailyForecast } from "@/api/resources/UserDailyForecasts";
|
||||||
import { EPathsFromHome } from "@/store/siteConfig";
|
import { EPathsFromHome } from "@/store/siteConfig";
|
||||||
import { buildFilename, saveFile } from "../WallpaperPage/utils";
|
import { buildFilename, saveFile } from "../WallpaperPage/utils";
|
||||||
import Onboarding from "../Onboarding";
|
import Onboarding from "../Onboarding";
|
||||||
import TextWithFinger from "../TextWithFinger";
|
import TextWithFinger from "../TextWithFinger";
|
||||||
import Slider from "../Slider";
|
// import Slider from "../Slider";
|
||||||
import BestiesHoroscopeSlider, { Horoscope } from "../BestiesHoroscopeSlider";
|
// import BestiesHoroscopeSlider, { Horoscope } from "../BestiesHoroscopeSlider";
|
||||||
import PredictionMoonsSlider, {
|
// import PredictionMoonsSlider, {
|
||||||
IPredictionMoon,
|
// IPredictionMoon,
|
||||||
} from "../PredictionMoonsSlider";
|
// } from "../PredictionMoonsSlider";
|
||||||
import { predictionMoonsPeriods } from "@/data";
|
import { predictionMoonsPeriods } from "@/data";
|
||||||
import WallpapersZodiacSign from "../WallpapersZodiacSign";
|
// import WallpapersZodiacSign from "../WallpapersZodiacSign";
|
||||||
import ThermalSlider from "../ThermalSlider";
|
// import ThermalSlider from "../ThermalSlider";
|
||||||
import MoonPhaseTracker from "../MoonPhaseTracker";
|
// import MoonPhaseTracker from "../MoonPhaseTracker";
|
||||||
import EnergyVampirism from "../EnergyVampirism";
|
// import EnergyVampirism from "../EnergyVampirism";
|
||||||
import NameHoroscopeSlider from "../NameHoroscopeSlider";
|
// import NameHoroscopeSlider from "../NameHoroscopeSlider";
|
||||||
|
|
||||||
const buttonTextFormatter = (text: string): JSX.Element => {
|
const buttonTextFormatter = (text: string): JSX.Element => {
|
||||||
const sentences = text.split(".");
|
const sentences = text.split(".");
|
||||||
@ -56,6 +56,7 @@ function HomePage(): JSX.Element {
|
|||||||
const zodiacSign = getZodiacSignByDate(birthdate);
|
const zodiacSign = getZodiacSignByDate(birthdate);
|
||||||
const [asset, setAsset] = useState<Asset>();
|
const [asset, setAsset] = useState<Asset>();
|
||||||
const [moonsAssets, setMoonsAssets] = useState<Asset[]>([]);
|
const [moonsAssets, setMoonsAssets] = useState<Asset[]>([]);
|
||||||
|
moonsAssets
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
|
||||||
const homeConfig = useSelector(selectors.selectHome);
|
const homeConfig = useSelector(selectors.selectHome);
|
||||||
@ -63,8 +64,10 @@ function HomePage(): JSX.Element {
|
|||||||
const onboardingConfigHome = useSelector(selectors.selectOnboardingHome);
|
const onboardingConfigHome = useSelector(selectors.selectOnboardingHome);
|
||||||
|
|
||||||
const compatibilities = useSelector(selectors.selectCompatibilities);
|
const compatibilities = useSelector(selectors.selectCompatibilities);
|
||||||
|
compatibilities
|
||||||
|
|
||||||
const user = useSelector(selectors.selectUser);
|
const user = useSelector(selectors.selectUser);
|
||||||
|
user
|
||||||
|
|
||||||
const [isShowOnboardingHome, setIsShowOnboardingHome] = useState(
|
const [isShowOnboardingHome, setIsShowOnboardingHome] = useState(
|
||||||
!onboardingConfigHome?.isShown
|
!onboardingConfigHome?.isShown
|
||||||
@ -168,36 +171,36 @@ function HomePage(): JSX.Element {
|
|||||||
saveFile(asset.url.replace("http://", "https://"), buildFilename("1"));
|
saveFile(asset.url.replace("http://", "https://"), buildFilename("1"));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBestiesHoroscope = (item: Horoscope) => {
|
// const handleBestiesHoroscope = (item: Horoscope) => {
|
||||||
const { name, birthDate } = item;
|
// const { name, birthDate } = item;
|
||||||
navigate(
|
// navigate(
|
||||||
`${routes.client.horoscopeBestiesResult()}?name=${name}&birthDate=${birthDate}`
|
// `${routes.client.horoscopeBestiesResult()}?name=${name}&birthDate=${birthDate}`
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleThermal = (item: Horoscope) => {
|
// const handleThermal = (item: Horoscope) => {
|
||||||
const { name, birthDate } = item;
|
// const { name, birthDate } = item;
|
||||||
navigate(
|
// navigate(
|
||||||
`${routes.client.thermalResult()}?name=${name}&birthDate=${birthDate}`
|
// `${routes.client.thermalResult()}?name=${name}&birthDate=${birthDate}`
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handlePredictionMoon = (item: IPredictionMoon) => {
|
// const handlePredictionMoon = (item: IPredictionMoon) => {
|
||||||
const { period } = item;
|
// const { period } = item;
|
||||||
navigate(`${routes.client.predictionMoonResult()}?period=${period}`);
|
// navigate(`${routes.client.predictionMoonResult()}?period=${period}`);
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleMoonPhaseTracker = () => {
|
// const handleMoonPhaseTracker = () => {
|
||||||
navigate(`${routes.client.moonPhaseTracker()}?period=today`);
|
// navigate(`${routes.client.moonPhaseTracker()}?period=today`);
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleEnergyVampirism = () => {
|
// const handleEnergyVampirism = () => {
|
||||||
navigate(`${routes.client.energyVampirismResult()}?period=today`);
|
// navigate(`${routes.client.energyVampirismResult()}?period=today`);
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleNameHoroscope = (item: IPredictionMoon) => {
|
// const handleNameHoroscope = (item: IPredictionMoon) => {
|
||||||
navigate(`${routes.client.nameHoroscopeResult()}?period=${item.period}`);
|
// navigate(`${routes.client.nameHoroscopeResult()}?period=${item.period}`);
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
@ -287,7 +290,7 @@ function HomePage(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* SLIDERS */}
|
{/* SLIDERS */}
|
||||||
<div className={styles.sliders}>
|
{/* <div className={styles.sliders}>
|
||||||
{!!compatibilities.length && (
|
{!!compatibilities.length && (
|
||||||
<div className={styles["slider"]}>
|
<div className={styles["slider"]}>
|
||||||
<Title variant="h2" className={styles["sliders__title"]}>
|
<Title variant="h2" className={styles["sliders__title"]}>
|
||||||
@ -323,16 +326,16 @@ function HomePage(): JSX.Element {
|
|||||||
))}
|
))}
|
||||||
</Slider>
|
</Slider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
{/* END SLIDERS */}
|
{/* END SLIDERS */}
|
||||||
|
|
||||||
<Title variant="h2" className={styles["sliders__title"]}>
|
{/* <Title variant="h2" className={styles["sliders__title"]}>
|
||||||
{"Energy Vampirism"}
|
{"Energy Vampirism"}
|
||||||
</Title>
|
</Title>
|
||||||
<EnergyVampirism onClick={handleEnergyVampirism} />
|
<EnergyVampirism onClick={handleEnergyVampirism} /> */}
|
||||||
|
|
||||||
{/* SLIDERS */}
|
{/* SLIDERS */}
|
||||||
<div className={styles.sliders}>
|
{/* <div className={styles.sliders}>
|
||||||
<div className={styles["slider"]}>
|
<div className={styles["slider"]}>
|
||||||
<Title variant="h2" className={styles["sliders__title"]}>
|
<Title variant="h2" className={styles["sliders__title"]}>
|
||||||
{t("Your Name's Horoscope")}
|
{t("Your Name's Horoscope")}
|
||||||
@ -349,16 +352,16 @@ function HomePage(): JSX.Element {
|
|||||||
))}
|
))}
|
||||||
</Slider>
|
</Slider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
{/* END SLIDERS */}
|
{/* END SLIDERS */}
|
||||||
|
|
||||||
<Title variant="h2" className={styles["sliders__title"]}>
|
{/* <Title variant="h2" className={styles["sliders__title"]}>
|
||||||
{"AI-based unique Walpapers"}
|
{"AI-based unique Walpapers"}
|
||||||
</Title>
|
</Title>
|
||||||
<WallpapersZodiacSign />
|
<WallpapersZodiacSign /> */}
|
||||||
|
|
||||||
{/* SLIDERS */}
|
{/* SLIDERS */}
|
||||||
<div className={styles.sliders}>
|
{/* <div className={styles.sliders}>
|
||||||
{!!compatibilities.length && (
|
{!!compatibilities.length && (
|
||||||
<div className={styles["slider"]}>
|
<div className={styles["slider"]}>
|
||||||
<Title variant="h2" className={styles["sliders__title"]}>
|
<Title variant="h2" className={styles["sliders__title"]}>
|
||||||
@ -377,10 +380,10 @@ function HomePage(): JSX.Element {
|
|||||||
</Slider>
|
</Slider>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div> */}
|
||||||
{/* END SLIDERS */}
|
{/* END SLIDERS */}
|
||||||
|
|
||||||
<MoonPhaseTracker onClick={handleMoonPhaseTracker} />
|
{/* <MoonPhaseTracker onClick={handleMoonPhaseTracker} /> */}
|
||||||
|
|
||||||
{/* <div className={styles["content__daily-forecast"]}>
|
{/* <div className={styles["content__daily-forecast"]}>
|
||||||
{dailyForecast &&
|
{dailyForecast &&
|
||||||
|
|||||||
@ -17,7 +17,6 @@ function OnboardingPage() {
|
|||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("onboardingTitles", activeIndexTitle);
|
|
||||||
setPeriodClassName("to-nontransparent");
|
setPeriodClassName("to-nontransparent");
|
||||||
classNameTimeOut.current = setTimeout(() => {
|
classNameTimeOut.current = setTimeout(() => {
|
||||||
setPeriodClassName("to-transparent");
|
setPeriodClassName("to-transparent");
|
||||||
|
|||||||
@ -22,6 +22,7 @@ function BirthdateCustomAnswer({
|
|||||||
const questionnaire = useSelector(selectors.selectQuestionnaire);
|
const questionnaire = useSelector(selectors.selectQuestionnaire);
|
||||||
const birthdateFromStore =
|
const birthdateFromStore =
|
||||||
affiliation === "self" ? selfBirthdate : questionnaire.partnerBirthdate;
|
affiliation === "self" ? selfBirthdate : questionnaire.partnerBirthdate;
|
||||||
|
|
||||||
const [birthdate, setBirthdate] = useState(birthdateFromStore);
|
const [birthdate, setBirthdate] = useState(birthdateFromStore);
|
||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
const handleValid = (_birthdate: string) => {
|
const handleValid = (_birthdate: string) => {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ function BirthtimeCustomAnswer({
|
|||||||
const questionnaire = useSelector(selectors.selectQuestionnaire);
|
const questionnaire = useSelector(selectors.selectQuestionnaire);
|
||||||
const birthtimeFromStore =
|
const birthtimeFromStore =
|
||||||
affiliation === "self" ? selfBirthtime : questionnaire.partnerBirthtime;
|
affiliation === "self" ? selfBirthtime : questionnaire.partnerBirthtime;
|
||||||
|
|
||||||
const [birthtime, setBirthtime] = useState(birthtimeFromStore);
|
const [birthtime, setBirthtime] = useState(birthtimeFromStore);
|
||||||
|
|
||||||
const handleChange = (_birthtime: string) => {
|
const handleChange = (_birthtime: string) => {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ function TrialChoicePage() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const selectedPrice = useSelector(selectors.selectSelectedPrice);
|
const selectedPrice = useSelector(selectors.selectSelectedPrice);
|
||||||
const homeConfig = useSelector(selectors.selectHome);
|
const homeConfig = useSelector(selectors.selectHome);
|
||||||
|
const email = useSelector(selectors.selectEmail);
|
||||||
const [subPlans, setSubPlans] = useState<ISubscriptionPlan[]>([]);
|
const [subPlans, setSubPlans] = useState<ISubscriptionPlan[]>([]);
|
||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
|
|
||||||
@ -117,6 +118,7 @@ function TrialChoicePage() {
|
|||||||
direction="right-left"
|
direction="right-left"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<p className={styles.email}>{email}</p>
|
||||||
<MainButton
|
<MainButton
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
|
|||||||
@ -121,3 +121,7 @@
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.email {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
@ -3,15 +3,24 @@ import DiscountExpires from "../DiscountExpires";
|
|||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
|
|
||||||
interface IHeaderProps {
|
interface IHeaderProps {
|
||||||
|
buttonText?: string;
|
||||||
|
buttonClassName?: string;
|
||||||
buttonClick: () => void;
|
buttonClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Header({ buttonClick }: IHeaderProps) {
|
function Header({
|
||||||
|
buttonClick,
|
||||||
|
buttonText = "get my reading",
|
||||||
|
buttonClassName = "",
|
||||||
|
}: IHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<DiscountExpires />
|
<DiscountExpires />
|
||||||
<CustomButton className={styles.button} onClick={buttonClick}>
|
<CustomButton
|
||||||
get my reading
|
className={`${styles.button} ${buttonClassName}`}
|
||||||
|
onClick={buttonClick}
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,6 +8,8 @@ interface IYourReadingProps {
|
|||||||
gender: string;
|
gender: string;
|
||||||
zodiacSign: string;
|
zodiacSign: string;
|
||||||
singleOrWithPartner: "single" | "partner";
|
singleOrWithPartner: "single" | "partner";
|
||||||
|
buttonText?: string;
|
||||||
|
callToActionText?: string;
|
||||||
buttonClick: () => void;
|
buttonClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,6 +17,8 @@ function YourReading({
|
|||||||
gender,
|
gender,
|
||||||
zodiacSign,
|
zodiacSign,
|
||||||
singleOrWithPartner = "single",
|
singleOrWithPartner = "single",
|
||||||
|
buttonText = "get my reading",
|
||||||
|
callToActionText = "To read the full reading you need get access",
|
||||||
buttonClick,
|
buttonClick,
|
||||||
}: IYourReadingProps) {
|
}: IYourReadingProps) {
|
||||||
const [points, setPoints] = useState(yourReadingList);
|
const [points, setPoints] = useState(yourReadingList);
|
||||||
@ -60,9 +64,9 @@ function YourReading({
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles["cover-container"]}>
|
<div className={styles["cover-container"]}>
|
||||||
<div className={styles["cover"]}></div>
|
<div className={styles["cover"]}></div>
|
||||||
<p>To read the full reading you need get access</p>
|
<p>{callToActionText}</p>
|
||||||
<CustomButton className={styles.button} onClick={buttonClick}>
|
<CustomButton className={styles.button} onClick={buttonClick}>
|
||||||
get my reading
|
{buttonText}
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -52,7 +52,11 @@ function TryAppPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`}>
|
||||||
<Header buttonClick={downloadApp} />
|
<Header
|
||||||
|
buttonClick={downloadApp}
|
||||||
|
buttonText="get my reading in the app"
|
||||||
|
buttonClassName={styles["header-button"]}
|
||||||
|
/>
|
||||||
{singleOrWithPartner === "partner" && (
|
{singleOrWithPartner === "partner" && (
|
||||||
<WithPartnerInformation
|
<WithPartnerInformation
|
||||||
zodiacSign={zodiacSign}
|
zodiacSign={zodiacSign}
|
||||||
@ -90,7 +94,7 @@ function TryAppPage() {
|
|||||||
alt="Download on the app store"
|
alt="Download on the app store"
|
||||||
onClick={downloadApp}
|
onClick={downloadApp}
|
||||||
/>
|
/>
|
||||||
<span className={styles["download-app-title"]}>1. Download App</span>
|
<span className={styles["download-app-title"]}>2. Enter Your Access Code</span>
|
||||||
<div className={styles["code-container"]}>FV1HBP</div>
|
<div className={styles["code-container"]}>FV1HBP</div>
|
||||||
<p className={styles["code-description"]}>
|
<p className={styles["code-description"]}>
|
||||||
Enter your access code in the app to access Your Personalized Reading.
|
Enter your access code in the app to access Your Personalized Reading.
|
||||||
@ -102,6 +106,8 @@ function TryAppPage() {
|
|||||||
zodiacSign={zodiacSign}
|
zodiacSign={zodiacSign}
|
||||||
buttonClick={downloadApp}
|
buttonClick={downloadApp}
|
||||||
singleOrWithPartner={singleOrWithPartner}
|
singleOrWithPartner={singleOrWithPartner}
|
||||||
|
callToActionText="To read the full reading you need get access through the app for your iPhone"
|
||||||
|
buttonText="get my reading in the app"
|
||||||
/>
|
/>
|
||||||
<Title
|
<Title
|
||||||
variant="h2"
|
variant="h2"
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
max-width: 270px;
|
max-width: 270px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
animation: 1.5s ease 0s infinite normal none running pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-container {
|
.code-container {
|
||||||
@ -46,3 +47,19 @@
|
|||||||
.title {
|
.title {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-button {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user