Files
simrsx-fe/app/components/app/person-relative/entry-form.vue
Munawwirul Jamal 3eb9dde21d Dev cleaning (#106)
2025-10-08 00:03:36 +07:00

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>