Skip to content

Commit a922057

Browse files
feat: Add user roles, authentication types, and logout functionality, while updating database schema and removing unused tables.
1 parent a8a4948 commit a922057

File tree

10 files changed

+337
-18
lines changed

10 files changed

+337
-18
lines changed

playground-dashboard/app/app.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ useSeoMeta({
2929
twitterImage: 'https://ui.nuxt.com/assets/templates/nuxt/dashboard-light.png',
3030
twitterCard: 'summary_large_image'
3131
})
32+
33+
const { user } = useUserSession()
3234
</script>
3335

3436
<template>
3537
<UApp>
3638
<NuxtLoadingIndicator />
3739

38-
<NuxtLayout>
40+
<NuxtLayout :name="user?.role === 'admin' ? 'dashboard' : 'default'">
3941
<NuxtPage />
4042
</NuxtLayout>
4143
</UApp>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
declare module '#auth-utils' {
2+
interface User {
3+
id: number
4+
email: string
5+
name: string
6+
avatar: string
7+
role: string
8+
}
9+
}
10.9 KB
Binary file not shown.
23.7 KB
Loading

playground-dashboard/server/api/auth/login.post.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default eventHandler(async (event) => {
2626
email: user.email,
2727
name: user.name,
2828
avatar: user.avatar,
29-
role: 'admin' // Hardcoded for now as we only have admin users in this table
29+
role: user.role || 'user'
3030
}
3131
})
3232

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE `users` ADD `role` text DEFAULT 'user';
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
{
2+
"version": "6",
3+
"dialect": "sqlite",
4+
"id": "590413d4-9f80-45bd-acf6-2a72e3bc6f5c",
5+
"prevId": "b8e67767-7273-4465-a435-0cc2fd467716",
6+
"tables": {
7+
"customers": {
8+
"name": "customers",
9+
"columns": {
10+
"id": {
11+
"name": "id",
12+
"type": "integer",
13+
"primaryKey": true,
14+
"notNull": true,
15+
"autoincrement": true
16+
},
17+
"name": {
18+
"name": "name",
19+
"type": "text",
20+
"primaryKey": false,
21+
"notNull": true,
22+
"autoincrement": false
23+
},
24+
"email": {
25+
"name": "email",
26+
"type": "text",
27+
"primaryKey": false,
28+
"notNull": true,
29+
"autoincrement": false
30+
},
31+
"avatar": {
32+
"name": "avatar",
33+
"type": "text",
34+
"primaryKey": false,
35+
"notNull": false,
36+
"autoincrement": false
37+
},
38+
"status": {
39+
"name": "status",
40+
"type": "text",
41+
"primaryKey": false,
42+
"notNull": true,
43+
"autoincrement": false
44+
},
45+
"location": {
46+
"name": "location",
47+
"type": "text",
48+
"primaryKey": false,
49+
"notNull": false,
50+
"autoincrement": false
51+
}
52+
},
53+
"indexes": {
54+
"customers_email_unique": {
55+
"name": "customers_email_unique",
56+
"columns": [
57+
"email"
58+
],
59+
"isUnique": true
60+
}
61+
},
62+
"foreignKeys": {},
63+
"compositePrimaryKeys": {},
64+
"uniqueConstraints": {},
65+
"checkConstraints": {}
66+
},
67+
"notifications": {
68+
"name": "notifications",
69+
"columns": {
70+
"id": {
71+
"name": "id",
72+
"type": "integer",
73+
"primaryKey": true,
74+
"notNull": true,
75+
"autoincrement": true
76+
},
77+
"unread": {
78+
"name": "unread",
79+
"type": "integer",
80+
"primaryKey": false,
81+
"notNull": false,
82+
"autoincrement": false,
83+
"default": true
84+
},
85+
"sender_id": {
86+
"name": "sender_id",
87+
"type": "integer",
88+
"primaryKey": false,
89+
"notNull": false,
90+
"autoincrement": false
91+
},
92+
"body": {
93+
"name": "body",
94+
"type": "text",
95+
"primaryKey": false,
96+
"notNull": true,
97+
"autoincrement": false
98+
},
99+
"date": {
100+
"name": "date",
101+
"type": "integer",
102+
"primaryKey": false,
103+
"notNull": true,
104+
"autoincrement": false
105+
}
106+
},
107+
"indexes": {},
108+
"foreignKeys": {
109+
"notifications_sender_id_users_id_fk": {
110+
"name": "notifications_sender_id_users_id_fk",
111+
"tableFrom": "notifications",
112+
"tableTo": "users",
113+
"columnsFrom": [
114+
"sender_id"
115+
],
116+
"columnsTo": [
117+
"id"
118+
],
119+
"onDelete": "no action",
120+
"onUpdate": "no action"
121+
}
122+
},
123+
"compositePrimaryKeys": {},
124+
"uniqueConstraints": {},
125+
"checkConstraints": {}
126+
},
127+
"products": {
128+
"name": "products",
129+
"columns": {
130+
"id": {
131+
"name": "id",
132+
"type": "integer",
133+
"primaryKey": true,
134+
"notNull": true,
135+
"autoincrement": true
136+
},
137+
"name": {
138+
"name": "name",
139+
"type": "text",
140+
"primaryKey": false,
141+
"notNull": true,
142+
"autoincrement": false
143+
},
144+
"price": {
145+
"name": "price",
146+
"type": "real",
147+
"primaryKey": false,
148+
"notNull": true,
149+
"autoincrement": false
150+
},
151+
"status": {
152+
"name": "status",
153+
"type": "text",
154+
"primaryKey": false,
155+
"notNull": true,
156+
"autoincrement": false
157+
},
158+
"inventory": {
159+
"name": "inventory",
160+
"type": "integer",
161+
"primaryKey": false,
162+
"notNull": true,
163+
"autoincrement": false,
164+
"default": 0
165+
},
166+
"image": {
167+
"name": "image",
168+
"type": "text",
169+
"primaryKey": false,
170+
"notNull": false,
171+
"autoincrement": false
172+
}
173+
},
174+
"indexes": {},
175+
"foreignKeys": {},
176+
"compositePrimaryKeys": {},
177+
"uniqueConstraints": {},
178+
"checkConstraints": {}
179+
},
180+
"sales": {
181+
"name": "sales",
182+
"columns": {
183+
"id": {
184+
"name": "id",
185+
"type": "integer",
186+
"primaryKey": true,
187+
"notNull": true,
188+
"autoincrement": true
189+
},
190+
"date": {
191+
"name": "date",
192+
"type": "integer",
193+
"primaryKey": false,
194+
"notNull": true,
195+
"autoincrement": false
196+
},
197+
"status": {
198+
"name": "status",
199+
"type": "text",
200+
"primaryKey": false,
201+
"notNull": true,
202+
"autoincrement": false
203+
},
204+
"email": {
205+
"name": "email",
206+
"type": "text",
207+
"primaryKey": false,
208+
"notNull": true,
209+
"autoincrement": false
210+
},
211+
"amount": {
212+
"name": "amount",
213+
"type": "real",
214+
"primaryKey": false,
215+
"notNull": true,
216+
"autoincrement": false
217+
}
218+
},
219+
"indexes": {},
220+
"foreignKeys": {},
221+
"compositePrimaryKeys": {},
222+
"uniqueConstraints": {},
223+
"checkConstraints": {}
224+
},
225+
"users": {
226+
"name": "users",
227+
"columns": {
228+
"id": {
229+
"name": "id",
230+
"type": "integer",
231+
"primaryKey": true,
232+
"notNull": true,
233+
"autoincrement": true
234+
},
235+
"email": {
236+
"name": "email",
237+
"type": "text",
238+
"primaryKey": false,
239+
"notNull": true,
240+
"autoincrement": false
241+
},
242+
"password": {
243+
"name": "password",
244+
"type": "text",
245+
"primaryKey": false,
246+
"notNull": true,
247+
"autoincrement": false
248+
},
249+
"name": {
250+
"name": "name",
251+
"type": "text",
252+
"primaryKey": false,
253+
"notNull": false,
254+
"autoincrement": false
255+
},
256+
"avatar": {
257+
"name": "avatar",
258+
"type": "text",
259+
"primaryKey": false,
260+
"notNull": false,
261+
"autoincrement": false
262+
},
263+
"role": {
264+
"name": "role",
265+
"type": "text",
266+
"primaryKey": false,
267+
"notNull": false,
268+
"autoincrement": false,
269+
"default": "'user'"
270+
},
271+
"created_at": {
272+
"name": "created_at",
273+
"type": "integer",
274+
"primaryKey": false,
275+
"notNull": true,
276+
"autoincrement": false
277+
},
278+
"updated_at": {
279+
"name": "updated_at",
280+
"type": "integer",
281+
"primaryKey": false,
282+
"notNull": true,
283+
"autoincrement": false
284+
}
285+
},
286+
"indexes": {
287+
"users_email_unique": {
288+
"name": "users_email_unique",
289+
"columns": [
290+
"email"
291+
],
292+
"isUnique": true
293+
}
294+
},
295+
"foreignKeys": {},
296+
"compositePrimaryKeys": {},
297+
"uniqueConstraints": {},
298+
"checkConstraints": {}
299+
}
300+
},
301+
"views": {},
302+
"enums": {},
303+
"_meta": {
304+
"schemas": {},
305+
"tables": {},
306+
"columns": {}
307+
},
308+
"internal": {
309+
"indexes": {}
310+
}
311+
}

playground-dashboard/server/database/migrations/meta/_journal.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
"when": 1764393664908,
99
"tag": "0000_mixed_thena",
1010
"breakpoints": true
11+
},
12+
{
13+
"idx": 1,
14+
"version": "6",
15+
"when": 1764395523431,
16+
"tag": "0001_loud_warlock",
17+
"breakpoints": true
1118
}
1219
]
1320
}

playground-dashboard/server/database/schema.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const users = sqliteTable('users', {
66
password: text('password').notNull(),
77
name: text('name'),
88
avatar: text('avatar'),
9+
role: text('role').default('user'),
910
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
1011
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull()
1112
})
@@ -27,19 +28,3 @@ export const products = sqliteTable('products', {
2728
inventory: integer('inventory').notNull().default(0),
2829
image: text('image')
2930
})
30-
31-
export const sales = sqliteTable('sales', {
32-
id: integer('id').primaryKey({ autoIncrement: true }),
33-
date: integer('date', { mode: 'timestamp' }).notNull(),
34-
status: text('status').notNull(), // 'paid' | 'failed' | 'refunded'
35-
email: text('email').notNull(),
36-
amount: real('amount').notNull()
37-
})
38-
39-
export const notifications = sqliteTable('notifications', {
40-
id: integer('id').primaryKey({ autoIncrement: true }),
41-
unread: integer('unread', { mode: 'boolean' }).default(true),
42-
senderId: integer('sender_id').references(() => users.id),
43-
body: text('body').notNull(),
44-
date: integer('date', { mode: 'timestamp' }).notNull()
45-
})

0 commit comments

Comments
 (0)