From 636623ee963128a4334b91a40096036a184c0ca1 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Mon, 9 Sep 2024 23:21:27 +0200 Subject: [PATCH] Added world deletion actions --- components/world/dialog/Delete.vue | 110 ++++++++++++++++++++++++++++ i18n.config.ts | 14 ++++ pages/my/index.vue | 27 +++++-- pages/my/worlds/[id].vue | 8 +- server/api/worlds/[id].delete.ts | 41 +++++++++++ supabase/migrations/202401_init.sql | 7 +- 6 files changed, 194 insertions(+), 13 deletions(-) create mode 100644 components/world/dialog/Delete.vue create mode 100644 server/api/worlds/[id].delete.ts diff --git a/components/world/dialog/Delete.vue b/components/world/dialog/Delete.vue new file mode 100644 index 0000000..5f08af5 --- /dev/null +++ b/components/world/dialog/Delete.vue @@ -0,0 +1,110 @@ + + + diff --git a/i18n.config.ts b/i18n.config.ts index a0cb46b..d59fc6e 100644 --- a/i18n.config.ts +++ b/i18n.config.ts @@ -83,6 +83,13 @@ export default defineI18nConfig(() => ({ title: "Create a world", subtitle: "Worlds are the building blocks which hold all your characters, your calendars…" }, + deleteDialog: { + title: "Delete this world ?", + subtitle: "This world will be deleted permanently, and all of its associated data will be lost !", + }, + deletedToast: { + title: "The world \"{world}\" has been successfuly deleted.", + }, }, calendar: { nameSingular: "Calendar", @@ -284,6 +291,13 @@ export default defineI18nConfig(() => ({ title: "Créer un monde", subtitle: "Un monde est la brique de base qui contient vos personnages, vos calendriers…" }, + deleteDialog: { + title: "Supprimer ce monde ?", + subtitle: "Le monde sera supprimé définitivement, vous perdrez toutes les données associées !", + }, + deletedToast: { + title: "Le monde \"{world}\" a été supprimé avec succès.", + }, }, calendar: { nameSingular: "Calendriers", diff --git a/pages/my/index.vue b/pages/my/index.vue index 8aae1aa..7ed7f45 100644 --- a/pages/my/index.vue +++ b/pages/my/index.vue @@ -1,5 +1,5 @@ diff --git a/pages/my/worlds/[id].vue b/pages/my/worlds/[id].vue index 9b6a158..184f5d8 100644 --- a/pages/my/worlds/[id].vue +++ b/pages/my/worlds/[id].vue @@ -86,15 +86,15 @@ onUnmounted(() => { }) const markedCalendar = ref(null) -const isDeleteEventModalOpen = ref(false) +const isDeleteCalendarModalOpen = ref(false) function deployDeleteModal(calendar: Calendar) { - isDeleteEventModalOpen.value = true + isDeleteCalendarModalOpen.value = true markedCalendar.value = calendar } function hideDeleteModal() { - isDeleteEventModalOpen.value = false + isDeleteCalendarModalOpen.value = false markedCalendar.value = null } @@ -176,7 +176,7 @@ function hideDeleteModal() { - + diff --git a/server/api/worlds/[id].delete.ts b/server/api/worlds/[id].delete.ts new file mode 100644 index 0000000..0b9bd0d --- /dev/null +++ b/server/api/worlds/[id].delete.ts @@ -0,0 +1,41 @@ +import { z } from "zod" +import { serverSupabaseClient } from "#supabase/server" +import type { World } from "~/models/World" + +const paramsSchema = z.object({ + id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + + const { data: params, error: paramsError} = await getValidatedRouterParams(event, paramsSchema.safeParse) + + if (paramsError) { + throw createError({ + cause: "Utilisateur", + fatal: false, + message: "L'identifiant du monde est manquant ou mal renseigné.", + status: 401, + }) + } + + try { + const { data, error } = await client + .from("worlds") + .delete() + .eq("id", params.id) + .maybeSingle() + + if (error) throw error + + return data + } catch (err) { + throw createError({ + cause: "Serveur", + status: 500, + fatal: false, + message: "Une erreur inconnue est survenue." + }) + } +}) diff --git a/supabase/migrations/202401_init.sql b/supabase/migrations/202401_init.sql index ca78c9d..5d34e3a 100644 --- a/supabase/migrations/202401_init.sql +++ b/supabase/migrations/202401_init.sql @@ -172,9 +172,10 @@ create policy "Allow individual update access" on public.users for update using create policy "Allow individual read access" on public.user_roles for select using ( auth.uid() = user_id ); -- World policies -create policy "Allow individual read access for GMs" on public.worlds for select using ( ( auth.uid() = gm_id ) ); -create policy "Allow individual insert access for GMs" on public.worlds for insert with check ( auth.uid() = gm_id ); -create policy "Allow individual update access for GMs" on public.worlds for update using ( auth.uid() = gm_id ); +create policy "Allow GMs to see their worlds" on public.worlds for select using ( ( auth.uid() = gm_id ) ); +create policy "Allow GMs to create worlds" on public.worlds for insert with check ( auth.uid() = gm_id ); +create policy "Allow GMs to edit their worlds" on public.worlds for update using ( auth.uid() = gm_id ); +create policy "Allow GMs to delete their worlds" on public.worlds for delete using ( auth.uid() = gm_id ); -- Calendar policies create policy "Allow GMs to see their calendars" on public.calendars for select using (