wexts 4.1.0 → 4.1.5

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 (199) hide show
  1. package/README.md +49 -49
  2. package/bin/wexts.cjs +2 -2
  3. package/package.json +153 -148
  4. package/templates/.dockerignore +43 -43
  5. package/templates/.env.example +17 -17
  6. package/templates/Dockerfile +60 -60
  7. package/templates/Procfile +1 -1
  8. package/templates/README.md +67 -67
  9. package/templates/api-sdk.ts +115 -115
  10. package/templates/docker-compose.yml +34 -34
  11. package/templates/nestjs-api/.env.example +3 -3
  12. package/templates/nestjs-api/README.md +87 -87
  13. package/templates/nestjs-api/nest-cli.json +6 -6
  14. package/templates/nestjs-api/package.json +40 -40
  15. package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +24 -24
  16. package/templates/nestjs-api/prisma/migrations/migration_lock.toml +3 -3
  17. package/templates/nestjs-api/prisma/schema.prisma +29 -29
  18. package/templates/nestjs-api/src/app.module.ts +17 -17
  19. package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
  20. package/templates/nestjs-api/src/auth/auth.module.ts +37 -37
  21. package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
  22. package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
  23. package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
  24. package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -27
  25. package/templates/nestjs-api/src/main.ts +32 -32
  26. package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
  27. package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
  28. package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
  29. package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
  30. package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
  31. package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
  32. package/templates/nestjs-api/src/users/users.controller.ts +14 -14
  33. package/templates/nestjs-api/src/users/users.module.ts +12 -12
  34. package/templates/nestjs-api/src/users/users.service.ts +19 -19
  35. package/templates/nestjs-api/tsconfig.json +39 -39
  36. package/templates/nextjs-web/README.md +76 -76
  37. package/templates/nextjs-web/app/actions/auth.ts +108 -108
  38. package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
  39. package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
  40. package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
  41. package/templates/nextjs-web/app/globals.css +93 -93
  42. package/templates/nextjs-web/app/layout.tsx +29 -29
  43. package/templates/nextjs-web/app/login/page.tsx +5 -5
  44. package/templates/nextjs-web/app/page.tsx +28 -28
  45. package/templates/nextjs-web/app/register/page.tsx +5 -5
  46. package/templates/nextjs-web/components/ui/button.tsx +56 -56
  47. package/templates/nextjs-web/components/ui/card.tsx +79 -79
  48. package/templates/nextjs-web/components/ui/input.tsx +25 -25
  49. package/templates/nextjs-web/components/ui/label.tsx +24 -24
  50. package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
  51. package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
  52. package/templates/nextjs-web/features/auth/api.ts +35 -35
  53. package/templates/nextjs-web/features/auth/index.ts +3 -3
  54. package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
  55. package/templates/nextjs-web/features/dashboard/api.ts +9 -9
  56. package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
  57. package/templates/nextjs-web/features/dashboard/index.ts +3 -3
  58. package/templates/nextjs-web/hooks/index.ts +4 -4
  59. package/templates/nextjs-web/lib/api-client.ts +89 -89
  60. package/templates/nextjs-web/lib/api.ts +115 -115
  61. package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
  62. package/templates/nextjs-web/lib/utils.ts +6 -6
  63. package/templates/nextjs-web/lib/wexts-client.ts +4 -4
  64. package/templates/nextjs-web/next-env.d.ts +6 -6
  65. package/templates/nextjs-web/next.config.ts +20 -20
  66. package/templates/nextjs-web/package.json +37 -37
  67. package/templates/nextjs-web/postcss.config.js +6 -6
  68. package/templates/nextjs-web/tailwind.config.ts +69 -69
  69. package/templates/nextjs-web/tsconfig.json +41 -41
  70. package/templates/nixpacks.toml +11 -11
  71. package/templates/root-package.json +31 -31
  72. package/templates/server.ts +66 -66
  73. package/templates/tsconfig.json +30 -30
  74. package/dist/chunk-2KAQYLVN.js +0 -1
  75. package/dist/chunk-2KAQYLVN.js.map +0 -1
  76. package/dist/chunk-2LJVUMXW.js +0 -228
  77. package/dist/chunk-2LJVUMXW.js.map +0 -1
  78. package/dist/chunk-342VRT25.mjs +0 -504
  79. package/dist/chunk-342VRT25.mjs.map +0 -1
  80. package/dist/chunk-7HNQWJWV.js +0 -504
  81. package/dist/chunk-7HNQWJWV.js.map +0 -1
  82. package/dist/chunk-7QKLIVRF.js +0 -94
  83. package/dist/chunk-7QKLIVRF.js.map +0 -1
  84. package/dist/chunk-7SSCNCTW.mjs +0 -137
  85. package/dist/chunk-7SSCNCTW.mjs.map +0 -1
  86. package/dist/chunk-7TLSPR65.mjs +0 -95
  87. package/dist/chunk-7TLSPR65.mjs.map +0 -1
  88. package/dist/chunk-7WULUGLH.mjs +0 -22
  89. package/dist/chunk-7WULUGLH.mjs.map +0 -1
  90. package/dist/chunk-AVMQJWYD.js +0 -95
  91. package/dist/chunk-AVMQJWYD.js.map +0 -1
  92. package/dist/chunk-BG56B4DE.js +0 -106
  93. package/dist/chunk-BG56B4DE.js.map +0 -1
  94. package/dist/chunk-CLM5PNSG.mjs +0 -496
  95. package/dist/chunk-CLM5PNSG.mjs.map +0 -1
  96. package/dist/chunk-DNLGCKTT.js +0 -31
  97. package/dist/chunk-DNLGCKTT.js.map +0 -1
  98. package/dist/chunk-JHOVXH3X.mjs +0 -65
  99. package/dist/chunk-JHOVXH3X.mjs.map +0 -1
  100. package/dist/chunk-MXINIFPC.js +0 -105
  101. package/dist/chunk-MXINIFPC.js.map +0 -1
  102. package/dist/chunk-O4II6N34.js +0 -137
  103. package/dist/chunk-O4II6N34.js.map +0 -1
  104. package/dist/chunk-SE32ZPOZ.js +0 -496
  105. package/dist/chunk-SE32ZPOZ.js.map +0 -1
  106. package/dist/chunk-UAL54DVV.mjs +0 -106
  107. package/dist/chunk-UAL54DVV.mjs.map +0 -1
  108. package/dist/chunk-WCKSKU3C.js +0 -65
  109. package/dist/chunk-WCKSKU3C.js.map +0 -1
  110. package/dist/chunk-WU6FW77M.mjs +0 -105
  111. package/dist/chunk-WU6FW77M.mjs.map +0 -1
  112. package/dist/chunk-XE4OXN2W.js +0 -12
  113. package/dist/chunk-XE4OXN2W.js.map +0 -1
  114. package/dist/chunk-YBM3IJEA.mjs +0 -94
  115. package/dist/chunk-YBM3IJEA.mjs.map +0 -1
  116. package/dist/chunk-YN6WIWNQ.mjs +0 -228
  117. package/dist/chunk-YN6WIWNQ.mjs.map +0 -1
  118. package/dist/chunk-YSLEF5C5.mjs +0 -1
  119. package/dist/chunk-YSLEF5C5.mjs.map +0 -1
  120. package/dist/chunk-ZX7QIN24.mjs +0 -31
  121. package/dist/chunk-ZX7QIN24.mjs.map +0 -1
  122. package/dist/cli/index.d.mts +0 -23
  123. package/dist/cli/index.d.ts +0 -23
  124. package/dist/cli/index.js +0 -716
  125. package/dist/cli/index.js.map +0 -1
  126. package/dist/cli/index.mjs +0 -718
  127. package/dist/cli/index.mjs.map +0 -1
  128. package/dist/client/index.d.mts +0 -21
  129. package/dist/client/index.d.ts +0 -21
  130. package/dist/client/index.js +0 -13
  131. package/dist/client/index.js.map +0 -1
  132. package/dist/client/index.mjs +0 -13
  133. package/dist/client/index.mjs.map +0 -1
  134. package/dist/codegen/index.d.mts +0 -2
  135. package/dist/codegen/index.d.ts +0 -2
  136. package/dist/codegen/index.js +0 -16
  137. package/dist/codegen/index.js.map +0 -1
  138. package/dist/codegen/index.mjs +0 -16
  139. package/dist/codegen/index.mjs.map +0 -1
  140. package/dist/decorators-BT1FFqN0.d.mts +0 -29
  141. package/dist/decorators-DvS58PqC.d.ts +0 -29
  142. package/dist/dev-server/index.d.mts +0 -1
  143. package/dist/dev-server/index.d.ts +0 -1
  144. package/dist/dev-server/index.js +0 -13
  145. package/dist/dev-server/index.js.map +0 -1
  146. package/dist/dev-server/index.mjs +0 -13
  147. package/dist/dev-server/index.mjs.map +0 -1
  148. package/dist/index-7QeQEf37.d.ts +0 -92
  149. package/dist/index-7RvU-jGE.d.mts +0 -66
  150. package/dist/index-7RvU-jGE.d.ts +0 -66
  151. package/dist/index-8nzxy0NN.d.mts +0 -92
  152. package/dist/index-Co5ZsLqq.d.ts +0 -58
  153. package/dist/index-D94W1__r.d.mts +0 -58
  154. package/dist/index-DQmyVp6F.d.mts +0 -27
  155. package/dist/index-KL_1BrQb.d.ts +0 -27
  156. package/dist/index.d.mts +0 -294
  157. package/dist/index.d.ts +0 -294
  158. package/dist/index.js +0 -424
  159. package/dist/index.js.map +0 -1
  160. package/dist/index.mjs +0 -424
  161. package/dist/index.mjs.map +0 -1
  162. package/dist/nest/index.d.mts +0 -3
  163. package/dist/nest/index.d.ts +0 -3
  164. package/dist/nest/index.js +0 -38
  165. package/dist/nest/index.js.map +0 -1
  166. package/dist/nest/index.mjs +0 -38
  167. package/dist/nest/index.mjs.map +0 -1
  168. package/dist/next/index.d.mts +0 -66
  169. package/dist/next/index.d.ts +0 -66
  170. package/dist/next/index.js +0 -289
  171. package/dist/next/index.js.map +0 -1
  172. package/dist/next/index.mjs +0 -251
  173. package/dist/next/index.mjs.map +0 -1
  174. package/dist/rpc/index.d.mts +0 -2
  175. package/dist/rpc/index.d.ts +0 -2
  176. package/dist/rpc/index.js +0 -23
  177. package/dist/rpc/index.js.map +0 -1
  178. package/dist/rpc/index.mjs +0 -23
  179. package/dist/rpc/index.mjs.map +0 -1
  180. package/dist/runtime/index.d.mts +0 -55
  181. package/dist/runtime/index.d.ts +0 -55
  182. package/dist/runtime/index.js +0 -221
  183. package/dist/runtime/index.js.map +0 -1
  184. package/dist/runtime/index.mjs +0 -221
  185. package/dist/runtime/index.mjs.map +0 -1
  186. package/dist/types/index.d.mts +0 -12
  187. package/dist/types/index.d.ts +0 -12
  188. package/dist/types/index.js +0 -2
  189. package/dist/types/index.js.map +0 -1
  190. package/dist/types/index.mjs +0 -3
  191. package/dist/types/index.mjs.map +0 -1
  192. package/dist/types-7d_fC-C3.d.mts +0 -32
  193. package/dist/types-7d_fC-C3.d.ts +0 -32
  194. package/dist/vercel-builder/index.d.mts +0 -58
  195. package/dist/vercel-builder/index.d.ts +0 -58
  196. package/dist/vercel-builder/index.js +0 -330
  197. package/dist/vercel-builder/index.js.map +0 -1
  198. package/dist/vercel-builder/index.mjs +0 -330
  199. package/dist/vercel-builder/index.mjs.map +0 -1
@@ -1,35 +1,35 @@
1
- import { postData, applyLogin, applyLogout } from '@/lib/api-client';
2
- import { toast } from 'react-hot-toast';
3
-
4
- export const login = async (data: any) => {
5
- try {
6
- const response = await postData('/auth/login', data, false);
7
- if (response.token) {
8
- applyLogin(response.token);
9
- toast.success('Logged in successfully! 🚀');
10
- return response;
11
- }
12
- } catch (error: any) {
13
- toast.error(error.response?.data?.message || 'Login failed');
14
- throw error;
15
- }
16
- };
17
-
18
- export const register = async (data: any) => {
19
- try {
20
- const response = await postData('/auth/register', data, false);
21
- if (response.token) {
22
- applyLogin(response.token);
23
- toast.success('Account created successfully! 🎉');
24
- return response;
25
- }
26
- } catch (error: any) {
27
- toast.error(error.response?.data?.message || 'Registration failed');
28
- throw error;
29
- }
30
- };
31
-
32
- export const logout = async () => {
33
- await applyLogout();
34
- toast.success('Logged out');
35
- };
1
+ import { postData, applyLogin, applyLogout } from '@/lib/api-client';
2
+ import { toast } from 'react-hot-toast';
3
+
4
+ export const login = async (data: any) => {
5
+ try {
6
+ const response = await postData('/auth/login', data, false);
7
+ if (response.token) {
8
+ applyLogin(response.token);
9
+ toast.success('Logged in successfully! 🚀');
10
+ return response;
11
+ }
12
+ } catch (error: any) {
13
+ toast.error(error.response?.data?.message || 'Login failed');
14
+ throw error;
15
+ }
16
+ };
17
+
18
+ export const register = async (data: any) => {
19
+ try {
20
+ const response = await postData('/auth/register', data, false);
21
+ if (response.token) {
22
+ applyLogin(response.token);
23
+ toast.success('Account created successfully! 🎉');
24
+ return response;
25
+ }
26
+ } catch (error: any) {
27
+ toast.error(error.response?.data?.message || 'Registration failed');
28
+ throw error;
29
+ }
30
+ };
31
+
32
+ export const logout = async () => {
33
+ await applyLogout();
34
+ toast.success('Logged out');
35
+ };
@@ -1,3 +1,3 @@
1
- export * from './api';
2
- export * from './LoginForm';
3
- export * from './RegisterForm';
1
+ export * from './api';
2
+ export * from './LoginForm';
3
+ export * from './RegisterForm';
@@ -1,204 +1,204 @@
1
- 'use client';
2
-
3
- import { motion } from 'framer-motion';
4
- import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
5
- import { Button } from '@/components/ui/button';
6
- import { logout } from '@/features/auth';
7
- import { toast } from 'react-hot-toast';
8
- import {
9
- DollarSign,
10
- Users,
11
- ShoppingBag,
12
- Activity,
13
- ClipboardList,
14
- CheckCircle2,
15
- Clock,
16
- Hourglass,
17
- Bell,
18
- LogOut
19
- } from 'lucide-react';
20
-
21
- // Mock Data for Demo
22
- const MOCK_STATS = [
23
- { title: 'Total Revenue', value: '$45,231.89', change: '+20.1% from last month', icon: DollarSign, color: 'from-green-500/20 to-emerald-500/20', iconColor: 'text-green-500' },
24
- { title: 'Subscriptions', value: '+2350', change: '+180.1% from last month', icon: Users, color: 'from-blue-500/20 to-indigo-500/20', iconColor: 'text-blue-500' },
25
- { title: 'Sales', value: '+12,234', change: '+19% from last month', icon: ShoppingBag, color: 'from-orange-500/20 to-red-500/20', iconColor: 'text-orange-500' },
26
- { title: 'Active Now', value: '+573', change: '+201 since last hour', icon: Activity, color: 'from-purple-500/20 to-pink-500/20', iconColor: 'text-purple-500' },
27
- ];
28
-
29
- const MOCK_TODOS = [
30
- { id: 1, title: 'Review project proposal', status: 'completed', date: 'Today, 10:00 AM' },
31
- { id: 2, title: 'Team meeting with design team', status: 'pending', date: 'Today, 2:00 PM' },
32
- { id: 3, title: 'Update documentation', status: 'in-progress', date: 'Tomorrow, 11:00 AM' },
33
- { id: 4, title: 'Deploy to production', status: 'pending', date: 'Wed, 4:00 PM' },
34
- ];
35
-
36
- const MOCK_ACTIVITIES = [
37
- { id: 1, user: 'Alice Smith', action: 'created a new project', time: '2 min ago' },
38
- { id: 2, user: 'Bob Johnson', action: 'commented on task #123', time: '15 min ago' },
39
- { id: 3, user: 'Charlie Brown', action: 'completed onboarding', time: '1 hour ago' },
40
- ];
41
-
42
- export function DashboardView() {
43
- const handleLogout = async () => {
44
- await logout();
45
- toast.success('Logged out successfully');
46
- };
47
-
48
- const container = {
49
- hidden: { opacity: 0 },
50
- show: {
51
- opacity: 1,
52
- transition: {
53
- staggerChildren: 0.1
54
- }
55
- }
56
- };
57
-
58
- const item = {
59
- hidden: { y: 20, opacity: 0 },
60
- show: { y: 0, opacity: 1 }
61
- };
62
-
63
- return (
64
- <div className="min-h-screen bg-background p-8 relative overflow-hidden">
65
- {/* Animated Background */}
66
- <div className="fixed inset-0 overflow-hidden pointer-events-none -z-10">
67
- <div className="absolute -top-[40%] -right-[30%] w-[70%] h-[70%] rounded-full bg-primary/10 blur-[120px] animate-float" />
68
- <div className="absolute top-[60%] -left-[20%] w-[50%] h-[50%] rounded-full bg-indigo-500/10 blur-[100px] animate-float" style={{ animationDelay: '3s' }} />
69
- </div>
70
-
71
- <div className="max-w-7xl mx-auto space-y-8">
72
- {/* Header */}
73
- <motion.div
74
- initial={{ opacity: 0, y: -20 }}
75
- animate={{ opacity: 1, y: 0 }}
76
- className="flex items-center justify-between"
77
- >
78
- <div>
79
- <h1 className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600 mb-2">
80
- Dashboard Overview
81
- </h1>
82
- <p className="text-muted-foreground">Welcome back, Ziad! Here's what's happening today.</p>
83
- </div>
84
- <Button onClick={handleLogout} variant="outline" className="border-primary/20 hover:bg-primary/10 hover:text-primary transition-colors gap-2">
85
- <LogOut className="w-4 h-4" />
86
- Sign out
87
- </Button>
88
- </motion.div>
89
-
90
- {/* Stats Grid */}
91
- <motion.div
92
- variants={container}
93
- initial="hidden"
94
- animate="show"
95
- className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
96
- >
97
- {MOCK_STATS.map((stat, index) => (
98
- <motion.div key={index} variants={item}>
99
- <Card className={`glass border-white/10 hover:border-primary/20 transition-all duration-300 hover:shadow-lg hover:shadow-primary/5 group overflow-hidden relative`}>
100
- <div className={`absolute inset-0 bg-gradient-to-br ${stat.color} opacity-0 group-hover:opacity-100 transition-opacity duration-500`} />
101
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2 relative z-10">
102
- <CardTitle className="text-sm font-medium">{stat.title}</CardTitle>
103
- <div className={`p-2 rounded-lg bg-background/50 ${stat.iconColor}`}>
104
- <stat.icon className="w-5 h-5" />
105
- </div>
106
- </CardHeader>
107
- <CardContent className="relative z-10">
108
- <div className="text-2xl font-bold">{stat.value}</div>
109
- <p className="text-xs text-muted-foreground mt-1">{stat.change}</p>
110
- </CardContent>
111
- </Card>
112
- </motion.div>
113
- ))}
114
- </motion.div>
115
-
116
- {/* Main Content Grid */}
117
- <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
118
- {/* Recent Tasks */}
119
- <motion.div
120
- initial={{ opacity: 0, x: -20 }}
121
- animate={{ opacity: 1, x: 0 }}
122
- transition={{ delay: 0.4 }}
123
- className="lg:col-span-2"
124
- >
125
- <Card className="glass border-white/10 h-full">
126
- <CardHeader>
127
- <CardTitle className="flex items-center gap-2">
128
- <ClipboardList className="w-5 h-5 text-primary" />
129
- Recent Tasks
130
- </CardTitle>
131
- </CardHeader>
132
- <CardContent>
133
- <div className="space-y-4">
134
- {MOCK_TODOS.map((todo) => (
135
- <div key={todo.id} className="flex items-center justify-between p-4 rounded-xl bg-secondary/30 hover:bg-secondary/50 transition-colors group cursor-pointer border border-transparent hover:border-primary/10">
136
- <div className="flex items-center gap-4">
137
- <div className={`h-10 w-10 rounded-full flex items-center justify-center ${todo.status === 'completed' ? 'bg-green-500/10 text-green-500' :
138
- todo.status === 'in-progress' ? 'bg-blue-500/10 text-blue-500' :
139
- 'bg-orange-500/10 text-orange-500'
140
- }`}>
141
- {todo.status === 'completed' ? <CheckCircle2 className="w-5 h-5" /> :
142
- todo.status === 'in-progress' ? <Activity className="w-5 h-5" /> :
143
- <Hourglass className="w-5 h-5" />}
144
- </div>
145
- <div>
146
- <p className="font-medium group-hover:text-primary transition-colors">{todo.title}</p>
147
- <p className="text-xs text-muted-foreground flex items-center gap-1">
148
- <Clock className="w-3 h-3" /> {todo.date}
149
- </p>
150
- </div>
151
- </div>
152
- <span className={`text-xs px-2 py-1 rounded-full capitalize ${todo.status === 'completed' ? 'bg-green-500/10 text-green-500' :
153
- todo.status === 'in-progress' ? 'bg-blue-500/10 text-blue-500' :
154
- 'bg-orange-500/10 text-orange-500'
155
- }`}>
156
- {todo.status.replace('-', ' ')}
157
- </span>
158
- </div>
159
- ))}
160
- </div>
161
- </CardContent>
162
- </Card>
163
- </motion.div>
164
-
165
- {/* Recent Activity */}
166
- <motion.div
167
- initial={{ opacity: 0, x: 20 }}
168
- animate={{ opacity: 1, x: 0 }}
169
- transition={{ delay: 0.5 }}
170
- >
171
- <Card className="glass border-white/10 h-full">
172
- <CardHeader>
173
- <CardTitle className="flex items-center gap-2">
174
- <Bell className="w-5 h-5 text-primary" />
175
- Recent Activity
176
- </CardTitle>
177
- </CardHeader>
178
- <CardContent>
179
- <div className="space-y-6">
180
- {MOCK_ACTIVITIES.map((activity, index) => (
181
- <div key={activity.id} className="flex gap-4 relative">
182
- {index !== MOCK_ACTIVITIES.length - 1 && (
183
- <div className="absolute left-[19px] top-10 bottom-[-24px] w-[2px] bg-secondary" />
184
- )}
185
- <div className="h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center shrink-0 text-sm font-bold text-primary">
186
- {activity.user[0]}
187
- </div>
188
- <div>
189
- <p className="text-sm">
190
- <span className="font-semibold">{activity.user}</span> {activity.action}
191
- </p>
192
- <p className="text-xs text-muted-foreground mt-1">{activity.time}</p>
193
- </div>
194
- </div>
195
- ))}
196
- </div>
197
- </CardContent>
198
- </Card>
199
- </motion.div>
200
- </div>
201
- </div>
202
- </div>
203
- );
204
- }
1
+ 'use client';
2
+
3
+ import { motion } from 'framer-motion';
4
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
5
+ import { Button } from '@/components/ui/button';
6
+ import { logout } from '@/features/auth';
7
+ import { toast } from 'react-hot-toast';
8
+ import {
9
+ DollarSign,
10
+ Users,
11
+ ShoppingBag,
12
+ Activity,
13
+ ClipboardList,
14
+ CheckCircle2,
15
+ Clock,
16
+ Hourglass,
17
+ Bell,
18
+ LogOut
19
+ } from 'lucide-react';
20
+
21
+ // Mock Data for Demo
22
+ const MOCK_STATS = [
23
+ { title: 'Total Revenue', value: '$45,231.89', change: '+20.1% from last month', icon: DollarSign, color: 'from-green-500/20 to-emerald-500/20', iconColor: 'text-green-500' },
24
+ { title: 'Subscriptions', value: '+2350', change: '+180.1% from last month', icon: Users, color: 'from-blue-500/20 to-indigo-500/20', iconColor: 'text-blue-500' },
25
+ { title: 'Sales', value: '+12,234', change: '+19% from last month', icon: ShoppingBag, color: 'from-orange-500/20 to-red-500/20', iconColor: 'text-orange-500' },
26
+ { title: 'Active Now', value: '+573', change: '+201 since last hour', icon: Activity, color: 'from-purple-500/20 to-pink-500/20', iconColor: 'text-purple-500' },
27
+ ];
28
+
29
+ const MOCK_TODOS = [
30
+ { id: 1, title: 'Review project proposal', status: 'completed', date: 'Today, 10:00 AM' },
31
+ { id: 2, title: 'Team meeting with design team', status: 'pending', date: 'Today, 2:00 PM' },
32
+ { id: 3, title: 'Update documentation', status: 'in-progress', date: 'Tomorrow, 11:00 AM' },
33
+ { id: 4, title: 'Deploy to production', status: 'pending', date: 'Wed, 4:00 PM' },
34
+ ];
35
+
36
+ const MOCK_ACTIVITIES = [
37
+ { id: 1, user: 'Alice Smith', action: 'created a new project', time: '2 min ago' },
38
+ { id: 2, user: 'Bob Johnson', action: 'commented on task #123', time: '15 min ago' },
39
+ { id: 3, user: 'Charlie Brown', action: 'completed onboarding', time: '1 hour ago' },
40
+ ];
41
+
42
+ export function DashboardView() {
43
+ const handleLogout = async () => {
44
+ await logout();
45
+ toast.success('Logged out successfully');
46
+ };
47
+
48
+ const container = {
49
+ hidden: { opacity: 0 },
50
+ show: {
51
+ opacity: 1,
52
+ transition: {
53
+ staggerChildren: 0.1
54
+ }
55
+ }
56
+ };
57
+
58
+ const item = {
59
+ hidden: { y: 20, opacity: 0 },
60
+ show: { y: 0, opacity: 1 }
61
+ };
62
+
63
+ return (
64
+ <div className="min-h-screen bg-background p-8 relative overflow-hidden">
65
+ {/* Animated Background */}
66
+ <div className="fixed inset-0 overflow-hidden pointer-events-none -z-10">
67
+ <div className="absolute -top-[40%] -right-[30%] w-[70%] h-[70%] rounded-full bg-primary/10 blur-[120px] animate-float" />
68
+ <div className="absolute top-[60%] -left-[20%] w-[50%] h-[50%] rounded-full bg-indigo-500/10 blur-[100px] animate-float" style={{ animationDelay: '3s' }} />
69
+ </div>
70
+
71
+ <div className="max-w-7xl mx-auto space-y-8">
72
+ {/* Header */}
73
+ <motion.div
74
+ initial={{ opacity: 0, y: -20 }}
75
+ animate={{ opacity: 1, y: 0 }}
76
+ className="flex items-center justify-between"
77
+ >
78
+ <div>
79
+ <h1 className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600 mb-2">
80
+ Dashboard Overview
81
+ </h1>
82
+ <p className="text-muted-foreground">Welcome back, Ziad! Here's what's happening today.</p>
83
+ </div>
84
+ <Button onClick={handleLogout} variant="outline" className="border-primary/20 hover:bg-primary/10 hover:text-primary transition-colors gap-2">
85
+ <LogOut className="w-4 h-4" />
86
+ Sign out
87
+ </Button>
88
+ </motion.div>
89
+
90
+ {/* Stats Grid */}
91
+ <motion.div
92
+ variants={container}
93
+ initial="hidden"
94
+ animate="show"
95
+ className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
96
+ >
97
+ {MOCK_STATS.map((stat, index) => (
98
+ <motion.div key={index} variants={item}>
99
+ <Card className={`glass border-white/10 hover:border-primary/20 transition-all duration-300 hover:shadow-lg hover:shadow-primary/5 group overflow-hidden relative`}>
100
+ <div className={`absolute inset-0 bg-gradient-to-br ${stat.color} opacity-0 group-hover:opacity-100 transition-opacity duration-500`} />
101
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2 relative z-10">
102
+ <CardTitle className="text-sm font-medium">{stat.title}</CardTitle>
103
+ <div className={`p-2 rounded-lg bg-background/50 ${stat.iconColor}`}>
104
+ <stat.icon className="w-5 h-5" />
105
+ </div>
106
+ </CardHeader>
107
+ <CardContent className="relative z-10">
108
+ <div className="text-2xl font-bold">{stat.value}</div>
109
+ <p className="text-xs text-muted-foreground mt-1">{stat.change}</p>
110
+ </CardContent>
111
+ </Card>
112
+ </motion.div>
113
+ ))}
114
+ </motion.div>
115
+
116
+ {/* Main Content Grid */}
117
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
118
+ {/* Recent Tasks */}
119
+ <motion.div
120
+ initial={{ opacity: 0, x: -20 }}
121
+ animate={{ opacity: 1, x: 0 }}
122
+ transition={{ delay: 0.4 }}
123
+ className="lg:col-span-2"
124
+ >
125
+ <Card className="glass border-white/10 h-full">
126
+ <CardHeader>
127
+ <CardTitle className="flex items-center gap-2">
128
+ <ClipboardList className="w-5 h-5 text-primary" />
129
+ Recent Tasks
130
+ </CardTitle>
131
+ </CardHeader>
132
+ <CardContent>
133
+ <div className="space-y-4">
134
+ {MOCK_TODOS.map((todo) => (
135
+ <div key={todo.id} className="flex items-center justify-between p-4 rounded-xl bg-secondary/30 hover:bg-secondary/50 transition-colors group cursor-pointer border border-transparent hover:border-primary/10">
136
+ <div className="flex items-center gap-4">
137
+ <div className={`h-10 w-10 rounded-full flex items-center justify-center ${todo.status === 'completed' ? 'bg-green-500/10 text-green-500' :
138
+ todo.status === 'in-progress' ? 'bg-blue-500/10 text-blue-500' :
139
+ 'bg-orange-500/10 text-orange-500'
140
+ }`}>
141
+ {todo.status === 'completed' ? <CheckCircle2 className="w-5 h-5" /> :
142
+ todo.status === 'in-progress' ? <Activity className="w-5 h-5" /> :
143
+ <Hourglass className="w-5 h-5" />}
144
+ </div>
145
+ <div>
146
+ <p className="font-medium group-hover:text-primary transition-colors">{todo.title}</p>
147
+ <p className="text-xs text-muted-foreground flex items-center gap-1">
148
+ <Clock className="w-3 h-3" /> {todo.date}
149
+ </p>
150
+ </div>
151
+ </div>
152
+ <span className={`text-xs px-2 py-1 rounded-full capitalize ${todo.status === 'completed' ? 'bg-green-500/10 text-green-500' :
153
+ todo.status === 'in-progress' ? 'bg-blue-500/10 text-blue-500' :
154
+ 'bg-orange-500/10 text-orange-500'
155
+ }`}>
156
+ {todo.status.replace('-', ' ')}
157
+ </span>
158
+ </div>
159
+ ))}
160
+ </div>
161
+ </CardContent>
162
+ </Card>
163
+ </motion.div>
164
+
165
+ {/* Recent Activity */}
166
+ <motion.div
167
+ initial={{ opacity: 0, x: 20 }}
168
+ animate={{ opacity: 1, x: 0 }}
169
+ transition={{ delay: 0.5 }}
170
+ >
171
+ <Card className="glass border-white/10 h-full">
172
+ <CardHeader>
173
+ <CardTitle className="flex items-center gap-2">
174
+ <Bell className="w-5 h-5 text-primary" />
175
+ Recent Activity
176
+ </CardTitle>
177
+ </CardHeader>
178
+ <CardContent>
179
+ <div className="space-y-6">
180
+ {MOCK_ACTIVITIES.map((activity, index) => (
181
+ <div key={activity.id} className="flex gap-4 relative">
182
+ {index !== MOCK_ACTIVITIES.length - 1 && (
183
+ <div className="absolute left-[19px] top-10 bottom-[-24px] w-[2px] bg-secondary" />
184
+ )}
185
+ <div className="h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center shrink-0 text-sm font-bold text-primary">
186
+ {activity.user[0]}
187
+ </div>
188
+ <div>
189
+ <p className="text-sm">
190
+ <span className="font-semibold">{activity.user}</span> {activity.action}
191
+ </p>
192
+ <p className="text-xs text-muted-foreground mt-1">{activity.time}</p>
193
+ </div>
194
+ </div>
195
+ ))}
196
+ </div>
197
+ </CardContent>
198
+ </Card>
199
+ </motion.div>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ );
204
+ }
@@ -1,9 +1,9 @@
1
- import { getData } from '@/lib/api-client';
2
-
3
- export const getTodos = async () => {
4
- return await getData('/todos');
5
- };
6
-
7
- export const getUser = async () => {
8
- return await getData('/auth/me');
9
- };
1
+ import { getData } from '@/lib/api-client';
2
+
3
+ export const getTodos = async () => {
4
+ return await getData('/todos');
5
+ };
6
+
7
+ export const getUser = async () => {
8
+ return await getData('/auth/me');
9
+ };