156 lines
4.9 KiB
Vue
156 lines
4.9 KiB
Vue
<script setup lang="ts">
|
|
import type { FormErrors } from '~/types/error'
|
|
import { toTypedSchema } from '@vee-validate/zod'
|
|
import { FieldArray } from 'vee-validate'
|
|
import InputBase from '~/components/pub/my-ui/form/input-base.vue'
|
|
import Label from '~/components/pub/my-ui/form/label.vue'
|
|
import SelectContactRelation from './_common/select-relations.vue'
|
|
import { Form } from '~/components/pub/ui/form'
|
|
|
|
const props = defineProps<{
|
|
title: string
|
|
schema: any
|
|
initialValues?: any
|
|
errors?: FormErrors
|
|
}>()
|
|
|
|
const formSchema = toTypedSchema(props.schema)
|
|
const formRef = ref()
|
|
|
|
defineExpose({
|
|
validate: () => formRef.value?.validate(),
|
|
resetForm: () => formRef.value?.resetForm(),
|
|
setValues: (values: any, shouldValidate = true) => formRef.value?.setValues(values, shouldValidate),
|
|
values: computed(() => formRef.value?.values),
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<Form
|
|
ref="formRef"
|
|
as=""
|
|
keep-values
|
|
:validation-schema="formSchema"
|
|
:validate-on-mount="false"
|
|
validation-mode="onSubmit"
|
|
:initial-values="initialValues || { contacts: [{ relation: '', name: '', address: '', phone: '' }] }"
|
|
>
|
|
<div>
|
|
<p
|
|
v-if="props.title"
|
|
class="text-md mb-2 mt-1 font-semibold"
|
|
>
|
|
{{ props.title || 'Kontak Pasien' }}
|
|
</p>
|
|
</div>
|
|
<div class="mb-5 space-y-4">
|
|
<FieldArray
|
|
v-slot="{ fields, push, remove }"
|
|
name="contacts"
|
|
>
|
|
<div class="space-y-4">
|
|
<div
|
|
v-for="(field, idx) in fields"
|
|
:key="field.key"
|
|
class="rounded-lg border border-gray-200 bg-gray-50/50 p-4 dark:border-gray-700 dark:bg-gray-800/50"
|
|
>
|
|
<div class="mb-3 flex items-center justify-between">
|
|
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300">Penanggung Jawab {{ idx + 1 }}</h4>
|
|
<Button
|
|
v-if="idx !== 0"
|
|
type="button"
|
|
variant="outline"
|
|
size="sm"
|
|
class="text-red-600 hover:border-red-400 hover:bg-red-50 hover:text-red-700 dark:border-red-400 dark:text-red-400 dark:hover:border-red-300 dark:hover:bg-red-900/20"
|
|
@click="remove(idx)"
|
|
>
|
|
<Icon
|
|
name="i-lucide-trash-2"
|
|
class="h-4 w-4"
|
|
/>
|
|
</Button>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
<div class="space-y-2">
|
|
<Label
|
|
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
is-required
|
|
>
|
|
Hubungan dengan Pasien
|
|
</Label>
|
|
<SelectContactRelation
|
|
:field-name="`contacts[${idx}].relation`"
|
|
placeholder="Pilih"
|
|
:errors="errors"
|
|
field-group-class="mb-0"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label
|
|
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
is-required
|
|
>
|
|
Nama
|
|
</Label>
|
|
<InputBase
|
|
label=""
|
|
:field-name="`contacts[${idx}].name`"
|
|
placeholder="Masukkan Nama"
|
|
:errors="errors"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label
|
|
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
is-required
|
|
>
|
|
Alamat
|
|
</Label>
|
|
<InputBase
|
|
:field-name="`contacts[${idx}].address`"
|
|
label=""
|
|
placeholder="Masukkan Alamat"
|
|
:errors="errors"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label
|
|
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
is-required
|
|
>
|
|
Nomor HP
|
|
</Label>
|
|
<InputBase
|
|
:field-name="`contacts[${idx}].phone`"
|
|
label=""
|
|
placeholder="081234567890"
|
|
:max-length="15"
|
|
numeric-only
|
|
:errors="errors"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
class="w-full rounded-md border border-primary bg-white px-4 py-2 text-primary hover:border-primary hover:bg-primary hover:text-white sm:w-auto sm:text-sm"
|
|
@click="push({ relation: '', name: '', address: '', phone: '' })"
|
|
>
|
|
<Icon
|
|
name="i-lucide-plus"
|
|
class="mr-2 h-4 w-4 align-middle transition-colors"
|
|
/>
|
|
Tambah Penanggung Jawab
|
|
</Button>
|
|
</FieldArray>
|
|
</div>
|
|
</Form>
|
|
</template>
|