first pass of discharge form
This commit is contained in:
91
ui/src/components/members/DischargeMember.vue
Normal file
91
ui/src/components/members/DischargeMember.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<script setup lang="ts">
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { Form, Field as VeeField } from 'vee-validate'
|
||||
import * as z from 'zod'
|
||||
import { X, AlertTriangle } from 'lucide-vue-next'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog'
|
||||
import { Field, FieldLabel, FieldError } from '@/components/ui/field'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import MemberCard from './MemberCard.vue'
|
||||
import { Member } from '@shared/types/member'
|
||||
|
||||
// 1. Props for control and data
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
member: Member | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['update:open', 'discharged'])
|
||||
|
||||
// 2. Discharge-specific schema
|
||||
const formSchema = toTypedSchema(z.object({
|
||||
reason: z.string().min(1, "Please provide a valid reason for discharge").max(200),
|
||||
effectiveDate: z.string().min(1, "Date is required"),
|
||||
}))
|
||||
|
||||
function onSubmit(values: any) {
|
||||
console.log('Discharging member:', props.member?.member_id)
|
||||
console.log('Discharge Data:', values)
|
||||
|
||||
// Notify parent to refresh/close
|
||||
emit('discharged', { memberId: props.member?.member_id, ...values })
|
||||
emit('update:open', false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog :open="open" @update:open="emit('update:open', $event)">
|
||||
<DialogContent class="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<!-- <AlertTriangle class="size-5" /> -->
|
||||
<DialogTitle>Discharge Member</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription>
|
||||
You are initiating the discharge process for <MemberCard :member-id="member.member_id"></MemberCard>
|
||||
<!-- <span class="font-semibold text-foreground">{{ member }}</span> -->
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<Form v-slot="{ handleSubmit }" as="" :validation-schema="formSchema">
|
||||
<form id="dischargeForm" @submit="handleSubmit($event, onSubmit)" class="space-y-4 py-2">
|
||||
<VeeField v-slot="{ componentField, errors }" name="reason">
|
||||
<Field :data-invalid="!!errors.length">
|
||||
<FieldLabel>Reason for Discharge</FieldLabel>
|
||||
<Textarea placeholder="Retirement, inactivity, etc. "
|
||||
v-bind="componentField" class="resize-none" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<VeeField v-slot="{ componentField, errors }" name="effectiveDate">
|
||||
<Field :data-invalid="!!errors.length">
|
||||
<FieldLabel>Effective Date</FieldLabel>
|
||||
<Input type="date" v-bind="componentField" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</Field>
|
||||
</VeeField>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
<DialogFooter class="gap-2 sm:gap-0">
|
||||
<Button variant="ghost" @click="emit('update:open', false)">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" form="dischargeForm" variant="destructive">
|
||||
Discharge
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
Reference in New Issue
Block a user