create-einja-app 0.2.17 → 0.2.18

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 (270) hide show
  1. package/package.json +2 -2
  2. package/templates/default/.claude/hooks/einja/playwright-resize.sh +12 -2
  3. package/templates/default/.claude/settings.json +15 -0
  4. package/templates/default/.cursor/commands/task-vibe-kanban-loop.md +107 -42
  5. package/templates/default/.env.develop +0 -4
  6. package/templates/default/.env.example +1 -0
  7. package/templates/default/.env.preview +0 -4
  8. package/templates/default/.env.staging +19 -0
  9. package/templates/default/.github/actions/ci/action.yml +39 -0
  10. package/templates/default/.github/actions/migrate/action.yml +39 -0
  11. package/templates/default/.github/actions/neon-export-env/action.yml +28 -0
  12. package/templates/default/.github/actions/setup/action.yml +20 -0
  13. package/templates/default/.github/workflows/claude.yml +1 -0
  14. package/templates/default/.github/workflows/{cleanup-neon-branches.yml → cleanup-pr-preview-db.yml} +28 -24
  15. package/templates/default/.github/workflows/cleanup-pr-preview-on-close.yml +50 -0
  16. package/templates/default/.github/workflows/deploy-pr-preview.yml +398 -0
  17. package/templates/default/.github/workflows/deploy-stable-branches.yml +259 -0
  18. package/templates/default/.github/workflows/release-create-einja-app.yml +95 -0
  19. package/templates/default/.mcp.json +6 -9
  20. package/templates/default/CLAUDE.md +46 -9
  21. package/templates/default/README.md +5 -14
  22. package/templates/default/apps/admin/next.config.ts +11 -0
  23. package/templates/default/apps/admin/package.json +55 -0
  24. package/templates/default/apps/admin/postcss.config.cjs +5 -0
  25. package/templates/default/apps/admin/src/app/(auth)/forgot-password/page.tsx +97 -0
  26. package/templates/default/apps/admin/src/app/(auth)/layout.tsx +18 -0
  27. package/templates/default/apps/admin/src/app/(auth)/otp/page.tsx +121 -0
  28. package/templates/default/apps/admin/src/app/(auth)/sign-in/page.tsx +145 -0
  29. package/templates/default/apps/admin/src/app/(auth)/sign-up/page.tsx +199 -0
  30. package/templates/default/apps/admin/src/app/(errors)/401/page.tsx +27 -0
  31. package/templates/default/apps/admin/src/app/(errors)/403/page.tsx +28 -0
  32. package/templates/default/apps/admin/src/app/(errors)/500/page.tsx +29 -0
  33. package/templates/default/apps/admin/src/app/(errors)/layout.tsx +7 -0
  34. package/templates/default/apps/admin/src/app/(errors)/maintenance/page.tsx +25 -0
  35. package/templates/default/apps/admin/src/app/dashboard/_components/analytics-chart.tsx +68 -0
  36. package/templates/default/apps/admin/src/app/dashboard/_components/analytics.tsx +182 -0
  37. package/templates/default/apps/admin/src/app/dashboard/_components/dashboard-page.tsx +74 -0
  38. package/templates/default/apps/admin/src/app/dashboard/_components/metric-cards.tsx +49 -0
  39. package/templates/default/apps/admin/src/app/dashboard/_components/overview-chart.tsx +73 -0
  40. package/templates/default/apps/admin/src/app/dashboard/_components/recent-sales.tsx +75 -0
  41. package/templates/default/apps/admin/src/app/dashboard/apps/_components/apps-page.tsx +135 -0
  42. package/templates/default/apps/admin/src/app/dashboard/apps/page.tsx +10 -0
  43. package/templates/default/apps/admin/src/app/dashboard/chats/_components/chat-list.tsx +82 -0
  44. package/templates/default/apps/admin/src/app/dashboard/chats/_components/chat-messages.tsx +194 -0
  45. package/templates/default/apps/admin/src/app/dashboard/chats/_components/chats-page.tsx +99 -0
  46. package/templates/default/apps/admin/src/app/dashboard/chats/_components/new-chat.tsx +118 -0
  47. package/templates/default/apps/admin/src/app/dashboard/chats/page.tsx +10 -0
  48. package/templates/default/apps/admin/src/app/dashboard/layout.tsx +9 -0
  49. package/templates/default/apps/admin/src/app/dashboard/not-found.tsx +14 -0
  50. package/templates/default/apps/admin/src/app/dashboard/page.tsx +10 -0
  51. package/templates/default/apps/admin/src/app/dashboard/settings/_components/content-section.tsx +20 -0
  52. package/templates/default/apps/admin/src/app/dashboard/settings/_components/sidebar-nav.tsx +66 -0
  53. package/templates/default/apps/admin/src/app/dashboard/settings/account/page.tsx +173 -0
  54. package/templates/default/apps/admin/src/app/dashboard/settings/appearance/page.tsx +156 -0
  55. package/templates/default/apps/admin/src/app/dashboard/settings/display/page.tsx +125 -0
  56. package/templates/default/apps/admin/src/app/dashboard/settings/layout.tsx +30 -0
  57. package/templates/default/apps/admin/src/app/dashboard/settings/notifications/page.tsx +196 -0
  58. package/templates/default/apps/admin/src/app/dashboard/settings/page.tsx +5 -0
  59. package/templates/default/apps/admin/src/app/dashboard/settings/profile/page.tsx +176 -0
  60. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/data-table-bulk-actions.tsx +183 -0
  61. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/data-table-row-actions.tsx +79 -0
  62. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-columns.tsx +107 -0
  63. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-dialogs.tsx +71 -0
  64. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-import-dialog.tsx +106 -0
  65. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-multi-delete-dialog.tsx +90 -0
  66. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-mutate-drawer.tsx +207 -0
  67. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-page.tsx +31 -0
  68. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-primary-buttons.tsx +19 -0
  69. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-provider.tsx +37 -0
  70. package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-table.tsx +155 -0
  71. package/templates/default/apps/admin/src/app/dashboard/tasks/page.tsx +14 -0
  72. package/templates/default/apps/admin/src/app/dashboard/users/_components/data-table-bulk-actions.tsx +136 -0
  73. package/templates/default/apps/admin/src/app/dashboard/users/_components/data-table-row-actions.tsx +62 -0
  74. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-action-dialog.tsx +297 -0
  75. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-columns.tsx +121 -0
  76. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-delete-dialog.tsx +72 -0
  77. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-dialogs.tsx +49 -0
  78. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-invite-dialog.tsx +139 -0
  79. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-multi-delete-dialog.tsx +89 -0
  80. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-page.tsx +30 -0
  81. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-primary-buttons.tsx +19 -0
  82. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-provider.tsx +35 -0
  83. package/templates/default/apps/admin/src/app/dashboard/users/_components/users-table.tsx +157 -0
  84. package/templates/default/apps/admin/src/app/dashboard/users/page.tsx +10 -0
  85. package/templates/default/apps/admin/src/app/globals.css +109 -0
  86. package/templates/default/apps/admin/src/app/layout.tsx +32 -0
  87. package/templates/default/apps/admin/src/app/not-found.tsx +14 -0
  88. package/templates/default/apps/admin/src/app/page.tsx +5 -0
  89. package/templates/default/apps/admin/src/components/layout/admin-layout.tsx +16 -0
  90. package/templates/default/apps/admin/src/components/layout/app-sidebar.tsx +52 -0
  91. package/templates/default/apps/admin/src/components/layout/nav-config.ts +131 -0
  92. package/templates/default/apps/admin/src/components/providers/theme-provider.tsx +10 -0
  93. package/templates/default/apps/admin/src/components/shared/long-text.tsx +78 -0
  94. package/templates/default/apps/admin/src/components/shared/search-input.tsx +16 -0
  95. package/templates/default/apps/admin/src/components/shared/select-dropdown.tsx +64 -0
  96. package/templates/default/apps/admin/src/data/apps.tsx +116 -0
  97. package/templates/default/apps/admin/src/data/chats.ts +114 -0
  98. package/templates/default/apps/admin/src/data/tasks.ts +114 -0
  99. package/templates/default/apps/admin/src/data/users.ts +90 -0
  100. package/templates/default/apps/admin/src/hooks/use-dialog-state.ts +17 -0
  101. package/templates/default/apps/admin/src/hooks/use-table-url-state.ts +243 -0
  102. package/templates/default/apps/admin/src/lib/show-submitted-data.tsx +12 -0
  103. package/templates/default/apps/admin/src/types/table.d.ts +9 -0
  104. package/templates/default/apps/admin/tsconfig.json +32 -0
  105. package/templates/default/apps/web/next.config.ts +1 -0
  106. package/templates/default/apps/web/package.json +0 -22
  107. package/templates/default/apps/web/postcss.config.cjs +0 -1
  108. package/templates/default/apps/web/src/app/(authenticated)/dashboard/page.tsx +4 -20
  109. package/templates/default/apps/web/src/app/(authenticated)/data/_components/UserTable.tsx +4 -4
  110. package/templates/default/apps/web/src/app/(authenticated)/data/page.tsx +1 -1
  111. package/templates/default/apps/web/src/app/(authenticated)/profile/page.tsx +1 -1
  112. package/templates/default/apps/web/src/app/error.tsx +8 -70
  113. package/templates/default/apps/web/src/app/global-error.tsx +8 -70
  114. package/templates/default/apps/web/src/app/globals.css +20 -0
  115. package/templates/default/apps/web/src/app/not-found.tsx +5 -39
  116. package/templates/default/apps/web/src/app/page.tsx +27 -203
  117. package/templates/default/apps/web/src/app/signin/page.tsx +27 -191
  118. package/templates/default/apps/web/src/app/signup/page.tsx +33 -240
  119. package/templates/default/apps/web/src/components/dashboard/dashboard-stats.tsx +11 -75
  120. package/templates/default/apps/web/src/components/shared/Sidebar.tsx +3 -3
  121. package/templates/default/apps/web/src/components/shared/header.tsx +17 -112
  122. package/templates/default/apps/web/tsconfig.json +0 -6
  123. package/templates/default/biome.json +1 -2
  124. package/templates/default/components.json +2 -2
  125. package/templates/default/docker-compose.yml +1 -1
  126. package/templates/default/gitignore +4 -0
  127. package/templates/default/package.json +1 -0
  128. package/templates/default/packages/admin-ui/catalog/catalog.css +54 -0
  129. package/templates/default/packages/admin-ui/catalog/catalog.tsx +401 -0
  130. package/templates/default/packages/admin-ui/catalog/index.html +12 -0
  131. package/templates/default/packages/admin-ui/catalog/main.tsx +9 -0
  132. package/templates/default/packages/admin-ui/components.json +21 -0
  133. package/templates/default/packages/admin-ui/package.json +105 -0
  134. package/templates/default/packages/admin-ui/src/command-menu/index.tsx +174 -0
  135. package/templates/default/packages/admin-ui/src/data-table/bulk-actions.tsx +215 -0
  136. package/templates/default/packages/admin-ui/src/data-table/column-header.tsx +73 -0
  137. package/templates/default/packages/admin-ui/src/data-table/data-table.tsx +127 -0
  138. package/templates/default/packages/admin-ui/src/data-table/faceted-filter.tsx +148 -0
  139. package/templates/default/packages/admin-ui/src/data-table/index.tsx +9 -0
  140. package/templates/default/packages/admin-ui/src/data-table/pagination.tsx +101 -0
  141. package/templates/default/packages/admin-ui/src/data-table/toolbar.tsx +87 -0
  142. package/templates/default/packages/admin-ui/src/data-table/view-options.tsx +57 -0
  143. package/templates/default/packages/admin-ui/src/hooks/use-mobile.tsx +23 -0
  144. package/templates/default/packages/admin-ui/src/layout/header.tsx +55 -0
  145. package/templates/default/packages/admin-ui/src/layout/index.ts +10 -0
  146. package/templates/default/packages/admin-ui/src/layout/main.tsx +23 -0
  147. package/templates/default/packages/admin-ui/src/layout/nav-group.tsx +111 -0
  148. package/templates/default/packages/admin-ui/src/layout/nav-user.tsx +114 -0
  149. package/templates/default/packages/admin-ui/src/layout/theme-switch.tsx +40 -0
  150. package/templates/default/packages/admin-ui/src/layout/types.ts +21 -0
  151. package/templates/default/packages/admin-ui/src/lib/utils.ts +6 -0
  152. package/templates/default/packages/admin-ui/src/styles/base.css +65 -0
  153. package/templates/default/packages/admin-ui/src/styles/tokens.css +91 -0
  154. package/templates/default/packages/admin-ui/src/tanstack-table.d.ts +10 -0
  155. package/templates/default/packages/admin-ui/src/ui/alert-dialog.tsx +157 -0
  156. package/templates/default/packages/admin-ui/src/ui/alert.tsx +66 -0
  157. package/templates/default/packages/admin-ui/src/ui/avatar.tsx +53 -0
  158. package/templates/default/packages/admin-ui/src/ui/badge.tsx +46 -0
  159. package/templates/default/packages/admin-ui/src/ui/breadcrumb.tsx +108 -0
  160. package/templates/default/packages/admin-ui/src/ui/button.tsx +59 -0
  161. package/templates/default/packages/admin-ui/src/ui/calendar.tsx +69 -0
  162. package/templates/default/packages/admin-ui/src/ui/card.tsx +92 -0
  163. package/templates/default/packages/admin-ui/src/ui/chart.tsx +345 -0
  164. package/templates/default/packages/admin-ui/src/ui/checkbox.tsx +32 -0
  165. package/templates/default/packages/admin-ui/src/ui/collapsible.tsx +27 -0
  166. package/templates/default/packages/admin-ui/src/ui/command.tsx +161 -0
  167. package/templates/default/packages/admin-ui/src/ui/confirm-dialog.tsx +72 -0
  168. package/templates/default/packages/admin-ui/src/ui/date-picker.tsx +53 -0
  169. package/templates/default/packages/admin-ui/src/ui/dialog.tsx +143 -0
  170. package/templates/default/packages/admin-ui/src/ui/dropdown-menu.tsx +257 -0
  171. package/templates/default/packages/admin-ui/src/ui/form.tsx +168 -0
  172. package/templates/default/packages/admin-ui/src/ui/input-otp.tsx +84 -0
  173. package/templates/default/packages/admin-ui/src/ui/input.tsx +21 -0
  174. package/templates/default/packages/admin-ui/src/ui/label.tsx +24 -0
  175. package/templates/default/packages/admin-ui/src/ui/pagination.tsx +126 -0
  176. package/templates/default/packages/admin-ui/src/ui/password-input.tsx +46 -0
  177. package/templates/default/packages/admin-ui/src/ui/popover.tsx +48 -0
  178. package/templates/default/packages/admin-ui/src/ui/progress.tsx +31 -0
  179. package/templates/default/packages/admin-ui/src/ui/radio-group.tsx +45 -0
  180. package/templates/default/packages/admin-ui/src/ui/scroll-area.tsx +52 -0
  181. package/templates/default/packages/admin-ui/src/ui/select.tsx +185 -0
  182. package/templates/default/packages/admin-ui/src/ui/separator.tsx +28 -0
  183. package/templates/default/packages/admin-ui/src/ui/sheet.tsx +149 -0
  184. package/templates/default/packages/admin-ui/src/ui/sidebar.tsx +728 -0
  185. package/templates/default/packages/admin-ui/src/ui/skeleton.tsx +13 -0
  186. package/templates/default/packages/admin-ui/src/ui/sonner.tsx +25 -0
  187. package/templates/default/packages/admin-ui/src/ui/switch.tsx +31 -0
  188. package/templates/default/packages/admin-ui/src/ui/table.tsx +116 -0
  189. package/templates/default/packages/admin-ui/src/ui/tabs.tsx +66 -0
  190. package/templates/default/packages/admin-ui/src/ui/textarea.tsx +18 -0
  191. package/templates/default/packages/admin-ui/src/ui/toggle-group.tsx +60 -0
  192. package/templates/default/packages/admin-ui/src/ui/toggle.tsx +44 -0
  193. package/templates/default/packages/admin-ui/src/ui/tooltip.tsx +61 -0
  194. package/templates/default/packages/admin-ui/tsconfig.json +8 -0
  195. package/templates/default/packages/admin-ui/vite.config.ts +11 -0
  196. package/templates/default/packages/config/package.json +0 -2
  197. package/templates/default/packages/server-core/package.json +1 -0
  198. package/templates/default/packages/ui/components.json +21 -0
  199. package/templates/default/packages/ui/package.json +42 -5
  200. package/templates/default/packages/ui/src/accordion.tsx +1 -1
  201. package/templates/default/packages/ui/src/alert-dialog.tsx +4 -4
  202. package/templates/default/packages/ui/src/alert.tsx +1 -1
  203. package/templates/default/packages/ui/src/avatar.tsx +1 -1
  204. package/templates/default/packages/ui/src/badge.tsx +1 -1
  205. package/templates/default/packages/ui/src/breadcrumb.tsx +1 -1
  206. package/templates/default/packages/ui/src/button.tsx +1 -1
  207. package/templates/default/packages/ui/src/card.tsx +1 -1
  208. package/templates/default/packages/ui/src/checkbox.tsx +1 -1
  209. package/templates/default/packages/ui/src/dialog.tsx +3 -3
  210. package/templates/default/packages/ui/src/drawer.tsx +3 -3
  211. package/templates/default/packages/ui/src/dropdown-menu.tsx +3 -3
  212. package/templates/default/packages/ui/src/form.tsx +2 -2
  213. package/templates/default/packages/ui/src/hover-card.tsx +2 -2
  214. package/templates/default/packages/ui/src/input.tsx +1 -1
  215. package/templates/default/packages/ui/src/label.tsx +1 -1
  216. package/templates/default/packages/ui/src/pagination.tsx +2 -2
  217. package/templates/default/packages/ui/src/popover.tsx +2 -2
  218. package/templates/default/packages/ui/src/progress.tsx +1 -1
  219. package/templates/default/packages/ui/src/select.tsx +2 -2
  220. package/templates/default/packages/ui/src/separator.tsx +1 -1
  221. package/templates/default/packages/ui/src/skeleton.tsx +1 -1
  222. package/templates/default/packages/ui/src/table.tsx +1 -1
  223. package/templates/default/packages/ui/src/tabs.tsx +1 -1
  224. package/templates/default/packages/ui/src/textarea.tsx +1 -1
  225. package/templates/default/packages/ui/src/tooltip.tsx +3 -3
  226. package/templates/default/packages/ui/src/typography.tsx +1 -1
  227. package/templates/default/packages/ui/tsconfig.json +1 -6
  228. package/templates/default/pnpm-lock.yaml +1319 -936
  229. package/templates/default/postcss.config.cjs +0 -1
  230. package/templates/default/turbo.json +11 -5
  231. package/templates/default/worktree.config.json +5 -0
  232. package/templates/default/.env.ci +0 -32
  233. package/templates/default/.github/workflows/ci.yml +0 -96
  234. package/templates/default/.github/workflows/preview-db.yml +0 -134
  235. package/templates/default/.playwright-mcp/dashboard.png +0 -0
  236. package/templates/default/.playwright-mcp/web-home.png +0 -0
  237. package/templates/default/apps/web/panda.config.ts +0 -114
  238. package/templates/default/apps/web/src/components/ui/accordion.tsx +0 -64
  239. package/templates/default/apps/web/src/components/ui/alert-dialog.tsx +0 -135
  240. package/templates/default/apps/web/src/components/ui/alert.tsx +0 -60
  241. package/templates/default/apps/web/src/components/ui/aspect-ratio.tsx +0 -9
  242. package/templates/default/apps/web/src/components/ui/avatar.tsx +0 -41
  243. package/templates/default/apps/web/src/components/ui/badge.tsx +0 -39
  244. package/templates/default/apps/web/src/components/ui/breadcrumb.tsx +0 -101
  245. package/templates/default/apps/web/src/components/ui/button.tsx +0 -56
  246. package/templates/default/apps/web/src/components/ui/card.tsx +0 -75
  247. package/templates/default/apps/web/src/components/ui/checkbox.tsx +0 -29
  248. package/templates/default/apps/web/src/components/ui/data-table.tsx +0 -189
  249. package/templates/default/apps/web/src/components/ui/dialog-hook.tsx +0 -210
  250. package/templates/default/apps/web/src/components/ui/dialog.tsx +0 -129
  251. package/templates/default/apps/web/src/components/ui/drawer.tsx +0 -124
  252. package/templates/default/apps/web/src/components/ui/dropdown-menu.tsx +0 -228
  253. package/templates/default/apps/web/src/components/ui/form.tsx +0 -152
  254. package/templates/default/apps/web/src/components/ui/hover-card.tsx +0 -38
  255. package/templates/default/apps/web/src/components/ui/input.tsx +0 -21
  256. package/templates/default/apps/web/src/components/ui/label.tsx +0 -21
  257. package/templates/default/apps/web/src/components/ui/pagination.tsx +0 -105
  258. package/templates/default/apps/web/src/components/ui/popover.tsx +0 -42
  259. package/templates/default/apps/web/src/components/ui/progress.tsx +0 -28
  260. package/templates/default/apps/web/src/components/ui/select.tsx +0 -170
  261. package/templates/default/apps/web/src/components/ui/separator.tsx +0 -28
  262. package/templates/default/apps/web/src/components/ui/skeleton.tsx +0 -13
  263. package/templates/default/apps/web/src/components/ui/sonner.tsx +0 -25
  264. package/templates/default/apps/web/src/components/ui/table.tsx +0 -92
  265. package/templates/default/apps/web/src/components/ui/tabs.tsx +0 -54
  266. package/templates/default/apps/web/src/components/ui/textarea.tsx +0 -18
  267. package/templates/default/apps/web/src/components/ui/tooltip.tsx +0 -57
  268. package/templates/default/apps/web/src/components/ui/typography.tsx +0 -158
  269. package/templates/default/packages/config/panda.config.ts +0 -114
  270. package/templates/default/panda.config.ts +0 -114
@@ -0,0 +1,182 @@
1
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "{{packageName}}/admin-ui/ui/card";
2
+ import { AnalyticsChart } from "./analytics-chart";
3
+
4
+ export function Analytics() {
5
+ return (
6
+ <div className="space-y-4">
7
+ <Card>
8
+ <CardHeader>
9
+ <CardTitle>Traffic Overview</CardTitle>
10
+ <CardDescription>Weekly clicks and unique visitors</CardDescription>
11
+ </CardHeader>
12
+ <CardContent className="px-6">
13
+ <AnalyticsChart />
14
+ </CardContent>
15
+ </Card>
16
+ <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
17
+ <Card>
18
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
19
+ <CardTitle className="text-sm font-medium">Total Clicks</CardTitle>
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ viewBox="0 0 24 24"
23
+ fill="none"
24
+ stroke="currentColor"
25
+ strokeLinecap="round"
26
+ strokeLinejoin="round"
27
+ strokeWidth="2"
28
+ className="h-4 w-4 text-muted-foreground"
29
+ role="img"
30
+ aria-label="Chart icon"
31
+ >
32
+ <path d="M3 3v18h18" />
33
+ <path d="M7 15l4-4 4 4 4-6" />
34
+ </svg>
35
+ </CardHeader>
36
+ <CardContent>
37
+ <div className="text-2xl font-bold">1,248</div>
38
+ <p className="text-xs text-muted-foreground">+12.4% vs last week</p>
39
+ </CardContent>
40
+ </Card>
41
+ <Card>
42
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
43
+ <CardTitle className="text-sm font-medium">Unique Visitors</CardTitle>
44
+ <svg
45
+ xmlns="http://www.w3.org/2000/svg"
46
+ viewBox="0 0 24 24"
47
+ fill="none"
48
+ stroke="currentColor"
49
+ strokeLinecap="round"
50
+ strokeLinejoin="round"
51
+ strokeWidth="2"
52
+ className="h-4 w-4 text-muted-foreground"
53
+ role="img"
54
+ aria-label="User icon"
55
+ >
56
+ <circle cx="12" cy="7" r="4" />
57
+ <path d="M6 21v-2a6 6 0 0 1 12 0v2" />
58
+ </svg>
59
+ </CardHeader>
60
+ <CardContent>
61
+ <div className="text-2xl font-bold">832</div>
62
+ <p className="text-xs text-muted-foreground">+5.8% vs last week</p>
63
+ </CardContent>
64
+ </Card>
65
+ <Card>
66
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
67
+ <CardTitle className="text-sm font-medium">Bounce Rate</CardTitle>
68
+ <svg
69
+ xmlns="http://www.w3.org/2000/svg"
70
+ viewBox="0 0 24 24"
71
+ fill="none"
72
+ stroke="currentColor"
73
+ strokeLinecap="round"
74
+ strokeLinejoin="round"
75
+ strokeWidth="2"
76
+ className="h-4 w-4 text-muted-foreground"
77
+ role="img"
78
+ aria-label="Activity icon"
79
+ >
80
+ <path d="M3 12h6l3 6 3-6h6" />
81
+ </svg>
82
+ </CardHeader>
83
+ <CardContent>
84
+ <div className="text-2xl font-bold">42%</div>
85
+ <p className="text-xs text-muted-foreground">-3.2% vs last week</p>
86
+ </CardContent>
87
+ </Card>
88
+ <Card>
89
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
90
+ <CardTitle className="text-sm font-medium">Avg. Session</CardTitle>
91
+ <svg
92
+ xmlns="http://www.w3.org/2000/svg"
93
+ viewBox="0 0 24 24"
94
+ fill="none"
95
+ stroke="currentColor"
96
+ strokeLinecap="round"
97
+ strokeLinejoin="round"
98
+ strokeWidth="2"
99
+ className="h-4 w-4 text-muted-foreground"
100
+ role="img"
101
+ aria-label="Clock icon"
102
+ >
103
+ <circle cx="12" cy="12" r="10" />
104
+ <path d="M12 6v6l4 2" />
105
+ </svg>
106
+ </CardHeader>
107
+ <CardContent>
108
+ <div className="text-2xl font-bold">3m 24s</div>
109
+ <p className="text-xs text-muted-foreground">+18s vs last week</p>
110
+ </CardContent>
111
+ </Card>
112
+ </div>
113
+ <div className="grid grid-cols-1 gap-4 lg:grid-cols-7">
114
+ <Card className="col-span-1 lg:col-span-4">
115
+ <CardHeader>
116
+ <CardTitle>Referrers</CardTitle>
117
+ <CardDescription>Top sources driving traffic</CardDescription>
118
+ </CardHeader>
119
+ <CardContent>
120
+ <SimpleBarList
121
+ items={[
122
+ { name: "Direct", value: 512 },
123
+ { name: "Product Hunt", value: 238 },
124
+ { name: "Twitter", value: 174 },
125
+ { name: "Blog", value: 104 },
126
+ ]}
127
+ barClass="bg-primary"
128
+ valueFormatter={(n) => `${n}`}
129
+ />
130
+ </CardContent>
131
+ </Card>
132
+ <Card className="col-span-1 lg:col-span-3">
133
+ <CardHeader>
134
+ <CardTitle>Devices</CardTitle>
135
+ <CardDescription>How users access your app</CardDescription>
136
+ </CardHeader>
137
+ <CardContent>
138
+ <SimpleBarList
139
+ items={[
140
+ { name: "Desktop", value: 74 },
141
+ { name: "Mobile", value: 22 },
142
+ { name: "Tablet", value: 4 },
143
+ ]}
144
+ barClass="bg-muted-foreground"
145
+ valueFormatter={(n) => `${n}%`}
146
+ />
147
+ </CardContent>
148
+ </Card>
149
+ </div>
150
+ </div>
151
+ );
152
+ }
153
+
154
+ function SimpleBarList({
155
+ items,
156
+ valueFormatter,
157
+ barClass,
158
+ }: {
159
+ items: { name: string; value: number }[];
160
+ valueFormatter: (n: number) => string;
161
+ barClass: string;
162
+ }) {
163
+ const max = Math.max(...items.map((i) => i.value), 1);
164
+ return (
165
+ <ul className="space-y-3">
166
+ {items.map((i) => {
167
+ const width = `${Math.round((i.value / max) * 100)}%`;
168
+ return (
169
+ <li key={i.name} className="flex items-center justify-between gap-3">
170
+ <div className="min-w-0 flex-1">
171
+ <div className="mb-1 truncate text-xs text-muted-foreground">{i.name}</div>
172
+ <div className="h-2.5 w-full rounded-full bg-muted">
173
+ <div className={`h-2.5 rounded-full ${barClass}`} style={{ width }} />
174
+ </div>
175
+ </div>
176
+ <div className="ps-2 text-xs font-medium tabular-nums">{valueFormatter(i.value)}</div>
177
+ </li>
178
+ );
179
+ })}
180
+ </ul>
181
+ );
182
+ }
@@ -0,0 +1,74 @@
1
+ "use client";
2
+
3
+ import { Header } from "{{packageName}}/admin-ui/layout";
4
+ import { Main } from "{{packageName}}/admin-ui/layout";
5
+ import { Button } from "{{packageName}}/admin-ui/ui/button";
6
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "{{packageName}}/admin-ui/ui/card";
7
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "{{packageName}}/admin-ui/ui/tabs";
8
+ import { Download } from "lucide-react";
9
+ import { Analytics } from "./analytics";
10
+ import { MetricCards } from "./metric-cards";
11
+ import { OverviewChart } from "./overview-chart";
12
+ import { RecentSales } from "./recent-sales";
13
+
14
+ export function DashboardPage() {
15
+ return (
16
+ <>
17
+ {/* ===== Top Heading ===== */}
18
+ <Header>
19
+ <div className="mb-2 flex items-center justify-between space-y-2">
20
+ <h1 className="text-2xl font-bold tracking-tight">Dashboard</h1>
21
+ <div className="flex items-center space-x-2">
22
+ <Button>
23
+ <Download className="mr-2 h-4 w-4" />
24
+ Download
25
+ </Button>
26
+ </div>
27
+ </div>
28
+ </Header>
29
+
30
+ {/* ===== Main ===== */}
31
+ <Main>
32
+ <Tabs orientation="vertical" defaultValue="overview" className="space-y-4">
33
+ <div className="w-full overflow-x-auto pb-2">
34
+ <TabsList>
35
+ <TabsTrigger value="overview">Overview</TabsTrigger>
36
+ <TabsTrigger value="analytics">Analytics</TabsTrigger>
37
+ <TabsTrigger value="reports" disabled>
38
+ Reports
39
+ </TabsTrigger>
40
+ <TabsTrigger value="notifications" disabled>
41
+ Notifications
42
+ </TabsTrigger>
43
+ </TabsList>
44
+ </div>
45
+ <TabsContent value="overview" className="space-y-4">
46
+ <MetricCards />
47
+ <div className="grid grid-cols-1 gap-4 lg:grid-cols-7">
48
+ <Card className="col-span-1 lg:col-span-4">
49
+ <CardHeader>
50
+ <CardTitle>Overview</CardTitle>
51
+ </CardHeader>
52
+ <CardContent className="ps-2">
53
+ <OverviewChart />
54
+ </CardContent>
55
+ </Card>
56
+ <Card className="col-span-1 lg:col-span-3">
57
+ <CardHeader>
58
+ <CardTitle>Recent Sales</CardTitle>
59
+ <CardDescription>You made 265 sales this month.</CardDescription>
60
+ </CardHeader>
61
+ <CardContent>
62
+ <RecentSales />
63
+ </CardContent>
64
+ </Card>
65
+ </div>
66
+ </TabsContent>
67
+ <TabsContent value="analytics" className="space-y-4">
68
+ <Analytics />
69
+ </TabsContent>
70
+ </Tabs>
71
+ </Main>
72
+ </>
73
+ );
74
+ }
@@ -0,0 +1,49 @@
1
+ import { Card, CardContent, CardHeader, CardTitle } from "{{packageName}}/admin-ui/ui/card";
2
+ import { Activity, CreditCard, DollarSign, Users } from "lucide-react";
3
+
4
+ export function MetricCards() {
5
+ return (
6
+ <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
7
+ <Card>
8
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
9
+ <CardTitle className="text-sm font-medium">Total Revenue</CardTitle>
10
+ <DollarSign className="h-4 w-4 text-muted-foreground" />
11
+ </CardHeader>
12
+ <CardContent>
13
+ <div className="text-2xl font-bold">$45,231.89</div>
14
+ <p className="text-xs text-muted-foreground">+20.1% from last month</p>
15
+ </CardContent>
16
+ </Card>
17
+ <Card>
18
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
19
+ <CardTitle className="text-sm font-medium">Subscriptions</CardTitle>
20
+ <Users className="h-4 w-4 text-muted-foreground" />
21
+ </CardHeader>
22
+ <CardContent>
23
+ <div className="text-2xl font-bold">+2350</div>
24
+ <p className="text-xs text-muted-foreground">+180.1% from last month</p>
25
+ </CardContent>
26
+ </Card>
27
+ <Card>
28
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
29
+ <CardTitle className="text-sm font-medium">Sales</CardTitle>
30
+ <CreditCard className="h-4 w-4 text-muted-foreground" />
31
+ </CardHeader>
32
+ <CardContent>
33
+ <div className="text-2xl font-bold">+12,234</div>
34
+ <p className="text-xs text-muted-foreground">+19% from last month</p>
35
+ </CardContent>
36
+ </Card>
37
+ <Card>
38
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
39
+ <CardTitle className="text-sm font-medium">Active Now</CardTitle>
40
+ <Activity className="h-4 w-4 text-muted-foreground" />
41
+ </CardHeader>
42
+ <CardContent>
43
+ <div className="text-2xl font-bold">+573</div>
44
+ <p className="text-xs text-muted-foreground">+201 since last hour</p>
45
+ </CardContent>
46
+ </Card>
47
+ </div>
48
+ );
49
+ }
@@ -0,0 +1,73 @@
1
+ "use client";
2
+
3
+ import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis } from "recharts";
4
+
5
+ const data = [
6
+ {
7
+ name: "Jan",
8
+ total: Math.floor(Math.random() * 5000) + 1000,
9
+ },
10
+ {
11
+ name: "Feb",
12
+ total: Math.floor(Math.random() * 5000) + 1000,
13
+ },
14
+ {
15
+ name: "Mar",
16
+ total: Math.floor(Math.random() * 5000) + 1000,
17
+ },
18
+ {
19
+ name: "Apr",
20
+ total: Math.floor(Math.random() * 5000) + 1000,
21
+ },
22
+ {
23
+ name: "May",
24
+ total: Math.floor(Math.random() * 5000) + 1000,
25
+ },
26
+ {
27
+ name: "Jun",
28
+ total: Math.floor(Math.random() * 5000) + 1000,
29
+ },
30
+ {
31
+ name: "Jul",
32
+ total: Math.floor(Math.random() * 5000) + 1000,
33
+ },
34
+ {
35
+ name: "Aug",
36
+ total: Math.floor(Math.random() * 5000) + 1000,
37
+ },
38
+ {
39
+ name: "Sep",
40
+ total: Math.floor(Math.random() * 5000) + 1000,
41
+ },
42
+ {
43
+ name: "Oct",
44
+ total: Math.floor(Math.random() * 5000) + 1000,
45
+ },
46
+ {
47
+ name: "Nov",
48
+ total: Math.floor(Math.random() * 5000) + 1000,
49
+ },
50
+ {
51
+ name: "Dec",
52
+ total: Math.floor(Math.random() * 5000) + 1000,
53
+ },
54
+ ];
55
+
56
+ export function OverviewChart() {
57
+ return (
58
+ <ResponsiveContainer width="100%" height={350}>
59
+ <BarChart data={data}>
60
+ <XAxis dataKey="name" stroke="#888888" fontSize={12} tickLine={false} axisLine={false} />
61
+ <YAxis
62
+ direction="ltr"
63
+ stroke="#888888"
64
+ fontSize={12}
65
+ tickLine={false}
66
+ axisLine={false}
67
+ tickFormatter={(value) => `$${value}`}
68
+ />
69
+ <Bar dataKey="total" fill="currentColor" radius={[4, 4, 0, 0]} className="fill-primary" />
70
+ </BarChart>
71
+ </ResponsiveContainer>
72
+ );
73
+ }
@@ -0,0 +1,75 @@
1
+ import { Avatar, AvatarFallback, AvatarImage } from "{{packageName}}/admin-ui/ui/avatar";
2
+
3
+ export function RecentSales() {
4
+ return (
5
+ <div className="space-y-8">
6
+ <div className="flex items-center gap-4">
7
+ <Avatar className="h-9 w-9">
8
+ <AvatarImage src="/avatars/01.png" alt="Avatar" />
9
+ <AvatarFallback>OM</AvatarFallback>
10
+ </Avatar>
11
+ <div className="flex flex-1 flex-wrap items-center justify-between">
12
+ <div className="space-y-1">
13
+ <p className="text-sm leading-none font-medium">Olivia Martin</p>
14
+ <p className="text-sm text-muted-foreground">olivia.martin@email.com</p>
15
+ </div>
16
+ <div className="font-medium">+$1,999.00</div>
17
+ </div>
18
+ </div>
19
+ <div className="flex items-center gap-4">
20
+ <Avatar className="flex h-9 w-9 items-center justify-center space-y-0 border">
21
+ <AvatarImage src="/avatars/02.png" alt="Avatar" />
22
+ <AvatarFallback>JL</AvatarFallback>
23
+ </Avatar>
24
+ <div className="flex flex-1 flex-wrap items-center justify-between">
25
+ <div className="space-y-1">
26
+ <p className="text-sm leading-none font-medium">Jackson Lee</p>
27
+ <p className="text-sm text-muted-foreground">jackson.lee@email.com</p>
28
+ </div>
29
+ <div className="font-medium">+$39.00</div>
30
+ </div>
31
+ </div>
32
+ <div className="flex items-center gap-4">
33
+ <Avatar className="h-9 w-9">
34
+ <AvatarImage src="/avatars/03.png" alt="Avatar" />
35
+ <AvatarFallback>IN</AvatarFallback>
36
+ </Avatar>
37
+ <div className="flex flex-1 flex-wrap items-center justify-between">
38
+ <div className="space-y-1">
39
+ <p className="text-sm leading-none font-medium">Isabella Nguyen</p>
40
+ <p className="text-sm text-muted-foreground">isabella.nguyen@email.com</p>
41
+ </div>
42
+ <div className="font-medium">+$299.00</div>
43
+ </div>
44
+ </div>
45
+
46
+ <div className="flex items-center gap-4">
47
+ <Avatar className="h-9 w-9">
48
+ <AvatarImage src="/avatars/04.png" alt="Avatar" />
49
+ <AvatarFallback>WK</AvatarFallback>
50
+ </Avatar>
51
+ <div className="flex flex-1 flex-wrap items-center justify-between">
52
+ <div className="space-y-1">
53
+ <p className="text-sm leading-none font-medium">William Kim</p>
54
+ <p className="text-sm text-muted-foreground">will@email.com</p>
55
+ </div>
56
+ <div className="font-medium">+$99.00</div>
57
+ </div>
58
+ </div>
59
+
60
+ <div className="flex items-center gap-4">
61
+ <Avatar className="h-9 w-9">
62
+ <AvatarImage src="/avatars/05.png" alt="Avatar" />
63
+ <AvatarFallback>SD</AvatarFallback>
64
+ </Avatar>
65
+ <div className="flex flex-1 flex-wrap items-center justify-between">
66
+ <div className="space-y-1">
67
+ <p className="text-sm leading-none font-medium">Sofia Davis</p>
68
+ <p className="text-sm text-muted-foreground">sofia.davis@email.com</p>
69
+ </div>
70
+ <div className="font-medium">+$39.00</div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ );
75
+ }
@@ -0,0 +1,135 @@
1
+ "use client";
2
+
3
+ import { apps } from "@/data/apps";
4
+ import { Header, Main } from "{{packageName}}/admin-ui/layout";
5
+ import { Button } from "{{packageName}}/admin-ui/ui/button";
6
+ import { Input } from "{{packageName}}/admin-ui/ui/input";
7
+ import {
8
+ Select,
9
+ SelectContent,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue,
13
+ } from "{{packageName}}/admin-ui/ui/select";
14
+ import { Separator } from "{{packageName}}/admin-ui/ui/separator";
15
+ import { ArrowDownAZ, ArrowUpAZ, SlidersHorizontal } from "lucide-react";
16
+ import { type ChangeEvent, useState } from "react";
17
+
18
+ type AppType = "all" | "connected" | "notConnected";
19
+
20
+ const appText = new Map<AppType, string>([
21
+ ["all", "All Apps"],
22
+ ["connected", "Connected"],
23
+ ["notConnected", "Not Connected"],
24
+ ]);
25
+
26
+ export function AppsPage() {
27
+ const [sort, setSort] = useState<"asc" | "desc">("asc");
28
+ const [appType, setAppType] = useState<AppType>("all");
29
+ const [searchTerm, setSearchTerm] = useState("");
30
+
31
+ const filteredApps = apps
32
+ .sort((a, b) => (sort === "asc" ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name)))
33
+ .filter((app) =>
34
+ appType === "connected" ? app.connected : appType === "notConnected" ? !app.connected : true
35
+ )
36
+ .filter((app) => app.name.toLowerCase().includes(searchTerm.toLowerCase()));
37
+
38
+ const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
39
+ setSearchTerm(e.target.value);
40
+ };
41
+
42
+ const handleTypeChange = (value: AppType) => {
43
+ setAppType(value);
44
+ };
45
+
46
+ const handleSortChange = (value: "asc" | "desc") => {
47
+ setSort(value);
48
+ };
49
+
50
+ return (
51
+ <>
52
+ {/* ===== Top Heading ===== */}
53
+ <Header>
54
+ <div className="flex items-center gap-4">
55
+ <h1 className="text-2xl font-bold tracking-tight">Apps</h1>
56
+ </div>
57
+ </Header>
58
+
59
+ {/* ===== Content ===== */}
60
+ <Main fixed>
61
+ <div>
62
+ <h1 className="text-2xl font-bold tracking-tight">App Integrations</h1>
63
+ <p className="text-muted-foreground">
64
+ Here&apos;s a list of your apps for the integration!
65
+ </p>
66
+ </div>
67
+ <div className="my-4 flex items-end justify-between sm:my-0 sm:items-center">
68
+ <div className="flex flex-col gap-4 sm:my-4 sm:flex-row">
69
+ <Input
70
+ placeholder="Filter apps..."
71
+ className="h-9 w-40 lg:w-[250px]"
72
+ value={searchTerm}
73
+ onChange={handleSearch}
74
+ />
75
+ <Select value={appType} onValueChange={handleTypeChange}>
76
+ <SelectTrigger className="w-36">
77
+ <SelectValue>{appText.get(appType)}</SelectValue>
78
+ </SelectTrigger>
79
+ <SelectContent>
80
+ <SelectItem value="all">All Apps</SelectItem>
81
+ <SelectItem value="connected">Connected</SelectItem>
82
+ <SelectItem value="notConnected">Not Connected</SelectItem>
83
+ </SelectContent>
84
+ </Select>
85
+ </div>
86
+
87
+ <Select value={sort} onValueChange={handleSortChange}>
88
+ <SelectTrigger className="w-16">
89
+ <SelectValue>
90
+ <SlidersHorizontal size={18} />
91
+ </SelectValue>
92
+ </SelectTrigger>
93
+ <SelectContent align="end">
94
+ <SelectItem value="asc">
95
+ <div className="flex items-center gap-4">
96
+ <ArrowUpAZ size={16} />
97
+ <span>Ascending</span>
98
+ </div>
99
+ </SelectItem>
100
+ <SelectItem value="desc">
101
+ <div className="flex items-center gap-4">
102
+ <ArrowDownAZ size={16} />
103
+ <span>Descending</span>
104
+ </div>
105
+ </SelectItem>
106
+ </SelectContent>
107
+ </Select>
108
+ </div>
109
+ <Separator className="shadow-sm" />
110
+ <ul className="faded-bottom no-scrollbar grid gap-4 overflow-auto pt-4 pb-16 md:grid-cols-2 lg:grid-cols-3">
111
+ {filteredApps.map((app) => (
112
+ <li key={app.name} className="rounded-lg border p-4 hover:shadow-md">
113
+ <div className="mb-8 flex items-center justify-between">
114
+ <div className="flex size-10 items-center justify-center rounded-lg bg-muted p-2">
115
+ {app.logo}
116
+ </div>
117
+ <Button
118
+ variant="outline"
119
+ size="sm"
120
+ className={`${app.connected ? "border border-blue-300 bg-blue-50 hover:bg-blue-100 dark:border-blue-700 dark:bg-blue-950 dark:hover:bg-blue-900" : ""}`}
121
+ >
122
+ {app.connected ? "Connected" : "Connect"}
123
+ </Button>
124
+ </div>
125
+ <div>
126
+ <h2 className="mb-1 font-semibold">{app.name}</h2>
127
+ <p className="line-clamp-2 text-gray-500">{app.desc}</p>
128
+ </div>
129
+ </li>
130
+ ))}
131
+ </ul>
132
+ </Main>
133
+ </>
134
+ );
135
+ }
@@ -0,0 +1,10 @@
1
+ import type { Metadata } from "next";
2
+ import { AppsPage } from "./_components/apps-page";
3
+
4
+ export const metadata: Metadata = {
5
+ title: "Apps",
6
+ };
7
+
8
+ export default function Page() {
9
+ return <AppsPage />;
10
+ }