main
edits
This commit is contained in:
parent
b26161f7d5
commit
851bcc1d4f
@ -1,8 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import Button from '@/components/ui/Button/Button';
|
||||
import Typography from '@/components/ui/Typography/Typography';
|
||||
import { useEffect } from 'react';
|
||||
import { Button, Typography } from '@/components/ui';
|
||||
import styles from "./error.module.scss"
|
||||
|
||||
export default function Error({
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import NavigationBar from "@/components/NavigationBar/NavigationBar";
|
||||
import { NavigationBar } from "@/components/layout";
|
||||
import styles from "./layout.module.scss";
|
||||
|
||||
export default function CoreLayout({
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import Spinner from "@/components/ui/Spinner/Spinner";
|
||||
import { Spinner } from "@/components/ui";
|
||||
import styles from "./loading.module.scss"
|
||||
|
||||
export default function Loading() {
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
import { Suspense } from "react";
|
||||
import Horoscope from "@/components/Horoscope/Horoscope";
|
||||
import styles from "./page.module.scss";
|
||||
import AdvisersSection, { AdvisersSectionSkeleton } from "@/components/AdvisersSection/AdvisersSection";
|
||||
import CompatibilitySection, { CompatibilitySectionSkeleton } from "@/components/CompatibilitySection/CompatibilitySection";
|
||||
import MeditationSection, { MeditationSectionSkeleton } from "@/components/MeditationSection/MeditationSection";
|
||||
import PalmSection, { PalmSectionSkeleton } from "@/components/PalmSection/PalmSection";
|
||||
import { loadAssistants, loadCompatibility, loadMeditations, loadPalms } from "@/entities/dashboard/loaders";
|
||||
import { Horoscope } from "@/components/widgets";
|
||||
import {
|
||||
AdvisersSection,
|
||||
AdvisersSectionSkeleton,
|
||||
CompatibilitySection,
|
||||
CompatibilitySectionSkeleton,
|
||||
MeditationSection,
|
||||
MeditationSectionSkeleton,
|
||||
PalmSection,
|
||||
PalmSectionSkeleton
|
||||
} from "@/components/domains/dashboard";
|
||||
import styles from "./page.module.scss";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import clsx from "clsx";
|
||||
import styles from "./layout.module.scss"
|
||||
import "@/styles/globals.css";
|
||||
import styles from "./layout.module.scss"
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin", "cyrillic"],
|
||||
@ -11,7 +11,7 @@ const inter = Inter({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Wit Apps | AURA",
|
||||
title: "WIT",
|
||||
description: "More than 14M people have experienced the value of our products. Wit Apps, headquartered in Silicon Valley, California, is a tech company that constructs global enterprises specializing in mobile-first products. We believe in the transformative power of technology, capable of turning chaos into miracles, thus enhancing the lives of millions. To realize this vision, we integrate leading expertise in artificial intelligence with a deep understanding of consumer needs and lifestyle trends.",
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
import Typography from "../ui/Typography/Typography";
|
||||
|
||||
export default function Logo() {
|
||||
return <Typography size="xl" weight="medium">AURA</Typography>
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
.card.adviserCard {
|
||||
.card.card {
|
||||
padding: 0;
|
||||
min-width: 160px;
|
||||
height: 235px;
|
||||
@ -1,10 +1,6 @@
|
||||
import clsx from "clsx"
|
||||
import Button from "../ui/Button/Button"
|
||||
import Card from "../ui/Card/Card"
|
||||
import Typography from "../ui/Typography/Typography"
|
||||
import styles from "./AdviserCard.module.scss"
|
||||
import { Assistant } from "@/entities/dashboard/types"
|
||||
import Stars from "../ui/Stars/Stars"
|
||||
import { Button, Card, Stars, Typography } from "@/components/ui"
|
||||
import styles from "./AdviserCard.module.scss"
|
||||
|
||||
type AdviserCardProps = Assistant;
|
||||
|
||||
@ -16,7 +12,7 @@ export default function AdviserCard({
|
||||
description
|
||||
}: AdviserCardProps) {
|
||||
return (
|
||||
<Card className={clsx(styles.card, styles.adviserCard)} style={{ backgroundImage: `url(${photoUrl})` }}>
|
||||
<Card className={styles.card} style={{ backgroundImage: `url(${photoUrl})` }}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.info}>
|
||||
<div className={styles.name}>
|
||||
@ -1,4 +1,4 @@
|
||||
.card {
|
||||
.card.card {
|
||||
padding: 0;
|
||||
min-width: 320px;
|
||||
height: 110px;
|
||||
@ -1,10 +1,8 @@
|
||||
import Image from "next/image";
|
||||
import Card from "../ui/Card/Card"
|
||||
import Typography from "../ui/Typography/Typography"
|
||||
import styles from "./CompatibilityCard.module.scss"
|
||||
import { IconName } from "../ui/Icon/Icon";
|
||||
import MetaLabel from "../ui/MetaLabel/MetaLabel";
|
||||
import { CompatibilityAction } from "@/entities/dashboard/types";
|
||||
import { Card, MetaLabel, Typography } from "@/components/ui";
|
||||
import { IconName } from "@/components/ui/Icon/Icon";
|
||||
import styles from "./CompatibilityCard.module.scss";
|
||||
|
||||
type CompatibilityCardProps = CompatibilityAction;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.card {
|
||||
.card.card {
|
||||
padding: 0;
|
||||
min-width: 342px;
|
||||
height: 308px;
|
||||
@ -1,11 +1,8 @@
|
||||
import Image from "next/image";
|
||||
import Card from "../ui/Card/Card"
|
||||
import Typography from "../ui/Typography/Typography"
|
||||
import styles from "./MeditationCard.module.scss"
|
||||
import Icon, { IconName } from "../ui/Icon/Icon";
|
||||
import MetaLabel from "../ui/MetaLabel/MetaLabel";
|
||||
import Button from "../ui/Button/Button";
|
||||
import { Meditation } from "@/entities/dashboard/types";
|
||||
import { Button, Card, Icon, MetaLabel, Typography } from "@/components/ui";
|
||||
import { IconName } from "@/components/ui/Icon/Icon";
|
||||
import styles from "./MeditationCard.module.scss"
|
||||
|
||||
type MeditationCardProps = Meditation;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.card {
|
||||
.card.card {
|
||||
padding: 0;
|
||||
min-width: 200px;
|
||||
height: 227px;
|
||||
@ -1,10 +1,8 @@
|
||||
import Image from "next/image";
|
||||
import Card from "../ui/Card/Card"
|
||||
import Typography from "../ui/Typography/Typography"
|
||||
import styles from "./PalmCard.module.scss"
|
||||
import { IconName } from "../ui/Icon/Icon";
|
||||
import MetaLabel from "../ui/MetaLabel/MetaLabel";
|
||||
import { PalmAction } from "@/entities/dashboard/types";
|
||||
import { Card, MetaLabel, Typography } from "@/components/ui";
|
||||
import { IconName } from "@/components/ui/Icon/Icon";
|
||||
import styles from "./PalmCard.module.scss";
|
||||
|
||||
type PalmCardProps = PalmAction;
|
||||
|
||||
4
src/components/domains/dashboard/cards/index.ts
Normal file
4
src/components/domains/dashboard/cards/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export { default as AdviserCard } from './AdviserCard/AdviserCard';
|
||||
export { default as CompatibilityCard } from './CompatibilityCard/CompatibilityCard';
|
||||
export { default as MeditationCard } from './MeditationCard/MeditationCard';
|
||||
export { default as PalmCard } from './PalmCard/PalmCard';
|
||||
2
src/components/domains/dashboard/index.ts
Normal file
2
src/components/domains/dashboard/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './cards';
|
||||
export * from './sections';
|
||||
@ -1,16 +1,10 @@
|
||||
.sectionContent {
|
||||
.sectionContent.sectionContent {
|
||||
overflow-x: scroll;
|
||||
width: calc(100% + 32px);
|
||||
padding: 32px 16px;
|
||||
padding-right: 0;
|
||||
margin: -32px -16px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.grid {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.advisersSkeleton.skeleton {
|
||||
.skeleton.skeleton {
|
||||
height: 486px;
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
import { Assistant } from "@/entities/dashboard/types";
|
||||
import AdviserCard from "../AdviserCard/AdviserCard";
|
||||
import Grid from "../ui/Grid/Grid"
|
||||
import Section from "../ui/Section/Section"
|
||||
import styles from "./AdvisersSection.module.scss"
|
||||
import { use } from "react";
|
||||
import Skeleton from "../ui/Skeleton/Skeleton";
|
||||
import clsx from "clsx";
|
||||
import { AdviserCard } from "../../cards";
|
||||
import { Grid, Section, Skeleton } from "@/components/ui";
|
||||
import styles from "./AdvisersSection.module.scss";
|
||||
|
||||
export default function AdvisersSection({ promise }: { promise: Promise<Assistant[]> }) {
|
||||
const assistants = use(promise);
|
||||
@ -25,7 +22,7 @@ export default function AdvisersSection({ promise }: { promise: Promise<Assistan
|
||||
export function AdvisersSectionSkeleton() {
|
||||
return (
|
||||
<Section title="Advisers" contentClassName={styles.sectionContent}>
|
||||
<Skeleton className={clsx(styles.advisersSkeleton, styles.skeleton)} />
|
||||
<Skeleton className={styles.skeleton} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@ -1,14 +1,10 @@
|
||||
.sectionContent {
|
||||
.sectionContent.sectionContent {
|
||||
overflow-x: scroll;
|
||||
width: calc(100% + 32px);
|
||||
padding: 16px;
|
||||
margin: -16px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.compatibilitySkeleton.skeleton {
|
||||
.skeleton.skeleton {
|
||||
height: 236px;
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
import { CompatibilityAction } from "@/entities/dashboard/types";
|
||||
import CompatibilityCard from "../CompatibilityCard/CompatibilityCard";
|
||||
import Grid from "../ui/Grid/Grid"
|
||||
import Section from "../ui/Section/Section"
|
||||
import styles from "./CompatibilitySection.module.scss"
|
||||
import { use } from "react";
|
||||
import Skeleton from "../ui/Skeleton/Skeleton";
|
||||
import clsx from "clsx";
|
||||
import { Grid, Section, Skeleton } from "@/components/ui";
|
||||
import { CompatibilityCard } from "../../cards";
|
||||
import styles from "./CompatibilitySection.module.scss";
|
||||
|
||||
export default function CompatibilitySection({ promise }: { promise: Promise<CompatibilityAction[]> }) {
|
||||
const compatibilities = use(promise);
|
||||
@ -25,7 +22,7 @@ export default function CompatibilitySection({ promise }: { promise: Promise<Com
|
||||
export function CompatibilitySectionSkeleton() {
|
||||
return (
|
||||
<Section title="Compatibility" contentClassName={styles.sectionContent}>
|
||||
<Skeleton className={clsx(styles.compatibilitySkeleton, styles.skeleton)} />
|
||||
<Skeleton className={styles.skeleton} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@ -1,14 +1,10 @@
|
||||
.sectionContent {
|
||||
.sectionContent.sectionContent {
|
||||
overflow-x: scroll;
|
||||
width: calc(100% + 32px);
|
||||
padding: 16px;
|
||||
margin: -16px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.meditationSkeleton.skeleton {
|
||||
.skeleton.skeleton {
|
||||
height: 308px;
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
import { Meditation } from "@/entities/dashboard/types";
|
||||
import MeditationCard from "../MeditationCard/MeditationCard";
|
||||
import Grid from "../ui/Grid/Grid"
|
||||
import Section from "../ui/Section/Section"
|
||||
import styles from "./MeditationSection.module.scss"
|
||||
import { use } from "react";
|
||||
import Skeleton from "../ui/Skeleton/Skeleton";
|
||||
import clsx from "clsx";
|
||||
import { Grid, Section, Skeleton } from "@/components/ui";
|
||||
import { MeditationCard } from "../../cards";
|
||||
import styles from "./MeditationSection.module.scss";
|
||||
|
||||
export default function MeditationSection({ promise }: { promise: Promise<Meditation[]> }) {
|
||||
const meditations = use(promise);
|
||||
@ -25,7 +22,7 @@ export default function MeditationSection({ promise }: { promise: Promise<Medita
|
||||
export function MeditationSectionSkeleton() {
|
||||
return (
|
||||
<Section title="Meditations" contentClassName={styles.sectionContent}>
|
||||
<Skeleton className={clsx(styles.meditationSkeleton, styles.skeleton)} />
|
||||
<Skeleton className={styles.skeleton} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@ -1,14 +1,10 @@
|
||||
.sectionContent {
|
||||
.sectionContent.sectionContent {
|
||||
overflow-x: scroll;
|
||||
width: calc(100% + 32px);
|
||||
padding: 16px;
|
||||
margin: -16px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.palmSkeleton.skeleton {
|
||||
.skeleton.skeleton {
|
||||
height: 227px;
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
import { PalmAction } from "@/entities/dashboard/types";
|
||||
import PalmCard from "../PalmCard/PalmCard";
|
||||
import Grid from "../ui/Grid/Grid"
|
||||
import Section from "../ui/Section/Section"
|
||||
import styles from "./PalmSection.module.scss"
|
||||
import { use } from "react";
|
||||
import Skeleton from "../ui/Skeleton/Skeleton";
|
||||
import clsx from "clsx";
|
||||
import { Grid, Section, Skeleton } from "@/components/ui";
|
||||
import { PalmCard } from "../../cards";
|
||||
import styles from "./PalmSection.module.scss";
|
||||
|
||||
export default function PalmSection({ promise }: { promise: Promise<PalmAction[]> }) {
|
||||
const palms = use(promise);
|
||||
@ -25,7 +22,7 @@ export default function PalmSection({ promise }: { promise: Promise<PalmAction[]
|
||||
export function PalmSectionSkeleton() {
|
||||
return (
|
||||
<Section title="Palm" contentClassName={styles.sectionContent}>
|
||||
<Skeleton className={clsx(styles.palmSkeleton, styles.skeleton)} />
|
||||
<Skeleton className={styles.skeleton} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
4
src/components/domains/dashboard/sections/index.ts
Normal file
4
src/components/domains/dashboard/sections/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export { default as AdvisersSection, AdvisersSectionSkeleton } from './AdvisersSection/AdvisersSection';
|
||||
export { default as CompatibilitySection, CompatibilitySectionSkeleton } from './CompatibilitySection/CompatibilitySection';
|
||||
export { default as MeditationSection, MeditationSectionSkeleton } from './MeditationSection/MeditationSection';
|
||||
export { default as PalmSection, PalmSectionSkeleton } from './PalmSection/PalmSection';
|
||||
5
src/components/layout/Logo/Logo.tsx
Normal file
5
src/components/layout/Logo/Logo.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { Typography } from "@/components/ui";
|
||||
|
||||
export default function Logo() {
|
||||
return <Typography size="xl" weight="medium">WIT</Typography>
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
import Logo from "../Logo/Logo"
|
||||
import Icon, { IconName } from "../ui/Icon/Icon"
|
||||
import styles from "./NavigationBar.module.scss"
|
||||
import { Icon } from "@/components/ui";
|
||||
import clsx from "clsx";
|
||||
import Logo from "../Logo/Logo";
|
||||
import { IconName } from "@/components/ui/Icon/Icon";
|
||||
import styles from "./NavigationBar.module.scss";
|
||||
|
||||
interface NavigationBarProps {
|
||||
className?: string;
|
||||
2
src/components/layout/index.ts
Normal file
2
src/components/layout/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { default as Logo } from './Logo/Logo';
|
||||
export { default as NavigationBar } from './NavigationBar/NavigationBar';
|
||||
@ -1,7 +1,7 @@
|
||||
import { ReactNode } from "react";
|
||||
import styles from "./MetaLabel.module.scss";
|
||||
import IconLabel, { IconLabelProps } from "../IconLabel/IconLabel";
|
||||
import Typography from "../Typography/Typography";
|
||||
import styles from "./MetaLabel.module.scss";
|
||||
|
||||
export type MetaLabelProps = {
|
||||
iconLabelProps: IconLabelProps;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ReactNode } from "react";
|
||||
import clsx from "clsx";
|
||||
import styles from "./Section.module.scss";
|
||||
import Typography from "../Typography/Typography";
|
||||
import styles from "./Section.module.scss";
|
||||
|
||||
interface SectionProps {
|
||||
title?: string;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import styles from "./styles.module.scss";
|
||||
import { CSSProperties } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
|
||||
export interface SpinnerProps {
|
||||
size?: number | string;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import styles from "./TabBar.module.scss";
|
||||
import Typography from "../Typography/Typography";
|
||||
import styles from "./TabBar.module.scss";
|
||||
|
||||
export type Tab<T extends string> = {
|
||||
label: string;
|
||||
|
||||
12
src/components/ui/index.ts
Normal file
12
src/components/ui/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export { default as Button } from './Button/Button';
|
||||
export { default as Card } from './Card/Card';
|
||||
export { default as Grid } from './Grid/Grid';
|
||||
export { default as Icon } from './Icon/Icon';
|
||||
export { default as IconLabel } from './IconLabel/IconLabel';
|
||||
export { default as MetaLabel } from './MetaLabel/MetaLabel';
|
||||
export { default as Section } from './Section/Section';
|
||||
export { default as Skeleton } from './Skeleton/Skeleton';
|
||||
export { default as Spinner } from './Spinner/Spinner';
|
||||
export { default as Stars } from './Stars/Stars';
|
||||
export { default as TabBar } from './TabBar/TabBar';
|
||||
export { default as Typography } from './Typography/Typography';
|
||||
@ -12,7 +12,7 @@
|
||||
color: #2A74DD;
|
||||
}
|
||||
|
||||
.card {
|
||||
.card.card {
|
||||
padding: 16px 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -1,11 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import TabBar, { Tab } from "../ui/TabBar/TabBar";
|
||||
import Text from "../ui/Typography/Typography";
|
||||
import { Button, Card, TabBar, Typography } from "@/components/ui";
|
||||
import { Tab } from "@/components/ui/TabBar/TabBar";
|
||||
import styles from "./Horoscope.module.scss";
|
||||
import Card from "../ui/Card/Card";
|
||||
import Button from "../ui/Button/Button";
|
||||
|
||||
type Period = "today" | "week" | "month" | "year";
|
||||
|
||||
@ -40,16 +38,16 @@ export default function Horoscope() {
|
||||
<Card className={styles.card}>
|
||||
<TabBar<Period> tabs={TABS} active={active} onChange={setActive} />
|
||||
<div className={styles.content}>
|
||||
<Text as="h3" weight="regular" className={styles.title}>
|
||||
<Typography as="h3" weight="regular" className={styles.title}>
|
||||
— Your Horoscope today —
|
||||
</Text>
|
||||
<Text as="p" weight="medium" className={styles.text}>
|
||||
</Typography>
|
||||
<Typography as="p" weight="medium" className={styles.text}>
|
||||
{text}
|
||||
</Text>
|
||||
</Typography>
|
||||
{enableCollapse && <Button className={styles.seeAllButton} onClick={() => setIscollapsed((prev) => !prev)}>
|
||||
<Text as="span" size="sm" weight="medium" color="secondary" align="right">
|
||||
<Typography as="span" size="sm" weight="medium" color="secondary" align="right">
|
||||
{isCollapsed ? "See All" : "Hide"}
|
||||
</Text>
|
||||
</Typography>
|
||||
</Button>}
|
||||
</div>
|
||||
</Card>
|
||||
1
src/components/widgets/index.ts
Normal file
1
src/components/widgets/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Horoscope } from './Horoscope/Horoscope';
|
||||
@ -1,12 +1,9 @@
|
||||
import { http } from "@/shared/api/httpClient";
|
||||
import { DashboardSchema, DashboardData } from "./types";
|
||||
import { delay } from "@/shared/utils/delay";
|
||||
|
||||
export const getDashboard = async () => {
|
||||
await delay(3_000);
|
||||
|
||||
return http.get<DashboardData>("/dashboard", {
|
||||
tags: ["dashboard"],
|
||||
schema: DashboardSchema,
|
||||
schema: DashboardSchema
|
||||
});
|
||||
}
|
||||
@ -15,6 +15,7 @@ type RequestOpts = Omit<RequestInit, "method" | "body"> & {
|
||||
tags?: string[]; // next.js cache-tag
|
||||
query?: Record<string, unknown>; // query-string
|
||||
schema?: z.ZodTypeAny; // runtime validation
|
||||
revalidate?: number;
|
||||
};
|
||||
|
||||
class HttpClient {
|
||||
@ -35,12 +36,18 @@ class HttpClient {
|
||||
opts: RequestOpts = {},
|
||||
body?: unknown
|
||||
): Promise<T> {
|
||||
const { tags = [], schema, query, ...rest } = opts;
|
||||
const {
|
||||
tags = [],
|
||||
schema,
|
||||
query,
|
||||
revalidate = 300,
|
||||
...rest
|
||||
} = opts;
|
||||
const res = await fetch(this.buildUrl(path, query), {
|
||||
method,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
next: { revalidate: 3600, tags },
|
||||
next: { revalidate, tags },
|
||||
...rest,
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user