| @@ -16,13 +16,77 @@ | ||
| 16 | 16 | body: string; |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | export async function fetchEmailTemplates(): Promise<unknown[]> { |
| 20 | - const raw = await apiClient.get(API_ENDPOINTS.EMAIL_TEMPLATES); | |
| 20 | + // The list is rendered client-side in full (no server paging in the UI); | |
| 21 | + // ask for everything so trip-specific overrides never fall off page 1. | |
| 22 | + const raw = await apiClient.get(API_ENDPOINTS.EMAIL_TEMPLATES, { | |
| 23 | + params: { per_page: 500 }, | |
| 24 | + }); | |
| 21 | 25 | const unwrapped = unwrapApiPayload<unknown>(raw); |
| 22 | 26 | return Array.isArray(unwrapped) ? unwrapped : []; |
| 23 | 27 | } |
| 24 | 28 | |
| 29 | +/** Trip targeting of an override template (mirrors the Pro `settings.targets`). */ | |
| 30 | +export type EmailTemplateTargets = { | |
| 31 | + trips?: number[]; | |
| 32 | + categories?: number[]; | |
| 33 | + trip_types?: string[]; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * Create a trip-specific override of a global template (Pro Email | |
| 38 | + * Automation). Same event and merge tags; used instead of the global | |
| 39 | + * template for bookings on the targeted trips. | |
| 40 | + */ | |
| 41 | +export async function createEmailTemplateOverride( | |
| 42 | + parentId: string | number, | |
| 43 | + data: { | |
| 44 | + targets: EmailTemplateTargets; | |
| 45 | + name?: string; | |
| 46 | + description?: string; | |
| 47 | + copy?: boolean; | |
| 48 | + }, | |
| 49 | +): Promise<unknown> { | |
| 50 | + return apiClient.post(API_ENDPOINTS.EMAIL_TEMPLATE_OVERRIDE(parentId), data); | |
| 51 | +} | |
| 52 | + | |
| 53 | +export async function reorderEmailTemplateOverrides( | |
| 54 | + parentKey: string, | |
| 55 | + ids: number[], | |
| 56 | +): Promise<unknown> { | |
| 57 | + return apiClient.post(API_ENDPOINTS.EMAIL_TEMPLATE_OVERRIDES_REORDER, { | |
| 58 | + parent_key: parentKey, | |
| 59 | + ids, | |
| 60 | + }); | |
| 61 | +} | |
| 62 | + | |
| 63 | +export type EmailTemplateResolution = { | |
| 64 | + trip: { id: number; trip_type: string; categories: number[] }; | |
| 65 | + resolved: Record< | |
| 66 | + string, | |
| 67 | + { | |
| 68 | + id: number; | |
| 69 | + template_key: string; | |
| 70 | + name: string; | |
| 71 | + specificity: number; | |
| 72 | + reason: string; | |
| 73 | + } | null | |
| 74 | + >; | |
| 75 | + overridable: string[]; | |
| 76 | +}; | |
| 77 | + | |
| 78 | +/** "View as a trip": which template each overridable email uses for a trip. */ | |
| 79 | +export async function resolveEmailTemplatesForTrip( | |
| 80 | + tripId: number, | |
| 81 | +): Promise<EmailTemplateResolution> { | |
| 82 | + return unwrapApiPayload<EmailTemplateResolution>( | |
| 83 | + await apiClient.get(API_ENDPOINTS.EMAIL_TEMPLATE_RESOLVE, { | |
| 84 | + params: { trip_id: tripId }, | |
| 85 | + }), | |
| 86 | + ); | |
| 87 | +} | |
| 88 | + | |
| 25 | 89 | export async function fetchEmailTemplate( |
| 26 | 90 | id: string | number, |
| 27 | 91 | ): Promise<Record<string, unknown> | null> { |
| 28 | 92 | return unwrapApiPayload<Record<string, unknown> | null>( |
| @@ -96,12 +160,13 @@ | ||
| 96 | 160 | } |
| 97 | 161 | |
| 98 | 162 | export async function previewEmailTemplate( |
| 99 | 163 | id: string | number, |
| 164 | + tripId?: number | null, | |
| 100 | 165 | ): Promise<EmailPreviewPayload> { |
| 101 | 166 | const response = await apiClient.post( |
| 102 | 167 | API_ENDPOINTS.EMAIL_TEMPLATE_PREVIEW(id), |
| 103 | - {}, | |
| 168 | + tripId ? { trip_id: tripId } : {}, | |
| 104 | 169 | ); |
| 105 | 170 | return unwrapApiPayload<EmailPreviewPayload>(response); |
| 106 | 171 | } |
| 107 | 172 | |
| @@ -107,10 +172,14 @@ | ||
| 107 | 172 | |
| 108 | 173 | export async function sendEmailTemplateTest( |
| 109 | 174 | id: string | number, |
| 110 | 175 | email: string, |
| 176 | + tripId?: number | null, | |
| 111 | 177 | ): Promise<unknown> { |
| 112 | - return apiClient.post(API_ENDPOINTS.EMAIL_TEMPLATE_TEST(id), { email }); | |
| 178 | + return apiClient.post(API_ENDPOINTS.EMAIL_TEMPLATE_TEST(id), { | |
| 179 | + email, | |
| 180 | + ...(tripId ? { trip_id: tripId } : {}), | |
| 181 | + }); | |
| 113 | 182 | } |
| 114 | 183 | |
| 115 | 184 | export async function fetchEmailSequences(): Promise<unknown[]> { |
| 116 | 185 | const raw = await apiClient.get(API_ENDPOINTS.EMAIL_SEQUENCES); |