Compare commits

...

6 Commits

Author SHA1 Message Date
7c6f21081f feat: 404 page 2025-04-07 17:06:08 +03:00
e6ab12f957 feat: page titles 2025-04-07 17:06:01 +03:00
a6eec16309 feat: change default path after login 2025-04-07 16:38:17 +03:00
2ef4b967f3 feat: styles update 2025-04-07 16:37:59 +03:00
083a0f27c0 feat: scrollbar styles 2025-04-07 16:06:28 +03:00
554ee083ab feat: profile styles 2025-04-07 15:59:04 +03:00
15 changed files with 144 additions and 35 deletions

View File

@@ -1,13 +1,16 @@
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { ErrorBoundary, lazy, LocationProvider, Route, Router, useLocation } from "preact-iso"; import { ErrorBoundary, lazy, LocationProvider, Route, Router, useLocation } from "preact-iso";
import "preact/debug"; import "preact/debug";
import Page404 from "./pages/404";
import LoginPage from "./pages/login"; import LoginPage from "./pages/login";
import { AppProvider } from "./providers/AuthProvider"; import { AppProvider, useAppContext } from "./providers/AuthProvider";
const HomePage: FunctionComponent = () => { const HomePage: FunctionComponent = () => {
const { route } = useLocation(); const { route } = useLocation();
route("/login"); const { isLoggedIn } = useAppContext();
return <div>Redirecting to login...</div>; if (isLoggedIn) route("/profile/tasks", true);
else route("/login", true);
return <div>Redirecting...</div>;
}; };
export function App() { export function App() {
@@ -19,7 +22,7 @@ export function App() {
<Route path="/" component={HomePage} /> <Route path="/" component={HomePage} />
<Route path="/login" component={LoginPage} /> <Route path="/login" component={LoginPage} />
<Route path="/profile/*" component={lazy(() => import("./pages/profile"))} /> <Route path="/profile/*" component={lazy(() => import("./pages/profile"))} />
<Route default component={() => <h1>404</h1>} /> <Route default component={() => <Page404 />} />
</Router> </Router>
</ErrorBoundary> </ErrorBoundary>
</LocationProvider> </LocationProvider>

View File

@@ -1,5 +1,5 @@
@reference "../index.scss"; @reference "../index.scss";
.task { .task {
@apply flex h-24 w-[300px] flex-col items-center justify-center rounded-md border-2 text-xl md:w-[500px]; @apply flex h-24 w-[300px] cursor-pointer flex-col items-center justify-center rounded-md border-2 text-xl transition-transform hover:scale-[1.05] active:scale-[1.05] md:w-[500px];
} }

View File

@@ -6,7 +6,12 @@ interface TaskProps {
} }
const Task: FunctionComponent<TaskProps> = ({ name }: TaskProps) => { const Task: FunctionComponent<TaskProps> = ({ name }: TaskProps) => {
return <div class={classes.task}>{name}</div>; return (
// Временное действие для тестирования
<button onClick={() => alert(name)}>
<div class={classes.task}>{name}</div>
</button>
);
}; };
export default Task; export default Task;

7
src/enums/urls.ts Normal file
View File

@@ -0,0 +1,7 @@
export enum UrlsTitle {
LOGIN = "Авторизация",
PROFILE = "Профиль",
TASKS = "Задачи",
CALENDAR = "Календарь",
PAGE404 = "404",
}

View File

@@ -3,3 +3,19 @@
:root { :root {
font-family: "Montserrat", sans-serif; font-family: "Montserrat", sans-serif;
} }
@layer base {
::-webkit-scrollbar {
@apply w-2;
}
::-webkit-scrollbar-track {
@apply bg-gray-100;
}
::-webkit-scrollbar-thumb {
@apply rounded-full bg-gray-300;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-gray-500;
}
}

View File

@@ -0,0 +1,9 @@
@reference "../index.scss";
#container {
@apply flex h-screen w-full flex-col items-center justify-center;
}
#main_container {
@apply flex flex-col items-center gap-8;
}

30
src/pages/404.tsx Normal file
View File

@@ -0,0 +1,30 @@
import Button from "@/components/ui/Button";
import { UrlsTitle } from "@/enums/urls";
import { FunctionComponent } from "preact";
import { useLocation } from "preact-iso";
import { useEffect } from "preact/hooks";
import classes from "./404.module.scss";
const Page404: FunctionComponent = () => {
const { route } = useLocation();
useEffect(() => {
document.title = UrlsTitle.PAGE404;
}, []);
return (
<div id={classes.container}>
<div id={classes.main_container}>
<p class="text-6xl font-semibold">404</p>
<Button
onClick={() => {
route("/", true);
}}
color="secondary"
>
На главную
</Button>
</div>
</div>
);
};
export default Page404;

View File

@@ -1,6 +1,7 @@
import { UrlsTitle } from "@/enums/urls";
import { cn } from "@/utils/class-merge"; import { cn } from "@/utils/class-merge";
import { FunctionComponent, h } from "preact"; import { FunctionComponent, h } from "preact";
import { useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
type MarkedDateType = "event" | "holiday" | "important" | string; type MarkedDateType = "event" | "holiday" | "important" | string;
type MarkedDates = Record<string, MarkedDateType>; type MarkedDates = Record<string, MarkedDateType>;
@@ -16,6 +17,9 @@ const BigCalendar: FunctionComponent<BigCalendarProps> = ({
markedDates = {}, markedDates = {},
className = "", className = "",
}: BigCalendarProps) => { }: BigCalendarProps) => {
useEffect(() => {
document.title = UrlsTitle.CALENDAR;
}, []);
const [currentDate, setCurrentDate] = useState<Date>(new Date()); const [currentDate, setCurrentDate] = useState<Date>(new Date());
const [selectedDate, setSelectedDate] = useState<Date | null>(null); const [selectedDate, setSelectedDate] = useState<Date | null>(null);

View File

@@ -1,12 +1,17 @@
import Button from "@/components/ui/Button"; import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input"; import Input from "@/components/ui/Input";
import { UrlsTitle } from "@/enums/urls";
import { useAppContext } from "@/providers/AuthProvider"; import { useAppContext } from "@/providers/AuthProvider";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { useLocation } from "preact-iso"; import { useLocation } from "preact-iso";
import { useEffect } from "preact/hooks";
import classes from "./login.module.scss"; import classes from "./login.module.scss";
const LoginPage: FunctionComponent = () => { const LoginPage: FunctionComponent = () => {
const { isLoggedIn } = useAppContext(); const { isLoggedIn } = useAppContext();
const { route } = useLocation(); const { route } = useLocation();
useEffect(() => {
document.title = UrlsTitle.LOGIN;
}, []);
return ( return (
<div class={classes.login_container}> <div class={classes.login_container}>
<div class={classes.login_card}> <div class={classes.login_card}>
@@ -16,7 +21,7 @@ const LoginPage: FunctionComponent = () => {
<Button <Button
onClick={() => { onClick={() => {
isLoggedIn.value = true; isLoggedIn.value = true;
route("/profile/settings", true); route("/profile/tasks", true);
}} }}
> >
Login Login

View File

@@ -1 +1,13 @@
@reference "../index.scss"; @reference "../index.scss";
#main_container {
@apply flex h-screen flex-col md:flex-row;
}
#router_container {
@apply flex-1 overflow-y-auto px-3 pb-[6rem] break-all md:pb-5;
}
#menu_container {
@apply md:sticky md:top-0 md:h-screen;
}

View File

@@ -1,12 +1,13 @@
import Menu from "@/components/menu"; import Menu from "@/components/menu";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { lazy, Route, Router, useLocation } from "preact-iso"; import { lazy, Route, Router, useLocation } from "preact-iso";
import ids from "./profile.module.scss";
const ProfilePage: FunctionComponent = () => { const ProfilePage: FunctionComponent = () => {
const { route } = useLocation(); const { route } = useLocation();
return ( return (
<div class="flex h-screen flex-col md:flex-row"> <div id={ids.main_container}>
<div class="flex-1 overflow-y-auto px-3 pb-20 break-all md:pb-0"> <div id={ids.router_container}>
<Router> <Router>
<Route path="/settings" component={lazy(() => import("./profile_settings"))} /> <Route path="/settings" component={lazy(() => import("./profile_settings"))} />
<Route path="/tasks" component={lazy(() => import("./profile_tasks"))} /> <Route path="/tasks" component={lazy(() => import("./profile_tasks"))} />
@@ -20,7 +21,7 @@ const ProfilePage: FunctionComponent = () => {
/> />
</Router> </Router>
</div> </div>
<div className="md:sticky md:top-0 md:h-screen"> <div id={ids.menu_container}>
<Menu /> <Menu />
</div> </div>
</div> </div>

View File

@@ -1,16 +1,24 @@
@reference "../index.scss"; @reference "../index.scss";
.container { .container {
@apply flex h-full w-full flex-col items-center gap-4 px-6 pt-3; @apply flex h-full w-full flex-col items-center px-6 pt-3 md:flex-row md:items-start;
} }
.header_block { #avatar {
@apply flex h-[12rem] w-full flex-row justify-between; @apply flex aspect-square h-40 flex-col items-center justify-center rounded-md border;
}
.profile_container {
@apply flex h-full w-full flex-col items-center;
}
.settings_block__buttons {
@apply flex w-[300px] flex-col gap-10;
} }
.header_block__name { .header_block__name {
@apply mt-5 flex w-full flex-col items-center justify-start gap-3; @apply mt-5 flex h-fit w-full flex-col items-center justify-start gap-3;
} }
.settings_block { .settings_block {
@apply flex h-full w-full flex-col items-center justify-center; @apply mt-12 flex h-full w-full flex-col items-center justify-start md:mt-0 md:justify-center;
} }

View File

@@ -1,35 +1,40 @@
import Button from "@/components/ui/Button"; import Button from "@/components/ui/Button";
import { UrlsTitle } from "@/enums/urls";
import { useAppContext } from "@/providers/AuthProvider"; import { useAppContext } from "@/providers/AuthProvider";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { useLocation } from "preact-iso"; import { useLocation } from "preact-iso";
import { useEffect } from "preact/hooks";
import classes from "./profile_settings.module.scss"; import classes from "./profile_settings.module.scss";
const ProfileSettings: FunctionComponent = () => { const ProfileSettings: FunctionComponent = () => {
const { isLoggedIn } = useAppContext(); const { isLoggedIn } = useAppContext();
const { route } = useLocation(); const { route } = useLocation();
useEffect(() => {
document.title = UrlsTitle.PROFILE;
}, []);
return ( return (
<div class={classes.container}> <div class={classes.container}>
<div class={classes.header_block}> <div id={classes.avatar}>Аватар</div>
{/* Вынести классы в стили */} <div class={classes.profile_container}>
<div class="flex aspect-square h-full flex-col items-center justify-center rounded-md border">Аватар</div>
<div class={classes.header_block__name}> <div class={classes.header_block__name}>
<p class="text-5xl font-semibold">Никнейм</p> <p class="text-5xl font-semibold">Никнейм</p>
<p class="text-2xl font-light">Статус</p> <p class="text-2xl font-light">Статус</p>
</div> </div>
</div>
<div class={classes.settings_block}> <div class={classes.settings_block}>
<div class="flex w-[300px] flex-col gap-10"> <div class={classes.settings_block__buttons}>
<Button>Сменить тему</Button> <Button>Сменить тему</Button>
<Button>Настройки</Button> <Button>Настройки</Button>
<Button <Button
color="secondary" color="secondary"
onClick={() => { onClick={() => {
isLoggedIn.value = false; isLoggedIn.value = false;
route("/login", true); route("/login", true);
}} }}
> >
Выйти Выйти
</Button> </Button>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,7 +1,7 @@
@reference "../index.scss"; @reference "../index.scss";
.container { .container {
@apply flex h-full w-full flex-col items-center gap-4 px-6 pt-3; @apply flex h-fit w-full flex-col items-center gap-4 px-6 pt-3;
} }
.header { .header {

View File

@@ -1,6 +1,7 @@
import Task from "@/components/task"; import Task from "@/components/task";
import { UrlsTitle } from "@/enums/urls";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { useMemo } from "preact/hooks"; import { useEffect, useMemo } from "preact/hooks";
import classes from "./profile_tasks.module.scss"; import classes from "./profile_tasks.module.scss";
const example_tasks = ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8"]; const example_tasks = ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8"];
@@ -11,6 +12,9 @@ const ProfileTasks: FunctionComponent = () => {
const formatter = new Intl.DateTimeFormat("ru-RU", { month: "long", day: "numeric" }); const formatter = new Intl.DateTimeFormat("ru-RU", { month: "long", day: "numeric" });
return formatter.format(date); return formatter.format(date);
}, []); }, []);
useEffect(() => {
document.title = UrlsTitle.TASKS;
}, []);
return ( return (
<div class={classes.container}> <div class={classes.container}>
<div class={classes.header}>Сегодня: {getDate}</div> <div class={classes.header}>Сегодня: {getDate}</div>