Files
Spanglish/frontend/src/lib/api/events.ts
T
MichilisandClaude Opus 5 5970d707af Paginate the admin events list.
The admin events page fetched every event on each load and rendered
them all, which grows without bound as the archive fills up. GET
/api/events now takes optional page and pageSize parameters and returns
total alongside the rows; pagination is opt-in, so the public pages and
the admin filter dropdowns that pass neither still get the full list
and the untouched response shape.

Page size is selectable (10/25/50/100) and deleting the last event on a
page falls back to the new last page instead of showing an empty table.
The ?edit=<id> deep link no longer depends on the target being in the
current page: when it is missing from the loaded rows the event is
fetched directly, guarded by a ref so the modal opens once.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 05:16:28 +00:00

46 lines
1.8 KiB
TypeScript

import { fetchApi } from './client';
import type { Event } from './types';
export const eventsApi = {
getAll: (params?: { status?: string; upcoming?: boolean; page?: number; pageSize?: number }) => {
const query = new URLSearchParams();
if (params?.status) query.set('status', params.status);
if (params?.upcoming) query.set('upcoming', 'true');
// Passing page/pageSize switches the endpoint into paginated mode, which also
// returns `total`; without them the full list comes back as before.
if (params?.page) query.set('page', String(params.page));
if (params?.pageSize) query.set('pageSize', String(params.pageSize));
return fetchApi<{ events: Event[]; total?: number }>(`/api/events?${query}`);
},
getById: (id: string) => fetchApi<{ event: Event }>(`/api/events/${id}`),
getNext: () => fetchApi<{ event: Event | null }>('/api/events/next'),
getNextUpcoming: () => fetchApi<{ event: Event | null }>('/api/events/next/upcoming'),
create: (data: Partial<Event>) =>
fetchApi<{ event: Event }>('/api/events', {
method: 'POST',
body: JSON.stringify(data),
}),
update: (id: string, data: Partial<Event>) =>
fetchApi<{ event: Event }>(`/api/events/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
delete: (id: string) =>
fetchApi<{ message: string }>(`/api/events/${id}`, { method: 'DELETE' }),
duplicate: (id: string) =>
fetchApi<{ event: Event; message: string }>(`/api/events/${id}/duplicate`, { method: 'POST' }),
getSlugAliases: (id: string) =>
fetchApi<{ aliases: { slug: string; createdAt: string }[] }>(`/api/events/${id}/slug-aliases`),
deleteSlugAlias: (id: string, slug: string) =>
fetchApi<{ message: string }>(`/api/events/${id}/slug-aliases/${encodeURIComponent(slug)}`, { method: 'DELETE' }),
};