die eventphotospage funktioniert nun zuverlässig

This commit is contained in:
Codex Agent
2025-11-26 17:49:55 +01:00
parent 8b395ab552
commit bfa15cc48e
15 changed files with 478 additions and 202 deletions

View File

@@ -1300,16 +1300,51 @@ export async function getEventTypes(): Promise<TenantEventType[]> {
.filter((row): row is TenantEventType => Boolean(row));
}
export async function getEventPhotos(slug: string): Promise<{ photos: TenantPhoto[]; limits: EventLimitSummary | null }> {
const response = await authorizedFetch(`${eventEndpoint(slug)}/photos`);
const data = await jsonOrThrow<{ data?: TenantPhoto[]; limits?: EventLimitSummary | null }>(
export type GetEventPhotosOptions = {
page?: number;
perPage?: number;
sort?: 'asc' | 'desc';
search?: string;
status?: string;
featured?: boolean;
ingestSource?: string;
visibility?: 'visible' | 'hidden' | 'all';
};
export async function getEventPhotos(
slug: string,
options: GetEventPhotosOptions = {}
): Promise<{ photos: TenantPhoto[]; limits: EventLimitSummary | null; meta: PaginationMeta }> {
const params = new URLSearchParams();
if (options.page) params.set('page', String(options.page));
if (options.perPage) params.set('per_page', String(options.perPage));
if (options.sort) params.set('sort', options.sort);
if (options.search) params.set('search', options.search);
if (options.status) params.set('status', options.status);
if (options.featured) params.set('featured', '1');
if (options.ingestSource) params.set('ingest_source', options.ingestSource);
if (options.visibility) params.set('visibility', options.visibility);
const response = await authorizedFetch(`${eventEndpoint(slug)}/photos${params.toString() ? `?${params.toString()}` : ''}`);
const data = await jsonOrThrow<{
data?: TenantPhoto[];
limits?: EventLimitSummary | null;
meta?: Partial<PaginationMeta>;
current_page?: number;
last_page?: number;
per_page?: number;
total?: number;
}>(
response,
'Failed to load photos'
);
const meta = buildPagination(data as unknown as JsonValue, options.perPage ?? 40);
return {
photos: (data.data ?? []).map(normalizePhoto),
limits: (data.limits ?? null) as EventLimitSummary | null,
meta,
};
}
@@ -1328,8 +1363,12 @@ export async function unfeaturePhoto(slug: string, id: number): Promise<TenantPh
export async function deletePhoto(slug: string, id: number): Promise<void> {
const response = await authorizedFetch(`${eventEndpoint(slug)}/photos/${id}`, { method: 'DELETE' });
if (!response.ok) {
await safeJson(response);
throw new Error('Failed to delete photo');
const payload = await safeJson(response);
if (response.status === 404) {
// Treat missing files as idempotent deletes to keep the UI in sync.
return;
}
throw new Error(typeof payload?.message === 'string' ? payload.message : 'Failed to delete photo');
}
}