feat: unify tenant admin ui and add photo moderation
This commit is contained in:
@@ -137,6 +137,11 @@ export type DashboardSummary = {
|
||||
expires_at?: string | null;
|
||||
remaining_events?: number | null;
|
||||
} | null;
|
||||
engagement_totals?: {
|
||||
tasks?: number;
|
||||
collections?: number;
|
||||
emotions?: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type TenantOnboardingStatus = {
|
||||
@@ -620,8 +625,31 @@ function normalizeDashboard(payload: JsonValue | null): DashboardSummary | null
|
||||
name: String(payload.active_package.name ?? 'Aktives Package'),
|
||||
expires_at: payload.active_package.expires_at ?? null,
|
||||
remaining_events: payload.active_package.remaining_events ?? payload.active_package.remainingEvents ?? null,
|
||||
}
|
||||
}
|
||||
: null,
|
||||
engagement_totals: {
|
||||
tasks:
|
||||
Number(
|
||||
payload.tasks?.summary?.total ??
|
||||
payload.tasks_total ??
|
||||
payload.engagement?.tasks ??
|
||||
0,
|
||||
),
|
||||
collections:
|
||||
Number(
|
||||
payload.task_collections?.summary?.total ??
|
||||
payload.collections_total ??
|
||||
payload.engagement?.collections ??
|
||||
0,
|
||||
),
|
||||
emotions:
|
||||
Number(
|
||||
payload.emotions?.summary?.total ??
|
||||
payload.emotions_total ??
|
||||
payload.engagement?.emotions ??
|
||||
0,
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -923,6 +951,18 @@ export async function deletePhoto(slug: string, id: number): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function updatePhotoVisibility(slug: string, id: number, visible: boolean): Promise<TenantPhoto> {
|
||||
const response = await authorizedFetch(`${eventEndpoint(slug)}/photos/${id}/visibility`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ visible }),
|
||||
});
|
||||
const data = await jsonOrThrow<PhotoResponse>(response, 'Failed to update photo visibility');
|
||||
return normalizePhoto(data.data);
|
||||
}
|
||||
|
||||
export async function toggleEvent(slug: string): Promise<TenantEvent> {
|
||||
const response = await authorizedFetch(`${eventEndpoint(slug)}/toggle`, { method: 'POST' });
|
||||
const data = await jsonOrThrow<{ message: string; data: JsonValue }>(response, 'Failed to toggle event');
|
||||
@@ -1026,22 +1066,22 @@ export async function getEventToolkit(slug: string): Promise<EventToolkit> {
|
||||
active_invites: Number((metrics as JsonValue).active_invites ?? 0),
|
||||
engagement_mode: ((metrics as JsonValue).engagement_mode as 'tasks' | 'photo_only') ?? 'tasks',
|
||||
},
|
||||
tasks: {
|
||||
summary: {
|
||||
total: Number((tasks as JsonValue)?.summary?.total ?? 0),
|
||||
completed: Number((tasks as JsonValue)?.summary?.completed ?? 0),
|
||||
pending: Number((tasks as JsonValue)?.summary?.pending ?? 0),
|
||||
},
|
||||
items: Array.isArray((tasks as JsonValue)?.items)
|
||||
? ((tasks as JsonValue).items as JsonValue[]).map((item) => ({
|
||||
id: Number(item?.id ?? 0),
|
||||
title: String(item?.title ?? ''),
|
||||
description: item?.description !== undefined && item?.description !== null ? String(item.description) : null,
|
||||
is_completed: Boolean(item?.is_completed ?? false),
|
||||
priority: item?.priority !== undefined ? String(item.priority) : null,
|
||||
}))
|
||||
: [],
|
||||
tasks: {
|
||||
summary: {
|
||||
total: Number((tasks as JsonValue)?.summary?.total ?? 0),
|
||||
completed: Number((tasks as JsonValue)?.summary?.completed ?? 0),
|
||||
pending: Number((tasks as JsonValue)?.summary?.pending ?? 0),
|
||||
},
|
||||
items: Array.isArray((tasks as JsonValue)?.items)
|
||||
? ((tasks as JsonValue).items as JsonValue[]).map((item) => ({
|
||||
id: Number(item?.id ?? 0),
|
||||
title: String(item?.title ?? ''),
|
||||
description: item?.description !== undefined && item?.description !== null ? String(item.description) : null,
|
||||
is_completed: Boolean(item?.is_completed ?? false),
|
||||
priority: item?.priority !== undefined ? String(item.priority) : null,
|
||||
}))
|
||||
: [],
|
||||
},
|
||||
photos: {
|
||||
pending: pendingPhotosRaw.map((photo: JsonValue) => normalizePhoto(photo as TenantPhoto)),
|
||||
recent: recentPhotosRaw.map((photo: JsonValue) => normalizePhoto(photo as TenantPhoto)),
|
||||
|
||||
Reference in New Issue
Block a user