create-aron-app 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -38
- package/dist/index.js +50 -115
- package/package.json +5 -2
- package/templates/{_base/.cursor → .cursor}/rules/api_architecture.mdc +27 -33
- package/templates/{_base/.cursor → .cursor}/rules/coding_standards.mdc +1 -1
- package/templates/{_base/.cursor → .cursor}/rules/convex_rules.mdc +78 -422
- package/templates/.cursor/rules/frontend_architecture_core.mdc +495 -0
- package/templates/.cursor/rules/frontend_architecture_nextjs.mdc +458 -0
- package/templates/.cursor/rules/frontend_architecture_reactrouter.mdc +473 -0
- package/templates/apps/api/_generated/api.d.ts +57 -0
- package/templates/apps/api/_generated/api.js +23 -0
- package/templates/apps/api/_generated/dataModel.d.ts +60 -0
- package/templates/apps/api/_generated/server.d.ts +143 -0
- package/templates/apps/api/_generated/server.js +93 -0
- package/templates/apps/api/http.ts +16 -0
- package/templates/apps/nextjs/.env.example +10 -0
- package/templates/{nextjs → apps/nextjs}/project.json +5 -5
- package/templates/{nextjs → apps/nextjs}/src/app/(auth)/not-allowed/page.tsx +1 -0
- package/templates/apps/nextjs/src/app/(dashboard)/layout.tsx +22 -0
- package/templates/apps/nextjs/src/app/(dashboard)/page.tsx +12 -0
- package/templates/{nextjs → apps/nextjs}/src/app/(dashboard)/todos/[id]/page.tsx +5 -2
- package/templates/apps/nextjs/src/app/(dashboard)/todos/page.tsx +19 -0
- package/templates/apps/nextjs/src/middleware.ts +18 -0
- package/templates/apps/nextjs/src/surfaces/home/bootstrap.ts +9 -0
- package/templates/apps/nextjs/src/surfaces/home/home.tsx +27 -0
- package/templates/apps/nextjs/src/surfaces/home/install.tsx +17 -0
- package/templates/apps/nextjs/src/surfaces/home/layout.tsx +44 -0
- package/templates/apps/nextjs/src/surfaces/home/main/create.tsx +34 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/install.tsx +23 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/layout.tsx +118 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/create.tsx +19 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/nav_config.ts +22 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/nav_main.tsx +25 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/nav_secondary/create.tsx +21 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/nav_secondary/nav_secondary.tsx +33 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/sidebar.tsx +23 -0
- package/templates/{nextjs/src/ui/sidebar/nav_link.tsx → apps/nextjs/src/surfaces/sidebar/ui/sidebar_nav_link.tsx} +13 -10
- package/templates/apps/nextjs/src/surfaces/sidebar/user_menu/create.tsx +28 -0
- package/templates/apps/nextjs/src/surfaces/sidebar/user_menu/user_menu.tsx +42 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/all_todos.tsx +29 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/all_todos_controller.ts +61 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/bootstrap.ts +21 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/header/create.tsx +23 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/install.tsx +23 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/layout.tsx +44 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/create.tsx +49 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/main.tsx +70 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/create.tsx +56 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/new_todo_sheet.tsx +99 -0
- package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/schema.ts +11 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/bootstrap.ts +32 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/header/create.tsx +26 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/header/header.tsx +22 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/install.tsx +27 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/layout.tsx +55 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/main/create.tsx +38 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/main/main.tsx +49 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/single_todo.tsx +29 -0
- package/templates/apps/nextjs/src/surfaces/todos/single_todo/single_todo_controller.ts +13 -0
- package/templates/apps/nextjs/src/utils/auth.ts +18 -0
- package/templates/apps/react-router/.env.example +10 -0
- package/templates/apps/react-router/.react-router/types/+future.ts +9 -0
- package/templates/apps/react-router/.react-router/types/+routes.ts +71 -0
- package/templates/apps/react-router/.react-router/types/+server-build.d.ts +18 -0
- package/templates/apps/react-router/.react-router/types/src/+types/root.ts +59 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(auth)/+types/layout.ts +62 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(auth)/sign-in/+types/index.ts +65 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/+types/index.ts +65 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/+types/layout.ts +62 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/todos/+types/[id].ts +65 -0
- package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/todos/+types/index.ts +65 -0
- package/templates/{react-router → apps/react-router}/project.json +4 -4
- package/templates/apps/react-router/src/app.css +3 -0
- package/templates/{react-router → apps/react-router}/src/components/error_boundary.tsx +1 -1
- package/templates/{react-router → apps/react-router}/src/providers/api_auth_provider.tsx +2 -0
- package/templates/{react-router/src/routes/auth → apps/react-router/src/routes/(auth)}/layout.tsx +1 -1
- package/templates/apps/react-router/src/routes/(dashboard)/index.tsx +19 -0
- package/templates/apps/react-router/src/routes/(dashboard)/layout.tsx +37 -0
- package/templates/apps/react-router/src/routes/(dashboard)/todos/[id].tsx +19 -0
- package/templates/apps/react-router/src/routes/(dashboard)/todos/index.tsx +19 -0
- package/templates/apps/react-router/src/routes.ts +12 -0
- package/templates/apps/react-router/src/surfaces/home/bootstrap.ts +9 -0
- package/templates/apps/react-router/src/surfaces/home/home.tsx +25 -0
- package/templates/apps/react-router/src/surfaces/home/install.tsx +17 -0
- package/templates/apps/react-router/src/surfaces/home/layout.tsx +35 -0
- package/templates/apps/react-router/src/surfaces/home/main/create.tsx +32 -0
- package/templates/apps/react-router/src/surfaces/sidebar/install.tsx +23 -0
- package/templates/apps/react-router/src/surfaces/sidebar/layout.tsx +110 -0
- package/templates/apps/react-router/src/surfaces/sidebar/nav_main/create.tsx +31 -0
- package/templates/apps/react-router/src/surfaces/sidebar/nav_main/nav_main.tsx +42 -0
- package/templates/apps/react-router/src/surfaces/sidebar/nav_secondary/create.tsx +21 -0
- package/templates/apps/react-router/src/surfaces/sidebar/nav_secondary/nav_secondary.tsx +31 -0
- package/templates/apps/react-router/src/surfaces/sidebar/sidebar.tsx +18 -0
- package/templates/apps/react-router/src/surfaces/sidebar/user_menu/create.tsx +26 -0
- package/templates/{react-router/src/layouts/sidebar/sidebar_aside → apps/react-router/src/surfaces/sidebar/user_menu}/user_menu.tsx +13 -9
- package/templates/apps/react-router/src/surfaces/todos/all_todos/all_todos.tsx +25 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/all_todos_controller.ts +47 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/bootstrap.ts +18 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/header/create.tsx +21 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/install.tsx +20 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/layout.tsx +35 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/main/create.tsx +47 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/main/main.tsx +68 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/create.tsx +54 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/new_todo_sheet.tsx +97 -0
- package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/schema.ts +11 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/bootstrap.ts +36 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/header/create.tsx +32 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/header/header.tsx +25 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/install.tsx +27 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/layout.tsx +45 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/main/create.tsx +35 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/main/main.tsx +47 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/single_todo.tsx +27 -0
- package/templates/apps/react-router/src/surfaces/todos/single_todo/single_todo_controller.ts +16 -0
- package/templates/{react-router → apps/react-router}/vite.config.ts +27 -3
- package/templates/{_base/biome.json → biome.json} +7 -0
- package/templates/bun.lock +3187 -0
- package/templates/{_base/emails → emails}/project.json +1 -1
- package/templates/{_base/nx.json → nx.json} +11 -0
- package/templates/package.json +92 -0
- package/templates/{_base/tsconfig.base.json → tsconfig.base.json} +4 -1
- package/templates/_base/.cursor/rules/frontend_rules.mdc +0 -268
- package/templates/_base/.env.convex.example +0 -3
- package/templates/_base/_gitignore +0 -58
- package/templates/_base/package.json +0 -73
- package/templates/nextjs/.env.example +0 -8
- package/templates/nextjs/src/app/(dashboard)/layout.tsx +0 -27
- package/templates/nextjs/src/app/(dashboard)/page.tsx +0 -5
- package/templates/nextjs/src/app/(dashboard)/todos/page.tsx +0 -16
- package/templates/nextjs/src/middleware.ts +0 -18
- package/templates/nextjs/src/surfaces/home_surface.tsx +0 -22
- package/templates/nextjs/src/surfaces/todos/all_todos_surface.tsx +0 -97
- package/templates/nextjs/src/surfaces/todos/create_todo_sheet.tsx +0 -107
- package/templates/nextjs/src/surfaces/todos/single_todo_surface.tsx +0 -90
- package/templates/nextjs/src/ui/sidebar/sidebar.tsx +0 -125
- package/templates/react-router/.env.example +0 -8
- package/templates/react-router/src/app.css +0 -3
- package/templates/react-router/src/layouts/sidebar/sidebar_aside/sidebar_aside.tsx +0 -76
- package/templates/react-router/src/layouts/sidebar/sidebar_layout.tsx +0 -22
- package/templates/react-router/src/routes/index.tsx +0 -9
- package/templates/react-router/src/routes/layout.tsx +0 -26
- package/templates/react-router/src/routes/todos/[id].tsx +0 -22
- package/templates/react-router/src/routes/todos/index.tsx +0 -13
- package/templates/react-router/src/routes.ts +0 -12
- package/templates/react-router/src/surfaces/home_surface.tsx +0 -20
- package/templates/react-router/src/surfaces/todos/all_todos_surface.tsx +0 -87
- package/templates/react-router/src/surfaces/todos/create_todo_sheet.tsx +0 -102
- package/templates/react-router/src/surfaces/todos/single_todo_surface.tsx +0 -81
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/api-specs-context.sh +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/execute-request.sh +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-endpoint-detail.sh +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tag-endpoints.sh +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tags.js +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-in.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-up.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-in.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-up.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/show-component.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/api-routes.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/caching-auth.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/middleware-strategies.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-actions.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-vs-client.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-webhooks/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/SKILL.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/agents/openai.yml +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn-small.png +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn.png +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/cli.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/customization.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/evals/evals.json +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/mcp.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/base-vs-radix.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/composition.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/forms.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/icons.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/styling.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/commands/builder.md +0 -0
- /package/templates/{_base/.cursor → .cursor}/commands/pr.md +0 -0
- /package/templates/{_base/.github → .github}/workflows/ci.yml +0 -0
- /package/templates/{_base/.nvmrc → .nvmrc} +0 -0
- /package/templates/{_base/.vscode → .vscode}/settings.json +0 -0
- /package/templates/{_base/apps → apps}/api/auth.config.ts +0 -0
- /package/templates/{_base/apps → apps}/api/functions.ts +0 -0
- /package/templates/{_base/apps → apps}/api/project.json +0 -0
- /package/templates/{_base/apps → apps}/api/schema.ts +0 -0
- /package/templates/{_base/apps → apps}/api/todos/crud.ts +0 -0
- /package/templates/{_base/apps → apps}/api/todos/schema.ts +0 -0
- /package/templates/{_base/apps → apps}/api/todos/types.ts +0 -0
- /package/templates/{_base/apps → apps}/api/tsconfig.json +0 -0
- /package/templates/{_base/apps → apps}/api/types.ts +0 -0
- /package/templates/{nextjs → apps/nextjs}/index.d.ts +0 -0
- /package/templates/{nextjs → apps/nextjs}/next-env.d.ts +0 -0
- /package/templates/{nextjs → apps/nextjs}/next.config.js +0 -0
- /package/templates/{nextjs → apps/nextjs}/postcss.config.js +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/app/(auth)/layout.tsx +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/app/app.css +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/app/layout.tsx +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/providers/convex_provider.tsx +0 -0
- /package/templates/{nextjs/src → apps/nextjs/src/utils}/convex.ts +0 -0
- /package/templates/{nextjs → apps/nextjs}/src/utils/font.ts +0 -0
- /package/templates/{nextjs → apps/nextjs}/tsconfig.json +0 -0
- /package/templates/{react-router → apps/react-router}/postcss.config.js +0 -0
- /package/templates/{react-router → apps/react-router}/public/favicon.ico +0 -0
- /package/templates/{react-router → apps/react-router}/react-router.config.ts +0 -0
- /package/templates/{react-router → apps/react-router}/src/root.tsx +0 -0
- /package/templates/{react-router/src/routes/auth/sign-in.tsx → apps/react-router/src/routes/(auth)/sign-in/index.tsx} +0 -0
- /package/templates/{react-router → apps/react-router}/tsconfig.json +0 -0
- /package/templates/{_base/convex.json → convex.json} +0 -0
- /package/templates/{_base/emails → emails}/tsconfig.json +0 -0
- /package/templates/{_base/emails → emails}/welcome_email.tsx +0 -0
- /package/templates/{_base/scripts → scripts}/sync_convex_env.ts +0 -0
- /package/templates/{_base/shared → shared}/assets/image.d.ts +0 -0
- /package/templates/{_base/shared → shared}/assets/src/styles/global.css +0 -0
- /package/templates/{_base/shared → shared}/assets/tsconfig.json +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/alert_dialog.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/badge.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/basic_data_table.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/button.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/button_group.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/card.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/checkbox.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/command.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/dialog.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/dropdown_menu.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/form.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/input.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/label.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/popover.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/radio_group.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/resizable.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/scroll_area.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/select.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/separator.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/sheet.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/side_bar.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/skeleton.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/spinner.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/switch.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/table.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/text_area.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/tooltip.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/base/utils.ts +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_press.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_release.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_mobile.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_click.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_location.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_outside_click.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/src/hooks/use_query_params.tsx +0 -0
- /package/templates/{_base/shared → shared}/ui/tsconfig.json +0 -0
- /package/templates/{_base/shared → shared}/utils/src/convex.ts +0 -0
- /package/templates/{_base/shared → shared}/utils/src/time.ts +0 -0
- /package/templates/{_base/shared → shared}/utils/tsconfig.json +0 -0
- /package/templates/{_base/skills-lock.json → skills-lock.json} +0 -0
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
"use client";
|
|
6
|
-
|
|
7
|
-
import { useUser } from "@clerk/nextjs";
|
|
8
|
-
import { convexQuery, useConvexMutation } from "@convex-dev/react-query";
|
|
9
|
-
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
10
|
-
import { Trash2 } from "lucide-react";
|
|
11
|
-
import Link from "next/link";
|
|
12
|
-
|
|
13
|
-
import { api } from "@/api/_generated/api";
|
|
14
|
-
import type { Id } from "@/api/_generated/dataModel";
|
|
15
|
-
import { Button } from "@/ui/base/button";
|
|
16
|
-
import { Checkbox } from "@/ui/base/checkbox";
|
|
17
|
-
import { Spinner } from "@/ui/base/spinner";
|
|
18
|
-
import { CreateTodoSheet } from "@/web/surfaces/todos/create_todo_sheet";
|
|
19
|
-
|
|
20
|
-
export const AllTodosSurface = () => {
|
|
21
|
-
const { user } = useUser();
|
|
22
|
-
|
|
23
|
-
const { data: todos, isPending } = useQuery(
|
|
24
|
-
convexQuery(
|
|
25
|
-
api.todos.crud.listTodos,
|
|
26
|
-
user?.id ? { userId: user.id } : "skip",
|
|
27
|
-
),
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
const { mutate: updateTodo } = useMutation({
|
|
31
|
-
mutationFn: useConvexMutation(api.todos.crud.updateTodo),
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const { mutate: deleteTodo } = useMutation({
|
|
35
|
-
mutationFn: useConvexMutation(api.todos.crud.deleteTodo),
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<main className="flex flex-1 flex-col overflow-auto p-6">
|
|
40
|
-
<div className="flex items-center justify-between mb-6">
|
|
41
|
-
<h1 className="text-2xl font-semibold">Todos</h1>
|
|
42
|
-
<CreateTodoSheet />
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
{isPending && (
|
|
46
|
-
<div className="flex flex-1 items-center justify-center">
|
|
47
|
-
<Spinner />
|
|
48
|
-
</div>
|
|
49
|
-
)}
|
|
50
|
-
|
|
51
|
-
{!isPending && todos?.length === 0 && (
|
|
52
|
-
<div className="flex flex-1 flex-col items-center justify-center gap-2 text-muted-foreground">
|
|
53
|
-
<p>No todos yet.</p>
|
|
54
|
-
<CreateTodoSheet />
|
|
55
|
-
</div>
|
|
56
|
-
)}
|
|
57
|
-
|
|
58
|
-
{todos && todos.length > 0 && (
|
|
59
|
-
<ul className="flex flex-col gap-2 max-w-2xl">
|
|
60
|
-
{todos.map((todo) => (
|
|
61
|
-
<li
|
|
62
|
-
key={todo._id}
|
|
63
|
-
className="flex items-center gap-3 rounded-lg border bg-card px-4 py-3"
|
|
64
|
-
>
|
|
65
|
-
<Checkbox
|
|
66
|
-
checked={todo.isCompleted}
|
|
67
|
-
onCheckedChange={(checked) =>
|
|
68
|
-
updateTodo({
|
|
69
|
-
todoId: todo._id as Id<"todos">,
|
|
70
|
-
isCompleted: !!checked,
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
/>
|
|
74
|
-
<Link
|
|
75
|
-
href={`/todos/${todo._id}`}
|
|
76
|
-
className="flex-1 truncate text-sm hover:underline"
|
|
77
|
-
style={{
|
|
78
|
-
textDecoration: todo.isCompleted ? "line-through" : undefined,
|
|
79
|
-
}}
|
|
80
|
-
>
|
|
81
|
-
{todo.title}
|
|
82
|
-
</Link>
|
|
83
|
-
<Button
|
|
84
|
-
variant="ghost"
|
|
85
|
-
size="icon"
|
|
86
|
-
className="size-7 shrink-0 text-muted-foreground hover:text-destructive"
|
|
87
|
-
onClick={() => deleteTodo({ todoId: todo._id as Id<"todos"> })}
|
|
88
|
-
>
|
|
89
|
-
<Trash2 className="size-4" />
|
|
90
|
-
</Button>
|
|
91
|
-
</li>
|
|
92
|
-
))}
|
|
93
|
-
</ul>
|
|
94
|
-
)}
|
|
95
|
-
</main>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useConvexMutation } from "@convex-dev/react-query";
|
|
4
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
-
import { useMutation } from "@tanstack/react-query";
|
|
6
|
-
import { PlusIcon } from "lucide-react";
|
|
7
|
-
import { useForm } from "react-hook-form";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
|
|
10
|
-
import { api } from "@/api/_generated/api";
|
|
11
|
-
import { Button } from "@/ui/base/button";
|
|
12
|
-
import { DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/ui/base/dialog";
|
|
13
|
-
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/ui/base/form";
|
|
14
|
-
import { Input } from "@/ui/base/input";
|
|
15
|
-
import { Sheet, SheetContent, SheetTrigger } from "@/ui/base/sheet";
|
|
16
|
-
import { TextArea } from "@/ui/base/text_area";
|
|
17
|
-
|
|
18
|
-
type CreateTodoSchema = z.infer<typeof createTodoSchema>;
|
|
19
|
-
const createTodoSchema = z.object({
|
|
20
|
-
title: z.string().min(1, "Title is required"),
|
|
21
|
-
description: z.string().optional(),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const CreateTodoSheet = () => {
|
|
25
|
-
const form = useForm<CreateTodoSchema>({
|
|
26
|
-
resolver: zodResolver(createTodoSchema),
|
|
27
|
-
defaultValues: {
|
|
28
|
-
title: "",
|
|
29
|
-
description: "",
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const { mutate: createTodo, isPending } = useMutation({
|
|
34
|
-
mutationFn: useConvexMutation(api.todos.crud.createTodo),
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const handleSubmit = form.handleSubmit(async (values) => {
|
|
38
|
-
createTodo(values);
|
|
39
|
-
form.reset();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<Sheet>
|
|
44
|
-
<SheetTrigger asChild>
|
|
45
|
-
<Button>
|
|
46
|
-
<PlusIcon className="mr-2 size-4" />
|
|
47
|
-
New Todo
|
|
48
|
-
</Button>
|
|
49
|
-
</SheetTrigger>
|
|
50
|
-
<SheetContent className="sm:max-w-[440px]">
|
|
51
|
-
<DialogHeader>
|
|
52
|
-
<DialogTitle>Create Todo</DialogTitle>
|
|
53
|
-
<DialogDescription>Add a new item to your todo list.</DialogDescription>
|
|
54
|
-
</DialogHeader>
|
|
55
|
-
<Form {...form}>
|
|
56
|
-
<form
|
|
57
|
-
onSubmit={handleSubmit}
|
|
58
|
-
className="flex flex-col gap-4 pt-4"
|
|
59
|
-
onKeyDown={(e) => {
|
|
60
|
-
if (e.key === "Enter") {
|
|
61
|
-
e.preventDefault();
|
|
62
|
-
handleSubmit();
|
|
63
|
-
}
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
<FormField
|
|
67
|
-
control={form.control}
|
|
68
|
-
name="title"
|
|
69
|
-
render={({ field }) => (
|
|
70
|
-
<FormItem>
|
|
71
|
-
<FormLabel>Title</FormLabel>
|
|
72
|
-
<FormControl>
|
|
73
|
-
<Input placeholder="Buy groceries..." {...field} />
|
|
74
|
-
</FormControl>
|
|
75
|
-
<FormMessage />
|
|
76
|
-
</FormItem>
|
|
77
|
-
)}
|
|
78
|
-
/>
|
|
79
|
-
<FormField
|
|
80
|
-
control={form.control}
|
|
81
|
-
name="description"
|
|
82
|
-
render={({ field }) => (
|
|
83
|
-
<FormItem>
|
|
84
|
-
<FormLabel>Description</FormLabel>
|
|
85
|
-
<FormControl>
|
|
86
|
-
<TextArea
|
|
87
|
-
placeholder="Optional details..."
|
|
88
|
-
className="resize-none"
|
|
89
|
-
rows={3}
|
|
90
|
-
{...field}
|
|
91
|
-
/>
|
|
92
|
-
</FormControl>
|
|
93
|
-
<FormMessage />
|
|
94
|
-
</FormItem>
|
|
95
|
-
)}
|
|
96
|
-
/>
|
|
97
|
-
<DialogFooter>
|
|
98
|
-
<Button type="submit" disabled={isPending}>
|
|
99
|
-
{isPending ? "Creating..." : "Create Todo"}
|
|
100
|
-
</Button>
|
|
101
|
-
</DialogFooter>
|
|
102
|
-
</form>
|
|
103
|
-
</Form>
|
|
104
|
-
</SheetContent>
|
|
105
|
-
</Sheet>
|
|
106
|
-
);
|
|
107
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
"use client";
|
|
6
|
-
|
|
7
|
-
import { convexQuery, useConvexMutation } from "@convex-dev/react-query";
|
|
8
|
-
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
9
|
-
import { ArrowLeft } from "lucide-react";
|
|
10
|
-
import Link from "next/link";
|
|
11
|
-
|
|
12
|
-
import { api } from "@/api/_generated/api";
|
|
13
|
-
import type { TodoId } from "@/api/todos/types";
|
|
14
|
-
import { Badge } from "@/ui/base/badge";
|
|
15
|
-
import { Button } from "@/ui/base/button";
|
|
16
|
-
import { Checkbox } from "@/ui/base/checkbox";
|
|
17
|
-
import { Spinner } from "@/ui/base/spinner";
|
|
18
|
-
|
|
19
|
-
type SingleTodoSurfaceProps = {
|
|
20
|
-
todoId: TodoId;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const SingleTodoSurface = ({ todoId }: SingleTodoSurfaceProps) => {
|
|
24
|
-
const { data: todo, isPending } = useQuery(convexQuery(api.todos.crud.getTodo, { todoId }));
|
|
25
|
-
|
|
26
|
-
const { mutate: updateTodo } = useMutation({
|
|
27
|
-
mutationFn: useConvexMutation(api.todos.crud.updateTodo),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
if (isPending) {
|
|
31
|
-
return (
|
|
32
|
-
<main className="flex flex-1 items-center justify-center">
|
|
33
|
-
<Spinner />
|
|
34
|
-
</main>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (!todo) {
|
|
39
|
-
return (
|
|
40
|
-
<main className="flex flex-1 flex-col items-center justify-center gap-4">
|
|
41
|
-
<p className="text-muted-foreground">Todo not found.</p>
|
|
42
|
-
<Button variant="outline" asChild>
|
|
43
|
-
<Link href="/todos">
|
|
44
|
-
<ArrowLeft className="mr-2 size-4" />
|
|
45
|
-
Back to todos
|
|
46
|
-
</Link>
|
|
47
|
-
</Button>
|
|
48
|
-
</main>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<main className="flex flex-1 flex-col gap-6 overflow-auto p-6 max-w-2xl">
|
|
54
|
-
<Button variant="ghost" className="w-fit -ml-2 text-muted-foreground" asChild>
|
|
55
|
-
<Link href="/todos">
|
|
56
|
-
<ArrowLeft className="mr-2 size-4" />
|
|
57
|
-
Back
|
|
58
|
-
</Link>
|
|
59
|
-
</Button>
|
|
60
|
-
|
|
61
|
-
<div className="flex items-start gap-3">
|
|
62
|
-
<Checkbox
|
|
63
|
-
className="mt-1"
|
|
64
|
-
checked={todo.isCompleted}
|
|
65
|
-
onCheckedChange={(checked) =>
|
|
66
|
-
updateTodo({
|
|
67
|
-
todoId,
|
|
68
|
-
isCompleted: !!checked,
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
/>
|
|
72
|
-
<div className="flex flex-col gap-2">
|
|
73
|
-
<h1
|
|
74
|
-
className="text-2xl font-semibold"
|
|
75
|
-
style={{
|
|
76
|
-
textDecoration: todo.isCompleted ? "line-through" : undefined,
|
|
77
|
-
}}
|
|
78
|
-
>
|
|
79
|
-
{todo.title}
|
|
80
|
-
</h1>
|
|
81
|
-
<Badge variant={todo.isCompleted ? "secondary" : "default"}>
|
|
82
|
-
{todo.isCompleted ? "Completed" : "In progress"}
|
|
83
|
-
</Badge>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
{todo.description && <p className="text-muted-foreground">{todo.description}</p>}
|
|
88
|
-
</main>
|
|
89
|
-
);
|
|
90
|
-
};
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
"use client";
|
|
6
|
-
|
|
7
|
-
import { UserButton, useUser } from "@clerk/nextjs";
|
|
8
|
-
import {
|
|
9
|
-
CheckSquareIcon,
|
|
10
|
-
HomeIcon,
|
|
11
|
-
type LucideIcon,
|
|
12
|
-
SettingsIcon,
|
|
13
|
-
} from "lucide-react";
|
|
14
|
-
import Link from "next/link";
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
Sidebar as BaseSidebar,
|
|
18
|
-
SidebarHeader as BaseSidebarHeader,
|
|
19
|
-
SidebarContent,
|
|
20
|
-
SidebarFooter,
|
|
21
|
-
SidebarGroup,
|
|
22
|
-
SidebarGroupContent,
|
|
23
|
-
SidebarMenu,
|
|
24
|
-
SidebarMenuItem,
|
|
25
|
-
} from "@/ui/base/side_bar";
|
|
26
|
-
import { Skeleton } from "@/ui/base/skeleton";
|
|
27
|
-
import { NavLink } from "@/web/ui/sidebar/nav_link";
|
|
28
|
-
|
|
29
|
-
export type NavItem = {
|
|
30
|
-
id: string;
|
|
31
|
-
title: string;
|
|
32
|
-
url: string;
|
|
33
|
-
icon: LucideIcon;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const nav: {
|
|
37
|
-
main: NavItem[];
|
|
38
|
-
secondary: NavItem[];
|
|
39
|
-
} = {
|
|
40
|
-
main: [
|
|
41
|
-
{
|
|
42
|
-
id: "dashboard",
|
|
43
|
-
title: "Dashboard",
|
|
44
|
-
url: "/",
|
|
45
|
-
icon: HomeIcon,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: "todos",
|
|
49
|
-
title: "Todos",
|
|
50
|
-
url: "/todos",
|
|
51
|
-
icon: CheckSquareIcon,
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
secondary: [
|
|
55
|
-
{
|
|
56
|
-
id: "settings",
|
|
57
|
-
title: "Settings",
|
|
58
|
-
url: "/settings",
|
|
59
|
-
icon: SettingsIcon,
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const Sidebar = ({
|
|
65
|
-
...props
|
|
66
|
-
}: React.ComponentProps<typeof BaseSidebar>) => {
|
|
67
|
-
const user = useUser();
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<BaseSidebar collapsible="offcanvas" {...props}>
|
|
71
|
-
<BaseSidebarHeader>
|
|
72
|
-
<SidebarMenu>
|
|
73
|
-
<SidebarMenuItem>
|
|
74
|
-
<Link href="/" className="flex flex-row items-center gap-3 w-full">
|
|
75
|
-
<span className="truncate font-medium">App</span>
|
|
76
|
-
</Link>
|
|
77
|
-
</SidebarMenuItem>
|
|
78
|
-
</SidebarMenu>
|
|
79
|
-
</BaseSidebarHeader>
|
|
80
|
-
<SidebarContent>
|
|
81
|
-
<SidebarGroup className="pt-0">
|
|
82
|
-
<SidebarGroupContent className="flex flex-col gap-2">
|
|
83
|
-
<SidebarMenu>
|
|
84
|
-
{nav.main.map((item) => (
|
|
85
|
-
<NavLink key={item.id} item={item} />
|
|
86
|
-
))}
|
|
87
|
-
</SidebarMenu>
|
|
88
|
-
</SidebarGroupContent>
|
|
89
|
-
</SidebarGroup>
|
|
90
|
-
</SidebarContent>
|
|
91
|
-
<SidebarFooter className="gap-0 p-2">
|
|
92
|
-
<SidebarGroup>
|
|
93
|
-
<SidebarGroupContent>
|
|
94
|
-
<SidebarMenu>
|
|
95
|
-
{nav.secondary.map((item) => (
|
|
96
|
-
<NavLink key={item.id} item={item} />
|
|
97
|
-
))}
|
|
98
|
-
</SidebarMenu>
|
|
99
|
-
</SidebarGroupContent>
|
|
100
|
-
</SidebarGroup>
|
|
101
|
-
<SidebarMenu>
|
|
102
|
-
{user.isLoaded ? (
|
|
103
|
-
<SidebarMenuItem className="w-full">
|
|
104
|
-
<div className="flex items-start gap-2 border rounded-md shadow-sm px-2 py-2 w-full">
|
|
105
|
-
<UserButton />
|
|
106
|
-
<div className="flex flex-col gap-0 text-left leading-tight w-fit">
|
|
107
|
-
<span className="text-sm font-medium break-words truncate">
|
|
108
|
-
{user.user?.fullName}
|
|
109
|
-
</span>
|
|
110
|
-
<span className="truncate text-xs font-light">
|
|
111
|
-
{user.user?.emailAddresses[0].emailAddress}
|
|
112
|
-
</span>
|
|
113
|
-
</div>
|
|
114
|
-
</div>
|
|
115
|
-
</SidebarMenuItem>
|
|
116
|
-
) : (
|
|
117
|
-
<SidebarMenuItem className="w-full">
|
|
118
|
-
<Skeleton className="h-12 w-full rounded-lg border" />
|
|
119
|
-
</SidebarMenuItem>
|
|
120
|
-
)}
|
|
121
|
-
</SidebarMenu>
|
|
122
|
-
</SidebarFooter>
|
|
123
|
-
</BaseSidebar>
|
|
124
|
-
);
|
|
125
|
-
};
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { CheckSquare, Home } from "lucide-react";
|
|
6
|
-
import { Link, useLocation } from "react-router";
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Sidebar,
|
|
10
|
-
SidebarContent,
|
|
11
|
-
SidebarFooter,
|
|
12
|
-
SidebarHeader,
|
|
13
|
-
SidebarMenu,
|
|
14
|
-
SidebarMenuButton,
|
|
15
|
-
SidebarMenuItem,
|
|
16
|
-
useSidebar,
|
|
17
|
-
} from "@/ui/base/side_bar";
|
|
18
|
-
import { cn } from "@/ui/base/utils";
|
|
19
|
-
import { UserMenu } from "@/web/layouts/sidebar/sidebar_aside/user_menu";
|
|
20
|
-
|
|
21
|
-
type SidebarAsideProps = React.ComponentProps<typeof Sidebar>;
|
|
22
|
-
|
|
23
|
-
const NAV_ITEMS = [
|
|
24
|
-
{ to: "/", label: "Home", icon: Home, exact: true },
|
|
25
|
-
{ to: "/todos", label: "Todos", icon: CheckSquare, exact: false },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
export const SidebarAside = ({ className, ...props }: SidebarAsideProps) => {
|
|
29
|
-
const { setOpenMobile } = useSidebar();
|
|
30
|
-
const location = useLocation();
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<Sidebar
|
|
34
|
-
data-slot="app-sidebar"
|
|
35
|
-
className={cn("border-r border-sidebar-border", className)}
|
|
36
|
-
collapsible="offcanvas"
|
|
37
|
-
{...props}
|
|
38
|
-
>
|
|
39
|
-
<SidebarHeader>
|
|
40
|
-
<SidebarMenu>
|
|
41
|
-
<SidebarMenuItem>
|
|
42
|
-
<SidebarMenuButton size="lg" asChild>
|
|
43
|
-
<Link to="/" onClick={() => setOpenMobile(false)}>
|
|
44
|
-
<div className="flex size-8 items-center justify-center rounded-md bg-primary text-primary-foreground text-sm font-bold">
|
|
45
|
-
A
|
|
46
|
-
</div>
|
|
47
|
-
<span className="font-semibold">My App</span>
|
|
48
|
-
</Link>
|
|
49
|
-
</SidebarMenuButton>
|
|
50
|
-
</SidebarMenuItem>
|
|
51
|
-
</SidebarMenu>
|
|
52
|
-
</SidebarHeader>
|
|
53
|
-
|
|
54
|
-
<SidebarContent className="px-2">
|
|
55
|
-
<SidebarMenu>
|
|
56
|
-
{NAV_ITEMS.map(({ to, label, icon: Icon, exact }) => {
|
|
57
|
-
const isActive = exact ? location.pathname === to : location.pathname.startsWith(to);
|
|
58
|
-
return (
|
|
59
|
-
<SidebarMenuItem key={to}>
|
|
60
|
-
<SidebarMenuButton isActive={isActive} asChild onClick={() => setOpenMobile(false)}>
|
|
61
|
-
<Link to={to}>
|
|
62
|
-
<Icon className="size-4" />
|
|
63
|
-
<span>{label}</span>
|
|
64
|
-
</Link>
|
|
65
|
-
</SidebarMenuButton>
|
|
66
|
-
</SidebarMenuItem>
|
|
67
|
-
);
|
|
68
|
-
})}
|
|
69
|
-
</SidebarMenu>
|
|
70
|
-
</SidebarContent>
|
|
71
|
-
<SidebarFooter>
|
|
72
|
-
<UserMenu />
|
|
73
|
-
</SidebarFooter>
|
|
74
|
-
</Sidebar>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { SidebarInset, SidebarProvider } from "@/ui/base/side_bar";
|
|
2
|
-
import { SidebarAside } from "@/web/layouts/sidebar/sidebar_aside/sidebar_aside";
|
|
3
|
-
|
|
4
|
-
type SideBarLayoutProps = {
|
|
5
|
-
children: React.ReactNode;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const SideBarLayout = ({ children }: SideBarLayoutProps) => {
|
|
9
|
-
return (
|
|
10
|
-
<SidebarProvider
|
|
11
|
-
style={
|
|
12
|
-
{
|
|
13
|
-
"--sidebar-width": "calc(var(--spacing) * 45)",
|
|
14
|
-
"--header-height": "calc(var(--spacing) * 12)",
|
|
15
|
-
} as React.CSSProperties
|
|
16
|
-
}
|
|
17
|
-
>
|
|
18
|
-
<SidebarAside variant="inset" />
|
|
19
|
-
<SidebarInset>{children}</SidebarInset>
|
|
20
|
-
</SidebarProvider>
|
|
21
|
-
);
|
|
22
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) SalesStar Limited 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { useAuth } from "@clerk/react-router";
|
|
6
|
-
import { Navigate, Outlet } from "react-router";
|
|
7
|
-
|
|
8
|
-
import { SideBarLayout } from "@/web/layouts/sidebar/sidebar_layout";
|
|
9
|
-
|
|
10
|
-
export default function Layout() {
|
|
11
|
-
const { isLoaded, isSignedIn } = useAuth();
|
|
12
|
-
|
|
13
|
-
if (!isLoaded) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (!isSignedIn) {
|
|
18
|
-
return <Navigate to="/sign-in" replace />;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<SideBarLayout>
|
|
23
|
-
<Outlet />
|
|
24
|
-
</SideBarLayout>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { useParams } from "react-router";
|
|
6
|
-
|
|
7
|
-
import type { TodoId } from "@/api/todos/types";
|
|
8
|
-
import { SingleTodoSurface } from "@/web/surfaces/todos/single_todo_surface";
|
|
9
|
-
|
|
10
|
-
export function meta() {
|
|
11
|
-
return [{ title: "Todo" }, { name: "description", content: "Todo" }];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default function TodoPage() {
|
|
15
|
-
const { id } = useParams<{ id: TodoId }>();
|
|
16
|
-
|
|
17
|
-
if (!id) {
|
|
18
|
-
return <div>Todo not found</div>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return <SingleTodoSurface todoId={id} />;
|
|
22
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) Aron Weston 2026.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { AllTodosSurface } from "@/web/surfaces/todos/all_todos_surface";
|
|
6
|
-
|
|
7
|
-
export function meta() {
|
|
8
|
-
return [{ title: "Todos" }, { name: "description", content: "Todos" }];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default function TodosPage() {
|
|
12
|
-
return <AllTodosSurface />;
|
|
13
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { index, layout, prefix, type RouteConfig, route } from "@react-router/dev/routes";
|
|
2
|
-
|
|
3
|
-
export default [
|
|
4
|
-
layout("./routes/auth/layout.tsx", [route("/sign-in/*", "./routes/auth/sign-in.tsx")]),
|
|
5
|
-
layout("./routes/layout.tsx", [
|
|
6
|
-
index("./routes/index.tsx"),
|
|
7
|
-
...prefix("todos", [
|
|
8
|
-
index("./routes/todos/index.tsx"),
|
|
9
|
-
route(":id", "./routes/todos/[id].tsx"),
|
|
10
|
-
]),
|
|
11
|
-
]),
|
|
12
|
-
] satisfies RouteConfig;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { useUser } from "@clerk/react-router";
|
|
2
|
-
import { Link } from "react-router";
|
|
3
|
-
|
|
4
|
-
import { Button } from "@/ui/base/button";
|
|
5
|
-
|
|
6
|
-
export const HomeSurface = () => {
|
|
7
|
-
const { user } = useUser();
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<main className="flex flex-1 flex-col items-center justify-center gap-4 p-8">
|
|
11
|
-
<h1 className="text-3xl font-bold">
|
|
12
|
-
Welcome{user?.firstName ? `, ${user.firstName}` : ""}
|
|
13
|
-
</h1>
|
|
14
|
-
<p className="text-muted-foreground">Get started by managing your todos.</p>
|
|
15
|
-
<Button asChild>
|
|
16
|
-
<Link to="/todos">View Todos</Link>
|
|
17
|
-
</Button>
|
|
18
|
-
</main>
|
|
19
|
-
);
|
|
20
|
-
};
|