Files
Spanglish/frontend/src/lib/api/emails.ts
T
MichilisandCursor 613bd7be1d Refactor monolithic modules and harden booking, email, and auth infrastructure.
Split oversized frontend API client, email service, and admin/booking pages into focused modules while preserving import surfaces, and add Redis-backed queues, stale booking cleanup, stronger auth, and scale deployment configs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 07:12:59 +00:00

91 lines
3.0 KiB
TypeScript

import { fetchApi } from './client';
import type { EmailTemplate, EmailVariable, EmailLog, EmailStats, Pagination } from './types';
export const emailsApi = {
// Templates
getTemplates: () => fetchApi<{ templates: EmailTemplate[] }>('/api/emails/templates'),
getTemplate: (id: string) => fetchApi<{ template: EmailTemplate }>(`/api/emails/templates/${id}`),
createTemplate: (data: Partial<EmailTemplate>) =>
fetchApi<{ template: EmailTemplate; message: string }>('/api/emails/templates', {
method: 'POST',
body: JSON.stringify(data),
}),
updateTemplate: (id: string, data: Partial<EmailTemplate>) =>
fetchApi<{ template: EmailTemplate; message: string }>(`/api/emails/templates/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
deleteTemplate: (id: string) =>
fetchApi<{ message: string }>(`/api/emails/templates/${id}`, { method: 'DELETE' }),
getTemplateVariables: (slug: string) =>
fetchApi<{ variables: EmailVariable[] }>(`/api/emails/templates/${slug}/variables`),
// Sending
sendToEvent: (eventId: string, data: {
templateSlug: string;
customVariables?: Record<string, any>;
recipientFilter?: 'all' | 'confirmed' | 'pending' | 'checked_in';
}) =>
fetchApi<{ success: boolean; queuedCount: number; error?: string }>(
`/api/emails/send/event/${eventId}`,
{
method: 'POST',
body: JSON.stringify(data),
}
),
sendCustom: (data: {
to: string;
toName?: string;
subject: string;
bodyHtml: string;
bodyText?: string;
eventId?: string;
}) =>
fetchApi<{ success: boolean; logId?: string; error?: string }>('/api/emails/send/custom', {
method: 'POST',
body: JSON.stringify(data),
}),
preview: (data: {
templateSlug: string;
variables?: Record<string, any>;
locale?: string;
}) =>
fetchApi<{ subject: string; bodyHtml: string }>('/api/emails/preview', {
method: 'POST',
body: JSON.stringify(data),
}),
// Logs
getLogs: (params?: { eventId?: string; status?: string; search?: string; limit?: number; offset?: number }) => {
const query = new URLSearchParams();
if (params?.eventId) query.set('eventId', params.eventId);
if (params?.status) query.set('status', params.status);
if (params?.search) query.set('search', params.search);
if (params?.limit) query.set('limit', params.limit.toString());
if (params?.offset) query.set('offset', params.offset.toString());
return fetchApi<{ logs: EmailLog[]; pagination: Pagination }>(`/api/emails/logs?${query}`);
},
getLog: (id: string) => fetchApi<{ log: EmailLog }>(`/api/emails/logs/${id}`),
resendLog: (id: string) =>
fetchApi<{ success: boolean; error?: string }>(`/api/emails/logs/${id}/resend`, {
method: 'POST',
}),
getStats: (eventId?: string) => {
const query = eventId ? `?eventId=${eventId}` : '';
return fetchApi<{ stats: EmailStats }>(`/api/emails/stats${query}`);
},
seedTemplates: () =>
fetchApi<{ message: string }>('/api/emails/seed-templates', { method: 'POST' }),
};