feat: email infrastructure frontend — settings, templates, and log tabs

Adds three new tabs to the organisation settings page:

- E-mail opmaak: replaces old EmailBrandingTab to use the new
  organisation_email_settings API (logo, colors, footer, reply-to)
- E-mail templates: list/edit/preview/test/reset all 6 template types
  with variable hints, defaults comparison, and iframe preview
- E-mail log: server-side paginated table with filters (search, status,
  type, date range), status chips, and expandable row details

Supporting files:
- types/email.ts: TypeScript interfaces for settings, templates, logs
- composables/api/useEmail.ts: TanStack Query hooks for all email endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-15 20:28:38 +02:00
parent 65978104d8
commit df68aa8aef
7 changed files with 1211 additions and 76 deletions

View File

@@ -4,6 +4,8 @@ import PersonTagsTab from '@/components/organisation/PersonTagsTab.vue'
import RegistrationFieldTemplatesTab from '@/components/organisation/RegistrationFieldTemplatesTab.vue'
import CrowdTypesManager from '@/components/organisations/CrowdTypesManager.vue'
import EmailBrandingTab from '@/components/organisation/EmailBrandingTab.vue'
import EmailTemplatesTab from '@/components/organisation/EmailTemplatesTab.vue'
import EmailLogTab from '@/components/organisation/EmailLogTab.vue'
const route = useRoute()
const router = useRouter()
@@ -15,7 +17,9 @@ const tabs = [
{ value: 'tags', label: 'Tags & Vaardigheden', icon: 'tabler-tag' },
{ value: 'templates', label: 'Registratieveld-templates', icon: 'tabler-forms' },
{ value: 'crowd-types', label: 'Crowd types', icon: 'tabler-users-group' },
{ value: 'email-branding', label: 'E-mail opmaak', icon: 'tabler-mail' },
{ value: 'email-branding', label: 'E-mail opmaak', icon: 'tabler-mail-cog' },
{ value: 'email-templates', label: 'E-mail templates', icon: 'tabler-template' },
{ value: 'email-log', label: 'E-mail log', icon: 'tabler-mail-search' },
]
const activeTab = computed({
@@ -72,6 +76,12 @@ const activeTab = computed({
<VWindowItem value="email-branding">
<EmailBrandingTab :org-id="orgId" />
</VWindowItem>
<VWindowItem value="email-templates">
<EmailTemplatesTab :org-id="orgId" />
</VWindowItem>
<VWindowItem value="email-log">
<EmailLogTab :org-id="orgId" />
</VWindowItem>
</VWindow>
</div>
</template>