Files
crewli/apps/app/src/components/event/RegistrationFieldCard.vue
bert.hausmans a9dcee0fc7 feat(app): registration fields management page in event settings
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>
2026-04-12 23:44:14 +02:00

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>