From 49e523485b7d73adb8405772bc15bc3ee1dd6906 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Wed, 15 May 2024 17:18:17 +0200 Subject: [PATCH 01/15] Remodeled database and api to prepare for move --- components/calendar/Dashboard.vue | 12 + components/profile/Dashboard.vue | 55 ++++ components/profile/Layout.vue | 9 - components/ui/card/Card.vue | 2 +- models/CalendarConfig.ts | 6 + models/World.ts | 7 + package.json | 3 +- pages/{calendar.vue => calendar-old.vue} | 0 pages/calendar/[id].vue | 30 +++ pages/index.vue | 2 +- pages/profile.vue | 6 +- pnpm-lock.yaml | 8 + server/api/calendars/query.get.ts | 23 ++ server/api/characters.ts | 252 ------------------ server/api/characters/index.get.ts | 18 ++ server/api/characters/query.get.ts | 29 ++ server/api/{events.ts => events/index.get.ts} | 0 server/api/events/query.get.ts | 23 ++ server/api/worlds/index.get.ts | 10 + supabase/migrations/202401_init.sql | 151 ++++++++++- supabase/seed.sql | 107 +++++++- 21 files changed, 479 insertions(+), 274 deletions(-) create mode 100644 components/calendar/Dashboard.vue create mode 100644 components/profile/Dashboard.vue delete mode 100644 components/profile/Layout.vue create mode 100644 models/CalendarConfig.ts create mode 100644 models/World.ts rename pages/{calendar.vue => calendar-old.vue} (100%) create mode 100644 pages/calendar/[id].vue create mode 100644 server/api/calendars/query.get.ts delete mode 100644 server/api/characters.ts create mode 100644 server/api/characters/index.get.ts create mode 100644 server/api/characters/query.get.ts rename server/api/{events.ts => events/index.get.ts} (100%) create mode 100644 server/api/events/query.get.ts create mode 100644 server/api/worlds/index.get.ts diff --git a/components/calendar/Dashboard.vue b/components/calendar/Dashboard.vue new file mode 100644 index 0000000..8b09064 --- /dev/null +++ b/components/calendar/Dashboard.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/profile/Dashboard.vue b/components/profile/Dashboard.vue new file mode 100644 index 0000000..17b9a6f --- /dev/null +++ b/components/profile/Dashboard.vue @@ -0,0 +1,55 @@ + + + diff --git a/components/profile/Layout.vue b/components/profile/Layout.vue deleted file mode 100644 index 623d0a6..0000000 --- a/components/profile/Layout.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/components/ui/card/Card.vue b/components/ui/card/Card.vue index 0dcc36a..18bebb2 100644 --- a/components/ui/card/Card.vue +++ b/components/ui/card/Card.vue @@ -12,7 +12,7 @@ const props = defineProps<{
+import type { MenuItem } from '~/components/global/SidebarProps'; + +const user = useSupabaseUser() + +useHead({ + title: 'Calendrier' +}) + +definePageMeta({ + middleware: ['auth-guard'] +}) + +// Redirect user back home when they log out on the page +watch(user, (n, _o) => { + if (!n) { + navigateTo('/') + } +}) + +const sidebarMenu: MenuItem[] = [] + + + diff --git a/pages/index.vue b/pages/index.vue index f4eb51d..9ec7533 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -13,7 +13,7 @@ const sidebarMenu: MenuItem[] = []
- + Calendrier diff --git a/pages/profile.vue b/pages/profile.vue index 8f95e87..4247710 100644 --- a/pages/profile.vue +++ b/pages/profile.vue @@ -21,9 +21,9 @@ const sidebarMenu: MenuItem[] = [] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb0846d..6078893 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: vue-router: specifier: ^4.3.2 version: 4.3.2(vue@3.4.27(typescript@5.4.5)) + zod: + specifier: ^3.23.8 + version: 3.23.8 devDependencies: '@nuxtjs/color-mode': specifier: ^3.4.1 @@ -4734,6 +4737,9 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -10202,3 +10208,5 @@ snapshots: archiver-utils: 5.0.2 compress-commons: 6.0.2 readable-stream: 4.5.2 + + zod@3.23.8: {} diff --git a/server/api/calendars/query.get.ts b/server/api/calendars/query.get.ts new file mode 100644 index 0000000..d6e8c39 --- /dev/null +++ b/server/api/calendars/query.get.ts @@ -0,0 +1,23 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('world_calendars') + .select(` + id, + months, + days_per_year, + events (*) + `) + .eq('world_id', query.world_id) + + return output +}) diff --git a/server/api/characters.ts b/server/api/characters.ts deleted file mode 100644 index d833251..0000000 --- a/server/api/characters.ts +++ /dev/null @@ -1,252 +0,0 @@ -export default defineEventHandler(() => { - return [ - /** - * Player characters - */ - // "Les Milles Cages" - { - name: 'Sulvan Trois-Barbes', - birth: { day: 20, month: 3, year: 3169 }, - wiki: 'https://alexcreates.fr/leim/index.php/Sulvan_Trois-Barbes', - category: 'joueur', - secondaryCategories: ['criminel', 'étincelle'] - }, - { - name: 'Vascylly', - birth: { day: 3, month: 5, year: 3181 }, - wiki: 'https://alexcreates.fr/leim/index.php/Vascylly', - category: 'joueur', - secondaryCategories: ['mage'] - }, - { - name: 'Tara Belyus', - birth: { day: 14, month: 9, year: 3186 }, - category: 'joueur', - secondaryCategories: ['mage'] - }, - // "Les Cloches de Cantane" - { - name: 'Malik', - birth: { day: 22, month: 8, year: 3181 }, - category: 'joueur', - secondaryCategories: ['scientifique'] - }, - { - name: 'Elie', - birth: { day: 5, month: 6, year: 3192 }, - category: 'joueur', - secondaryCategories: ['ecclésiastique'] - }, - { - name: 'Clayron', - birth: { day: 3, month: 5, year: 3178 }, - category: 'joueur', - secondaryCategories: ['sentinelle'] - }, - - /** - * NPC - */ - // Counts of the Alliance - { - name: 'Alfrid de Lagarde', - birth: { day: 29, month: 7, year: 3193 }, - wiki: 'https://alexcreates.fr/leim/index.php/Alfrid_de_Lagarde', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Alaric de Lagarde', - birth: { day: 23, month: 8, year: 3192 }, - wiki: 'https://alexcreates.fr/leim/index.php/Alaric_de_Lagarde', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Anastael III de Quillon', - birth: { day: 1, month: 5, year: 3184 }, - wiki: 'https://alexcreates.fr/leim/index.php/Anastael_III_de_Quillon', - category: 'comte', - secondaryCategories: ['sentinelle', 'buse blanche'] - }, - { - name: 'Antoine de Mireloin', - birth: { day: 31, month: 5, year: 3190 }, - wiki: 'https://alexcreates.fr/leim/index.php/Antoine_de_Mireloin', - category: 'comte' - }, - { - name: 'Armance Ronchère', - birth: { day: 1, month: 1, year: 3132 }, - wiki: 'https://alexcreates.fr/leim/index.php/Armance_Ronchère', - category: 'comte' - }, - { - name: 'Baranne Rougefer', - birth: { day: 1, month: 0, year: 3175 }, - wiki: 'https://alexcreates.fr/leim/index.php/Baranne_Rougefer', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Béatrice II de Grandlac', - birth: { day: 21, month: 4, year: 3158 }, - wiki: 'https://alexcreates.fr/leim/index.php/Béatrice_II_de_Grandlac', - category: 'comte', - secondaryCategories: ['mage'] - }, - { - name: 'Favio Asharos-Losantelle', - birth: { day: 17, month: 3, year: 3091 }, - wiki: 'https://alexcreates.fr/leim/index.php/Favio_Asharos-Losantelle', - category: 'comte', - secondaryCategories: ['mage'] - }, - { - name: 'Firmin de Montardieu', - birth: { day: 9, month: 2, year: 3203 }, - wiki: 'https://alexcreates.fr/leim/index.php/Firmin_de_Montardieu', - category: 'comte' - }, - { - name: 'Laura de Montardieu', - birth: { day: 32, month: 3, year: 3167 }, - death: { day: 1, month: 4, year: 3217 }, - hiddenDeath: true, - wiki: 'https://alexcreates.fr/leim/index.php/Laura_de_Montardieu', - category: 'comte' - }, - { - name: 'Lazarus Tymos', - birth: { day: 29, month: 9, year: 3145 }, - wiki: 'https://alexcreates.fr/leim/index.php/Lazarus_Tymos', - category: 'comte', - secondaryCategories: ['mage', 'buse blanche'] - }, - { - name: 'Marion de Corambre', - birth: { day: 14, month: 7, year: 3190 }, - wiki: 'https://alexcreates.fr/leim/index.php/Marion_de_Corambre', - category: 'comte', - secondaryCategories: ['scientifique', 'ecclésiastique'] - }, - { - name: 'Relforg Pergaré', - birth: { day: 18, month: 9, year: 3182 }, - wiki: 'https://alexcreates.fr/leim/index.php/Relforg_Pergaré', - category: 'comte' - }, - { - name: 'Vilgarde de Ternâcre', - birth: { day: 3, month: 3, year: 2998 }, - wiki: 'https://alexcreates.fr/leim/index.php/Vilgarde_de_Ternâcre', - category: 'comte' - }, - { - name: 'Ysildy Milopée', - birth: { day: 3, month: 1, year: 3187 }, - wiki: 'https://alexcreates.fr/leim/index.php/Ysildy_Milopée', - category: 'comte', - secondaryCategories: ['mage', 'scientifique', 'professeur'] - }, - - // Sparks - { - name: 'Izàc Tymos', - birth: { day: 13, month: 6, year: 3192 }, - wiki: 'https://alexcreates.fr/leim/index.php/Izàc_Tymos', - category: 'mage', - secondaryCategories: ['étincelle', 'criminel', 'professeur', 'scientifique'] - }, - { - name: 'Tvernée', - birth: { day: 19, month: 2, year: 3205 }, - wiki: 'https://alexcreates.fr/leim/index.php/Tvernée', - category: 'étincelle', - secondaryCategories: ['criminel'] - }, - - // Pirates - { - name: 'Räzal', - birth: { day: 13, month: 8, year: 3178 }, - wiki: 'https://alexcreates.fr/leim/index.php/Räzal' - }, - - // Legends - { - name: 'Jorhas Kirendre', - birth: { day: 2, month: 9, year: -452 }, - death: { day: 2, month: 2, year: -419 }, - category: 'sentinelle', - wiki: 'https://alexcreates.fr/leim/index.php/Jorhas_Kirendre' - }, - - // "Les Milles Cages" - { - name: 'Ernestin Pomel', - birth: { day: 11, month: 2, year: 3179 }, - wiki: 'https://alexcreates.fr/leim/index.php/Ernestin_Pomel', - category: 'mage' - }, - { - name: 'Quacille Lévios', - birth: { day: 3, month: 6, year: 3162 }, - wiki: 'https://alexcreates.fr/leim/index.php/Quacille_Lévios', - category: 'professeur', - secondaryCategories: ['mage'] - }, - { - name: 'Morel Lévios', - birth: { day: 26, month: 3, year: 3157 }, - wiki: 'https://alexcreates.fr/leim/index.php/Morel_Lévios', - category: 'sentinelle', - secondaryCategories: ['mage', 'buse blanche'] - }, - { - name: 'Anastael Simon', - birth: { day: 32, month: 2, year: 3166 }, - wiki: 'https://alexcreates.fr/leim/index.php/Anastael_Simon', - category: 'étincelle', - secondaryCategories: ['mage'] - }, - { - name: 'Grestain', - birth: { day: 9, month: 2, year: 3162 }, - wiki: 'https://alexcreates.fr/leim/index.php/Grestain', - category: 'criminel', - secondaryCategories: ['mage'] - }, - { - name: 'Lucien Malanth', - birth: { day: 31, month: 4, year: 3167 }, - wiki: 'https://alexcreates.fr/leim/index.php/Lucien_Malanth', - category: 'criminel', - secondaryCategories: ['mage'] - }, - { - name: 'Tivian Rodhus', - birth: { day: 13, month: 3, year: 3157 }, - wiki: 'https://alexcreates.fr/leim/index.php/Tivian_Rodhus', - category: 'professeur', - secondaryCategories: ['mage', 'criminel'] - }, - - // "Les Cloches de Cantane" - { - name: 'Bénédicte Vaht', - description: "Moine d'Ikami ayant entrepris la construction du Pilier Blanc de Cantane", - birth: { day: 28, month: 6, year: 3139 }, - category: 'ecclésiastique' - }, - { - name: 'Taleb Vaht', - description: - "Fils de Bénédicte, il s'est engagé auprès des Étincelles comme alchimiste artificier.", - birth: { day: 9, month: 1, year: 3180 }, - death: { day: 28, month: 7, year: 3209 }, - category: 'étincelle', - secondaryCategories: ['scientifique'] - } - ] -}) diff --git a/server/api/characters/index.get.ts b/server/api/characters/index.get.ts new file mode 100644 index 0000000..1f9fa2e --- /dev/null +++ b/server/api/characters/index.get.ts @@ -0,0 +1,18 @@ +import { serverSupabaseClient } from "#supabase/server"; +import type { Character } from "~/models/Characters"; + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + + return client.from('characters') + .select(` + id, + name, + description, + birth, + death, + wiki, + characters_category (id, name) + `) + .returns() +}) diff --git a/server/api/characters/query.get.ts b/server/api/characters/query.get.ts new file mode 100644 index 0000000..4ad61fe --- /dev/null +++ b/server/api/characters/query.get.ts @@ -0,0 +1,29 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('characters') + .select(` + id, + name, + description, + birth, + death, + wiki, + characters_category (id, name) + `) + + if (query.world_id) { + output.eq('world_id', query.world_id) + } + + return output +}) diff --git a/server/api/events.ts b/server/api/events/index.get.ts similarity index 100% rename from server/api/events.ts rename to server/api/events/index.get.ts diff --git a/server/api/events/query.get.ts b/server/api/events/query.get.ts new file mode 100644 index 0000000..0331304 --- /dev/null +++ b/server/api/events/query.get.ts @@ -0,0 +1,23 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('events') + .select(` + id, + title, + description, + world_calendars (id, world_id) + `) + .eq('world_calendars.world_id', query.world_id) + + return output +}) diff --git a/server/api/worlds/index.get.ts b/server/api/worlds/index.get.ts new file mode 100644 index 0000000..3dbc6e2 --- /dev/null +++ b/server/api/worlds/index.get.ts @@ -0,0 +1,10 @@ +import { serverSupabaseClient } from "#supabase/server"; +import type { World } from "~/models/World"; + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + + return client.from('worlds') + .select(`id, name, description, color`) + .returns() +}) diff --git a/supabase/migrations/202401_init.sql b/supabase/migrations/202401_init.sql index 8cbfaa8..7b81467 100644 --- a/supabase/migrations/202401_init.sql +++ b/supabase/migrations/202401_init.sql @@ -4,9 +4,11 @@ -- Custom types create type public.app_permission as enum ('events.see.hidden', 'users.ban'); -create type public.app_role as enum ('sa', 'gm'); +create type public.app_role as enum ('sa', 'admin', 'moderator', 'user'); +create type public.app_colors as enum ('red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose', 'black', 'white'); --- USERS +-- DATA STRUCTURES +-- Users create table public.users ( id uuid references auth.users not null primary key, -- UUID from auth.users username text @@ -14,16 +16,16 @@ create table public.users ( comment on table public.users is 'Profile data for each user.'; comment on column public.users.id is 'References the internal Supabase Auth user.'; --- USER ROLES +-- Roles create table public.user_roles ( id bigint generated by default as identity primary key, - user_id uuid references public.users on delete cascade not null, role app_role not null, + user_id uuid references public.users on delete cascade not null, unique (user_id, role) ); comment on table public.user_roles is 'Application roles for each user.'; --- ROLE PERMISSIONS +-- Permissions create table public.role_permissions ( id bigint generated by default as identity primary key, role app_role not null, @@ -32,6 +34,70 @@ create table public.role_permissions ( ); comment on table public.role_permissions is 'Application permissions for each role.'; +-- Worlds +create table public.worlds ( + id bigint generated by default as identity primary key, + name text not null, + description text, + color app_colors, + gm_id uuid references public.users on delete cascade +); +comment on table public.worlds is 'Worlds belonging to a single user ; a game master.'; + +-- World Calendars +create table public.world_calendars ( + id bigint generated by default as identity primary key, + months text array, + days_per_year int not null, + world_id bigint references public.worlds on delete cascade not null +); +comment on table public.world_calendars is 'Calendar settings and configuration attached to a single world.'; + +-- Event categories +create table public.events_category ( + id bigint generated by default as identity primary key, + name text not null, + unique (name) +); +comment on table public.events_category is 'Categories describing events'; + +-- Events +create table public.events ( + id bigint generated by default as identity primary key, + title text not null, + description text, + start_date json not null, + end_date json, + category bigint references public.events_category on delete cascade, + hidden boolean, + wiki text, + calendar_id bigint references public.world_calendars on delete cascade not null +); +comment on table public.events is 'Events linked to a world'; + +-- Character categories +create table public.characters_category ( + id bigint generated by default as identity primary key, + name text not null, + unique (name) +); +comment on table public.characters_category is 'Categories describing characters'; + +-- Characters +create table public.characters ( + id bigint generated by default as identity primary key, + name text not null, + description text, + birth json not null, + death json, + category bigint references public.characters_category on delete cascade, + hidden_birth boolean, + hidden_death boolean, + wiki text, + world_id bigint references public.worlds on delete cascade not null +); +comment on table public.characters is 'Characters linked to a world'; + -- authorize with role-based access control (RBAC) create function public.authorize( requested_permission app_permission @@ -54,11 +120,84 @@ $$ language plpgsql security definer set search_path = public; alter table public.users enable row level security; alter table public.user_roles enable row level security; alter table public.role_permissions enable row level security; +alter table public.worlds enable row level security; +alter table public.world_calendars enable row level security; +alter table public.events_category enable row level security; +alter table public.characters_category enable row level security; +alter table public.characters enable row level security; +alter table public.events enable row level security; + +-- User policies create policy "Allow logged-in read access" on public.users for select using ( auth.role() = 'authenticated' ); create policy "Allow individual insert access" on public.users for insert with check ( auth.uid() = id ); create policy "Allow individual update access" on public.users for update using ( auth.uid() = id ); 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 ); + +-- Calendar policies +create policy "Allow individual read access for GMs" on public.world_calendars for select using ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); +create policy "Allow individual insert access for GMs" on public.world_calendars for insert with check ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); +create policy "Allow individual update access for GMs" on public.world_calendars for update with check ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); + +-- Event policies +create policy "Allow individual read access for GMs" on public.events for select using ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); +create policy "Allow individual insert access for GMs" on public.events for insert with check ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); +create policy "Allow individual update access for GMs" on public.events for update with check ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); + +-- Character policies +create policy "Allow individual read access for GMs" on public.characters for select using ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); +create policy "Allow individual insert access for GMs" on public.characters for insert with check ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); +create policy "Allow individual update access for GMs" on public.characters for update with check ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); + -- Send "previous data" on change alter table public.users replica identity full; @@ -69,6 +208,8 @@ declare is_admin boolean; begin insert into public.users (id, username) values (new.id, new.email); + insert into public.user_roles (role, user_id) + values ('user', new.id); return new; end; diff --git a/supabase/seed.sql b/supabase/seed.sql index f9b307a..efb1df7 100644 --- a/supabase/seed.sql +++ b/supabase/seed.sql @@ -1,4 +1,107 @@ -insert into public.role_permissions (role, permission) values ('gm', 'events.see.hidden'); - insert into public.role_permissions (role, permission) values ('sa', 'events.see.hidden'); insert into public.role_permissions (role, permission) values ('sa', 'users.ban'); + +-- Event categories +insert into public.events_category (name) values ('naissance'); +insert into public.events_category (name) values ('mort'); +insert into public.events_category (name) values ('catastrophe'); +insert into public.events_category (name) values ('catastrophe naturelle'); +insert into public.events_category (name) values ('inauguration'); +insert into public.events_category (name) values ('religion'); +insert into public.events_category (name) values ('invention'); +insert into public.events_category (name) values ('science'); +insert into public.events_category (name) values ('bénédiction'); +insert into public.events_category (name) values ('joueurs'); +insert into public.events_category (name) values ('découverte'); +insert into public.events_category (name) values ('exploration'); +insert into public.events_category (name) values ('construction'); +insert into public.events_category (name) values ('arcanologie'); +insert into public.events_category (name) values ('criminalité'); +insert into public.events_category (name) values ('scandale'); +insert into public.events_category (name) values ('commerce'); +insert into public.events_category (name) values ('législation'); + +-- Character categories +insert into public.characters_category (name) values ('joueur'); +insert into public.characters_category (name) values ('comte'); +insert into public.characters_category (name) values ('scientifique'); +insert into public.characters_category (name) values ('mage'); +insert into public.characters_category (name) values ('professeur'); +insert into public.characters_category (name) values ('criminel'); +insert into public.characters_category (name) values ('étincelle'); +insert into public.characters_category (name) values ('buse blanche'); +insert into public.characters_category (name) values ('ecclésiastique'); +insert into public.characters_category (name) values ('militaire'); +insert into public.characters_category (name) values ('activiste'); +insert into public.characters_category (name) values ('commerçant'); + +-- Worlds +insert into public.worlds (name, description, color) values ('Léïm', 'Monde d''aventures et d''intrigues med-fan', 'black'); + +-- Worlds' calendars +insert into public.world_calendars (world_id, months, days_per_year) values (1, ARRAY['Jalen', 'Malsen', 'Verlys', 'Nalys', 'Verdore', 'Sidore', 'Lyllion', 'Rion', 'Farene', 'Dalvene'], 320); + +-- Events +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Laurdieu devient la première cité de l''empire de Kaliatos', + 'L''empire de Kaliatos établi sa capitale dans la cité de Laurdieu, qui connaitra une prospérité nouvelle au sein d''Aldys.', + '{ "day": 3, "month": 4, "year": -1932 }', + 18, + true, + 'https://alexcreates.fr/leim/index.php/Laurdieu', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Apparition d''Asménys', + 'La défunte chanteuse Asménys apparaît à un barde pendant son jeune public, démarrant la religion des Prêtresses d''Asménys.', + '{ "day": 19, "month": 7, "year": -1358 }', + 6, + true, + 'https://alexcreates.fr/leim/index.php/Pr%C3%AAtresses_d%27Asm%C3%A9nys', + 1 +); +insert into public.events (title, description, start_date, end_date, category, hidden, wiki, calendar_id) values ( + 'La Rupture', + 'Les Abysses se déversent à la surface de Léim, à travers plusieurs brèches. Plusieurs hordes de démons se rapprochent des villes, et ce qu''on appellera l''Âge des Abysses commencent alors sur la planète entière.', + '{ "day": 26, "month": 5, "year": -756 }', + '{ "day": 4, "month": 9, "year": 29 }', + 3, + true, + 'https://alexcreates.fr/leim/index.php/Seconde_Rupture', + 1 +); +insert into public.events (title, description, start_date, end_date, category, hidden, wiki, calendar_id) values ( + 'Marche du sang', + 'L''empereur de Kaliatos ordonne personnellement la traque de Jorhas Kirendre pour connivence avec les démons. Plusieurs bataillons sont affectés à la chasse de Jorhas, qui se terminera par son incarcération ainsi que la mort de plusieurs centaines de soldats.', + '{ "day": 18, "month": 9, "year": -420 }', + '{ "day": 27, "month": 1, "year": -419 }', + 15, + true, + 'https://alexcreates.fr/leim/index.php/Jorhas_Kirendre', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Exécution de Tyhos', + 'Le léviathan Tyhos rend l''âme après un combat de plusieurs années contre Lystos, le dieu du Soleil.', + '{ "day": 1, "month": 0, "year": 0 }', + 9, + true, + 'https://alexcreates.fr/leim/index.php/Tyhos', + 1 +); +insert into public.events (title, start_date, category, wiki, calendar_id) values ( + 'Traité de Kadel', + '{ "day": 29, "month": 4, "year": 100 }', + 5, + 'https://alexcreates.fr/leim/index.php/Alliance_Kald%C3%A9lienne#Trait%C3%A9_de_Kadel', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Découverte des Plaines de Poussières', + 'Les troupes de la reconquête aldienne explorent le littoral d''une immense étendue grise et inerte.', + '{ "day": 17, "month": 7, "year": 305 }', + 11, + true, + 'https://alexcreates.fr/leim/index.php/Plaines_de_poussi%C3%A8re', + 1 +); From 67f5a270af7950f2b736a4a816f82260c1398661 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Thu, 16 May 2024 22:58:19 +0200 Subject: [PATCH 02/15] Huge refactor for backend and client This is barely functionnal, but at least it can display some data without crashing Most other functionnalities other than displaying events are broken, and so are the relative date operations, they need to be fixed asap --- components/calendar/Calendar.vue | 2 - components/calendar/CalendarEvent.vue | 6 +- components/calendar/CalendarEventDetails.vue | 4 +- components/calendar/CalendarMenuSubnav.vue | 4 +- components/calendar/Dashboard.vue | 12 +- components/calendar/search/CalendarSearch.vue | 6 +- .../search/lists/CharacterCallout.vue | 4 +- .../calendar/search/lists/EventCallout.vue | 4 +- .../calendar/search/lists/SearchList.vue | 12 +- components/calendar/state/monthly/DayTile.vue | 6 +- components/calendar/state/monthly/Layout.vue | 43 +------ components/calendar/state/yearly/DayTile.vue | 4 +- components/calendar/state/yearly/Layout.vue | 13 +- .../calendar/state/yearly/MonthTile.vue | 20 ++- models/CalendarConfig.ts | 12 +- models/CalendarEvent.ts | 18 +++ models/CalendarMonth.ts | 6 + models/Category.ts | 4 + models/Characters.ts | 6 +- models/Date.ts | 28 ++--- models/Events.ts | 39 ------ pages/index.vue | 16 --- server/api/calendars/query.get.ts | 17 ++- server/api/events/query.get.ts | 2 +- stores/CalendarStore.ts | 119 +++++------------- stores/EventStore.ts | 12 +- supabase/migrations/202401_init.sql | 65 +++++++--- supabase/seed.sql | 66 ++++++---- 28 files changed, 247 insertions(+), 303 deletions(-) create mode 100644 models/CalendarEvent.ts create mode 100644 models/CalendarMonth.ts create mode 100644 models/Category.ts delete mode 100644 models/Events.ts diff --git a/components/calendar/Calendar.vue b/components/calendar/Calendar.vue index e9b65df..6c39ec0 100644 --- a/components/calendar/Calendar.vue +++ b/components/calendar/Calendar.vue @@ -2,8 +2,6 @@ import { useCalendar } from '@/stores/CalendarStore' import { computed, type Component, type ComputedRef } from 'vue' -import CalendarMenu from './CalendarMenu.vue' - import MonthlyLayout from './state/monthly/Layout.vue' import CenturyLayout from './state/centennially/Layout.vue' import DecadeLayout from './state/decennially/Layout.vue' diff --git a/components/calendar/CalendarEvent.vue b/components/calendar/CalendarEvent.vue index cfb6b74..e80d2ce 100644 --- a/components/calendar/CalendarEvent.vue +++ b/components/calendar/CalendarEvent.vue @@ -1,14 +1,14 @@ diff --git a/components/calendar/search/CalendarSearch.vue b/components/calendar/search/CalendarSearch.vue index f01ba74..c1a266c 100644 --- a/components/calendar/search/CalendarSearch.vue +++ b/components/calendar/search/CalendarSearch.vue @@ -5,13 +5,13 @@ import { type Character, type CharacterCategory } from '@/models/Characters' -import type { LeimDateOrder } from '@/models/Date' +import type { RPGDateOrder } from '@/models/Date' import { calendarEventCategories, isCalendarEvent, type CalendarEvent, type CalendarEventCategory -} from '@/models/Events' +} from '~/models/CalendarEvent' import { useCharacters } from '@/stores/CharacterStore' import { useCalendarEvents } from '@/stores/EventStore' import { capitalize } from '@/utils/Strings' @@ -41,7 +41,7 @@ const searchQuery = ref('') const selectedEntity = useStorage('se', 'events' as SearchMode) // Order -const selectedOrder = ref('asc') +const selectedOrder = ref('asc') function setOrderAsc() { selectedOrder.value = 'asc' resetPage() diff --git a/components/calendar/search/lists/CharacterCallout.vue b/components/calendar/search/lists/CharacterCallout.vue index 932fde1..44df23c 100644 --- a/components/calendar/search/lists/CharacterCallout.vue +++ b/components/calendar/search/lists/CharacterCallout.vue @@ -1,6 +1,6 @@