From 7d7e5b1160424879497210784bd316de764a88a5 Mon Sep 17 00:00:00 2001 From: daniel-barbosaa Date: Mon, 1 Dec 2025 16:48:26 -0300 Subject: [PATCH 1/2] feat(referrals-modal): creates a referrals modal --- .../pacientes/[id]/informacoes/page.tsx | 11 +- src/modules/referrals/referral-button.tsx | 38 ++++ src/modules/referrals/referrals-modal.tsx | 163 ++++++++++++++++++ 3 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 src/modules/referrals/referral-button.tsx create mode 100644 src/modules/referrals/referrals-modal.tsx diff --git a/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx b/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx index 993a5f5..763789f 100644 --- a/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx +++ b/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx @@ -1,12 +1,12 @@ -import { ForwardIcon, UserRoundIcon } from 'lucide-react' +import { UserRoundIcon } from 'lucide-react' import type { Metadata } from 'next' import { redirect } from 'next/navigation' import { getPatient } from '@/actions/patients/get-patient' -import { Button } from '@/components/ui/button' import { ROUTES } from '@/constants/routes' import { PatientForm } from '@/modules/patients/form' import { InactivatePatientButton } from '@/modules/patients/inactivate-button' +import { ReferPatientButton } from '@/modules/referrals/referral-button' export const metadata: Metadata = { title: 'Informações do paciente', @@ -45,10 +45,9 @@ export default async function Page({
{isPatientActive && } - +
diff --git a/src/modules/referrals/referral-button.tsx b/src/modules/referrals/referral-button.tsx new file mode 100644 index 0000000..4bc126b --- /dev/null +++ b/src/modules/referrals/referral-button.tsx @@ -0,0 +1,38 @@ +'use client' + +import { ForwardIcon } from 'lucide-react' +import { useState } from 'react' + +import { Dialog, DialogTrigger } from '@/components/ui/dialog' + +import type { ButtonProps } from '../../components/ui/button' +import { ReferralsPatientModal } from './referrals-modal' + +interface ReferPatientButtonProps extends ButtonProps { + patient: { + id: string + name: string + } +} +export function ReferPatientButton({ + patient, + ...props +}: Readonly) { + const [modalOpen, setModalOpen] = useState(false) + + return ( + + + + Encaminhar paciente + + + {modalOpen && ( + setModalOpen(false)} + /> + )} + + ) +} diff --git a/src/modules/referrals/referrals-modal.tsx b/src/modules/referrals/referrals-modal.tsx new file mode 100644 index 0000000..b17f23b --- /dev/null +++ b/src/modules/referrals/referrals-modal.tsx @@ -0,0 +1,163 @@ +'use client' + +import { zodResolver } from '@hookform/resolvers/zod' +import { ForwardIcon } from 'lucide-react' +import { FormProvider, useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { z } from 'zod' + +import { revalidateCache } from '@/actions/cache' +import { DateInput } from '@/components/form/date-input' +import { FormContainer } from '@/components/form/form-container' +import { SelectInput } from '@/components/form/select-input' +import { TextInput } from '@/components/form/text-input' +import { TextareaInput } from '@/components/form/textarea-input' +import { Button } from '@/components/ui/button' +import { + DialogContainer, + DialogContent, + DialogFooter, + DialogHeader, + DialogIcon, + DialogTitle, +} from '@/components/ui/dialog' +import { NEXT_CACHE_TAGS, QUERY_CACHE_KEYS } from '@/constants/cache' +import { api } from '@/lib/api' +import { queryClient } from '@/lib/tanstack-query' +import { + PATIENT_CONDITION_ENUM, + PATIENT_CONDITION_OPTIONS, +} from '@/types/patients' +import { + REFERRAL_CATEGORY_ENUM, + REFERRAL_CATEGORY_OPTIONS, +} from '@/types/referrals' + +const referralsFormSchema = z.object({ + date: z.string().datetime('A data é obrigatória'), + category: z.enum(REFERRAL_CATEGORY_ENUM, { + message: 'Categoria é obrigatório', + }), + condition: z.enum(PATIENT_CONDITION_ENUM, { + message: 'O quadro é obrigatório', + }), + annotation: z + .string() + .max(500) + .nullable() + .transform((value) => (!value ? null : value)), + referred_to: z + .string() + .nullable() + .transform((value) => (!value ? null : value)), +}) +type ReferralsFormSchema = z.infer + +interface ReferralsModalProps { + onClose(): void + patient: { + id: string + name: string + } +} + +export function ReferralsPatientModal({ + onClose, + patient, +}: ReferralsModalProps) { + const formMethods = useForm({ + resolver: zodResolver(referralsFormSchema), + defaultValues: { + name: patient.name, + date: '', + category: '', + referred_to: '', + condition: '', + annotation: '', + } as unknown as ReferralsFormSchema, + mode: 'onBlur', + }) + + async function submitForm(data: ReferralsFormSchema) { + const response = await api('/referrals', { + method: 'POST', + body: JSON.stringify({ ...data, patient_id: patient.id }), + }) + if (!response.success) { + toast.error(response.message) + return + } + queryClient.invalidateQueries({ + queryKey: [QUERY_CACHE_KEYS.referrals.list], + }) + revalidateCache(NEXT_CACHE_TAGS.patient(patient.id)) + toast.success(response.message) + onClose() + } + + return ( + + }> + Encaminhar paciente + + + + + + + + + + + + + + + + + + + + ) +} From 726cd2d8c9efabb0722f38f254feeee46c1313f2 Mon Sep 17 00:00:00 2001 From: daniel-barbosaa Date: Thu, 4 Dec 2025 08:58:51 -0300 Subject: [PATCH 2/2] chore(referrals-modal): adjustment of the referred patient display --- .../pacientes/[id]/informacoes/page.tsx | 4 +- src/modules/referrals/referral-button.tsx | 14 +-- src/modules/referrals/referrals-modal.tsx | 87 ++++++++++--------- 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx b/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx index 763789f..558aabe 100644 --- a/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx +++ b/src/app/(dashboard)/pacientes/[id]/informacoes/page.tsx @@ -45,9 +45,7 @@ export default async function Page({
{isPatientActive && } - +
diff --git a/src/modules/referrals/referral-button.tsx b/src/modules/referrals/referral-button.tsx index 4bc126b..06946e3 100644 --- a/src/modules/referrals/referral-button.tsx +++ b/src/modules/referrals/referral-button.tsx @@ -6,16 +6,13 @@ import { useState } from 'react' import { Dialog, DialogTrigger } from '@/components/ui/dialog' import type { ButtonProps } from '../../components/ui/button' -import { ReferralsPatientModal } from './referrals-modal' +import { ReferralPatientModal } from './referrals-modal' interface ReferPatientButtonProps extends ButtonProps { - patient: { - id: string - name: string - } + id?: string } export function ReferPatientButton({ - patient, + id, ...props }: Readonly) { const [modalOpen, setModalOpen] = useState(false) @@ -28,10 +25,7 @@ export function ReferPatientButton({ {modalOpen && ( - setModalOpen(false)} - /> + setModalOpen(false)} /> )} ) diff --git a/src/modules/referrals/referrals-modal.tsx b/src/modules/referrals/referrals-modal.tsx index b17f23b..3c8a22d 100644 --- a/src/modules/referrals/referrals-modal.tsx +++ b/src/modules/referrals/referrals-modal.tsx @@ -7,6 +7,7 @@ import { toast } from 'sonner' import { z } from 'zod' import { revalidateCache } from '@/actions/cache' +import { ComboboxInput } from '@/components/form/combobox-input' import { DateInput } from '@/components/form/date-input' import { FormContainer } from '@/components/form/form-container' import { SelectInput } from '@/components/form/select-input' @@ -14,6 +15,7 @@ import { TextInput } from '@/components/form/text-input' import { TextareaInput } from '@/components/form/textarea-input' import { Button } from '@/components/ui/button' import { + DialogClose, DialogContainer, DialogContent, DialogFooter, @@ -22,6 +24,7 @@ import { DialogTitle, } from '@/components/ui/dialog' import { NEXT_CACHE_TAGS, QUERY_CACHE_KEYS } from '@/constants/cache' +import { usePatientOptions } from '@/hooks/use-patient-otions' import { api } from '@/lib/api' import { queryClient } from '@/lib/tanstack-query' import { @@ -33,42 +36,38 @@ import { REFERRAL_CATEGORY_OPTIONS, } from '@/types/referrals' -const referralsFormSchema = z.object({ - date: z.string().datetime('A data é obrigatória'), - category: z.enum(REFERRAL_CATEGORY_ENUM, { - message: 'Categoria é obrigatório', - }), - condition: z.enum(PATIENT_CONDITION_ENUM, { - message: 'O quadro é obrigatório', - }), - annotation: z - .string() - .max(500) - .nullable() - .transform((value) => (!value ? null : value)), - referred_to: z - .string() - .nullable() - .transform((value) => (!value ? null : value)), -}) -type ReferralsFormSchema = z.infer - -interface ReferralsModalProps { +interface ReferralModalProps { onClose(): void - patient: { - id: string - name: string - } + id?: string } -export function ReferralsPatientModal({ - onClose, - patient, -}: ReferralsModalProps) { +export function ReferralPatientModal({ onClose, id }: ReferralModalProps) { + const { patientOptions } = usePatientOptions() + const referralFormSchema = z.object({ + patient_id: z.string().uuid('Paciente é obrigatório'), + date: z.string().datetime('A data é obrigatória'), + category: z.enum(REFERRAL_CATEGORY_ENUM, { + message: 'Categoria é obrigatório', + }), + condition: z.enum(PATIENT_CONDITION_ENUM, { + message: 'O quadro é obrigatório', + }), + annotation: z + .string() + .max(500) + .nullable() + .transform((value) => (!value ? null : value)), + referred_to: z + .string() + .nullable() + .transform((value) => (!value ? null : value)), + }) + type ReferralsFormSchema = z.infer + const formMethods = useForm({ - resolver: zodResolver(referralsFormSchema), + resolver: zodResolver(referralFormSchema), defaultValues: { - name: patient.name, + patient_id: id ?? '', date: '', category: '', referred_to: '', @@ -81,7 +80,7 @@ export function ReferralsPatientModal({ async function submitForm(data: ReferralsFormSchema) { const response = await api('/referrals', { method: 'POST', - body: JSON.stringify({ ...data, patient_id: patient.id }), + body: JSON.stringify(data), }) if (!response.success) { toast.error(response.message) @@ -90,7 +89,7 @@ export function ReferralsPatientModal({ queryClient.invalidateQueries({ queryKey: [QUERY_CACHE_KEYS.referrals.list], }) - revalidateCache(NEXT_CACHE_TAGS.patient(patient.id)) + revalidateCache(NEXT_CACHE_TAGS.patient(data.patient_id)) toast.success(response.message) onClose() } @@ -107,17 +106,21 @@ export function ReferralsPatientModal({ className='grid gap-4 sm:grid-cols-4' onSubmit={formMethods.handleSubmit(submitForm)} > - - Encaminhar paciente + Encaminhar + + Cancelar + )