feat: wallpaper page zodiac metas, cross compatibility result page, fix button start breath page, fix percents user aura

This commit is contained in:
gofnnp 2023-09-25 22:58:28 +04:00
parent d6a5a3a458
commit 8b78a612fb
10 changed files with 146 additions and 27 deletions

View File

@ -18,7 +18,8 @@ import {
AICompats, AICompats,
AIRequests, AIRequests,
UserCallbacks, UserCallbacks,
Translations Translations,
Zodiacs
} from './resources' } from './resources'
const api = { const api = {
@ -44,6 +45,7 @@ const api = {
createUserCallbacks: createMethod<UserCallbacks.PayloadPost, UserCallbacks.Response>(UserCallbacks.createRequestPost), createUserCallbacks: createMethod<UserCallbacks.PayloadPost, UserCallbacks.Response>(UserCallbacks.createRequestPost),
getUserCallbacks: createMethod<UserCallbacks.PayloadGet, UserCallbacks.Response>(UserCallbacks.createRequestGet), getUserCallbacks: createMethod<UserCallbacks.PayloadGet, UserCallbacks.Response>(UserCallbacks.createRequestGet),
getTranslations: createMethod<Translations.Payload, Translations.Response>(Translations.createRequest), getTranslations: createMethod<Translations.Payload, Translations.Response>(Translations.createRequest),
getZodiacs: createMethod<Zodiacs.Payload, Zodiacs.Response>(Zodiacs.createRequest),
} }
export type ApiContextValue = typeof api export type ApiContextValue = typeof api

View File

@ -0,0 +1,33 @@
import routes from "@/routes";
import { AuthPayload } from "../types";
import { getAuthHeaders } from "../utils";
export interface Payload extends AuthPayload {
zodiac: string;
}
export interface Response {
zodiac: Zodiac;
}
export interface Zodiac {
sign: string;
metas: ZodiacMeta[];
aurapic: string | null;
paragraphs: ZodiacParagraph[];
}
export interface ZodiacMeta {
value: number;
label: string;
}
export interface ZodiacParagraph {
title: string;
content: string[] | ZodiacParagraph[];
}
export const createRequest = ({ zodiac, token }: Payload): Request => {
const url = new URL(routes.server.zodiacs(zodiac));
return new Request(url, { method: "GET", headers: getAuthHeaders(token) });
};

View File

@ -17,3 +17,4 @@ export * as AICompats from './AICompats'
export * as AIRequests from './AIRequests' export * as AIRequests from './AIRequests'
export * as UserCallbacks from './UserCallbacks' export * as UserCallbacks from './UserCallbacks'
export * as Translations from './Translations' export * as Translations from './Translations'
export * as Zodiacs from './Zodiacs'

View File

@ -168,7 +168,7 @@ function BreathPage(): JSX.Element {
</div> </div>
)} )}
<FullScreenModal isOpen={isOpenModal}> <FullScreenModal isOpen={isOpenModal}>
<StartBreathModalChild handleBegin={beginBreath} /> <StartBreathModalChild handleBegin={beginBreath} isShowNavbar={showNavbarFooter} />
</FullScreenModal> </FullScreenModal>
{!isOpenModal && !isShowPreview && ( {!isOpenModal && !isShowPreview && (
<div className={styles["text-container"]}> <div className={styles["text-container"]}>

View File

@ -40,6 +40,8 @@ function CompatResultPage(): JSX.Element {
} }
}; };
const handleCompatibility = () => navigate(routes.client.compatibility());
const loadData = useCallback(async () => { const loadData = useCallback(async () => {
const right_bday = const right_bday =
typeof rightUser.birthDate === "string" typeof rightUser.birthDate === "string"
@ -78,10 +80,16 @@ function CompatResultPage(): JSX.Element {
useApiCall<AICompats.ICompat | AIRequests.IAiRequest>(loadData); useApiCall<AICompats.ICompat | AIRequests.IAiRequest>(loadData);
const getPaddingBottomPage = () => { const getPaddingBottomPage = () => {
if (homeConfig.pathFromHome === EPathsFromHome.compatibility && showNavbarFooter) return "246px"; if (
homeConfig.pathFromHome === EPathsFromHome.compatibility &&
showNavbarFooter
)
return "246px";
if (showNavbarFooter) return "164px"; if (showNavbarFooter) return "164px";
if (homeConfig.pathFromHome === EPathsFromHome.compatibility)
return "174px";
return "108px"; return "108px";
} };
return ( return (
<section <section
@ -96,9 +104,7 @@ function CompatResultPage(): JSX.Element {
}} }}
/> />
</FullScreenModal> </FullScreenModal>
{text !== "Loading..." && !showNavbarFooter && ( <div className={styles.cross} onClick={handleCompatibility}></div>
<div className={styles.cross} onClick={handleNext}></div>
)}
<div className={styles["title-container"]}> <div className={styles["title-container"]}>
<Title variant="h2">{t("you_and", { user: rightUser.name })}</Title> <Title variant="h2">{t("you_and", { user: rightUser.name })}</Title>
</div> </div>
@ -110,7 +116,10 @@ function CompatResultPage(): JSX.Element {
</div> </div>
{text !== "Loading..." && {text !== "Loading..." &&
homeConfig.pathFromHome === EPathsFromHome.compatibility && ( homeConfig.pathFromHome === EPathsFromHome.compatibility && (
<div className={styles["button-container"]} style={{ bottom: showNavbarFooter ? "75px" : "0" }}> <div
className={styles["button-container"]}
style={{ bottom: showNavbarFooter ? "72px" : "0" }}
>
<p className={styles["button-container__text"]}> <p className={styles["button-container__text"]}>
{t("now-you-know")} {t("now-you-know")}
</p> </p>

View File

@ -4,15 +4,19 @@ import styles from "./styles.module.css";
interface IStartBreathModalChildProps { interface IStartBreathModalChildProps {
handleBegin: () => void; handleBegin: () => void;
isShowNavbar: boolean;
} }
function StartBreathModalChild({ function StartBreathModalChild({
handleBegin, handleBegin,
isShowNavbar=false
}: IStartBreathModalChildProps): JSX.Element { }: IStartBreathModalChildProps): JSX.Element {
const { t } = useTranslation(); const { t } = useTranslation();
console.log(isShowNavbar);
return ( return (
<section className={`${styles["start-breath"]} page`}> <section className={`${styles["start-breath"]} page ${isShowNavbar ? styles["show-navbar"] : ""}`}>
{/* <div className={styles.cross} onClick={handleBegin}></div> */} {/* <div className={styles.cross} onClick={handleBegin}></div> */}
<div className={styles.text}> <div className={styles.text}>
<Title variant="h4" className={styles["breathe-title"]}> <Title variant="h4" className={styles["breathe-title"]}>

View File

@ -24,6 +24,16 @@
border: none; border: none;
} }
.show-navbar {
padding-top: 52px;
justify-content: flex-start;
}
.show-navbar .begin {
position: absolute;
bottom: 172px;
}
.symbol { .symbol {
opacity: 0; opacity: 0;
will-change: opacity; will-change: opacity;

View File

@ -4,16 +4,21 @@ import { useAuth } from "@/auth";
import { useApi, useApiCall, Assets, DailyForecasts } from "@/api"; import { useApi, useApiCall, Assets, DailyForecasts } from "@/api";
import { saveFile, buildFilename } from "./utils"; import { saveFile, buildFilename } from "./utils";
import Loader, { LoaderColor } from "../Loader"; import Loader, { LoaderColor } from "../Loader";
import "./styles.css"; 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 { getCategoryIdByZodiacSign, getZodiacSignByDate } from "@/services/zodiac-sign"; import {
getCategoryIdByZodiacSign,
getZodiacSignByDate,
} from "@/services/zodiac-sign";
import { Zodiac } from "@/api/resources/Zodiacs";
type Forecasts = DailyForecasts.Forecast[]; type Forecasts = DailyForecasts.Forecast[];
type PersonalAssets = Assets.Asset[]; type PersonalAssets = Assets.Asset[];
interface WallpaperData { interface WallpaperData {
assets: PersonalAssets; assets: PersonalAssets;
forecasts: Forecasts; forecasts: Forecasts;
zodiac: Zodiac;
} }
function WallpaperPage(): JSX.Element { function WallpaperPage(): JSX.Element {
@ -22,7 +27,7 @@ function WallpaperPage(): JSX.Element {
const locale = i18n.language; const locale = i18n.language;
const token = const token =
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw";
const { const {
user, user,
// token // token
@ -30,15 +35,16 @@ function WallpaperPage(): JSX.Element {
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const category = user?.profile.sign?.sign || ""; const category = user?.profile.sign?.sign || "";
console.log(category);
const loadData = useCallback(async () => { const loadData = useCallback(async () => {
const { asset_categories } = await api.getAssetCategories({ locale }); const { asset_categories } = await api.getAssetCategories({ locale });
const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories); const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories);
return Promise.all([ return Promise.all([
api.getAssets({ category: String(categoryId || "1"), }), api.getZodiacs({ zodiac: zodiacSign.toLowerCase(), token }),
api.getAssets({ category: String(categoryId || "1") }),
api.getDailyForecasts({ token }), api.getDailyForecasts({ token }),
]).then(([{ assets }, { user_daily_forecast }]) => ({ ]).then(([{ zodiac }, { assets }, { user_daily_forecast }]) => ({
zodiac,
assets, assets,
forecasts: user_daily_forecast.forecasts, forecasts: user_daily_forecast.forecasts,
})); }));
@ -46,25 +52,46 @@ function WallpaperPage(): JSX.Element {
const { data, isPending } = useApiCall<WallpaperData>(loadData); const { data, isPending } = useApiCall<WallpaperData>(loadData);
const forecasts = data ? data.forecasts : []; const forecasts = data ? data.forecasts : [];
const asset = data ? data.assets.at(0) : null; const asset = data ? data.assets.at(0) : null;
const zodiacInfo = data ? data.zodiac : null;
const handleClick = () => const handleClick = () =>
asset && saveFile(asset.url.replace("http://", "https://"), buildFilename(category)); asset &&
saveFile(asset.url.replace("http://", "https://"), buildFilename(category));
return ( return (
<section className="wallpaper-page"> <section className={styles["wallpaper-page"]}>
<div className="wallpaper-image"> <div
{asset ? <img src={asset.url} alt={category} /> : null} className={styles["wallpaper-image"]}
{asset ? <div className="btn-download" onClick={handleClick} /> : null} style={{ backgroundImage: `url(${asset?.url})` }}
>
<div className={styles["zodiac-metas"]}>
{zodiacInfo?.metas.map((meta, index) => (
<div key={index} className={styles["zodiac-meta"]}>
<p className={styles["zodiac-meta-label"]}>{meta.label}</p>
<p className={styles["zodiac-meta-value"]}>{meta.value}</p>
</div>
))}
</div>
{asset ? (
<div className={styles["btn-download"]} onClick={handleClick} />
) : null}
{isPending ? <Loader color={LoaderColor.White} /> : null} {isPending ? <Loader color={LoaderColor.White} /> : null}
</div> </div>
<div className="wallpaper-content"> <div className={styles["wallpaper-content"]}>
{isPending ? null : ( {isPending ? null : (
<> <>
<h1 className="wallpaper-title">{t("analysis_background")}</h1> <h1 className={styles["wallpaper-title"]}>
{t("analysis_background")}
</h1>
{forecasts.map((forecast) => ( {forecasts.map((forecast) => (
<div key={forecast.category_name} className="wallpaper-forecast"> <div
<h2 className="wallpaper-subtitle">{forecast.category}</h2> key={forecast.category_name}
<p className="wallpaper-text">{forecast.body}</p> className={styles["wallpaper-forecast"]}
>
<h2 className={styles["wallpaper-subtitle"]}>
{forecast.category}
</h2>
<p className={styles["wallpaper-text"]}>{forecast.body}</p>
</div> </div>
))} ))}
</> </>

View File

@ -13,10 +13,14 @@
.wallpaper-image { .wallpaper-image {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: flex-end;
background-color: #04040a; background-color: #04040a;
width: 100%; width: 100%;
height: 500px; height: 500px;
padding: 0 32px 32px;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
} }
.wallpaper-content { .wallpaper-content {
@ -65,4 +69,32 @@
background-position: center; background-position: center;
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
}
.zodiac-metas {
width: 100%;
height: fit-content;
padding: 16px;
background-color: #5d5d5d;
display: flex;
flex-direction: column;
gap: 6px;
border-radius: 16px;
}
.zodiac-meta {
display: flex;
flex-direction: row;
font-size: 18px;
gap: 8px;
}
.zodiac-meta-label {
font-weight: 400;
color: #fff;
text-transform: uppercase;
}
.zodiac-meta-value {
font-weight: 700;
} }

View File

@ -31,6 +31,7 @@ const routes = {
user: () => [apiHost, prefix, "user.json"].join("/"), user: () => [apiHost, prefix, "user.json"].join("/"),
token: () => [apiHost, prefix, "auth", "token.json"].join("/"), token: () => [apiHost, prefix, "auth", "token.json"].join("/"),
elements: () => [apiHost, prefix, "elements.json"].join("/"), elements: () => [apiHost, prefix, "elements.json"].join("/"),
zodiacs: (zodiac: string) => [apiHost, prefix, "zodiacs", `${zodiac}.json`].join("/"),
element: (type: string) => element: (type: string) =>
[apiHost, prefix, "elements", `${type}.json`].join("/"), [apiHost, prefix, "elements", `${type}.json`].join("/"),
apps: (bundleId: string) => apps: (bundleId: string) =>