create-aron-app 0.1.6 → 0.1.8

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.
Files changed (234) hide show
  1. package/README.md +24 -31
  2. package/dist/index.js +39 -115
  3. package/package.json +7 -4
  4. package/templates/.cursor/rules/backend.mdc +112 -0
  5. package/templates/.cursor/rules/coding_standards.mdc +145 -0
  6. package/templates/.cursor/rules/frontend_architecture.mdc +334 -0
  7. package/templates/.github/workflows/ci.yml +40 -0
  8. package/templates/apps/api/_generated/api.d.ts +57 -0
  9. package/templates/apps/api/_generated/api.js +23 -0
  10. package/templates/apps/api/_generated/dataModel.d.ts +60 -0
  11. package/templates/apps/api/_generated/server.d.ts +143 -0
  12. package/templates/apps/api/_generated/server.js +93 -0
  13. package/templates/apps/api/http.ts +16 -0
  14. package/templates/apps/web/.env.example +10 -0
  15. package/templates/apps/web/.react-router/types/+future.ts +9 -0
  16. package/templates/apps/web/.react-router/types/+routes.ts +76 -0
  17. package/templates/apps/web/.react-router/types/+server-build.d.ts +18 -0
  18. package/templates/apps/web/.react-router/types/src/+types/root.ts +59 -0
  19. package/templates/apps/web/.react-router/types/src/routes/(auth)/+types/layout.ts +62 -0
  20. package/templates/apps/web/.react-router/types/src/routes/(auth)/sign-in/+types/index.ts +65 -0
  21. package/templates/apps/web/.react-router/types/src/routes/(dashboard)/(todos)/+types/[id].ts +68 -0
  22. package/templates/apps/web/.react-router/types/src/routes/(dashboard)/(todos)/+types/index.ts +68 -0
  23. package/templates/apps/web/.react-router/types/src/routes/(dashboard)/(todos)/+types/layout.ts +65 -0
  24. package/templates/apps/web/.react-router/types/src/routes/(dashboard)/+types/index.ts +65 -0
  25. package/templates/apps/web/.react-router/types/src/routes/(dashboard)/+types/layout.ts +62 -0
  26. package/templates/{react-router → apps/web}/project.json +9 -2
  27. package/templates/{react-router → apps/web}/react-router.config.ts +1 -1
  28. package/templates/apps/web/src/app.css +3 -0
  29. package/templates/{react-router → apps/web}/src/components/error_boundary.tsx +1 -1
  30. package/templates/apps/web/src/libs/convex_query_client.ts +11 -0
  31. package/templates/apps/web/src/libs/react_query_client.ts +17 -0
  32. package/templates/apps/web/src/libs/server/auth.ts +32 -0
  33. package/templates/apps/web/src/libs/server/protected.ts +17 -0
  34. package/templates/apps/web/src/providers/api_auth_provider.tsx +26 -0
  35. package/templates/apps/web/src/providers/global_provider.tsx +28 -0
  36. package/templates/apps/web/src/providers/navigation_loading_bar_provider.tsx +72 -0
  37. package/templates/apps/web/src/root.tsx +68 -0
  38. package/templates/{react-router/src/routes/auth → apps/web/src/routes/(auth)}/layout.tsx +1 -1
  39. package/templates/apps/web/src/routes/(dashboard)/(todos)/[id].tsx +33 -0
  40. package/templates/apps/web/src/routes/(dashboard)/(todos)/index.tsx +26 -0
  41. package/templates/apps/web/src/routes/(dashboard)/(todos)/layout.tsx +9 -0
  42. package/templates/apps/web/src/routes/(dashboard)/index.tsx +20 -0
  43. package/templates/apps/web/src/routes/(dashboard)/layout.tsx +20 -0
  44. package/templates/apps/web/src/routes.ts +14 -0
  45. package/templates/apps/web/src/surfaces/home/bootstrap.ts +9 -0
  46. package/templates/apps/web/src/surfaces/home/home.tsx +25 -0
  47. package/templates/apps/web/src/surfaces/home/install.tsx +17 -0
  48. package/templates/apps/web/src/surfaces/home/layout.tsx +35 -0
  49. package/templates/apps/web/src/surfaces/home/main/create.tsx +32 -0
  50. package/templates/apps/web/src/surfaces/sidebar/install.tsx +19 -0
  51. package/templates/apps/web/src/surfaces/sidebar/layout.tsx +119 -0
  52. package/templates/apps/web/src/surfaces/sidebar/nav_main/create.tsx +31 -0
  53. package/templates/apps/web/src/surfaces/sidebar/nav_main/nav_main.tsx +42 -0
  54. package/templates/apps/web/src/surfaces/sidebar/sidebar.tsx +18 -0
  55. package/templates/apps/web/src/surfaces/sidebar/user_menu/create.tsx +26 -0
  56. package/templates/{react-router/src/layouts/sidebar/sidebar_aside → apps/web/src/surfaces/sidebar/user_menu}/user_menu.tsx +13 -9
  57. package/templates/apps/web/src/surfaces/todos/all_todos/all_todos.tsx +25 -0
  58. package/templates/apps/web/src/surfaces/todos/all_todos/all_todos_controller.ts +47 -0
  59. package/templates/apps/web/src/surfaces/todos/all_todos/bootstrap.ts +21 -0
  60. package/templates/apps/web/src/surfaces/todos/all_todos/header/create.tsx +21 -0
  61. package/templates/apps/web/src/surfaces/todos/all_todos/install.tsx +20 -0
  62. package/templates/apps/web/src/surfaces/todos/all_todos/layout.tsx +35 -0
  63. package/templates/apps/web/src/surfaces/todos/all_todos/main/create.tsx +47 -0
  64. package/templates/apps/web/src/surfaces/todos/all_todos/main/main.tsx +68 -0
  65. package/templates/apps/web/src/surfaces/todos/all_todos/main/new_todo_sheet/create.tsx +54 -0
  66. package/templates/apps/web/src/surfaces/todos/all_todos/main/new_todo_sheet/new_todo_sheet.tsx +97 -0
  67. package/templates/apps/web/src/surfaces/todos/all_todos/main/new_todo_sheet/schema.ts +11 -0
  68. package/templates/apps/web/src/surfaces/todos/single_todo/bootstrap.ts +35 -0
  69. package/templates/apps/web/src/surfaces/todos/single_todo/header/create.tsx +24 -0
  70. package/templates/apps/web/src/surfaces/todos/single_todo/header/header.tsx +25 -0
  71. package/templates/apps/web/src/surfaces/todos/single_todo/install.tsx +27 -0
  72. package/templates/apps/web/src/surfaces/todos/single_todo/layout.tsx +45 -0
  73. package/templates/apps/web/src/surfaces/todos/single_todo/main/create.tsx +35 -0
  74. package/templates/apps/web/src/surfaces/todos/single_todo/main/main.tsx +47 -0
  75. package/templates/apps/web/src/surfaces/todos/single_todo/single_todo.tsx +27 -0
  76. package/templates/apps/web/src/surfaces/todos/single_todo/single_todo_controller.ts +16 -0
  77. package/templates/{react-router → apps/web}/vite.config.ts +27 -3
  78. package/templates/{_base/biome.json → biome.json} +12 -0
  79. package/templates/bun.lock +1917 -0
  80. package/templates/{_base/emails → emails}/project.json +1 -1
  81. package/templates/package.json +91 -0
  82. package/templates/{_base/shared → shared}/assets/src/styles/global.css +14 -8
  83. package/templates/shared/ui/src/base/collapsible.tsx +31 -0
  84. package/templates/shared/ui/src/base/hover-card.tsx +42 -0
  85. package/templates/shared/ui/src/base/input-group.tsx +168 -0
  86. package/templates/shared/ui/src/base/panel.tsx +93 -0
  87. package/templates/{_base/shared → shared}/ui/src/hooks/use_mobile.tsx +1 -1
  88. package/templates/{_base/shared → shared}/ui/src/hooks/use_query_params.tsx +6 -7
  89. package/templates/{_base/shared → shared}/ui/tsconfig.json +1 -1
  90. package/templates/shared/utils/src/convex.ts +4 -0
  91. package/templates/{_base/tsconfig.base.json → tsconfig.base.json} +2 -1
  92. package/templates/_base/.cursor/commands/builder.md +0 -0
  93. package/templates/_base/.cursor/rules/api_architecture.mdc +0 -268
  94. package/templates/_base/.cursor/rules/coding_standards.mdc +0 -64
  95. package/templates/_base/.cursor/rules/convex_rules.mdc +0 -675
  96. package/templates/_base/.cursor/rules/frontend_rules.mdc +0 -268
  97. package/templates/_base/.env.convex.example +0 -3
  98. package/templates/_base/.github/workflows/ci.yml +0 -29
  99. package/templates/_base/_gitignore +0 -58
  100. package/templates/_base/package.json +0 -73
  101. package/templates/_base/shared/utils/src/convex.ts +0 -3
  102. package/templates/nextjs/.env.example +0 -8
  103. package/templates/nextjs/index.d.ts +0 -6
  104. package/templates/nextjs/next-env.d.ts +0 -5
  105. package/templates/nextjs/next.config.js +0 -22
  106. package/templates/nextjs/postcss.config.js +0 -17
  107. package/templates/nextjs/project.json +0 -22
  108. package/templates/nextjs/src/app/(auth)/layout.tsx +0 -21
  109. package/templates/nextjs/src/app/(auth)/not-allowed/page.tsx +0 -22
  110. package/templates/nextjs/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +0 -15
  111. package/templates/nextjs/src/app/(dashboard)/layout.tsx +0 -27
  112. package/templates/nextjs/src/app/(dashboard)/page.tsx +0 -5
  113. package/templates/nextjs/src/app/(dashboard)/todos/[id]/page.tsx +0 -23
  114. package/templates/nextjs/src/app/(dashboard)/todos/page.tsx +0 -16
  115. package/templates/nextjs/src/app/app.css +0 -3
  116. package/templates/nextjs/src/app/layout.tsx +0 -26
  117. package/templates/nextjs/src/convex.ts +0 -11
  118. package/templates/nextjs/src/middleware.ts +0 -18
  119. package/templates/nextjs/src/providers/convex_provider.tsx +0 -44
  120. package/templates/nextjs/src/surfaces/home_surface.tsx +0 -22
  121. package/templates/nextjs/src/surfaces/todos/all_todos_surface.tsx +0 -97
  122. package/templates/nextjs/src/surfaces/todos/create_todo_sheet.tsx +0 -107
  123. package/templates/nextjs/src/surfaces/todos/single_todo_surface.tsx +0 -90
  124. package/templates/nextjs/src/ui/sidebar/nav_link.tsx +0 -36
  125. package/templates/nextjs/src/ui/sidebar/sidebar.tsx +0 -125
  126. package/templates/nextjs/src/utils/font.ts +0 -9
  127. package/templates/nextjs/tsconfig.json +0 -42
  128. package/templates/react-router/.env.example +0 -8
  129. package/templates/react-router/src/app.css +0 -3
  130. package/templates/react-router/src/layouts/sidebar/sidebar_aside/sidebar_aside.tsx +0 -76
  131. package/templates/react-router/src/layouts/sidebar/sidebar_layout.tsx +0 -22
  132. package/templates/react-router/src/providers/api_auth_provider.tsx +0 -38
  133. package/templates/react-router/src/root.tsx +0 -37
  134. package/templates/react-router/src/routes/index.tsx +0 -9
  135. package/templates/react-router/src/routes/layout.tsx +0 -26
  136. package/templates/react-router/src/routes/todos/[id].tsx +0 -22
  137. package/templates/react-router/src/routes/todos/index.tsx +0 -13
  138. package/templates/react-router/src/routes.ts +0 -12
  139. package/templates/react-router/src/surfaces/home_surface.tsx +0 -20
  140. package/templates/react-router/src/surfaces/todos/all_todos_surface.tsx +0 -87
  141. package/templates/react-router/src/surfaces/todos/create_todo_sheet.tsx +0 -102
  142. package/templates/react-router/src/surfaces/todos/single_todo_surface.tsx +0 -81
  143. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/SKILL.md +0 -0
  144. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/SKILL.md +0 -0
  145. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/api-specs-context.sh +0 -0
  146. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/execute-request.sh +0 -0
  147. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-endpoint-detail.sh +0 -0
  148. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tag-endpoints.sh +0 -0
  149. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tags.js +0 -0
  150. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/SKILL.md +0 -0
  151. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-in.md +0 -0
  152. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-up.md +0 -0
  153. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-in.md +0 -0
  154. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-up.md +0 -0
  155. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/show-component.md +0 -0
  156. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/SKILL.md +0 -0
  157. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/api-routes.md +0 -0
  158. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/caching-auth.md +0 -0
  159. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/middleware-strategies.md +0 -0
  160. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-actions.md +0 -0
  161. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-vs-client.md +0 -0
  162. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-webhooks/SKILL.md +0 -0
  163. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/SKILL.md +0 -0
  164. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/agents/openai.yml +0 -0
  165. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn-small.png +0 -0
  166. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn.png +0 -0
  167. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/cli.md +0 -0
  168. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/customization.md +0 -0
  169. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/evals/evals.json +0 -0
  170. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/mcp.md +0 -0
  171. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/base-vs-radix.md +0 -0
  172. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/composition.md +0 -0
  173. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/forms.md +0 -0
  174. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/icons.md +0 -0
  175. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/styling.md +0 -0
  176. /package/templates/{_base/.cursor → .cursor}/commands/pr.md +0 -0
  177. /package/templates/{_base/.nvmrc → .nvmrc} +0 -0
  178. /package/templates/{_base/.vscode → .vscode}/settings.json +0 -0
  179. /package/templates/{_base/apps → apps}/api/auth.config.ts +0 -0
  180. /package/templates/{_base/apps → apps}/api/functions.ts +0 -0
  181. /package/templates/{_base/apps → apps}/api/project.json +0 -0
  182. /package/templates/{_base/apps → apps}/api/schema.ts +0 -0
  183. /package/templates/{_base/apps → apps}/api/todos/crud.ts +0 -0
  184. /package/templates/{_base/apps → apps}/api/todos/schema.ts +0 -0
  185. /package/templates/{_base/apps → apps}/api/todos/types.ts +0 -0
  186. /package/templates/{_base/apps → apps}/api/tsconfig.json +0 -0
  187. /package/templates/{_base/apps → apps}/api/types.ts +0 -0
  188. /package/templates/{react-router → apps/web}/postcss.config.js +0 -0
  189. /package/templates/{react-router → apps/web}/public/favicon.ico +0 -0
  190. /package/templates/{react-router/src/routes/auth/sign-in.tsx → apps/web/src/routes/(auth)/sign-in/index.tsx} +0 -0
  191. /package/templates/{react-router → apps/web}/tsconfig.json +0 -0
  192. /package/templates/{_base/convex.json → convex.json} +0 -0
  193. /package/templates/{_base/emails → emails}/tsconfig.json +0 -0
  194. /package/templates/{_base/emails → emails}/welcome_email.tsx +0 -0
  195. /package/templates/{_base/nx.json → nx.json} +0 -0
  196. /package/templates/{_base/scripts → scripts}/sync_convex_env.ts +0 -0
  197. /package/templates/{_base/shared → shared}/assets/image.d.ts +0 -0
  198. /package/templates/{_base/shared → shared}/assets/tsconfig.json +0 -0
  199. /package/templates/{_base/shared → shared}/ui/src/base/alert_dialog.tsx +0 -0
  200. /package/templates/{_base/shared → shared}/ui/src/base/badge.tsx +0 -0
  201. /package/templates/{_base/shared → shared}/ui/src/base/basic_data_table.tsx +0 -0
  202. /package/templates/{_base/shared → shared}/ui/src/base/button.tsx +0 -0
  203. /package/templates/{_base/shared → shared}/ui/src/base/button_group.tsx +0 -0
  204. /package/templates/{_base/shared → shared}/ui/src/base/card.tsx +0 -0
  205. /package/templates/{_base/shared → shared}/ui/src/base/checkbox.tsx +0 -0
  206. /package/templates/{_base/shared → shared}/ui/src/base/command.tsx +0 -0
  207. /package/templates/{_base/shared → shared}/ui/src/base/dialog.tsx +0 -0
  208. /package/templates/{_base/shared → shared}/ui/src/base/dropdown_menu.tsx +0 -0
  209. /package/templates/{_base/shared → shared}/ui/src/base/form.tsx +0 -0
  210. /package/templates/{_base/shared → shared}/ui/src/base/input.tsx +0 -0
  211. /package/templates/{_base/shared → shared}/ui/src/base/label.tsx +0 -0
  212. /package/templates/{_base/shared → shared}/ui/src/base/popover.tsx +0 -0
  213. /package/templates/{_base/shared → shared}/ui/src/base/radio_group.tsx +0 -0
  214. /package/templates/{_base/shared → shared}/ui/src/base/resizable.tsx +0 -0
  215. /package/templates/{_base/shared → shared}/ui/src/base/scroll_area.tsx +0 -0
  216. /package/templates/{_base/shared → shared}/ui/src/base/select.tsx +0 -0
  217. /package/templates/{_base/shared → shared}/ui/src/base/separator.tsx +0 -0
  218. /package/templates/{_base/shared → shared}/ui/src/base/sheet.tsx +0 -0
  219. /package/templates/{_base/shared → shared}/ui/src/base/side_bar.tsx +0 -0
  220. /package/templates/{_base/shared → shared}/ui/src/base/skeleton.tsx +0 -0
  221. /package/templates/{_base/shared → shared}/ui/src/base/spinner.tsx +0 -0
  222. /package/templates/{_base/shared → shared}/ui/src/base/switch.tsx +0 -0
  223. /package/templates/{_base/shared → shared}/ui/src/base/table.tsx +0 -0
  224. /package/templates/{_base/shared → shared}/ui/src/base/text_area.tsx +0 -0
  225. /package/templates/{_base/shared → shared}/ui/src/base/tooltip.tsx +0 -0
  226. /package/templates/{_base/shared → shared}/ui/src/base/utils.ts +0 -0
  227. /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_press.tsx +0 -0
  228. /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_release.tsx +0 -0
  229. /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_click.tsx +0 -0
  230. /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_location.tsx +0 -0
  231. /package/templates/{_base/shared → shared}/ui/src/hooks/use_outside_click.tsx +0 -0
  232. /package/templates/{_base/shared → shared}/utils/src/time.ts +0 -0
  233. /package/templates/{_base/shared → shared}/utils/tsconfig.json +0 -0
  234. /package/templates/{_base/skills-lock.json → skills-lock.json} +0 -0
@@ -0,0 +1,65 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../index.js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(auth)/sign-in/index.tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../../root.js");
15
+ }, {
16
+ id: "routes/(auth)/layout";
17
+ module: typeof import("../../layout.js");
18
+ }, {
19
+ id: "routes/(auth)/sign-in/index";
20
+ module: typeof import("../index.js");
21
+ }];
22
+
23
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
24
+
25
+ export namespace Route {
26
+ // links
27
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
28
+ export type LinksFunction = Annotations["LinksFunction"];
29
+
30
+ // meta
31
+ export type MetaArgs = Annotations["MetaArgs"];
32
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
33
+ export type MetaFunction = Annotations["MetaFunction"];
34
+
35
+ // headers
36
+ export type HeadersArgs = Annotations["HeadersArgs"];
37
+ export type HeadersFunction = Annotations["HeadersFunction"];
38
+
39
+ // middleware
40
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
41
+
42
+ // clientMiddleware
43
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
44
+
45
+ // loader
46
+ export type LoaderArgs = Annotations["LoaderArgs"];
47
+
48
+ // clientLoader
49
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
50
+
51
+ // action
52
+ export type ActionArgs = Annotations["ActionArgs"];
53
+
54
+ // clientAction
55
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
56
+
57
+ // HydrateFallback
58
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
59
+
60
+ // Component
61
+ export type ComponentProps = Annotations["ComponentProps"];
62
+
63
+ // ErrorBoundary
64
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
65
+ }
@@ -0,0 +1,68 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../[id].js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(dashboard)/(todos)/[id].tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../../root.js");
15
+ }, {
16
+ id: "routes/(dashboard)/layout";
17
+ module: typeof import("../../layout.js");
18
+ }, {
19
+ id: "routes/(dashboard)/(todos)/layout";
20
+ module: typeof import("../layout.js");
21
+ }, {
22
+ id: "routes/(dashboard)/(todos)/[id]";
23
+ module: typeof import("../[id].js");
24
+ }];
25
+
26
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
27
+
28
+ export namespace Route {
29
+ // links
30
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
31
+ export type LinksFunction = Annotations["LinksFunction"];
32
+
33
+ // meta
34
+ export type MetaArgs = Annotations["MetaArgs"];
35
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
36
+ export type MetaFunction = Annotations["MetaFunction"];
37
+
38
+ // headers
39
+ export type HeadersArgs = Annotations["HeadersArgs"];
40
+ export type HeadersFunction = Annotations["HeadersFunction"];
41
+
42
+ // middleware
43
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
44
+
45
+ // clientMiddleware
46
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
47
+
48
+ // loader
49
+ export type LoaderArgs = Annotations["LoaderArgs"];
50
+
51
+ // clientLoader
52
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
53
+
54
+ // action
55
+ export type ActionArgs = Annotations["ActionArgs"];
56
+
57
+ // clientAction
58
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
59
+
60
+ // HydrateFallback
61
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
62
+
63
+ // Component
64
+ export type ComponentProps = Annotations["ComponentProps"];
65
+
66
+ // ErrorBoundary
67
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
68
+ }
@@ -0,0 +1,68 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../index.js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(dashboard)/(todos)/index.tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../../root.js");
15
+ }, {
16
+ id: "routes/(dashboard)/layout";
17
+ module: typeof import("../../layout.js");
18
+ }, {
19
+ id: "routes/(dashboard)/(todos)/layout";
20
+ module: typeof import("../layout.js");
21
+ }, {
22
+ id: "routes/(dashboard)/(todos)/index";
23
+ module: typeof import("../index.js");
24
+ }];
25
+
26
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
27
+
28
+ export namespace Route {
29
+ // links
30
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
31
+ export type LinksFunction = Annotations["LinksFunction"];
32
+
33
+ // meta
34
+ export type MetaArgs = Annotations["MetaArgs"];
35
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
36
+ export type MetaFunction = Annotations["MetaFunction"];
37
+
38
+ // headers
39
+ export type HeadersArgs = Annotations["HeadersArgs"];
40
+ export type HeadersFunction = Annotations["HeadersFunction"];
41
+
42
+ // middleware
43
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
44
+
45
+ // clientMiddleware
46
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
47
+
48
+ // loader
49
+ export type LoaderArgs = Annotations["LoaderArgs"];
50
+
51
+ // clientLoader
52
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
53
+
54
+ // action
55
+ export type ActionArgs = Annotations["ActionArgs"];
56
+
57
+ // clientAction
58
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
59
+
60
+ // HydrateFallback
61
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
62
+
63
+ // Component
64
+ export type ComponentProps = Annotations["ComponentProps"];
65
+
66
+ // ErrorBoundary
67
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
68
+ }
@@ -0,0 +1,65 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../layout.js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(dashboard)/(todos)/layout.tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../../root.js");
15
+ }, {
16
+ id: "routes/(dashboard)/layout";
17
+ module: typeof import("../../layout.js");
18
+ }, {
19
+ id: "routes/(dashboard)/(todos)/layout";
20
+ module: typeof import("../layout.js");
21
+ }];
22
+
23
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
24
+
25
+ export namespace Route {
26
+ // links
27
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
28
+ export type LinksFunction = Annotations["LinksFunction"];
29
+
30
+ // meta
31
+ export type MetaArgs = Annotations["MetaArgs"];
32
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
33
+ export type MetaFunction = Annotations["MetaFunction"];
34
+
35
+ // headers
36
+ export type HeadersArgs = Annotations["HeadersArgs"];
37
+ export type HeadersFunction = Annotations["HeadersFunction"];
38
+
39
+ // middleware
40
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
41
+
42
+ // clientMiddleware
43
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
44
+
45
+ // loader
46
+ export type LoaderArgs = Annotations["LoaderArgs"];
47
+
48
+ // clientLoader
49
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
50
+
51
+ // action
52
+ export type ActionArgs = Annotations["ActionArgs"];
53
+
54
+ // clientAction
55
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
56
+
57
+ // HydrateFallback
58
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
59
+
60
+ // Component
61
+ export type ComponentProps = Annotations["ComponentProps"];
62
+
63
+ // ErrorBoundary
64
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
65
+ }
@@ -0,0 +1,65 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../index.js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(dashboard)/index.tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../root.js");
15
+ }, {
16
+ id: "routes/(dashboard)/layout";
17
+ module: typeof import("../layout.js");
18
+ }, {
19
+ id: "routes/(dashboard)/index";
20
+ module: typeof import("../index.js");
21
+ }];
22
+
23
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
24
+
25
+ export namespace Route {
26
+ // links
27
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
28
+ export type LinksFunction = Annotations["LinksFunction"];
29
+
30
+ // meta
31
+ export type MetaArgs = Annotations["MetaArgs"];
32
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
33
+ export type MetaFunction = Annotations["MetaFunction"];
34
+
35
+ // headers
36
+ export type HeadersArgs = Annotations["HeadersArgs"];
37
+ export type HeadersFunction = Annotations["HeadersFunction"];
38
+
39
+ // middleware
40
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
41
+
42
+ // clientMiddleware
43
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
44
+
45
+ // loader
46
+ export type LoaderArgs = Annotations["LoaderArgs"];
47
+
48
+ // clientLoader
49
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
50
+
51
+ // action
52
+ export type ActionArgs = Annotations["ActionArgs"];
53
+
54
+ // clientAction
55
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
56
+
57
+ // HydrateFallback
58
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
59
+
60
+ // Component
61
+ export type ComponentProps = Annotations["ComponentProps"];
62
+
63
+ // ErrorBoundary
64
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
65
+ }
@@ -0,0 +1,62 @@
1
+ // Generated by React Router
2
+
3
+ import type { GetInfo, GetAnnotations } from "react-router/internal";
4
+
5
+ type Module = typeof import("../layout.js")
6
+
7
+ type Info = GetInfo<{
8
+ file: "./routes/(dashboard)/layout.tsx",
9
+ module: Module
10
+ }>
11
+
12
+ type Matches = [{
13
+ id: "root";
14
+ module: typeof import("../../../root.js");
15
+ }, {
16
+ id: "routes/(dashboard)/layout";
17
+ module: typeof import("../layout.js");
18
+ }];
19
+
20
+ type Annotations = GetAnnotations<Info & { module: Module, matches: Matches }, false>;
21
+
22
+ export namespace Route {
23
+ // links
24
+ export type LinkDescriptors = Annotations["LinkDescriptors"];
25
+ export type LinksFunction = Annotations["LinksFunction"];
26
+
27
+ // meta
28
+ export type MetaArgs = Annotations["MetaArgs"];
29
+ export type MetaDescriptors = Annotations["MetaDescriptors"];
30
+ export type MetaFunction = Annotations["MetaFunction"];
31
+
32
+ // headers
33
+ export type HeadersArgs = Annotations["HeadersArgs"];
34
+ export type HeadersFunction = Annotations["HeadersFunction"];
35
+
36
+ // middleware
37
+ export type MiddlewareFunction = Annotations["MiddlewareFunction"];
38
+
39
+ // clientMiddleware
40
+ export type ClientMiddlewareFunction = Annotations["ClientMiddlewareFunction"];
41
+
42
+ // loader
43
+ export type LoaderArgs = Annotations["LoaderArgs"];
44
+
45
+ // clientLoader
46
+ export type ClientLoaderArgs = Annotations["ClientLoaderArgs"];
47
+
48
+ // action
49
+ export type ActionArgs = Annotations["ActionArgs"];
50
+
51
+ // clientAction
52
+ export type ClientActionArgs = Annotations["ClientActionArgs"];
53
+
54
+ // HydrateFallback
55
+ export type HydrateFallbackProps = Annotations["HydrateFallbackProps"];
56
+
57
+ // Component
58
+ export type ComponentProps = Annotations["ComponentProps"];
59
+
60
+ // ErrorBoundary
61
+ export type ErrorBoundaryProps = Annotations["ErrorBoundaryProps"];
62
+ }
@@ -1,10 +1,17 @@
1
1
  {
2
- "name": "my-app:web",
2
+ "name": "web",
3
3
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "./apps/web",
4
+ "sourceRoot": "apps/web",
5
5
  "projectType": "application",
6
6
  "tags": [],
7
7
  "targets": {
8
+ "typecheck": {
9
+ "executor": "nx:run-commands",
10
+ "options": {
11
+ "cwd": "apps/web",
12
+ "command": "bunx react-router typecheck"
13
+ }
14
+ },
8
15
  "dev": {
9
16
  "executor": "nx:run-commands",
10
17
  "options": {
@@ -2,7 +2,7 @@ import type { Config } from "@react-router/dev/config";
2
2
 
3
3
  export default {
4
4
  appDirectory: "src",
5
- ssr: false,
5
+ ssr: true,
6
6
  future: {
7
7
  v8_middleware: true,
8
8
  },
@@ -0,0 +1,3 @@
1
+ @import "../../../shared/assets/src/styles/global.css";
2
+ @source "../../../shared/ui/src/**/*.{js,ts,jsx,tsx}";
3
+ @source "../../../apps/web/src/**/*.{js,ts,jsx,tsx}";
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) SalesStar Limited 2026.
3
3
  */
4
4
 
5
- import type { Route } from "apps/web/.react-router/types/app/+types/root";
5
+ import type { Route } from "../+types/root";
6
6
  import { isRouteErrorResponse } from "react-router";
7
7
 
8
8
  export const ErrorBoundary = ({ error }: Route.ErrorBoundaryProps) => {
@@ -0,0 +1,11 @@
1
+ import { ConvexQueryClient } from "@convex-dev/react-query";
2
+ import { ConvexReactClient } from "convex/react";
3
+
4
+ const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string, {
5
+ expectAuth: true,
6
+ logger: true,
7
+ });
8
+
9
+ const convexQueryClient = new ConvexQueryClient(convex);
10
+
11
+ export { convex, convexQueryClient };
@@ -0,0 +1,17 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+
3
+ import { convexQueryClient } from "@/web/libs/convex_query_client";
4
+
5
+ const reactQueryClient = new QueryClient({
6
+ defaultOptions: {
7
+ queries: {
8
+ queryFn: convexQueryClient.queryFn(),
9
+ gcTime: 0,
10
+ staleTime: 0,
11
+ },
12
+ },
13
+ });
14
+
15
+ convexQueryClient.connect(reactQueryClient);
16
+
17
+ export { reactQueryClient };
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2026.
3
+ */
4
+
5
+ import { getAuth } from "@clerk/react-router/server";
6
+ import { ConvexHttpClient } from "convex/browser";
7
+ import type { LoaderFunctionArgs } from "react-router";
8
+ import { redirect } from "react-router";
9
+
10
+ const CONVEX_URL = process.env.VITE_CONVEX_URL;
11
+
12
+ if (!CONVEX_URL) {
13
+ throw new Error("VITE_CONVEX_URL is not set");
14
+ }
15
+
16
+ export const createConvexClient = async (args: LoaderFunctionArgs): Promise<ConvexHttpClient> => {
17
+ try {
18
+ const auth = await getAuth(args);
19
+ if (!auth.isAuthenticated) {
20
+ throw redirect(`/sign-in?redirect_url=${encodeURIComponent(args.request.url)}`);
21
+ }
22
+ const token = await auth.getToken({ template: "convex" });
23
+ const client = new ConvexHttpClient(CONVEX_URL);
24
+ if (token) {
25
+ client.setAuth(token);
26
+ }
27
+ return client;
28
+ } catch (error) {
29
+ console.error(error);
30
+ throw error;
31
+ }
32
+ };
@@ -0,0 +1,17 @@
1
+ import { getAuth } from "@clerk/react-router/server";
2
+ import { type MiddlewareFunction, redirect } from "react-router";
3
+
4
+ const PUBLIC_ROUTES = ["/sign-in"];
5
+
6
+ export const protectedRoute: MiddlewareFunction<Response> = async ({ request, context }, next) => {
7
+ const { pathname } = new URL(request.url);
8
+ const isPublic = PUBLIC_ROUTES.some((route) => pathname.startsWith(route));
9
+
10
+ if (!isPublic) {
11
+ const auth = await getAuth({ request, context } as Parameters<typeof getAuth>[0]);
12
+ if (!auth.isAuthenticated) {
13
+ throw redirect(`/sign-in?redirect_url=${encodeURIComponent(request.url)}`);
14
+ }
15
+ }
16
+ return next();
17
+ };
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2026.
3
+ */
4
+
5
+ import { ClerkProvider, useAuth } from "@clerk/react-router";
6
+ import { QueryClientProvider } from "@tanstack/react-query";
7
+ import type { Route } from "apps/web/.react-router/types/src/+types/root";
8
+ import { ConvexProviderWithClerk } from "convex/react-clerk";
9
+
10
+ import { convex } from "@/web/libs/convex_query_client";
11
+ import { reactQueryClient } from "@/web/libs/react_query_client";
12
+
13
+ type ApiAuthProviderProps = {
14
+ children: React.ReactNode;
15
+ loaderData: Route.ComponentProps["loaderData"];
16
+ };
17
+
18
+ export const ApiAuthProvider = ({ children, loaderData }: ApiAuthProviderProps) => {
19
+ return (
20
+ <ClerkProvider signInUrl="/sign-in" loaderData={loaderData}>
21
+ <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
22
+ <QueryClientProvider client={reactQueryClient}>{children}</QueryClientProvider>
23
+ </ConvexProviderWithClerk>
24
+ </ClerkProvider>
25
+ );
26
+ };
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2026.
3
+ */
4
+
5
+ import type { ReactNode } from "react";
6
+ import { createContext, useContext } from "react";
7
+
8
+ export type GlobalContextValue = Record<string, never>;
9
+
10
+ const GlobalContext = createContext<GlobalContextValue | undefined>(undefined);
11
+
12
+ type GlobalProviderProps = {
13
+ children: ReactNode;
14
+ };
15
+
16
+ export const GlobalProvider = ({ children }: GlobalProviderProps) => {
17
+ return <GlobalContext.Provider value={{}}>{children}</GlobalContext.Provider>;
18
+ };
19
+
20
+ export const useGlobal = (): GlobalContextValue => {
21
+ const context = useContext(GlobalContext);
22
+
23
+ if (context === undefined) {
24
+ throw new Error("useGlobal must be used within a GlobalProvider");
25
+ }
26
+
27
+ return context;
28
+ };
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2026.
3
+ */
4
+
5
+ import { createContext, type ReactNode, useContext, useEffect, useMemo, useRef } from "react";
6
+ import { useNavigation } from "react-router";
7
+ import { LoadingBarContainer, useLoadingBar } from "react-top-loading-bar";
8
+
9
+ export type NavigationLoadingBarApi = {
10
+ start: () => void;
11
+ complete: () => void;
12
+ };
13
+
14
+ const NavigationLoadingBarContext = createContext<NavigationLoadingBarApi | null>(null);
15
+
16
+ type NavigationLoadingBarProviderProps = {
17
+ children: ReactNode;
18
+ };
19
+
20
+ const NavigationLoadingBarInner = ({ children }: NavigationLoadingBarProviderProps) => {
21
+ const navigation = useNavigation();
22
+
23
+ const { start, complete } = useLoadingBar({
24
+ color: "hsl(var(--primary))",
25
+ height: 2,
26
+ shadow: true,
27
+ });
28
+
29
+ const api = useMemo((): NavigationLoadingBarApi => {
30
+ return { start, complete };
31
+ }, [start, complete]);
32
+
33
+ const skippedInitialIdle = useRef(false);
34
+
35
+ useEffect(() => {
36
+ if (navigation.state !== "idle") {
37
+ start();
38
+ return;
39
+ }
40
+
41
+ if (!skippedInitialIdle.current) {
42
+ skippedInitialIdle.current = true;
43
+ return;
44
+ }
45
+
46
+ complete();
47
+ }, [navigation.state, start, complete]);
48
+
49
+ return (
50
+ <NavigationLoadingBarContext.Provider value={api}>
51
+ {children}
52
+ </NavigationLoadingBarContext.Provider>
53
+ );
54
+ };
55
+
56
+ export const NavigationLoadingBarProvider = ({ children }: NavigationLoadingBarProviderProps) => {
57
+ return (
58
+ <LoadingBarContainer>
59
+ <NavigationLoadingBarInner>{children}</NavigationLoadingBarInner>
60
+ </LoadingBarContainer>
61
+ );
62
+ };
63
+
64
+ export const useNavigationLoadingBar = (): NavigationLoadingBarApi => {
65
+ const ctx = useContext(NavigationLoadingBarContext);
66
+
67
+ if (!ctx) {
68
+ throw new Error("useNavigationLoadingBar must be used within NavigationLoadingBarProvider");
69
+ }
70
+
71
+ return ctx;
72
+ };