edits
This commit is contained in:
gofnnp 2025-06-16 20:38:32 +04:00
parent b26161f7d5
commit 851bcc1d4f
39 changed files with 114 additions and 122 deletions

View File

@ -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({

View File

@ -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({

View File

@ -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() {

View File

@ -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 (

View File

@ -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.",
};

View File

@ -1,5 +0,0 @@
import Typography from "../ui/Typography/Typography";
export default function Logo() {
return <Typography size="xl" weight="medium">AURA</Typography>
}

View File

@ -1,4 +1,4 @@
.card.adviserCard {
.card.card {
padding: 0;
min-width: 160px;
height: 235px;

View File

@ -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}>

View File

@ -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;

View File

@ -1,4 +1,4 @@
.card {
.card.card {
padding: 0;
min-width: 342px;
height: 308px;

View File

@ -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;

View File

@ -1,4 +1,4 @@
.card {
.card.card {
padding: 0;
min-width: 200px;
height: 227px;

View File

@ -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;

View 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';

View File

@ -0,0 +1,2 @@
export * from './cards';
export * from './sections';

View File

@ -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;
}

View File

@ -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>
)
}

View File

@ -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;
}

View File

@ -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>
)
}

View File

@ -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;
}

View File

@ -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>
)
}

View File

@ -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;
}

View File

@ -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>
)
}

View 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';

View File

@ -0,0 +1,5 @@
import { Typography } from "@/components/ui";
export default function Logo() {
return <Typography size="xl" weight="medium">WIT</Typography>
}

View File

@ -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;

View File

@ -0,0 +1,2 @@
export { default as Logo } from './Logo/Logo';
export { default as NavigationBar } from './NavigationBar/NavigationBar';

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View 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';

View File

@ -12,7 +12,7 @@
color: #2A74DD;
}
.card {
.card.card {
padding: 16px 0px;
display: flex;
flex-direction: column;

View File

@ -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>

View File

@ -0,0 +1 @@
export { default as Horoscope } from './Horoscope/Horoscope';

View File

@ -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
});
}

View File

@ -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,
});