Files
gremiumhub/legalconsenthub/pages/application-forms/[id]/[sectionIndex].vue

150 lines
4.5 KiB
Vue

<template>
<UDashboardPanel id="home">
<template #header>
<UDashboardNavbar title="Home" :ui="{ right: 'gap-3' }">
<template #leading>
<UDashboardSidebarCollapse />
</template>
<template #right>
<UDropdownMenu :items="items">
<UButton icon="i-lucide-plus" size="md" class="rounded-full" />
</UDropdownMenu>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #right>
<UButton icon="i-lucide-file-text" size="md" color="primary" variant="solid" target="_blank" :to="`/api/application-forms/${applicationForm.id}/pdf`">PDF Vorschau</UButton>
</template>
</UDashboardToolbar>
</template>
<template #body>
<div class="flex flex-col w-full lg:max-w-4xl mx-auto">
<UStepper ref="stepper" v-model="activeStepperItemIndex" :items="stepperItems" class="w-full" />
<h1 class="text-xl text-pretty font-bold text-highlighted">
{{ currentFormElementSection.title }}
</h1>
<UCard variant="subtle">
<FormEngine
v-if="applicationForm"
v-model="currentFormElementSection.formElements"
:application-form-id="applicationForm.id"
:disabled="isReadOnly"
@click:comments="openComments"
/>
<div class="flex gap-2 justify-between mt-4">
<UButton
leading-icon="i-lucide-arrow-left"
:disabled="!stepper?.hasPrev"
@click="navigateStepper('backward')"
>
Prev
</UButton>
<UButton
v-if="stepper?.hasNext"
trailing-icon="i-lucide-arrow-right"
:disabled="!stepper?.hasNext"
@click="navigateStepper('forward')"
>
Next
</UButton>
<UButton
v-if="!stepper?.hasNext"
trailing-icon="i-lucide-send-horizontal"
:disabled="isReadOnly"
@click="onSubmit"
>
Submit
</UButton>
</div>
</UCard>
</div>
</template>
</UDashboardPanel>
</template>
<script setup lang="ts">
import type { ApplicationFormDto, FormElementSectionDto } from '~/.api-client'
import type { StepperItem } from '@nuxt/ui'
const { getApplicationFormById, updateApplicationForm } = useApplicationForm()
const route = useRoute()
const { user } = useAuth()
definePageMeta({
// Prevent whole page from re-rendering when navigating between sections to keep state
key: (route) => `${route.params.id}`,
})
onMounted(() => {
const sectionIndex = parseInt(route.params.sectionIndex[0])
activeStepperItemIndex.value = !isNaN(sectionIndex) ? sectionIndex : 0
})
const items = [
[
{
label: 'Neuer Mitbestimmungsantrag',
icon: 'i-lucide-send',
to: '/create'
}
]
]
const stepper = useTemplateRef('stepper')
const activeStepperItemIndex = ref<number>(0)
const currentFormElementSection = computed<FormElementSectionDto>(
() => applicationForm.value?.formElementSections[activeStepperItemIndex.value]
)
const { data, error } = await useAsyncData<ApplicationFormDto>(`application-form-${route.params.id}`, async () => {
console.log('Fetching application form with ID:', route.params.id)
return await getApplicationFormById(Array.isArray(route.params.id) ? route.params.id[0] : route.params.id)
})
if (error.value) {
throw createError({ statusText: error.value.message })
}
const applicationForm = computed<ApplicationFormDto>(() => data?.value as ApplicationFormDto)
const isReadOnly = computed(() => {
return applicationForm.value?.createdBy.id !== user.value?.id
})
const stepperItems = computed(() => {
const stepperItems: StepperItem[] = []
applicationForm.value.formElementSections.forEach((section: FormElementSectionDto) => {
stepperItems.push({
title: section.shortTitle,
description: section.description
})
})
return stepperItems
})
async function navigateStepper(direction: 'forward' | 'backward') {
if (direction === 'forward') {
stepper.value?.next()
} else {
stepper.value?.prev()
}
await navigateTo(`/application-forms/${route.params.id}/${activeStepperItemIndex.value}`)
}
async function onSubmit() {
if (data?.value) {
await updateApplicationForm(data.value.id, data.value)
await navigateTo('/')
}
}
function openComments(formElementId: string) {
console.log('open comments for', formElementId)
}
</script>