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.
- package/package.json +2 -2
- package/templates/default/.claude/hooks/einja/playwright-resize.sh +12 -2
- package/templates/default/.claude/settings.json +15 -0
- package/templates/default/.cursor/commands/task-vibe-kanban-loop.md +107 -42
- package/templates/default/.env.develop +0 -4
- package/templates/default/.env.example +1 -0
- package/templates/default/.env.preview +0 -4
- package/templates/default/.env.staging +19 -0
- package/templates/default/.github/actions/ci/action.yml +39 -0
- package/templates/default/.github/actions/migrate/action.yml +39 -0
- package/templates/default/.github/actions/neon-export-env/action.yml +28 -0
- package/templates/default/.github/actions/setup/action.yml +20 -0
- package/templates/default/.github/workflows/claude.yml +1 -0
- package/templates/default/.github/workflows/{cleanup-neon-branches.yml → cleanup-pr-preview-db.yml} +28 -24
- package/templates/default/.github/workflows/cleanup-pr-preview-on-close.yml +50 -0
- package/templates/default/.github/workflows/deploy-pr-preview.yml +398 -0
- package/templates/default/.github/workflows/deploy-stable-branches.yml +259 -0
- package/templates/default/.github/workflows/release-create-einja-app.yml +95 -0
- package/templates/default/.mcp.json +6 -9
- package/templates/default/CLAUDE.md +46 -9
- package/templates/default/README.md +5 -14
- package/templates/default/apps/admin/next.config.ts +11 -0
- package/templates/default/apps/admin/package.json +55 -0
- package/templates/default/apps/admin/postcss.config.cjs +5 -0
- package/templates/default/apps/admin/src/app/(auth)/forgot-password/page.tsx +97 -0
- package/templates/default/apps/admin/src/app/(auth)/layout.tsx +18 -0
- package/templates/default/apps/admin/src/app/(auth)/otp/page.tsx +121 -0
- package/templates/default/apps/admin/src/app/(auth)/sign-in/page.tsx +145 -0
- package/templates/default/apps/admin/src/app/(auth)/sign-up/page.tsx +199 -0
- package/templates/default/apps/admin/src/app/(errors)/401/page.tsx +27 -0
- package/templates/default/apps/admin/src/app/(errors)/403/page.tsx +28 -0
- package/templates/default/apps/admin/src/app/(errors)/500/page.tsx +29 -0
- package/templates/default/apps/admin/src/app/(errors)/layout.tsx +7 -0
- package/templates/default/apps/admin/src/app/(errors)/maintenance/page.tsx +25 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/analytics-chart.tsx +68 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/analytics.tsx +182 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/dashboard-page.tsx +74 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/metric-cards.tsx +49 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/overview-chart.tsx +73 -0
- package/templates/default/apps/admin/src/app/dashboard/_components/recent-sales.tsx +75 -0
- package/templates/default/apps/admin/src/app/dashboard/apps/_components/apps-page.tsx +135 -0
- package/templates/default/apps/admin/src/app/dashboard/apps/page.tsx +10 -0
- package/templates/default/apps/admin/src/app/dashboard/chats/_components/chat-list.tsx +82 -0
- package/templates/default/apps/admin/src/app/dashboard/chats/_components/chat-messages.tsx +194 -0
- package/templates/default/apps/admin/src/app/dashboard/chats/_components/chats-page.tsx +99 -0
- package/templates/default/apps/admin/src/app/dashboard/chats/_components/new-chat.tsx +118 -0
- package/templates/default/apps/admin/src/app/dashboard/chats/page.tsx +10 -0
- package/templates/default/apps/admin/src/app/dashboard/layout.tsx +9 -0
- package/templates/default/apps/admin/src/app/dashboard/not-found.tsx +14 -0
- package/templates/default/apps/admin/src/app/dashboard/page.tsx +10 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/_components/content-section.tsx +20 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/_components/sidebar-nav.tsx +66 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/account/page.tsx +173 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/appearance/page.tsx +156 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/display/page.tsx +125 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/layout.tsx +30 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/notifications/page.tsx +196 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/page.tsx +5 -0
- package/templates/default/apps/admin/src/app/dashboard/settings/profile/page.tsx +176 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/data-table-bulk-actions.tsx +183 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/data-table-row-actions.tsx +79 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-columns.tsx +107 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-dialogs.tsx +71 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-import-dialog.tsx +106 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-multi-delete-dialog.tsx +90 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-mutate-drawer.tsx +207 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-page.tsx +31 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-primary-buttons.tsx +19 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-provider.tsx +37 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/_components/tasks-table.tsx +155 -0
- package/templates/default/apps/admin/src/app/dashboard/tasks/page.tsx +14 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/data-table-bulk-actions.tsx +136 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/data-table-row-actions.tsx +62 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-action-dialog.tsx +297 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-columns.tsx +121 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-delete-dialog.tsx +72 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-dialogs.tsx +49 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-invite-dialog.tsx +139 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-multi-delete-dialog.tsx +89 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-page.tsx +30 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-primary-buttons.tsx +19 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-provider.tsx +35 -0
- package/templates/default/apps/admin/src/app/dashboard/users/_components/users-table.tsx +157 -0
- package/templates/default/apps/admin/src/app/dashboard/users/page.tsx +10 -0
- package/templates/default/apps/admin/src/app/globals.css +109 -0
- package/templates/default/apps/admin/src/app/layout.tsx +32 -0
- package/templates/default/apps/admin/src/app/not-found.tsx +14 -0
- package/templates/default/apps/admin/src/app/page.tsx +5 -0
- package/templates/default/apps/admin/src/components/layout/admin-layout.tsx +16 -0
- package/templates/default/apps/admin/src/components/layout/app-sidebar.tsx +52 -0
- package/templates/default/apps/admin/src/components/layout/nav-config.ts +131 -0
- package/templates/default/apps/admin/src/components/providers/theme-provider.tsx +10 -0
- package/templates/default/apps/admin/src/components/shared/long-text.tsx +78 -0
- package/templates/default/apps/admin/src/components/shared/search-input.tsx +16 -0
- package/templates/default/apps/admin/src/components/shared/select-dropdown.tsx +64 -0
- package/templates/default/apps/admin/src/data/apps.tsx +116 -0
- package/templates/default/apps/admin/src/data/chats.ts +114 -0
- package/templates/default/apps/admin/src/data/tasks.ts +114 -0
- package/templates/default/apps/admin/src/data/users.ts +90 -0
- package/templates/default/apps/admin/src/hooks/use-dialog-state.ts +17 -0
- package/templates/default/apps/admin/src/hooks/use-table-url-state.ts +243 -0
- package/templates/default/apps/admin/src/lib/show-submitted-data.tsx +12 -0
- package/templates/default/apps/admin/src/types/table.d.ts +9 -0
- package/templates/default/apps/admin/tsconfig.json +32 -0
- package/templates/default/apps/web/next.config.ts +1 -0
- package/templates/default/apps/web/package.json +0 -22
- package/templates/default/apps/web/postcss.config.cjs +0 -1
- package/templates/default/apps/web/src/app/(authenticated)/dashboard/page.tsx +4 -20
- package/templates/default/apps/web/src/app/(authenticated)/data/_components/UserTable.tsx +4 -4
- package/templates/default/apps/web/src/app/(authenticated)/data/page.tsx +1 -1
- package/templates/default/apps/web/src/app/(authenticated)/profile/page.tsx +1 -1
- package/templates/default/apps/web/src/app/error.tsx +8 -70
- package/templates/default/apps/web/src/app/global-error.tsx +8 -70
- package/templates/default/apps/web/src/app/globals.css +20 -0
- package/templates/default/apps/web/src/app/not-found.tsx +5 -39
- package/templates/default/apps/web/src/app/page.tsx +27 -203
- package/templates/default/apps/web/src/app/signin/page.tsx +27 -191
- package/templates/default/apps/web/src/app/signup/page.tsx +33 -240
- package/templates/default/apps/web/src/components/dashboard/dashboard-stats.tsx +11 -75
- package/templates/default/apps/web/src/components/shared/Sidebar.tsx +3 -3
- package/templates/default/apps/web/src/components/shared/header.tsx +17 -112
- package/templates/default/apps/web/tsconfig.json +0 -6
- package/templates/default/biome.json +1 -2
- package/templates/default/components.json +2 -2
- package/templates/default/docker-compose.yml +1 -1
- package/templates/default/gitignore +4 -0
- package/templates/default/package.json +1 -0
- package/templates/default/packages/admin-ui/catalog/catalog.css +54 -0
- package/templates/default/packages/admin-ui/catalog/catalog.tsx +401 -0
- package/templates/default/packages/admin-ui/catalog/index.html +12 -0
- package/templates/default/packages/admin-ui/catalog/main.tsx +9 -0
- package/templates/default/packages/admin-ui/components.json +21 -0
- package/templates/default/packages/admin-ui/package.json +105 -0
- package/templates/default/packages/admin-ui/src/command-menu/index.tsx +174 -0
- package/templates/default/packages/admin-ui/src/data-table/bulk-actions.tsx +215 -0
- package/templates/default/packages/admin-ui/src/data-table/column-header.tsx +73 -0
- package/templates/default/packages/admin-ui/src/data-table/data-table.tsx +127 -0
- package/templates/default/packages/admin-ui/src/data-table/faceted-filter.tsx +148 -0
- package/templates/default/packages/admin-ui/src/data-table/index.tsx +9 -0
- package/templates/default/packages/admin-ui/src/data-table/pagination.tsx +101 -0
- package/templates/default/packages/admin-ui/src/data-table/toolbar.tsx +87 -0
- package/templates/default/packages/admin-ui/src/data-table/view-options.tsx +57 -0
- package/templates/default/packages/admin-ui/src/hooks/use-mobile.tsx +23 -0
- package/templates/default/packages/admin-ui/src/layout/header.tsx +55 -0
- package/templates/default/packages/admin-ui/src/layout/index.ts +10 -0
- package/templates/default/packages/admin-ui/src/layout/main.tsx +23 -0
- package/templates/default/packages/admin-ui/src/layout/nav-group.tsx +111 -0
- package/templates/default/packages/admin-ui/src/layout/nav-user.tsx +114 -0
- package/templates/default/packages/admin-ui/src/layout/theme-switch.tsx +40 -0
- package/templates/default/packages/admin-ui/src/layout/types.ts +21 -0
- package/templates/default/packages/admin-ui/src/lib/utils.ts +6 -0
- package/templates/default/packages/admin-ui/src/styles/base.css +65 -0
- package/templates/default/packages/admin-ui/src/styles/tokens.css +91 -0
- package/templates/default/packages/admin-ui/src/tanstack-table.d.ts +10 -0
- package/templates/default/packages/admin-ui/src/ui/alert-dialog.tsx +157 -0
- package/templates/default/packages/admin-ui/src/ui/alert.tsx +66 -0
- package/templates/default/packages/admin-ui/src/ui/avatar.tsx +53 -0
- package/templates/default/packages/admin-ui/src/ui/badge.tsx +46 -0
- package/templates/default/packages/admin-ui/src/ui/breadcrumb.tsx +108 -0
- package/templates/default/packages/admin-ui/src/ui/button.tsx +59 -0
- package/templates/default/packages/admin-ui/src/ui/calendar.tsx +69 -0
- package/templates/default/packages/admin-ui/src/ui/card.tsx +92 -0
- package/templates/default/packages/admin-ui/src/ui/chart.tsx +345 -0
- package/templates/default/packages/admin-ui/src/ui/checkbox.tsx +32 -0
- package/templates/default/packages/admin-ui/src/ui/collapsible.tsx +27 -0
- package/templates/default/packages/admin-ui/src/ui/command.tsx +161 -0
- package/templates/default/packages/admin-ui/src/ui/confirm-dialog.tsx +72 -0
- package/templates/default/packages/admin-ui/src/ui/date-picker.tsx +53 -0
- package/templates/default/packages/admin-ui/src/ui/dialog.tsx +143 -0
- package/templates/default/packages/admin-ui/src/ui/dropdown-menu.tsx +257 -0
- package/templates/default/packages/admin-ui/src/ui/form.tsx +168 -0
- package/templates/default/packages/admin-ui/src/ui/input-otp.tsx +84 -0
- package/templates/default/packages/admin-ui/src/ui/input.tsx +21 -0
- package/templates/default/packages/admin-ui/src/ui/label.tsx +24 -0
- package/templates/default/packages/admin-ui/src/ui/pagination.tsx +126 -0
- package/templates/default/packages/admin-ui/src/ui/password-input.tsx +46 -0
- package/templates/default/packages/admin-ui/src/ui/popover.tsx +48 -0
- package/templates/default/packages/admin-ui/src/ui/progress.tsx +31 -0
- package/templates/default/packages/admin-ui/src/ui/radio-group.tsx +45 -0
- package/templates/default/packages/admin-ui/src/ui/scroll-area.tsx +52 -0
- package/templates/default/packages/admin-ui/src/ui/select.tsx +185 -0
- package/templates/default/packages/admin-ui/src/ui/separator.tsx +28 -0
- package/templates/default/packages/admin-ui/src/ui/sheet.tsx +149 -0
- package/templates/default/packages/admin-ui/src/ui/sidebar.tsx +728 -0
- package/templates/default/packages/admin-ui/src/ui/skeleton.tsx +13 -0
- package/templates/default/packages/admin-ui/src/ui/sonner.tsx +25 -0
- package/templates/default/packages/admin-ui/src/ui/switch.tsx +31 -0
- package/templates/default/packages/admin-ui/src/ui/table.tsx +116 -0
- package/templates/default/packages/admin-ui/src/ui/tabs.tsx +66 -0
- package/templates/default/packages/admin-ui/src/ui/textarea.tsx +18 -0
- package/templates/default/packages/admin-ui/src/ui/toggle-group.tsx +60 -0
- package/templates/default/packages/admin-ui/src/ui/toggle.tsx +44 -0
- package/templates/default/packages/admin-ui/src/ui/tooltip.tsx +61 -0
- package/templates/default/packages/admin-ui/tsconfig.json +8 -0
- package/templates/default/packages/admin-ui/vite.config.ts +11 -0
- package/templates/default/packages/config/package.json +0 -2
- package/templates/default/packages/server-core/package.json +1 -0
- package/templates/default/packages/ui/components.json +21 -0
- package/templates/default/packages/ui/package.json +42 -5
- package/templates/default/packages/ui/src/accordion.tsx +1 -1
- package/templates/default/packages/ui/src/alert-dialog.tsx +4 -4
- package/templates/default/packages/ui/src/alert.tsx +1 -1
- package/templates/default/packages/ui/src/avatar.tsx +1 -1
- package/templates/default/packages/ui/src/badge.tsx +1 -1
- package/templates/default/packages/ui/src/breadcrumb.tsx +1 -1
- package/templates/default/packages/ui/src/button.tsx +1 -1
- package/templates/default/packages/ui/src/card.tsx +1 -1
- package/templates/default/packages/ui/src/checkbox.tsx +1 -1
- package/templates/default/packages/ui/src/dialog.tsx +3 -3
- package/templates/default/packages/ui/src/drawer.tsx +3 -3
- package/templates/default/packages/ui/src/dropdown-menu.tsx +3 -3
- package/templates/default/packages/ui/src/form.tsx +2 -2
- package/templates/default/packages/ui/src/hover-card.tsx +2 -2
- package/templates/default/packages/ui/src/input.tsx +1 -1
- package/templates/default/packages/ui/src/label.tsx +1 -1
- package/templates/default/packages/ui/src/pagination.tsx +2 -2
- package/templates/default/packages/ui/src/popover.tsx +2 -2
- package/templates/default/packages/ui/src/progress.tsx +1 -1
- package/templates/default/packages/ui/src/select.tsx +2 -2
- package/templates/default/packages/ui/src/separator.tsx +1 -1
- package/templates/default/packages/ui/src/skeleton.tsx +1 -1
- package/templates/default/packages/ui/src/table.tsx +1 -1
- package/templates/default/packages/ui/src/tabs.tsx +1 -1
- package/templates/default/packages/ui/src/textarea.tsx +1 -1
- package/templates/default/packages/ui/src/tooltip.tsx +3 -3
- package/templates/default/packages/ui/src/typography.tsx +1 -1
- package/templates/default/packages/ui/tsconfig.json +1 -6
- package/templates/default/pnpm-lock.yaml +1319 -936
- package/templates/default/postcss.config.cjs +0 -1
- package/templates/default/turbo.json +11 -5
- package/templates/default/worktree.config.json +5 -0
- package/templates/default/.env.ci +0 -32
- package/templates/default/.github/workflows/ci.yml +0 -96
- package/templates/default/.github/workflows/preview-db.yml +0 -134
- package/templates/default/.playwright-mcp/dashboard.png +0 -0
- package/templates/default/.playwright-mcp/web-home.png +0 -0
- package/templates/default/apps/web/panda.config.ts +0 -114
- package/templates/default/apps/web/src/components/ui/accordion.tsx +0 -64
- package/templates/default/apps/web/src/components/ui/alert-dialog.tsx +0 -135
- package/templates/default/apps/web/src/components/ui/alert.tsx +0 -60
- package/templates/default/apps/web/src/components/ui/aspect-ratio.tsx +0 -9
- package/templates/default/apps/web/src/components/ui/avatar.tsx +0 -41
- package/templates/default/apps/web/src/components/ui/badge.tsx +0 -39
- package/templates/default/apps/web/src/components/ui/breadcrumb.tsx +0 -101
- package/templates/default/apps/web/src/components/ui/button.tsx +0 -56
- package/templates/default/apps/web/src/components/ui/card.tsx +0 -75
- package/templates/default/apps/web/src/components/ui/checkbox.tsx +0 -29
- package/templates/default/apps/web/src/components/ui/data-table.tsx +0 -189
- package/templates/default/apps/web/src/components/ui/dialog-hook.tsx +0 -210
- package/templates/default/apps/web/src/components/ui/dialog.tsx +0 -129
- package/templates/default/apps/web/src/components/ui/drawer.tsx +0 -124
- package/templates/default/apps/web/src/components/ui/dropdown-menu.tsx +0 -228
- package/templates/default/apps/web/src/components/ui/form.tsx +0 -152
- package/templates/default/apps/web/src/components/ui/hover-card.tsx +0 -38
- package/templates/default/apps/web/src/components/ui/input.tsx +0 -21
- package/templates/default/apps/web/src/components/ui/label.tsx +0 -21
- package/templates/default/apps/web/src/components/ui/pagination.tsx +0 -105
- package/templates/default/apps/web/src/components/ui/popover.tsx +0 -42
- package/templates/default/apps/web/src/components/ui/progress.tsx +0 -28
- package/templates/default/apps/web/src/components/ui/select.tsx +0 -170
- package/templates/default/apps/web/src/components/ui/separator.tsx +0 -28
- package/templates/default/apps/web/src/components/ui/skeleton.tsx +0 -13
- package/templates/default/apps/web/src/components/ui/sonner.tsx +0 -25
- package/templates/default/apps/web/src/components/ui/table.tsx +0 -92
- package/templates/default/apps/web/src/components/ui/tabs.tsx +0 -54
- package/templates/default/apps/web/src/components/ui/textarea.tsx +0 -18
- package/templates/default/apps/web/src/components/ui/tooltip.tsx +0 -57
- package/templates/default/apps/web/src/components/ui/typography.tsx +0 -158
- package/templates/default/packages/config/panda.config.ts +0 -114
- 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'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
|
+
}
|