feat: event team management with departments and roles - Migration 023: event_roles, event_departments, event_member_departments tables - Auto-seed default roles (Head Organizer, Team Lead, Organizer, Volunteer, Sponsor) and departments (Logistics, IT & Tech, Marketing, Finance, Program, Sponsorship, Design, Volunteers) on event creation - API: full CRUD for roles, departments, member-department assignments - Enhanced fetchEventMembers with role + department resolution - Team page: sidebar with department filter + role legend, list/dept view toggle, add/edit/remove members with role + multi-department + notes - i18n: 25 new keys in EN and ET for team management - svelte-check: 0 errors, vitest: 112/112 passed
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import type { LayoutServerLoad } from './$types';
|
||||
import { fetchEventBySlug, fetchEventMembers } from '$lib/api/events';
|
||||
import { fetchEventBySlug, fetchEventMembers, fetchEventRoles, fetchEventDepartments } from '$lib/api/events';
|
||||
import { createLogger } from '$lib/utils/logger';
|
||||
|
||||
const log = createLogger('page.event-detail');
|
||||
@@ -16,9 +16,13 @@ export const load: LayoutServerLoad = async ({ params, locals, parent }) => {
|
||||
const event = await fetchEventBySlug(locals.supabase, orgId, params.eventSlug);
|
||||
if (!event) error(404, 'Event not found');
|
||||
|
||||
const members = await fetchEventMembers(locals.supabase, event.id);
|
||||
const [members, roles, departments] = await Promise.all([
|
||||
fetchEventMembers(locals.supabase, event.id),
|
||||
fetchEventRoles(locals.supabase, event.id),
|
||||
fetchEventDepartments(locals.supabase, event.id),
|
||||
]);
|
||||
|
||||
return { event, eventMembers: members };
|
||||
return { event, eventMembers: members, eventRoles: roles, eventDepartments: departments };
|
||||
} catch (e: any) {
|
||||
if (e?.status === 404) throw e;
|
||||
log.error('Failed to load event', { error: e, data: { orgId, eventSlug: params.eventSlug } });
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { page } from "$app/stores";
|
||||
import { Avatar } from "$lib/components/ui";
|
||||
import type { Snippet } from "svelte";
|
||||
import type { Event, EventMember } from "$lib/api/events";
|
||||
import type { Event, EventMemberWithDetails, EventRole, EventDepartment } from "$lib/api/events";
|
||||
import * as m from "$lib/paraglide/messages";
|
||||
|
||||
interface Props {
|
||||
@@ -10,14 +10,9 @@
|
||||
org: { id: string; name: string; slug: string };
|
||||
userRole: string;
|
||||
event: Event;
|
||||
eventMembers: (EventMember & {
|
||||
profile?: {
|
||||
id: string;
|
||||
email: string;
|
||||
full_name: string | null;
|
||||
avatar_url: string | null;
|
||||
};
|
||||
})[];
|
||||
eventMembers: EventMemberWithDetails[];
|
||||
eventRoles: EventRole[];
|
||||
eventDepartments: EventDepartment[];
|
||||
};
|
||||
children: Snippet;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { SupabaseClient } from "@supabase/supabase-js";
|
||||
import type { Database } from "$lib/supabase/types";
|
||||
import { toasts } from "$lib/stores/ui";
|
||||
import type { Event, EventMember } from "$lib/api/events";
|
||||
import type { Event, EventMemberWithDetails, EventRole, EventDepartment } from "$lib/api/events";
|
||||
import * as m from "$lib/paraglide/messages";
|
||||
|
||||
interface Props {
|
||||
@@ -13,14 +13,9 @@
|
||||
org: { id: string; name: string; slug: string };
|
||||
userRole: string;
|
||||
event: Event;
|
||||
eventMembers: (EventMember & {
|
||||
profile?: {
|
||||
id: string;
|
||||
email: string;
|
||||
full_name: string | null;
|
||||
avatar_url: string | null;
|
||||
};
|
||||
})[];
|
||||
eventMembers: EventMemberWithDetails[];
|
||||
eventRoles: EventRole[];
|
||||
eventDepartments: EventDepartment[];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user