diff --git a/src/hooks.server.ts b/src/hooks.server.ts index ad0ee34..7b7b926 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -13,6 +13,17 @@ export const handle: Handle = async ({ event, resolve }) => { } + if (event.url.pathname.startsWith('/admin')) { + const current_user = await authenticateUser(event); + if (!current_user) { + throw redirect(302, '/login'); + } + if (!current_user.is_admin) { + throw redirect(302, '/'); + } + event.locals.user = current_user; + } + const response = await resolve(event); return response; }; \ No newline at end of file diff --git a/src/routes/admin/+page.server.ts b/src/routes/admin/+page.server.ts new file mode 100644 index 0000000..14e8286 --- /dev/null +++ b/src/routes/admin/+page.server.ts @@ -0,0 +1,112 @@ +import { error } from '@sveltejs/kit'; +import type { Actions } from './$types'; + +const api_url = import.meta.env.VITE_API_URL; + +export const actions: Actions = { + addUser: async ({ request, fetch }) => { + const formData = await request.formData(); + const userData = Object.fromEntries(formData); + + const response = await fetch(`${api_url}/admin/user`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(userData) + }); + + if (!response.ok) { + throw error(response.status, 'Failed to add user'); + } + + return { success: true }; + }, + + deleteUser: async ({ request, fetch }) => { + const formData = await request.formData(); + const userId = formData.get('userId'); + + const response = await fetch(`${api_url}/admin/user/${userId}`, { + method: 'DELETE' + }); + + if (!response.ok) { + throw error(response.status, 'Failed to delete user'); + } + + return { success: true }; + }, + + addMovie: async ({ request, fetch }) => { + const formData = await request.formData(); + const movieData = Object.fromEntries(formData); + + const response = await fetch(`${api_url}/admin/movie`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(movieData) + }); + + if (!response.ok) { + throw error(response.status, 'Failed to add movie'); + } + + return { success: true }; + }, + + setMovieWatched: async ({ request, fetch }) => { + const formData = await request.formData(); + const movieId = formData.get('movieId'); + + const response = await fetch(`${api_url}/admin/movie/${movieId}`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ is_watched: true }) + }); + + if (!response.ok) { + throw error(response.status, 'Failed to update movie status'); + } + + return { success: true }; + }, + + addCard: async ({ request, fetch }) => { + const formData = await request.formData(); + const cardData = Object.fromEntries(formData); + + const response = await fetch(`${api_url}/admin/card`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(cardData) + }); + + if (!response.ok) { + throw error(response.status, 'Failed to add card'); + } + + return { success: true }; + }, + + deleteCard: async ({ request, fetch }) => { + const formData = await request.formData(); + const cardId = formData.get('cardId'); + + const response = await fetch(`${api_url}/admin/card/${cardId}`, { + method: 'DELETE' + }); + + if (!response.ok) { + throw error(response.status, 'Failed to delete card'); + } + + return { success: true }; + } +}; \ No newline at end of file diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte new file mode 100644 index 0000000..5988f2a --- /dev/null +++ b/src/routes/admin/+page.svelte @@ -0,0 +1,187 @@ + + +
+ + +
+ {#if activeTab === 'users'} +
+

Add User

+
+
+ + +
+
+ + +
+ +
+ +

Delete User

+
+
+ + +
+ +
+
+ {/if} + + {#if activeTab === 'movies'} +
+

Add Movie

+
+
+ + +
+
+ + +
+ +
+ +

Mark Movie as Watched

+
+
+ + +
+ +
+
+ {/if} + + {#if activeTab === 'cards'} +
+

Add Card

+
+
+ + +
+
+ + +
+ +
+ +

Delete Card

+
+
+ + +
+ +
+
+ {/if} +
+
+ + \ No newline at end of file