Compare commits

...

3 Commits

Author SHA1 Message Date
02ee281ae5 feat: menu styles 2025-04-03 11:26:48 +03:00
c2dd2e89b3 feat: initial auth provider 2025-04-03 11:11:44 +03:00
cbb28fac6f feat: some profile page upgrades 2025-04-03 11:11:30 +03:00
7 changed files with 152 additions and 34 deletions

View File

@@ -1,8 +1,8 @@
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { ErrorBoundary, LocationProvider, Route, Router, useLocation } from "preact-iso"; import { ErrorBoundary, lazy, LocationProvider, Route, Router, useLocation } from "preact-iso";
import "preact/debug"; import "preact/debug";
import LoginPage from "./pages/login"; import LoginPage from "./pages/login";
import ProfilePage from "./pages/profile"; import { AppProvider } from "./providers/AuthProvider";
const HomePage: FunctionComponent = () => { const HomePage: FunctionComponent = () => {
const location = useLocation(); const location = useLocation();
@@ -12,14 +12,17 @@ const HomePage: FunctionComponent = () => {
export function App() { export function App() {
return ( return (
<AppProvider>
<LocationProvider> <LocationProvider>
<ErrorBoundary> <ErrorBoundary>
<Router> <Router>
<Route path="/" component={HomePage} /> <Route path="/" component={HomePage} />
<Route path="/login" component={LoginPage} /> <Route path="/login" component={LoginPage} />
<Route path="/profile" component={ProfilePage} /> <Route path="/profile/*" component={lazy(() => import("./pages/profile"))} />
<Route default component={() => <h1>404</h1>} />
</Router> </Router>
</ErrorBoundary> </ErrorBoundary>
</LocationProvider> </LocationProvider>
</AppProvider>
); );
} }

View File

@@ -1,13 +0,0 @@
import { FunctionComponent } from "preact";
import Menu from "./menu";
const Layout: FunctionComponent = (props) => {
return (
<div class="flex min-w-screen flex-row justify-between">
{props.children}
<Menu />
</div>
);
};
export default Layout;

View File

@@ -1,9 +1,9 @@
@reference "../index.scss"; @reference "../index.scss";
.menu_container { .menu_container {
@apply flex min-h-8 min-w-screen flex-col items-center gap-4 border-l border-l-gray-500 px-5 pt-5 md:min-h-screen md:min-w-[300px]; @apply fixed bottom-0 flex min-h-8 min-w-screen flex-row items-center gap-1 border-t border-t-gray-500 bg-white px-1 py-5 md:relative md:min-h-screen md:min-w-[300px] md:flex-col md:gap-4 md:border-t-0 md:border-l md:border-l-gray-500 md:px-5;
} }
.menu_item { .menu_item {
@apply w-full cursor-pointer rounded-md px-6 py-2 text-center hover:bg-gray-200; @apply w-full cursor-pointer rounded-md px-3 py-2 text-center hover:bg-gray-200 md:px-6;
} }

View File

@@ -39,15 +39,15 @@ const Menu: FunctionComponent = () => {
const menu_items: MenuItems[] = [ const menu_items: MenuItems[] = [
{ {
title: "Профиль", title: "Профиль",
link: "/profile", link: "/profile/settings",
}, },
{ {
title: "Задачи", title: "Задачи",
link: "/tasks", link: "/profile/tasks",
}, },
{ {
title: "Календарь", title: "Календарь",
link: "/calendar", link: "/profile/calendar",
}, },
]; ];
return ( return (

View File

@@ -1,14 +1,25 @@
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 { useAppContext } from "@/providers/AuthProvider";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { useLocation } from "preact-iso";
import classes from "./login.module.scss"; import classes from "./login.module.scss";
const LoginPage: FunctionComponent = () => { const LoginPage: FunctionComponent = () => {
const { isLoggedIn } = useAppContext();
const location = useLocation();
return ( return (
<div class={classes.login_container}> <div class={classes.login_container}>
<div class={classes.login_card}> <div class={classes.login_card}>
<Input placeholder="Login" textAlign="center" /> <Input placeholder="Login" textAlign="center" />
<Input isPassword placeholder="Password" textAlign="center" /> <Input isPassword placeholder="Password" textAlign="center" />
<Button onClick={() => {}}>Login</Button> <Button
onClick={() => {
isLoggedIn.value = true;
location.route("/profile/settings");
}}
>
Login
</Button>
</div> </div>
</div> </div>
); );

View File

@@ -1,11 +1,99 @@
import Layout from "@/components/layout"; import Menu from "@/components/menu";
import { FunctionComponent } from "preact"; import { FunctionComponent } from "preact";
import { Route, Router, useLocation } from "preact-iso";
const ProfilePage: FunctionComponent = () => { const ProfilePage: FunctionComponent = () => {
const { route } = useLocation();
return ( return (
<Layout> <div class="flex min-w-screen flex-row justify-between">
<p>Profile</p> <div class="w-full overflow-x-hidden overflow-y-auto px-3 pb-20 break-all md:pb-0">
</Layout> <Router>
<Route
path="/settings"
component={() => (
<p class="text-2xl">
information sets circus station three entirely outer fun event free thirty breathing race snow planned
surface fully he cast town group plant egg journeyearly city thread fight outline wear key flame special
voice carefully exactly entire notice practical biggest television find particular middle noise cloud
tobacco cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight
son front motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us
broke warn prevent follow depth been buffalo bag classroom before term repeat want here plant division
camera hang preparechurch call member it build rose who potatoes easy sides exclaimed foot independent
point alone gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving
whale quick tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing
instant result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during
electricity available managed comfortable eight left scientist article which stove term information sets
circus station three entirely outer fun event free thirty breathing race snow planned surface fully he
cast town group plant egg journeyearly city thread fight outline wear key flame special voice carefully
exactly entire notice practical biggest television find particular middle noise cloud tobacco
cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight son front
motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us broke warn
prevent follow depth been buffalo bag classroom before term repeat want here plant division camera hang
preparechurch call member it build rose who potatoes easy sides exclaimed foot independent point alone
gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving whale quick
tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing instant
result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during electricity
available managed comfortable eight left scientist article which stove terminformation sets circus
station three entirely outer fun event free thirty breathing race snow planned surface fully he cast
town group plant egg journeyearly city thread fight outline wear key flame special voice carefully
exactly entire notice practical biggest television find particular middle noise cloud tobacco
cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight son front
motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us broke warn
prevent follow depth been buffalo bag classroom before term repeat want here plant division camera hang
preparechurch call member it build rose who potatoes easy sides exclaimed foot independent point alone
gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving whale quick
tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing instant
result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during electricity
available managed comfortable eight left scientist article which stove terminformation sets circus
station three entirely outer fun event free thirty breathing race snow planned surface fully he cast
town group plant egg journeyearly city thread fight outline wear key flame special voice carefully
exactly entire notice practical biggest television find particular middle noise cloud tobacco
cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight son front
motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us broke warn
prevent follow depth been buffalo bag classroom before term repeat want here plant division camera hang
preparechurch call member it build rose who potatoes easy sides exclaimed foot independent point alone
gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving whale quick
tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing instant
result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during electricity
available managed comfortable eight left scientist article which stove terminformation sets circus
station three entirely outer fun event free thirty breathing race snow planned surface fully he cast
town group plant egg journeyearly city thread fight outline wear key flame special voice carefully
exactly entire notice practical biggest television find particular middle noise cloud tobacco
cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight son front
motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us broke warn
prevent follow depth been buffalo bag classroom before term repeat want here plant division camera hang
preparechurch call member it build rose who potatoes easy sides exclaimed foot independent point alone
gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving whale quick
tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing instant
result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during electricity
available managed comfortable eight left scientist article which stove terminformation sets circus
station three entirely outer fun event free thirty breathing race snow planned surface fully he cast
town group plant egg journeyearly city thread fight outline wear key flame special voice carefully
exactly entire notice practical biggest television find particular middle noise cloud tobacco
cameraowner rule factor lift within order somewhere rocky powerful steam expect forty tonight son front
motor knowledge law easily equipment worse adult straw declaredhave famous choose ants us broke warn
prevent follow depth been buffalo bag classroom before term repeat want here plant division camera hang
preparechurch call member it build rose who potatoes easy sides exclaimed foot independent point alone
gone forty completely habit slept heard stand forest paperjoy repeat shot wrote label giving whale quick
tomorrow feathers additional active unless reader angle copy blanket white pitch my seeing instant
result asideexcited front word guess each wolf leader steady rhyme sound thy chapter during electricity
available managed comfortable eight left scientist article which stove term
</p>
)}
/>
<Route path="/tasks" component={() => <p class="text-2xl">Tasks</p>} />
<Route path="/calendar" component={() => <p class="text-2xl">Calendar</p>} />
<Route
default
component={() => {
route("/profile/tasks", true);
return null;
}}
/>
</Router>
</div>
<Menu />
</div>
); );
}; };

View File

@@ -0,0 +1,29 @@
import { signal, Signal } from "@preact/signals";
import { createContext, JSX } from "preact";
import { useContext } from "preact/hooks";
interface AppContextValue {
isLoggedIn: Signal<boolean>;
}
const AppContext = createContext<AppContextValue>({
isLoggedIn: signal(false),
});
const AppProvider = ({ children }: { children: JSX.Element }) => {
const value: AppContextValue = {
isLoggedIn: signal(false),
};
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};
const useAppContext = () => {
const context = useContext(AppContext);
if (!context) {
throw new Error("useAppContext must be used within AppProvider");
}
return context;
};
export { AppProvider, useAppContext };