feat: add email settings management

- Introduced EmailSettings component for managing SMTP services.
- Added API endpoints for organization email services including CRUD operations.
- Created database migrations for organization_email_settings and organization_email_services tables.
- Updated the settings page to include EmailSettings component.
- Implemented validation and error handling for email service operations.
This commit is contained in:
2026-04-15 09:33:50 -04:00
parent 44facf7f4a
commit e1d5975e57
12 changed files with 1877 additions and 18 deletions
+42
View File
@@ -302,6 +302,36 @@ export interface OrganizationSSOConfig {
updated_at: string;
}
export interface OrganizationEmailService {
id: string;
organization_id: string;
service_type: string;
provider_key: string;
display_name: string;
smtp_enabled: boolean;
is_default: boolean;
smtp_host?: string;
smtp_port: number;
smtp_from?: string;
smtp_username?: string;
smtp_starttls: boolean;
has_password: boolean;
}
export interface UpsertOrganizationEmailServicePayload {
service_type: string;
provider_key: string;
display_name: string;
smtp_enabled: boolean;
is_default: boolean;
smtp_host?: string;
smtp_port: number;
smtp_from?: string;
smtp_username?: string;
smtp_password?: string;
smtp_starttls: boolean;
}
export interface ProvisionPayload {
org_name: string;
org_domain?: string;
@@ -881,6 +911,18 @@ export const cmsApi = {
},
getSSOConfig: (): Promise<OrganizationSSOConfig> => apiFetch('/organization/sso'),
updateSSOConfig: (payload: Partial<OrganizationSSOConfig>): Promise<void> => apiFetch('/organization/sso', { method: 'PUT', body: JSON.stringify(payload) }),
getOrganizationEmailSettings: (): Promise<OrganizationEmailService> => apiFetch('/organization/email-settings'),
updateOrganizationEmailSettings: (payload: UpsertOrganizationEmailServicePayload): Promise<OrganizationEmailService> =>
apiFetch('/organization/email-settings', { method: 'PUT', body: JSON.stringify(payload) }),
listOrganizationEmailServices: (): Promise<OrganizationEmailService[]> => apiFetch('/organization/email-services'),
createOrganizationEmailService: (payload: UpsertOrganizationEmailServicePayload): Promise<OrganizationEmailService> =>
apiFetch('/organization/email-services', { method: 'POST', body: JSON.stringify(payload) }),
updateOrganizationEmailService: (id: string, payload: UpsertOrganizationEmailServicePayload): Promise<OrganizationEmailService> =>
apiFetch(`/organization/email-services/${id}`, { method: 'PUT', body: JSON.stringify(payload) }),
deleteOrganizationEmailService: (id: string): Promise<void> =>
apiFetch(`/organization/email-services/${id}`, { method: 'DELETE' }),
selectOrganizationEmailService: (id: string): Promise<void> =>
apiFetch(`/organization/email-services/${id}/select`, { method: 'POST' }),
getOrganizationExerciseSettings: (): Promise<OrganizationExerciseSettings> => apiFetch('/organization/exercise-settings'),
updateOrganizationExerciseSettings: (payload: Omit<OrganizationExerciseSettings, 'organization_id'>): Promise<OrganizationExerciseSettings> =>
apiFetch('/organization/exercise-settings', { method: 'PUT', body: JSON.stringify(payload) }),