refactor: polish shift create dialog layout and hierarchy

Made-with: Cursor
This commit is contained in:
2026-04-14 22:45:12 +02:00
parent 1c6aed71fe
commit 1c3ce547fa

View File

@@ -5,7 +5,6 @@ import { useTimeSlotList } from '@/composables/api/useTimeSlots'
import { useEventDetail } from '@/composables/api/useEvents'
import { useAuthStore } from '@/stores/useAuthStore'
import { useTimeSlotDropdown } from '@/composables/useTimeSlotDropdown'
import InfoTooltip from '@/components/common/InfoTooltip.vue'
import { requiredValidator } from '@core/utils/validators'
import type { FestivalSection, Shift, ShiftStatus } from '@/types/section'
@@ -196,41 +195,63 @@ function onSubmit() {
<template>
<VDialog
v-model="modelValue"
max-width="600"
max-width="640"
scrollable
@after-leave="!isEditing && resetForm()"
>
<VCard :title="isEditing ? 'Shift bewerken' : 'Shift toevoegen'">
<VCard rounded="lg">
<VCardItem class="py-4">
<VCardTitle class="text-h6">
{{ isEditing ? 'Shift bewerken' : 'Shift toevoegen' }}
</VCardTitle>
<VCardSubtitle
v-if="section"
class="text-body-2 text-high-emphasis opacity-100 mt-1"
>
<span>{{ section.name }}</span>
<VChip
v-if="section.type === 'cross_event'"
size="x-small"
color="info"
variant="tonal"
class="ms-2"
>
festival-breed
</VChip>
<span
v-else-if="isSubEvent && eventDetail?.name"
class="text-medium-emphasis"
> · {{ eventDetail.name }}</span>
</VCardSubtitle>
</VCardItem>
<VDivider />
<VForm
ref="refVForm"
@submit.prevent="onSubmit"
>
<VCardText>
<!-- Cross_event section context indicator -->
<div
v-if="section?.type === 'cross_event'"
class="mb-4"
<VCardText class="pt-5">
<VAlert
v-if="showInfoTooltip && tooltipText"
type="info"
variant="tonal"
density="compact"
class="mb-6"
title="Tijdsloten in dit evenement"
>
<span class="text-body-2 text-medium-emphasis">
{{ section.name }}
</span>
<VChip
size="x-small"
color="info"
variant="tonal"
class="ml-2"
>
festival-breed
</VChip>
</div>
<div
v-else-if="isSubEvent && section"
class="mb-4"
>
<span class="text-body-2 text-medium-emphasis">
{{ section.name }} · {{ eventDetail?.name }}
</span>
</div>
<p class="text-body-2 mb-0">
{{ tooltipText.main }}
</p>
<p class="text-caption text-medium-emphasis mb-0 mt-2">
<span class="font-weight-medium text-high-emphasis">Tip:</span>
{{ tooltipText.tip }}
</p>
</VAlert>
<p class="text-overline text-medium-emphasis letter-spacing-normal mb-3">
Tijd & rol
</p>
<VRow>
<VCol cols="12">
<VAutocomplete
@@ -243,22 +264,8 @@ function onSubmit() {
:loading="timeSlotsLoading"
:rules="[requiredValidator]"
:error-messages="errors.time_slot_id"
hide-details="auto"
>
<template
v-if="showInfoTooltip"
#prepend-inner
>
<InfoTooltip>
<p>{{ tooltipText?.main }}</p>
<div
class="mt-2 pa-2 rounded text-caption"
style="background: rgb(var(--v-theme-surface-variant)); line-height: 1.5;"
>
<strong>Tip:</strong> {{ tooltipText?.tip }}
</div>
</InfoTooltip>
</template>
<template #item="{ props: itemProps, item, index }">
<!-- Group header: rendered when event_name changes -->
<VListSubheader
@@ -313,14 +320,27 @@ function onSubmit() {
autocomplete="one-time-code"
/>
</VCol>
</VRow>
<VDivider class="my-5" />
<p class="text-overline text-medium-emphasis letter-spacing-normal mb-3">
Tijden (optioneel)
</p>
<p class="text-caption text-medium-emphasis mb-4">
Laat leeg om de start- en eindtijd van het gekozen tijdslot te gebruiken.
</p>
<VRow>
<VCol
cols="12"
sm="4"
>
<AppTextField
v-model="form.report_time"
label="Aanwezig om (rapport tijd)"
label="Rapporttijd"
type="time"
hint="Aanwezig vanaf"
persistent-hint
:error-messages="errors.report_time"
/>
</VCol>
@@ -330,9 +350,9 @@ function onSubmit() {
>
<AppTextField
v-model="form.actual_start_time"
label="Afwijkende starttijd"
label="Starttijd"
type="time"
hint="Leeg = time slot tijd"
hint="Leeg = time slot"
persistent-hint
:error-messages="errors.actual_start_time"
/>
@@ -343,11 +363,21 @@ function onSubmit() {
>
<AppTextField
v-model="form.actual_end_time"
label="Afwijkende eindtijd"
label="Eindtijd"
type="time"
hint="Leeg = time slot"
persistent-hint
:error-messages="errors.actual_end_time"
/>
</VCol>
</VRow>
<VDivider class="my-5" />
<p class="text-overline text-medium-emphasis letter-spacing-normal mb-3">
Capaciteit
</p>
<VRow>
<VCol
cols="12"
sm="6"
@@ -367,7 +397,7 @@ function onSubmit() {
>
<AppTextField
v-model.number="form.slots_open_for_claiming"
label="Open voor claimen"
label="Open voor vrijwilligers (claimen)"
type="number"
min="0"
:max="form.slots_total"
@@ -375,20 +405,46 @@ function onSubmit() {
:error-messages="errors.slots_open_for_claiming"
/>
</VCol>
<VCol cols="12">
</VRow>
<VDivider class="my-5" />
<p class="text-overline text-medium-emphasis letter-spacing-normal mb-3">
Opties
</p>
<VRow>
<VCol
cols="12"
md="6"
>
<VSwitch
v-model="form.is_lead_role"
label="Dit is een leidinggevende rol"
/>
</VCol>
<VCol cols="12">
<VSwitch
v-model="form.allow_overlap"
label="Overlap toegestaan"
hint="Persoon mag meerdere shifts in hetzelfde tijdvak hebben"
color="primary"
label="Leidinggevende rol"
hint="Coördinatie / verantwoordelijke"
persistent-hint
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VSwitch
v-model="form.allow_overlap"
color="primary"
label="Overlap toegestaan"
hint="Zelfde tijdvak, meerdere shifts voor één persoon"
persistent-hint
/>
</VCol>
</VRow>
<VDivider class="my-5" />
<p class="text-overline text-medium-emphasis letter-spacing-normal mb-3">
Documentatie & status
</p>
<VRow>
<VCol cols="12">
<AppTextarea
v-model="form.instructions"
@@ -408,7 +464,10 @@ function onSubmit() {
</VCol>
</VRow>
</VCardText>
<VCardActions>
<VDivider />
<VCardActions class="px-6 py-4">
<VSpacer />
<VBtn
variant="text"