diff --git a/apps/web/CLAUDE.md b/apps/web/CLAUDE.md new file mode 100644 index 0000000..d87b4f6 --- /dev/null +++ b/apps/web/CLAUDE.md @@ -0,0 +1,5 @@ +# ZENDEGI WEB APP + +Zendegi is a web app for creating and exploring timelines. They could be personal or professional. + +The timelines are shown horizontally and are interactive. diff --git a/apps/web/package.json b/apps/web/package.json index 7f46f69..553150b 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -11,6 +11,8 @@ }, "dependencies": { "@base-ui/react": "^1.0.0", + "@fontsource-variable/inter": "^5.2.8", + "@fontsource/instrument-serif": "^5.2.8", "@tailwindcss/vite": "^4.1.8", "@tanstack/react-form": "^1.23.5", "@tanstack/react-query": "^5.80.6", diff --git a/apps/web/public/logo.png b/apps/web/public/logo.png new file mode 100644 index 0000000..6024348 Binary files /dev/null and b/apps/web/public/logo.png differ diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx index 810fa00..3ae8fd8 100644 --- a/apps/web/src/components/header.tsx +++ b/apps/web/src/components/header.tsx @@ -6,6 +6,7 @@ export default function Header() { const links = [ { to: "/", label: "Home" }, { to: "/dashboard", label: "Dashboard" }, + { to: "/timelines", label: "Timelines" }, ] as const; return ( diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 2856988..88b5dd6 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1,6 +1,9 @@ @import "tailwindcss"; @import "tw-animate-css"; +@import "@fontsource-variable/inter"; +@import "@fontsource/instrument-serif"; + @custom-variant dark (&:is(.dark *)); :root { @@ -74,6 +77,7 @@ @theme inline { --font-sans: "Inter Variable", sans-serif; + --font-mono: "Instrument Serif", monospace; --color-sidebar-ring: var(--sidebar-ring); --color-sidebar-border: var(--sidebar-border); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); diff --git a/apps/web/src/routeTree.gen.ts b/apps/web/src/routeTree.gen.ts index f147546..ec5a963 100644 --- a/apps/web/src/routeTree.gen.ts +++ b/apps/web/src/routeTree.gen.ts @@ -9,12 +9,25 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' +import { Route as TimelinesRouteImport } from './routes/timelines' +import { Route as TimelineRouteImport } from './routes/timeline' import { Route as LoginRouteImport } from './routes/login' import { Route as DemoRouteImport } from './routes/demo' import { Route as DashboardRouteImport } from './routes/dashboard' import { Route as IndexRouteImport } from './routes/index' +import { Route as TimelineTimelineIdRouteImport } from './routes/timeline.$timelineId' import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$' +const TimelinesRoute = TimelinesRouteImport.update({ + id: '/timelines', + path: '/timelines', + getParentRoute: () => rootRouteImport, +} as any) +const TimelineRoute = TimelineRouteImport.update({ + id: '/timeline', + path: '/timeline', + getParentRoute: () => rootRouteImport, +} as any) const LoginRoute = LoginRouteImport.update({ id: '/login', path: '/login', @@ -35,6 +48,11 @@ const IndexRoute = IndexRouteImport.update({ path: '/', getParentRoute: () => rootRouteImport, } as any) +const TimelineTimelineIdRoute = TimelineTimelineIdRouteImport.update({ + id: '/$timelineId', + path: '/$timelineId', + getParentRoute: () => TimelineRoute, +} as any) const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({ id: '/api/auth/$', path: '/api/auth/$', @@ -46,6 +64,9 @@ export interface FileRoutesByFullPath { '/dashboard': typeof DashboardRoute '/demo': typeof DemoRoute '/login': typeof LoginRoute + '/timeline': typeof TimelineRouteWithChildren + '/timelines': typeof TimelinesRoute + '/timeline/$timelineId': typeof TimelineTimelineIdRoute '/api/auth/$': typeof ApiAuthSplatRoute } export interface FileRoutesByTo { @@ -53,6 +74,9 @@ export interface FileRoutesByTo { '/dashboard': typeof DashboardRoute '/demo': typeof DemoRoute '/login': typeof LoginRoute + '/timeline': typeof TimelineRouteWithChildren + '/timelines': typeof TimelinesRoute + '/timeline/$timelineId': typeof TimelineTimelineIdRoute '/api/auth/$': typeof ApiAuthSplatRoute } export interface FileRoutesById { @@ -61,14 +85,42 @@ export interface FileRoutesById { '/dashboard': typeof DashboardRoute '/demo': typeof DemoRoute '/login': typeof LoginRoute + '/timeline': typeof TimelineRouteWithChildren + '/timelines': typeof TimelinesRoute + '/timeline/$timelineId': typeof TimelineTimelineIdRoute '/api/auth/$': typeof ApiAuthSplatRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' | '/dashboard' | '/demo' | '/login' | '/api/auth/$' + fullPaths: + | '/' + | '/dashboard' + | '/demo' + | '/login' + | '/timeline' + | '/timelines' + | '/timeline/$timelineId' + | '/api/auth/$' fileRoutesByTo: FileRoutesByTo - to: '/' | '/dashboard' | '/demo' | '/login' | '/api/auth/$' - id: '__root__' | '/' | '/dashboard' | '/demo' | '/login' | '/api/auth/$' + to: + | '/' + | '/dashboard' + | '/demo' + | '/login' + | '/timeline' + | '/timelines' + | '/timeline/$timelineId' + | '/api/auth/$' + id: + | '__root__' + | '/' + | '/dashboard' + | '/demo' + | '/login' + | '/timeline' + | '/timelines' + | '/timeline/$timelineId' + | '/api/auth/$' fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -76,11 +128,27 @@ export interface RootRouteChildren { DashboardRoute: typeof DashboardRoute DemoRoute: typeof DemoRoute LoginRoute: typeof LoginRoute + TimelineRoute: typeof TimelineRouteWithChildren + TimelinesRoute: typeof TimelinesRoute ApiAuthSplatRoute: typeof ApiAuthSplatRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { + '/timelines': { + id: '/timelines' + path: '/timelines' + fullPath: '/timelines' + preLoaderRoute: typeof TimelinesRouteImport + parentRoute: typeof rootRouteImport + } + '/timeline': { + id: '/timeline' + path: '/timeline' + fullPath: '/timeline' + preLoaderRoute: typeof TimelineRouteImport + parentRoute: typeof rootRouteImport + } '/login': { id: '/login' path: '/login' @@ -109,6 +177,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } + '/timeline/$timelineId': { + id: '/timeline/$timelineId' + path: '/$timelineId' + fullPath: '/timeline/$timelineId' + preLoaderRoute: typeof TimelineTimelineIdRouteImport + parentRoute: typeof TimelineRoute + } '/api/auth/$': { id: '/api/auth/$' path: '/api/auth/$' @@ -119,11 +194,25 @@ declare module '@tanstack/react-router' { } } +interface TimelineRouteChildren { + TimelineTimelineIdRoute: typeof TimelineTimelineIdRoute +} + +const TimelineRouteChildren: TimelineRouteChildren = { + TimelineTimelineIdRoute: TimelineTimelineIdRoute, +} + +const TimelineRouteWithChildren = TimelineRoute._addFileChildren( + TimelineRouteChildren, +) + const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, DashboardRoute: DashboardRoute, DemoRoute: DemoRoute, LoginRoute: LoginRoute, + TimelineRoute: TimelineRouteWithChildren, + TimelinesRoute: TimelinesRoute, ApiAuthSplatRoute: ApiAuthSplatRoute, } export const routeTree = rootRouteImport diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx index 4449f24..645db06 100644 --- a/apps/web/src/routes/index.tsx +++ b/apps/web/src/routes/index.tsx @@ -4,31 +4,24 @@ export const Route = createFileRoute("/")({ component: HomeComponent, }); -const TITLE_TEXT = ` - ██████╗ ███████╗████████╗████████╗███████╗██████╗ - ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗ - ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝ - ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗ - ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║ - ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ - - ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗ - ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝ - ██║ ███████╗ ██║ ███████║██║ █████╔╝ - ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗ - ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗ - ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ - `; - function HomeComponent() { return ( -
-
{TITLE_TEXT}
-
-
-

API Status

-
+
+
+
+ Zendegi +
+
+

+ Everything you need to visualize your story +

+

+ With our web app, bring to life stunning timelines of your + milestones, stories, and plans. Unleash creativity, boost + productivity, and transform how you experience your world. +

+
-
+ ); } diff --git a/apps/web/src/routes/timeline.$timelineId.tsx b/apps/web/src/routes/timeline.$timelineId.tsx new file mode 100644 index 0000000..7cdb3d2 --- /dev/null +++ b/apps/web/src/routes/timeline.$timelineId.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/timeline/$timelineId")({ + component: RouteComponent, +}); + +function RouteComponent() { + return
Timeline detail
; +} diff --git a/apps/web/src/routes/timeline.tsx b/apps/web/src/routes/timeline.tsx new file mode 100644 index 0000000..7525046 --- /dev/null +++ b/apps/web/src/routes/timeline.tsx @@ -0,0 +1,14 @@ +import { Outlet, createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/timeline")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ( +
+ Shell of timeline + +
+ ); +} diff --git a/apps/web/src/routes/timelines.tsx b/apps/web/src/routes/timelines.tsx new file mode 100644 index 0000000..6af7fba --- /dev/null +++ b/apps/web/src/routes/timelines.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/timelines")({ + component: RouteComponent, +}); + +function RouteComponent() { + return
List of timelines
; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3adb8e5..69d82e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,6 +60,12 @@ importers: '@base-ui/react': specifier: ^1.0.0 version: 1.1.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@fontsource-variable/inter': + specifier: ^5.2.8 + version: 5.2.8 + '@fontsource/instrument-serif': + specifier: ^5.2.8 + version: 5.2.8 '@tailwindcss/vite': specifier: ^4.1.8 version: 4.1.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) @@ -1050,6 +1056,12 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@fontsource-variable/inter@5.2.8': + resolution: {integrity: sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==} + + '@fontsource/instrument-serif@5.2.8': + resolution: {integrity: sha512-s+bkz+syj2rO00Rmq9g0P+PwuLig33DR1xDR8pTWmovH1pUjwnncrFk++q9mmOex8fUQ7oW80gPpPDaw7V1MMw==} + '@hono/node-server@1.19.9': resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} engines: {node: '>=18.14.1'} @@ -5178,6 +5190,10 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@fontsource-variable/inter@5.2.8': {} + + '@fontsource/instrument-serif@5.2.8': {} + '@hono/node-server@1.19.9(hono@4.11.9)': dependencies: hono: 4.11.9