wexts 4.0.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 (189) 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-7QKLIVRF.js +0 -94
  79. package/dist/chunk-7QKLIVRF.js.map +0 -1
  80. package/dist/chunk-7WULUGLH.mjs +0 -22
  81. package/dist/chunk-7WULUGLH.mjs.map +0 -1
  82. package/dist/chunk-BG56B4DE.js +0 -106
  83. package/dist/chunk-BG56B4DE.js.map +0 -1
  84. package/dist/chunk-CLM5PNSG.mjs +0 -496
  85. package/dist/chunk-CLM5PNSG.mjs.map +0 -1
  86. package/dist/chunk-DNLGCKTT.js +0 -31
  87. package/dist/chunk-DNLGCKTT.js.map +0 -1
  88. package/dist/chunk-JHOVXH3X.mjs +0 -65
  89. package/dist/chunk-JHOVXH3X.mjs.map +0 -1
  90. package/dist/chunk-MXINIFPC.js +0 -105
  91. package/dist/chunk-MXINIFPC.js.map +0 -1
  92. package/dist/chunk-SE32ZPOZ.js +0 -496
  93. package/dist/chunk-SE32ZPOZ.js.map +0 -1
  94. package/dist/chunk-UAL54DVV.mjs +0 -106
  95. package/dist/chunk-UAL54DVV.mjs.map +0 -1
  96. package/dist/chunk-WCKSKU3C.js +0 -65
  97. package/dist/chunk-WCKSKU3C.js.map +0 -1
  98. package/dist/chunk-WU6FW77M.mjs +0 -105
  99. package/dist/chunk-WU6FW77M.mjs.map +0 -1
  100. package/dist/chunk-XE4OXN2W.js +0 -12
  101. package/dist/chunk-XE4OXN2W.js.map +0 -1
  102. package/dist/chunk-YBM3IJEA.mjs +0 -94
  103. package/dist/chunk-YBM3IJEA.mjs.map +0 -1
  104. package/dist/chunk-YN6WIWNQ.mjs +0 -228
  105. package/dist/chunk-YN6WIWNQ.mjs.map +0 -1
  106. package/dist/chunk-YSLEF5C5.mjs +0 -1
  107. package/dist/chunk-YSLEF5C5.mjs.map +0 -1
  108. package/dist/chunk-ZX7QIN24.mjs +0 -31
  109. package/dist/chunk-ZX7QIN24.mjs.map +0 -1
  110. package/dist/cli/index.d.mts +0 -11
  111. package/dist/cli/index.d.ts +0 -11
  112. package/dist/cli/index.js +0 -332
  113. package/dist/cli/index.js.map +0 -1
  114. package/dist/cli/index.mjs +0 -334
  115. package/dist/cli/index.mjs.map +0 -1
  116. package/dist/client/index.d.mts +0 -21
  117. package/dist/client/index.d.ts +0 -21
  118. package/dist/client/index.js +0 -12
  119. package/dist/client/index.js.map +0 -1
  120. package/dist/client/index.mjs +0 -12
  121. package/dist/client/index.mjs.map +0 -1
  122. package/dist/codegen/index.d.mts +0 -2
  123. package/dist/codegen/index.d.ts +0 -2
  124. package/dist/codegen/index.js +0 -15
  125. package/dist/codegen/index.js.map +0 -1
  126. package/dist/codegen/index.mjs +0 -15
  127. package/dist/codegen/index.mjs.map +0 -1
  128. package/dist/decorators-BT1FFqN0.d.mts +0 -29
  129. package/dist/decorators-DvS58PqC.d.ts +0 -29
  130. package/dist/dev-server/index.d.mts +0 -1
  131. package/dist/dev-server/index.d.ts +0 -1
  132. package/dist/dev-server/index.js +0 -13
  133. package/dist/dev-server/index.js.map +0 -1
  134. package/dist/dev-server/index.mjs +0 -13
  135. package/dist/dev-server/index.mjs.map +0 -1
  136. package/dist/index-7QeQEf37.d.ts +0 -92
  137. package/dist/index-7RvU-jGE.d.mts +0 -66
  138. package/dist/index-7RvU-jGE.d.ts +0 -66
  139. package/dist/index-8nzxy0NN.d.mts +0 -92
  140. package/dist/index-Co5ZsLqq.d.ts +0 -58
  141. package/dist/index-D94W1__r.d.mts +0 -58
  142. package/dist/index-DQmyVp6F.d.mts +0 -27
  143. package/dist/index-KL_1BrQb.d.ts +0 -27
  144. package/dist/index.d.mts +0 -258
  145. package/dist/index.d.ts +0 -258
  146. package/dist/index.js +0 -410
  147. package/dist/index.js.map +0 -1
  148. package/dist/index.mjs +0 -410
  149. package/dist/index.mjs.map +0 -1
  150. package/dist/nest/index.d.mts +0 -3
  151. package/dist/nest/index.d.ts +0 -3
  152. package/dist/nest/index.js +0 -38
  153. package/dist/nest/index.js.map +0 -1
  154. package/dist/nest/index.mjs +0 -38
  155. package/dist/nest/index.mjs.map +0 -1
  156. package/dist/next/index.d.mts +0 -66
  157. package/dist/next/index.d.ts +0 -66
  158. package/dist/next/index.js +0 -226
  159. package/dist/next/index.js.map +0 -1
  160. package/dist/next/index.mjs +0 -188
  161. package/dist/next/index.mjs.map +0 -1
  162. package/dist/rpc/index.d.mts +0 -2
  163. package/dist/rpc/index.d.ts +0 -2
  164. package/dist/rpc/index.js +0 -23
  165. package/dist/rpc/index.js.map +0 -1
  166. package/dist/rpc/index.mjs +0 -23
  167. package/dist/rpc/index.mjs.map +0 -1
  168. package/dist/runtime/index.d.mts +0 -55
  169. package/dist/runtime/index.d.ts +0 -55
  170. package/dist/runtime/index.js +0 -213
  171. package/dist/runtime/index.js.map +0 -1
  172. package/dist/runtime/index.mjs +0 -213
  173. package/dist/runtime/index.mjs.map +0 -1
  174. package/dist/types/index.d.mts +0 -12
  175. package/dist/types/index.d.ts +0 -12
  176. package/dist/types/index.js +0 -2
  177. package/dist/types/index.js.map +0 -1
  178. package/dist/types/index.mjs +0 -3
  179. package/dist/types/index.mjs.map +0 -1
  180. package/dist/types-7d_fC-C3.d.mts +0 -32
  181. package/dist/types-7d_fC-C3.d.ts +0 -32
  182. package/dist/vercel-builder/index.d.mts +0 -58
  183. package/dist/vercel-builder/index.d.ts +0 -58
  184. package/dist/vercel-builder/index.js +0 -330
  185. package/dist/vercel-builder/index.js.map +0 -1
  186. package/dist/vercel-builder/index.mjs +0 -330
  187. package/dist/vercel-builder/index.mjs.map +0 -1
  188. package/templates/nestjs-api/package-lock.json +0 -5623
  189. package/templates/nextjs-web/package-lock.json +0 -3254
@@ -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
+ };