Adds a new settings sub-page for managing dynamic registration form fields per event. Includes sortable field list, create/edit dialog, template picker, and import-from-event functionality. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
157 lines
3.9 KiB
Vue
157 lines
3.9 KiB
Vue
<script setup lang="ts">
|
|
import type { RegistrationFormField } from '@/types/registration-form-field'
|
|
import { FIELD_TYPE_LABELS } from '@/types/registration-field-template'
|
|
|
|
defineProps<{
|
|
field: RegistrationFormField
|
|
}>()
|
|
|
|
defineEmits<{
|
|
edit: [field: RegistrationFormField]
|
|
delete: [field: RegistrationFormField]
|
|
}>()
|
|
|
|
function formatOptions(options: string[] | null): string {
|
|
if (!options?.length) return ''
|
|
if (options.length <= 5) return options.join(', ')
|
|
return `${options.slice(0, 5).join(', ')}, +${options.length - 5} meer`
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<VCard
|
|
variant="outlined"
|
|
class="mb-2"
|
|
>
|
|
<VCardText class="pa-4">
|
|
<div class="d-flex align-start gap-3">
|
|
<!-- Drag handle -->
|
|
<div class="drag-handle d-flex align-center pt-1 cursor-grab">
|
|
<VIcon
|
|
icon="tabler-grip-vertical"
|
|
size="20"
|
|
class="text-disabled"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="flex-grow-1 min-width-0">
|
|
<div class="d-flex align-center justify-space-between gap-2 mb-1">
|
|
<span class="text-body-1 font-weight-medium">
|
|
{{ field.label }}
|
|
</span>
|
|
<VChip
|
|
size="small"
|
|
variant="tonal"
|
|
color="default"
|
|
>
|
|
{{ FIELD_TYPE_LABELS[field.field_type] ?? field.field_type }}
|
|
</VChip>
|
|
</div>
|
|
|
|
<!-- Section -->
|
|
<div
|
|
v-if="field.section"
|
|
class="text-body-2 text-medium-emphasis mb-1"
|
|
>
|
|
Sectie: {{ field.section }}
|
|
</div>
|
|
|
|
<!-- Options preview -->
|
|
<div
|
|
v-if="field.options?.length"
|
|
class="text-body-2 text-medium-emphasis mb-1"
|
|
>
|
|
Opties: {{ formatOptions(field.options) }}
|
|
</div>
|
|
|
|
<!-- Tag category -->
|
|
<div
|
|
v-if="field.field_type === 'tag_picker' && field.tag_category"
|
|
class="text-body-2 text-medium-emphasis mb-1"
|
|
>
|
|
Categorie: {{ field.tag_category }}
|
|
</div>
|
|
|
|
<!-- Help text -->
|
|
<div
|
|
v-if="field.help_text"
|
|
class="text-body-2 text-disabled mb-1 text-truncate"
|
|
>
|
|
{{ field.help_text }}
|
|
</div>
|
|
|
|
<!-- Status badges -->
|
|
<div class="d-flex flex-wrap gap-1 mt-2">
|
|
<VChip
|
|
v-if="field.is_required"
|
|
size="x-small"
|
|
variant="tonal"
|
|
color="error"
|
|
>
|
|
Verplicht
|
|
</VChip>
|
|
<VChip
|
|
v-if="field.is_filterable"
|
|
size="x-small"
|
|
variant="tonal"
|
|
color="info"
|
|
>
|
|
Filterbaar
|
|
</VChip>
|
|
<VChip
|
|
v-if="field.is_portal_visible"
|
|
size="x-small"
|
|
variant="tonal"
|
|
color="success"
|
|
>
|
|
Zichtbaar
|
|
</VChip>
|
|
<VChip
|
|
v-if="field.is_admin_only"
|
|
size="x-small"
|
|
variant="tonal"
|
|
color="warning"
|
|
>
|
|
Admin-only
|
|
</VChip>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="d-flex align-center gap-x-1 pt-1">
|
|
<VBtn
|
|
icon="tabler-edit"
|
|
variant="text"
|
|
size="small"
|
|
title="Bewerken"
|
|
@click="$emit('edit', field)"
|
|
/>
|
|
<VBtn
|
|
icon="tabler-trash"
|
|
variant="text"
|
|
size="small"
|
|
color="error"
|
|
title="Verwijderen"
|
|
@click="$emit('delete', field)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</VCardText>
|
|
</VCard>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.min-width-0 {
|
|
min-inline-size: 0;
|
|
}
|
|
|
|
.cursor-grab {
|
|
cursor: grab;
|
|
}
|
|
|
|
.cursor-grab:active {
|
|
cursor: grabbing;
|
|
}
|
|
</style>
|