create-aron-app 0.1.6 → 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.
Files changed (260) hide show
  1. package/dist/index.js +50 -115
  2. package/package.json +5 -2
  3. package/templates/{_base/.cursor → .cursor}/rules/api_architecture.mdc +27 -33
  4. package/templates/{_base/.cursor → .cursor}/rules/coding_standards.mdc +1 -1
  5. package/templates/{_base/.cursor → .cursor}/rules/convex_rules.mdc +78 -422
  6. package/templates/.cursor/rules/frontend_architecture_core.mdc +495 -0
  7. package/templates/.cursor/rules/frontend_architecture_nextjs.mdc +458 -0
  8. package/templates/.cursor/rules/frontend_architecture_reactrouter.mdc +473 -0
  9. package/templates/apps/api/_generated/api.d.ts +57 -0
  10. package/templates/apps/api/_generated/api.js +23 -0
  11. package/templates/apps/api/_generated/dataModel.d.ts +60 -0
  12. package/templates/apps/api/_generated/server.d.ts +143 -0
  13. package/templates/apps/api/_generated/server.js +93 -0
  14. package/templates/apps/api/http.ts +16 -0
  15. package/templates/apps/nextjs/.env.example +10 -0
  16. package/templates/{nextjs → apps/nextjs}/project.json +5 -5
  17. package/templates/{nextjs → apps/nextjs}/src/app/(auth)/not-allowed/page.tsx +1 -0
  18. package/templates/apps/nextjs/src/app/(dashboard)/layout.tsx +22 -0
  19. package/templates/apps/nextjs/src/app/(dashboard)/page.tsx +12 -0
  20. package/templates/{nextjs → apps/nextjs}/src/app/(dashboard)/todos/[id]/page.tsx +5 -2
  21. package/templates/apps/nextjs/src/app/(dashboard)/todos/page.tsx +19 -0
  22. package/templates/apps/nextjs/src/middleware.ts +18 -0
  23. package/templates/apps/nextjs/src/surfaces/home/bootstrap.ts +9 -0
  24. package/templates/apps/nextjs/src/surfaces/home/home.tsx +27 -0
  25. package/templates/apps/nextjs/src/surfaces/home/install.tsx +17 -0
  26. package/templates/apps/nextjs/src/surfaces/home/layout.tsx +44 -0
  27. package/templates/apps/nextjs/src/surfaces/home/main/create.tsx +34 -0
  28. package/templates/apps/nextjs/src/surfaces/sidebar/install.tsx +23 -0
  29. package/templates/apps/nextjs/src/surfaces/sidebar/layout.tsx +118 -0
  30. package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/create.tsx +19 -0
  31. package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/nav_config.ts +22 -0
  32. package/templates/apps/nextjs/src/surfaces/sidebar/nav_main/nav_main.tsx +25 -0
  33. package/templates/apps/nextjs/src/surfaces/sidebar/nav_secondary/create.tsx +21 -0
  34. package/templates/apps/nextjs/src/surfaces/sidebar/nav_secondary/nav_secondary.tsx +33 -0
  35. package/templates/apps/nextjs/src/surfaces/sidebar/sidebar.tsx +23 -0
  36. package/templates/{nextjs/src/ui/sidebar/nav_link.tsx → apps/nextjs/src/surfaces/sidebar/ui/sidebar_nav_link.tsx} +13 -10
  37. package/templates/apps/nextjs/src/surfaces/sidebar/user_menu/create.tsx +28 -0
  38. package/templates/apps/nextjs/src/surfaces/sidebar/user_menu/user_menu.tsx +42 -0
  39. package/templates/apps/nextjs/src/surfaces/todos/all_todos/all_todos.tsx +29 -0
  40. package/templates/apps/nextjs/src/surfaces/todos/all_todos/all_todos_controller.ts +61 -0
  41. package/templates/apps/nextjs/src/surfaces/todos/all_todos/bootstrap.ts +21 -0
  42. package/templates/apps/nextjs/src/surfaces/todos/all_todos/header/create.tsx +23 -0
  43. package/templates/apps/nextjs/src/surfaces/todos/all_todos/install.tsx +23 -0
  44. package/templates/apps/nextjs/src/surfaces/todos/all_todos/layout.tsx +44 -0
  45. package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/create.tsx +49 -0
  46. package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/main.tsx +70 -0
  47. package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/create.tsx +56 -0
  48. package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/new_todo_sheet.tsx +99 -0
  49. package/templates/apps/nextjs/src/surfaces/todos/all_todos/main/new_todo_sheet/schema.ts +11 -0
  50. package/templates/apps/nextjs/src/surfaces/todos/single_todo/bootstrap.ts +32 -0
  51. package/templates/apps/nextjs/src/surfaces/todos/single_todo/header/create.tsx +26 -0
  52. package/templates/apps/nextjs/src/surfaces/todos/single_todo/header/header.tsx +22 -0
  53. package/templates/apps/nextjs/src/surfaces/todos/single_todo/install.tsx +27 -0
  54. package/templates/apps/nextjs/src/surfaces/todos/single_todo/layout.tsx +55 -0
  55. package/templates/apps/nextjs/src/surfaces/todos/single_todo/main/create.tsx +38 -0
  56. package/templates/apps/nextjs/src/surfaces/todos/single_todo/main/main.tsx +49 -0
  57. package/templates/apps/nextjs/src/surfaces/todos/single_todo/single_todo.tsx +29 -0
  58. package/templates/apps/nextjs/src/surfaces/todos/single_todo/single_todo_controller.ts +13 -0
  59. package/templates/apps/nextjs/src/utils/auth.ts +18 -0
  60. package/templates/apps/react-router/.env.example +10 -0
  61. package/templates/apps/react-router/.react-router/types/+future.ts +9 -0
  62. package/templates/apps/react-router/.react-router/types/+routes.ts +71 -0
  63. package/templates/apps/react-router/.react-router/types/+server-build.d.ts +18 -0
  64. package/templates/apps/react-router/.react-router/types/src/+types/root.ts +59 -0
  65. package/templates/apps/react-router/.react-router/types/src/routes/(auth)/+types/layout.ts +62 -0
  66. package/templates/apps/react-router/.react-router/types/src/routes/(auth)/sign-in/+types/index.ts +65 -0
  67. package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/+types/index.ts +65 -0
  68. package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/+types/layout.ts +62 -0
  69. package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/todos/+types/[id].ts +65 -0
  70. package/templates/apps/react-router/.react-router/types/src/routes/(dashboard)/todos/+types/index.ts +65 -0
  71. package/templates/{react-router → apps/react-router}/project.json +4 -4
  72. package/templates/apps/react-router/src/app.css +3 -0
  73. package/templates/{react-router → apps/react-router}/src/components/error_boundary.tsx +1 -1
  74. package/templates/{react-router → apps/react-router}/src/providers/api_auth_provider.tsx +2 -0
  75. package/templates/{react-router/src/routes/auth → apps/react-router/src/routes/(auth)}/layout.tsx +1 -1
  76. package/templates/apps/react-router/src/routes/(dashboard)/index.tsx +19 -0
  77. package/templates/apps/react-router/src/routes/(dashboard)/layout.tsx +37 -0
  78. package/templates/apps/react-router/src/routes/(dashboard)/todos/[id].tsx +19 -0
  79. package/templates/apps/react-router/src/routes/(dashboard)/todos/index.tsx +19 -0
  80. package/templates/apps/react-router/src/routes.ts +12 -0
  81. package/templates/apps/react-router/src/surfaces/home/bootstrap.ts +9 -0
  82. package/templates/apps/react-router/src/surfaces/home/home.tsx +25 -0
  83. package/templates/apps/react-router/src/surfaces/home/install.tsx +17 -0
  84. package/templates/apps/react-router/src/surfaces/home/layout.tsx +35 -0
  85. package/templates/apps/react-router/src/surfaces/home/main/create.tsx +32 -0
  86. package/templates/apps/react-router/src/surfaces/sidebar/install.tsx +23 -0
  87. package/templates/apps/react-router/src/surfaces/sidebar/layout.tsx +110 -0
  88. package/templates/apps/react-router/src/surfaces/sidebar/nav_main/create.tsx +31 -0
  89. package/templates/apps/react-router/src/surfaces/sidebar/nav_main/nav_main.tsx +42 -0
  90. package/templates/apps/react-router/src/surfaces/sidebar/nav_secondary/create.tsx +21 -0
  91. package/templates/apps/react-router/src/surfaces/sidebar/nav_secondary/nav_secondary.tsx +31 -0
  92. package/templates/apps/react-router/src/surfaces/sidebar/sidebar.tsx +18 -0
  93. package/templates/apps/react-router/src/surfaces/sidebar/user_menu/create.tsx +26 -0
  94. package/templates/{react-router/src/layouts/sidebar/sidebar_aside → apps/react-router/src/surfaces/sidebar/user_menu}/user_menu.tsx +13 -9
  95. package/templates/apps/react-router/src/surfaces/todos/all_todos/all_todos.tsx +25 -0
  96. package/templates/apps/react-router/src/surfaces/todos/all_todos/all_todos_controller.ts +47 -0
  97. package/templates/apps/react-router/src/surfaces/todos/all_todos/bootstrap.ts +18 -0
  98. package/templates/apps/react-router/src/surfaces/todos/all_todos/header/create.tsx +21 -0
  99. package/templates/apps/react-router/src/surfaces/todos/all_todos/install.tsx +20 -0
  100. package/templates/apps/react-router/src/surfaces/todos/all_todos/layout.tsx +35 -0
  101. package/templates/apps/react-router/src/surfaces/todos/all_todos/main/create.tsx +47 -0
  102. package/templates/apps/react-router/src/surfaces/todos/all_todos/main/main.tsx +68 -0
  103. package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/create.tsx +54 -0
  104. package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/new_todo_sheet.tsx +97 -0
  105. package/templates/apps/react-router/src/surfaces/todos/all_todos/main/new_todo_sheet/schema.ts +11 -0
  106. package/templates/apps/react-router/src/surfaces/todos/single_todo/bootstrap.ts +36 -0
  107. package/templates/apps/react-router/src/surfaces/todos/single_todo/header/create.tsx +32 -0
  108. package/templates/apps/react-router/src/surfaces/todos/single_todo/header/header.tsx +25 -0
  109. package/templates/apps/react-router/src/surfaces/todos/single_todo/install.tsx +27 -0
  110. package/templates/apps/react-router/src/surfaces/todos/single_todo/layout.tsx +45 -0
  111. package/templates/apps/react-router/src/surfaces/todos/single_todo/main/create.tsx +35 -0
  112. package/templates/apps/react-router/src/surfaces/todos/single_todo/main/main.tsx +47 -0
  113. package/templates/apps/react-router/src/surfaces/todos/single_todo/single_todo.tsx +27 -0
  114. package/templates/apps/react-router/src/surfaces/todos/single_todo/single_todo_controller.ts +16 -0
  115. package/templates/{react-router → apps/react-router}/vite.config.ts +27 -3
  116. package/templates/{_base/biome.json → biome.json} +7 -0
  117. package/templates/bun.lock +3187 -0
  118. package/templates/{_base/emails → emails}/project.json +1 -1
  119. package/templates/{_base/nx.json → nx.json} +11 -0
  120. package/templates/package.json +92 -0
  121. package/templates/{_base/tsconfig.base.json → tsconfig.base.json} +4 -1
  122. package/templates/_base/.cursor/rules/frontend_rules.mdc +0 -268
  123. package/templates/_base/.env.convex.example +0 -3
  124. package/templates/_base/_gitignore +0 -58
  125. package/templates/_base/package.json +0 -73
  126. package/templates/nextjs/.env.example +0 -8
  127. package/templates/nextjs/src/app/(dashboard)/layout.tsx +0 -27
  128. package/templates/nextjs/src/app/(dashboard)/page.tsx +0 -5
  129. package/templates/nextjs/src/app/(dashboard)/todos/page.tsx +0 -16
  130. package/templates/nextjs/src/middleware.ts +0 -18
  131. package/templates/nextjs/src/surfaces/home_surface.tsx +0 -22
  132. package/templates/nextjs/src/surfaces/todos/all_todos_surface.tsx +0 -97
  133. package/templates/nextjs/src/surfaces/todos/create_todo_sheet.tsx +0 -107
  134. package/templates/nextjs/src/surfaces/todos/single_todo_surface.tsx +0 -90
  135. package/templates/nextjs/src/ui/sidebar/sidebar.tsx +0 -125
  136. package/templates/react-router/.env.example +0 -8
  137. package/templates/react-router/src/app.css +0 -3
  138. package/templates/react-router/src/layouts/sidebar/sidebar_aside/sidebar_aside.tsx +0 -76
  139. package/templates/react-router/src/layouts/sidebar/sidebar_layout.tsx +0 -22
  140. package/templates/react-router/src/routes/index.tsx +0 -9
  141. package/templates/react-router/src/routes/layout.tsx +0 -26
  142. package/templates/react-router/src/routes/todos/[id].tsx +0 -22
  143. package/templates/react-router/src/routes/todos/index.tsx +0 -13
  144. package/templates/react-router/src/routes.ts +0 -12
  145. package/templates/react-router/src/surfaces/home_surface.tsx +0 -20
  146. package/templates/react-router/src/surfaces/todos/all_todos_surface.tsx +0 -87
  147. package/templates/react-router/src/surfaces/todos/create_todo_sheet.tsx +0 -102
  148. package/templates/react-router/src/surfaces/todos/single_todo_surface.tsx +0 -81
  149. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/SKILL.md +0 -0
  150. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/SKILL.md +0 -0
  151. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/api-specs-context.sh +0 -0
  152. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/execute-request.sh +0 -0
  153. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-endpoint-detail.sh +0 -0
  154. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tag-endpoints.sh +0 -0
  155. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-backend-api/scripts/extract-tags.js +0 -0
  156. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/SKILL.md +0 -0
  157. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-in.md +0 -0
  158. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-up.md +0 -0
  159. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-in.md +0 -0
  160. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-up.md +0 -0
  161. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-custom-ui/core-3/show-component.md +0 -0
  162. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/SKILL.md +0 -0
  163. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/api-routes.md +0 -0
  164. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/caching-auth.md +0 -0
  165. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/middleware-strategies.md +0 -0
  166. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-actions.md +0 -0
  167. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-nextjs-patterns/references/server-vs-client.md +0 -0
  168. /package/templates/{_base/.cursor → .cursor}/agents/skills/clerk/clerk-webhooks/SKILL.md +0 -0
  169. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/SKILL.md +0 -0
  170. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/agents/openai.yml +0 -0
  171. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn-small.png +0 -0
  172. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/assets/shadcn.png +0 -0
  173. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/cli.md +0 -0
  174. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/customization.md +0 -0
  175. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/evals/evals.json +0 -0
  176. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/mcp.md +0 -0
  177. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/base-vs-radix.md +0 -0
  178. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/composition.md +0 -0
  179. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/forms.md +0 -0
  180. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/icons.md +0 -0
  181. /package/templates/{_base/.cursor → .cursor}/agents/skills/shadcn/rules/styling.md +0 -0
  182. /package/templates/{_base/.cursor → .cursor}/commands/builder.md +0 -0
  183. /package/templates/{_base/.cursor → .cursor}/commands/pr.md +0 -0
  184. /package/templates/{_base/.github → .github}/workflows/ci.yml +0 -0
  185. /package/templates/{_base/.nvmrc → .nvmrc} +0 -0
  186. /package/templates/{_base/.vscode → .vscode}/settings.json +0 -0
  187. /package/templates/{_base/apps → apps}/api/auth.config.ts +0 -0
  188. /package/templates/{_base/apps → apps}/api/functions.ts +0 -0
  189. /package/templates/{_base/apps → apps}/api/project.json +0 -0
  190. /package/templates/{_base/apps → apps}/api/schema.ts +0 -0
  191. /package/templates/{_base/apps → apps}/api/todos/crud.ts +0 -0
  192. /package/templates/{_base/apps → apps}/api/todos/schema.ts +0 -0
  193. /package/templates/{_base/apps → apps}/api/todos/types.ts +0 -0
  194. /package/templates/{_base/apps → apps}/api/tsconfig.json +0 -0
  195. /package/templates/{_base/apps → apps}/api/types.ts +0 -0
  196. /package/templates/{nextjs → apps/nextjs}/index.d.ts +0 -0
  197. /package/templates/{nextjs → apps/nextjs}/next-env.d.ts +0 -0
  198. /package/templates/{nextjs → apps/nextjs}/next.config.js +0 -0
  199. /package/templates/{nextjs → apps/nextjs}/postcss.config.js +0 -0
  200. /package/templates/{nextjs → apps/nextjs}/src/app/(auth)/layout.tsx +0 -0
  201. /package/templates/{nextjs → apps/nextjs}/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +0 -0
  202. /package/templates/{nextjs → apps/nextjs}/src/app/app.css +0 -0
  203. /package/templates/{nextjs → apps/nextjs}/src/app/layout.tsx +0 -0
  204. /package/templates/{nextjs → apps/nextjs}/src/providers/convex_provider.tsx +0 -0
  205. /package/templates/{nextjs/src → apps/nextjs/src/utils}/convex.ts +0 -0
  206. /package/templates/{nextjs → apps/nextjs}/src/utils/font.ts +0 -0
  207. /package/templates/{nextjs → apps/nextjs}/tsconfig.json +0 -0
  208. /package/templates/{react-router → apps/react-router}/postcss.config.js +0 -0
  209. /package/templates/{react-router → apps/react-router}/public/favicon.ico +0 -0
  210. /package/templates/{react-router → apps/react-router}/react-router.config.ts +0 -0
  211. /package/templates/{react-router → apps/react-router}/src/root.tsx +0 -0
  212. /package/templates/{react-router/src/routes/auth/sign-in.tsx → apps/react-router/src/routes/(auth)/sign-in/index.tsx} +0 -0
  213. /package/templates/{react-router → apps/react-router}/tsconfig.json +0 -0
  214. /package/templates/{_base/convex.json → convex.json} +0 -0
  215. /package/templates/{_base/emails → emails}/tsconfig.json +0 -0
  216. /package/templates/{_base/emails → emails}/welcome_email.tsx +0 -0
  217. /package/templates/{_base/scripts → scripts}/sync_convex_env.ts +0 -0
  218. /package/templates/{_base/shared → shared}/assets/image.d.ts +0 -0
  219. /package/templates/{_base/shared → shared}/assets/src/styles/global.css +0 -0
  220. /package/templates/{_base/shared → shared}/assets/tsconfig.json +0 -0
  221. /package/templates/{_base/shared → shared}/ui/src/base/alert_dialog.tsx +0 -0
  222. /package/templates/{_base/shared → shared}/ui/src/base/badge.tsx +0 -0
  223. /package/templates/{_base/shared → shared}/ui/src/base/basic_data_table.tsx +0 -0
  224. /package/templates/{_base/shared → shared}/ui/src/base/button.tsx +0 -0
  225. /package/templates/{_base/shared → shared}/ui/src/base/button_group.tsx +0 -0
  226. /package/templates/{_base/shared → shared}/ui/src/base/card.tsx +0 -0
  227. /package/templates/{_base/shared → shared}/ui/src/base/checkbox.tsx +0 -0
  228. /package/templates/{_base/shared → shared}/ui/src/base/command.tsx +0 -0
  229. /package/templates/{_base/shared → shared}/ui/src/base/dialog.tsx +0 -0
  230. /package/templates/{_base/shared → shared}/ui/src/base/dropdown_menu.tsx +0 -0
  231. /package/templates/{_base/shared → shared}/ui/src/base/form.tsx +0 -0
  232. /package/templates/{_base/shared → shared}/ui/src/base/input.tsx +0 -0
  233. /package/templates/{_base/shared → shared}/ui/src/base/label.tsx +0 -0
  234. /package/templates/{_base/shared → shared}/ui/src/base/popover.tsx +0 -0
  235. /package/templates/{_base/shared → shared}/ui/src/base/radio_group.tsx +0 -0
  236. /package/templates/{_base/shared → shared}/ui/src/base/resizable.tsx +0 -0
  237. /package/templates/{_base/shared → shared}/ui/src/base/scroll_area.tsx +0 -0
  238. /package/templates/{_base/shared → shared}/ui/src/base/select.tsx +0 -0
  239. /package/templates/{_base/shared → shared}/ui/src/base/separator.tsx +0 -0
  240. /package/templates/{_base/shared → shared}/ui/src/base/sheet.tsx +0 -0
  241. /package/templates/{_base/shared → shared}/ui/src/base/side_bar.tsx +0 -0
  242. /package/templates/{_base/shared → shared}/ui/src/base/skeleton.tsx +0 -0
  243. /package/templates/{_base/shared → shared}/ui/src/base/spinner.tsx +0 -0
  244. /package/templates/{_base/shared → shared}/ui/src/base/switch.tsx +0 -0
  245. /package/templates/{_base/shared → shared}/ui/src/base/table.tsx +0 -0
  246. /package/templates/{_base/shared → shared}/ui/src/base/text_area.tsx +0 -0
  247. /package/templates/{_base/shared → shared}/ui/src/base/tooltip.tsx +0 -0
  248. /package/templates/{_base/shared → shared}/ui/src/base/utils.ts +0 -0
  249. /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_press.tsx +0 -0
  250. /package/templates/{_base/shared → shared}/ui/src/hooks/use_keyboard_release.tsx +0 -0
  251. /package/templates/{_base/shared → shared}/ui/src/hooks/use_mobile.tsx +0 -0
  252. /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_click.tsx +0 -0
  253. /package/templates/{_base/shared → shared}/ui/src/hooks/use_mouse_location.tsx +0 -0
  254. /package/templates/{_base/shared → shared}/ui/src/hooks/use_outside_click.tsx +0 -0
  255. /package/templates/{_base/shared → shared}/ui/src/hooks/use_query_params.tsx +0 -0
  256. /package/templates/{_base/shared → shared}/ui/tsconfig.json +0 -0
  257. /package/templates/{_base/shared → shared}/utils/src/convex.ts +0 -0
  258. /package/templates/{_base/shared → shared}/utils/src/time.ts +0 -0
  259. /package/templates/{_base/shared → shared}/utils/tsconfig.json +0 -0
  260. /package/templates/{_base/skills-lock.json → skills-lock.json} +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "project:emails",
2
+ "name": "emails",
3
3
  "$schema": "../node_modules/nx/schemas/project-schema.json",
4
4
  "sourceRoot": "emails",
5
5
  "projectType": "library",
@@ -24,6 +24,17 @@
24
24
  "watchDepsName": "watch-deps"
25
25
  }
26
26
  }
27
+ },
28
+ {
29
+ "plugin": "@nx/next/plugin",
30
+ "options": {
31
+ "startTargetName": "start",
32
+ "buildTargetName": "build",
33
+ "devTargetName": "dev",
34
+ "serveStaticTargetName": "serve-static",
35
+ "buildDepsTargetName": "build-deps",
36
+ "watchDepsTargetName": "watch-deps"
37
+ }
27
38
  }
28
39
  ]
29
40
  }
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@/source",
3
+ "version": "0.0.0",
4
+ "license": "MIT",
5
+ "private": true,
6
+ "scripts": {},
7
+ "dependencies": {
8
+ "@clerk/nextjs": "^6.33.7",
9
+ "@clerk/react-router": "^3.0.4",
10
+ "@convex-dev/react-query": "^0.0.0-alpha.8",
11
+ "@hookform/resolvers": "^3.9.1",
12
+ "@radix-ui/react-accordion": "^1.2.2",
13
+ "@radix-ui/react-alert-dialog": "^1.1.4",
14
+ "@radix-ui/react-aspect-ratio": "^1.1.1",
15
+ "@radix-ui/react-checkbox": "^1.1.3",
16
+ "@radix-ui/react-collapsible": "^1.1.2",
17
+ "@radix-ui/react-dropdown-menu": "^2.1.4",
18
+ "@radix-ui/react-hover-card": "^1.1.4",
19
+ "@radix-ui/react-label": "^2.1.1",
20
+ "@radix-ui/react-popover": "^1.1.4",
21
+ "@radix-ui/react-progress": "^1.1.1",
22
+ "@radix-ui/react-radio-group": "^1.2.2",
23
+ "@radix-ui/react-scroll-area": "^1.2.2",
24
+ "@radix-ui/react-select": "^2.1.4",
25
+ "@radix-ui/react-separator": "^1.1.1",
26
+ "@radix-ui/react-slider": "^1.2.2",
27
+ "@radix-ui/react-switch": "^1.1.2",
28
+ "@radix-ui/react-tabs": "^1.1.2",
29
+ "@radix-ui/react-tooltip": "^1.1.6",
30
+ "@react-router/node": "^7.13.1",
31
+ "@react-router/serve": "^7.13.1",
32
+ "@stepperize/react": "^5.1.5",
33
+ "@tailwindcss/typography": "^0.5.16",
34
+ "@tanstack/react-query": "^5.66.0",
35
+ "@tanstack/react-store": "^0.7.0",
36
+ "@tanstack/react-table": "^8.20.6",
37
+ "class-variance-authority": "^0.7.1",
38
+ "cmdk": "^1.0.4",
39
+ "convex": "^1.28.0",
40
+ "convex-ents": "^0.16.0",
41
+ "convex-helpers": "^0.1.114",
42
+ "dayjs": "^1.11.13",
43
+ "hono": "^4.12.9",
44
+ "isbot": "^5",
45
+ "lodash-es": "^4.17.21",
46
+ "lucide-react": "^0.469.0",
47
+ "mobx": "^6.15.0",
48
+ "mobx-react": "^9.2.1",
49
+ "mobx-react-lite": "^4.1.1",
50
+ "nanoid": "^5.1.6",
51
+ "next": "~15.1.4",
52
+ "react": "19.0.0",
53
+ "react-dom": "19.0.0",
54
+ "react-hook-form": "^7.54.2",
55
+ "react-resizable-panels": "^4.7.2",
56
+ "react-router": "^7.5.0",
57
+ "sharp": "^0.33.5",
58
+ "sonner": "^2.0.1",
59
+ "ts-essentials": "^10.1.1",
60
+ "tw-animate-css": "^1.3.8",
61
+ "zod": "^3"
62
+ },
63
+ "devDependencies": {
64
+ "@biomejs/biome": "^2.2.3",
65
+ "@nx/js": "20.6.2",
66
+ "@nx/next": "20.6.2",
67
+ "@nx/workspace": "20.6.2",
68
+ "@react-router/dev": "^7.5.0",
69
+ "@swc-node/register": "~1.9.1",
70
+ "@swc/core": "~1.5.7",
71
+ "@swc/helpers": "~0.5.11",
72
+ "@tailwindcss/postcss": "^4.1.11",
73
+ "@tailwindcss/vite": "^4.1.11",
74
+ "@types/react": "^19.0.0",
75
+ "@vitejs/plugin-react": "^4.3.4",
76
+ "@types/react-dom": "19.0.0",
77
+ "autoprefixer": "10.4.13",
78
+ "nx": "20.6.2",
79
+ "postcss": "8.4.38",
80
+ "tailwind-merge": "^3.0.2",
81
+ "tailwindcss": "^4.1.13",
82
+ "tailwindcss-animate": "^1.0.7",
83
+ "tslib": "^2.3.0",
84
+ "typescript": "~5.7.2",
85
+ "vite": "^6.3.2",
86
+ "vite-plugin-devtools-json": "^1.0.0",
87
+ "vite-tsconfig-paths": "^5.1.4"
88
+ },
89
+ "workspaces": [
90
+ "apps/*"
91
+ ]
92
+ }
@@ -21,13 +21,16 @@
21
21
  "@/ui/*": ["./shared/ui/src/*"],
22
22
  "@/utils/*": ["./shared/utils/src/*"],
23
23
  "@/emails/*": ["./emails/*"],
24
- "@/web/*": ["./apps/web/src/*"]
24
+ "@/web/*": ["./apps/web/src/*", "./apps/nextjs/src/*", "./apps/react-router/src/*"],
25
+ "@/router/*": ["./apps/react-router/.react-router/types/*"],
25
26
  }
26
27
  },
27
28
  "exclude": ["node_modules", "dist", "build", "public"],
28
29
  "include": [
29
30
  "./apps/api/src/**/*",
30
31
  "./apps/web/src/**/*",
32
+ "./apps/nextjs/src/**/*",
33
+ "./apps/react-router/src/**/*",
31
34
  "./shared/**/*",
32
35
  "./tsconfig.json"
33
36
  ]
@@ -1,268 +0,0 @@
1
- ---
2
- description: Frontend coding standards for the Next.js web app. Covers TanStack Query + Convex data fetching, component structure, form handling, and UI patterns.
3
- globs: apps/web/**/*.tsx,apps/web/**/*.ts
4
- ---
5
-
6
- # Frontend Rules
7
-
8
- ## Surfaces & File Structure
9
-
10
- ### Surfaces as Route Entry Points
11
-
12
- Every route must have a corresponding **surface** — the single entry point for that page. Surfaces are isolated vertical slices: they own their data fetching and pass data strictly downward to child components. Pages are thin wrappers that simply render the surface.
13
-
14
- ```
15
- app/(dashboard)/todos/page.tsx → renders <AllTodosSurface />
16
- app/(dashboard)/todos/[id]/page.tsx → renders <SingleTodoSurface />
17
- ```
18
-
19
- ```typescript
20
- // app/(dashboard)/todos/page.tsx
21
- import { AllTodosSurface } from "@/surfaces/todos/all_todos_surface";
22
-
23
- export default function TodosPage() {
24
- return <AllTodosSurface />;
25
- }
26
- ```
27
-
28
- ### Naming Convention
29
-
30
- All file names must be **snake_case** (e.g. `all_todos_surface.tsx`, `create_todo_sheet.tsx`).
31
-
32
- Use **`All`** for list pages and **`Single`** for id-specific pages — both in the surface name and the file name:
33
-
34
- | Route | Surface component | File |
35
- |---|---|---|
36
- | `/todos` | `AllTodosSurface` | `surfaces/todos/all_todos_surface.tsx` |
37
- | `/todos/[id]` | `SingleTodoSurface` | `surfaces/todos/single_todo_surface.tsx` |
38
-
39
- ### Component Placement
40
-
41
- | What | Where |
42
- |---|---|
43
- | Shared components (used across surfaces) | `src/ui/` |
44
- | Components scoped to one surface | inside that surface's folder |
45
- | Multiple shared components within a surface | `src/surfaces/<feature>/ui/` subfolder |
46
- | Providers | `src/providers/` |
47
-
48
- ```
49
- src/
50
- surfaces/
51
- todos/
52
- all_todos_surface.tsx
53
- single_todo_surface.tsx
54
- ui/ ← shared components for this surface only
55
- todo_card.tsx
56
- todo_filters.tsx
57
- ui/ ← truly shared across the app
58
- sidebar/
59
- sidebar.tsx
60
- providers/
61
- convex_provider.tsx
62
- ```
63
-
64
-
65
-
66
-
67
-
68
- ## Data Fetching with TanStack Query
69
-
70
- **ALWAYS use TanStack Query for Convex queries and mutations**, never the direct Convex hooks.
71
-
72
- ### Queries
73
-
74
- ```typescript
75
- import { useQuery } from "@tanstack/react-query";
76
- import { convexQuery } from "@convex-dev/react-query";
77
- import { api } from "@/api/_generated/api";
78
-
79
- // Basic query
80
- const { data: todos } = useQuery(
81
- convexQuery(api.todos.crud.listTodos, { userId: user.id }),
82
- );
83
-
84
- // Conditional / skipped query
85
- const { data: todos } = useQuery(
86
- convexQuery(
87
- api.todos.crud.listTodos,
88
- user?.id ? { userId: user.id } : "skip"
89
- ),
90
- );
91
- ```
92
-
93
- ### Mutations
94
-
95
- ```typescript
96
- import { useMutation } from "@tanstack/react-query";
97
- import { useConvexMutation } from "@convex-dev/react-query";
98
- import { api } from "@/api/_generated/api";
99
-
100
- const { mutate, isPending } = useMutation({
101
- mutationFn: useConvexMutation(api.todos.crud.createTodo),
102
- });
103
-
104
- const handleButtonClick = () => {
105
- mutate({ title, userId });
106
- }
107
-
108
- ```
109
-
110
- ## Component Structure
111
-
112
- ### Declaration
113
-
114
- Always export components as **const arrow functions**:
115
-
116
- ```typescript
117
- // Good
118
- export const ComponentName = ({ prop1, prop2 }: ComponentNameProps) => {
119
- return <div />;
120
- };
121
-
122
- // Bad
123
- export function ComponentName({ prop1, prop2 }: ComponentNameProps) {
124
- return <div />;
125
- }
126
- ```
127
-
128
- ### Props Types
129
-
130
- Always define props as a **separate named type** above the component:
131
-
132
- ```typescript
133
- type ComponentNameProps = {
134
- entityId: Id<"entities">;
135
- onComplete: () => void;
136
- };
137
-
138
- export const ComponentName = ({ entityId, onComplete }: ComponentNameProps) => {
139
- // ...
140
- };
141
- ```
142
-
143
- ## Form Handling
144
-
145
- Use `react-hook-form` + `zod` + TanStack `useMutation`. Standard pattern:
146
-
147
- ```typescript
148
- export const CreateEntityForm = ({ onSuccess }: CreateEntityFormProps) => {
149
- const form = useForm<FormSchema>({
150
- resolver: zodResolver(formSchema),
151
- defaultValues: { title: "" },
152
- });
153
-
154
- const { mutate: createEntity, isPending } = useMutation({
155
- mutationFn: useConvexMutation(api.entities.crud.createEntity),
156
- onSuccess,
157
- });
158
-
159
- const handleSubmit = form.handleSubmit((values) => {
160
- createEntity(values);
161
- });
162
-
163
- return (
164
- <Form {...form}>
165
- <form
166
- onSubmit={handleSubmit}
167
- className="space-y-4"
168
- onKeyDown={(e) => {
169
- if (e.key === "Enter") {
170
- e.preventDefault();
171
- handleSubmit();
172
- }
173
- }}
174
- >
175
- <FormField
176
- control={form.control}
177
- name="title"
178
- render={({ field }) => (
179
- <FormItem>
180
- <FormLabel>Title</FormLabel>
181
- <FormControl>
182
- <Input {...field} />
183
- </FormControl>
184
- <FormMessage />
185
- </FormItem>
186
- )}
187
- />
188
- <Button type="submit" disabled={isPending}>
189
- {isPending ? "Saving..." : "Save"}
190
- </Button>
191
- </form>
192
- </Form>
193
- );
194
- };
195
- ```
196
-
197
- Key rules:
198
- - Store `form.handleSubmit(...)` in a `handleSubmit` const
199
- - Include `onKeyDown` to prevent implicit form submission on Enter
200
- - Use `isPending` for loading states
201
-
202
- ## Sheet / Dialog Components
203
-
204
- ```typescript
205
- export const CreateEntitySheet = ({ entityId }: CreateEntitySheetProps) => {
206
- return (
207
- <Sheet>
208
- <SheetTrigger asChild>
209
- <Button>
210
- <PlusIcon className="mr-2 h-4 w-4" />
211
- Add Entity
212
- </Button>
213
- </SheetTrigger>
214
- <SheetContent className="sm:max-w-[500px]">
215
- <DialogHeader>
216
- <DialogTitle>Add Entity</DialogTitle>
217
- <DialogDescription>Fill in the details below.</DialogDescription>
218
- </DialogHeader>
219
- {/* form content */}
220
- <DialogFooter>
221
- <Button type="submit">Save</Button>
222
- </DialogFooter>
223
- </SheetContent>
224
- </Sheet>
225
- );
226
- };
227
- ```
228
-
229
- - Use `SheetContent` with `DialogHeader` / `DialogTitle` / `DialogDescription` for consistent styling
230
- - Use `DialogFooter` for action buttons
231
-
232
- ## Import Aliases
233
-
234
- Always use alias-based imports — never relative paths outside the same directory:
235
-
236
- ```typescript
237
- import { api } from "@/api/_generated/api";
238
- import { Button } from "@/ui/base/button";
239
- import { SomeUtil } from "@/utils/some_util";
240
- ```
241
-
242
-
243
- ## Routing
244
-
245
- The app uses Next.js App Router:
246
-
247
- | Path | Description |
248
- |---|---|
249
- | `(auth)/sign-in` | Clerk sign-in (public) |
250
- | `(dashboard)/` | Authenticated area — wrapped in sidebar layout |
251
-
252
- Add new authenticated pages inside `apps/web/src/app/(dashboard)/`.
253
-
254
- ## Sidebar Navigation
255
-
256
- To add a nav item, update `apps/web/src/components/sidebar/sidebar.tsx`:
257
-
258
- ```typescript
259
- export const nav = {
260
- main: [
261
- { id: "dashboard", title: "Dashboard", url: "/", icon: HomeIcon },
262
- { id: "my-feature", title: "My Feature", url: "/my-feature", icon: SomeIcon },
263
- ],
264
- secondary: [
265
- { id: "settings", title: "Settings", url: "/settings", icon: SettingsIcon },
266
- ],
267
- };
268
- ```
@@ -1,3 +0,0 @@
1
- CLERK_SECRET_KEY=
2
- CLERK_JWT_ISSUER_DOMAIN=
3
- RESEND_API_KEY=
@@ -1,58 +0,0 @@
1
- # See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
2
-
3
- # compiled output
4
- dist
5
- tmp
6
- out-tsc
7
-
8
- # dependencies
9
- node_modules
10
-
11
- # IDEs and editors
12
- /.idea
13
- .project
14
- .classpath
15
- .c9/
16
- *.launch
17
- .settings/
18
- *.sublime-workspace
19
-
20
- # IDE - VSCode
21
- .vscode/*
22
- !.vscode/settings.json
23
- !.vscode/tasks.json
24
- !.vscode/launch.json
25
- !.vscode/extensions.json
26
-
27
- # misc
28
- .dist
29
- /.sass-cache
30
- /connect.lock
31
- /coverage
32
- /libpeerconnection.log
33
- npm-debug.log
34
- yarn-error.log
35
- testem.log
36
- /typings
37
-
38
- # environment variables
39
- .env
40
- .env.local
41
- .env.convex
42
-
43
- # System Files
44
- .DS_Store
45
- Thumbs.db
46
-
47
- .nx/cache
48
- .nx/workspace-data
49
-
50
- # Next.js
51
- .next
52
- out
53
-
54
- .cursor/rules/nx-rules.mdc
55
- .github/instructions/nx.instructions.md
56
-
57
- # clerk configuration (can include secrets)
58
- /.clerk/
@@ -1,73 +0,0 @@
1
- {
2
- "name": "@/source",
3
- "version": "0.0.0",
4
- "license": "MIT",
5
- "private": true,
6
- "scripts": {},
7
- "dependencies": {
8
- "@convex-dev/react-query": "^0.0.0-alpha.8",
9
- "@hookform/resolvers": "^3.9.1",
10
- "@radix-ui/react-accordion": "^1.2.2",
11
- "@radix-ui/react-alert-dialog": "^1.1.4",
12
- "@radix-ui/react-aspect-ratio": "^1.1.1",
13
- "@radix-ui/react-checkbox": "^1.1.3",
14
- "@radix-ui/react-collapsible": "^1.1.2",
15
- "@radix-ui/react-dropdown-menu": "^2.1.4",
16
- "@radix-ui/react-hover-card": "^1.1.4",
17
- "@radix-ui/react-label": "^2.1.1",
18
- "@radix-ui/react-popover": "^1.1.4",
19
- "@radix-ui/react-progress": "^1.1.1",
20
- "@radix-ui/react-radio-group": "^1.2.2",
21
- "@radix-ui/react-scroll-area": "^1.2.2",
22
- "@radix-ui/react-select": "^2.1.4",
23
- "@radix-ui/react-separator": "^1.1.1",
24
- "@radix-ui/react-slider": "^1.2.2",
25
- "@radix-ui/react-switch": "^1.1.2",
26
- "@radix-ui/react-tabs": "^1.1.2",
27
- "@radix-ui/react-tooltip": "^1.1.6",
28
- "@stepperize/react": "^5.1.5",
29
- "@tailwindcss/typography": "^0.5.16",
30
- "@tanstack/react-query": "^5.66.0",
31
- "@tanstack/react-store": "^0.7.0",
32
- "@tanstack/react-table": "^8.20.6",
33
- "class-variance-authority": "^0.7.1",
34
- "cmdk": "^1.0.4",
35
- "convex": "^1.28.0",
36
- "convex-ents": "^0.16.0",
37
- "convex-helpers": "^0.1.104",
38
- "dayjs": "^1.11.13",
39
- "lodash-es": "^4.17.21",
40
- "lucide-react": "^0.469.0",
41
- "nanoid": "^5.1.6",
42
- "react": "19.0.0",
43
- "react-dom": "19.0.0",
44
- "react-hook-form": "^7.54.2",
45
- "react-resizable-panels": "^4.7.2",
46
- "sonner": "^2.0.1",
47
- "ts-essentials": "^10.1.1",
48
- "tw-animate-css": "^1.3.8",
49
- "zod": "^3"
50
- },
51
- "devDependencies": {
52
- "@biomejs/biome": "^2.2.3",
53
- "@nx/js": "20.6.2",
54
- "@nx/workspace": "20.6.2",
55
- "@swc-node/register": "~1.9.1",
56
- "@swc/core": "~1.5.7",
57
- "@swc/helpers": "~0.5.11",
58
- "@tailwindcss/postcss": "^4.1.11",
59
- "@types/react": "19.0.0",
60
- "@types/react-dom": "19.0.0",
61
- "autoprefixer": "10.4.13",
62
- "nx": "20.6.2",
63
- "postcss": "8.4.38",
64
- "tailwind-merge": "^3.0.2",
65
- "tailwindcss": "^4.1.13",
66
- "tailwindcss-animate": "^1.0.7",
67
- "tslib": "^2.3.0",
68
- "typescript": "~5.7.2"
69
- },
70
- "workspaces": [
71
- "apps/*"
72
- ]
73
- }
@@ -1,8 +0,0 @@
1
- # Convex
2
- CONVEX_DEPLOYMENT=
3
- CONVEX_DEPLOYMENT_URL=
4
- NEXT_PUBLIC_CONVEX_URL=
5
-
6
- # Authentication
7
- CLERK_SECRET_KEY=
8
- NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
@@ -1,27 +0,0 @@
1
- /*
2
- * Copyright (c) Aron Weston 2025.
3
- */
4
-
5
- import { SidebarInset, SidebarProvider } from "@/ui/base/side_bar";
6
- import { Sidebar as AppSidebar } from "@/web/ui/sidebar/sidebar";
7
-
8
- type DashboardLayoutProps = {
9
- children: React.ReactNode;
10
- modal: React.ReactNode;
11
- };
12
-
13
- export default function DashboardLayout({ children }: DashboardLayoutProps) {
14
- return (
15
- <SidebarProvider
16
- style={
17
- {
18
- "--sidebar-width": "calc(var(--spacing) * 45)",
19
- "--header-height": "calc(var(--spacing) * 12)",
20
- } as React.CSSProperties
21
- }
22
- >
23
- <AppSidebar variant="inset" />
24
- <SidebarInset>{children}</SidebarInset>
25
- </SidebarProvider>
26
- );
27
- }
@@ -1,5 +0,0 @@
1
- import { HomeSurface } from "@/web/surfaces/home_surface";
2
-
3
- export default function HomePage() {
4
- return <HomeSurface />;
5
- }
@@ -1,16 +0,0 @@
1
- /*
2
- * Copyright (c) Aron Weston 2026.
3
- */
4
-
5
- import type { Metadata } from "next";
6
-
7
- import { AllTodosSurface } from "@/web/surfaces/todos/all_todos_surface";
8
-
9
- export const metadata: Metadata = {
10
- title: "Todos",
11
- description: "Todos",
12
- };
13
-
14
- export default function AllTodosPage() {
15
- return <AllTodosSurface />;
16
- }
@@ -1,18 +0,0 @@
1
- import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
2
-
3
- const isPublicRoute = createRouteMatcher(["/sign-in(.*)"]);
4
-
5
- export default clerkMiddleware(async (auth, req) => {
6
- if (!isPublicRoute(req)) {
7
- await auth.protect();
8
- }
9
- });
10
-
11
- export const config = {
12
- matcher: [
13
- // Skip Next.js internals and all static files, unless found in search params
14
- "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
15
- // Always run for API routes
16
- "/(api|trpc)(.*)",
17
- ],
18
- };
@@ -1,22 +0,0 @@
1
- "use client";
2
-
3
- import { useUser } from "@clerk/nextjs";
4
- import Link from "next/link";
5
-
6
- import { Button } from "@/ui/base/button";
7
-
8
- export const HomeSurface = () => {
9
- const { user } = useUser();
10
-
11
- return (
12
- <main className="flex flex-1 flex-col items-center justify-center gap-4 p-8">
13
- <h1 className="text-3xl font-bold">
14
- Welcome{user?.firstName ? `, ${user.firstName}` : ""}
15
- </h1>
16
- <p className="text-muted-foreground">Get started by managing your todos.</p>
17
- <Button asChild>
18
- <Link href="/todos">View Todos</Link>
19
- </Button>
20
- </main>
21
- );
22
- };