From 30b5609f2fc49c56c8ae86f95d759756f51ad949 Mon Sep 17 00:00:00 2001 From: M-Gabrielly Date: Tue, 16 Sep 2025 22:25:59 -0300 Subject: [PATCH] feat: adds new fields and cards to the physician registry --- susconecta/app/globals.css | 2 +- .../forms/doctor-registration-form.tsx | 351 ++++++++++++++++-- .../forms/patient-registration-form.tsx | 32 +- susconecta/components/ui/popover.tsx | 2 +- 4 files changed, 346 insertions(+), 41 deletions(-) diff --git a/susconecta/app/globals.css b/susconecta/app/globals.css index 7c20887..8c02557 100644 --- a/susconecta/app/globals.css +++ b/susconecta/app/globals.css @@ -6,7 +6,7 @@ :root { --background: #ffffff; --foreground: #475569; - --card: #f8fafc; + --card: #ffffff; --card-foreground: #334155; --popover: #ffffff; --popover-foreground: #475569; diff --git a/susconecta/components/forms/doctor-registration-form.tsx b/susconecta/components/forms/doctor-registration-form.tsx index ce8cbf0..a7d6396 100644 --- a/susconecta/components/forms/doctor-registration-form.tsx +++ b/susconecta/components/forms/doctor-registration-form.tsx @@ -5,14 +5,30 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { AlertCircle, ChevronDown, ChevronUp, FileImage, Loader2, Save, Upload, User, X, XCircle, Trash2 } from "lucide-react"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover"; // Mock data and types since API is not used for now + +type FormacaoAcademica = { + instituicao: string; + curso: string; + ano_conclusao: string; +}; + +type DadosBancarios = { + banco: string; + agencia: string; + conta: string; + tipo_conta: string; +}; + export type Medico = { id: string; nome?: string; @@ -22,11 +38,22 @@ export type Medico = { sexo?: string | null; data_nascimento?: string | null; telefone?: string; + celular?: string; + contato_emergencia?: string; email?: string; crm?: string; + estado_crm?: string; + rqe?: string; + formacao_academica?: FormacaoAcademica[]; + curriculo_url?: string | null; especialidade?: string; observacoes?: string | null; foto_url?: string | null; + tipo_vinculo?: string; + dados_bancarios?: DadosBancarios; + + agenda_horario?: string; + valor_consulta?: number | string; }; type Mode = "create" | "edit"; @@ -46,6 +73,10 @@ type FormData = { nome: string; nome_social: string; crm: string; + estado_crm: string; + rqe: string; + formacao_academica: FormacaoAcademica[]; + curriculo: File | null; especialidade: string; cpf: string; rg: string; @@ -53,6 +84,8 @@ type FormData = { data_nascimento: string; email: string; telefone: string; + celular: string; + contato_emergencia: string; cep: string; logradouro: string; numero: string; @@ -62,6 +95,11 @@ type FormData = { estado: string; observacoes: string; anexos: File[]; + tipo_vinculo: string; + dados_bancarios: DadosBancarios; + + agenda_horario: string; + valor_consulta: string; }; const initial: FormData = { @@ -69,6 +107,10 @@ const initial: FormData = { nome: "", nome_social: "", crm: "", + estado_crm: "", + rqe: "", + formacao_academica: [], + curriculo: null, especialidade: "", cpf: "", rg: "", @@ -76,6 +118,8 @@ const initial: FormData = { data_nascimento: "", email: "", telefone: "", + celular: "", + contato_emergencia: "", cep: "", logradouro: "", numero: "", @@ -85,8 +129,19 @@ const initial: FormData = { estado: "", observacoes: "", anexos: [], + tipo_vinculo: "", + dados_bancarios: { + banco: "", + agencia: "", + conta: "", + tipo_conta: "", + }, + agenda_horario: "", + valor_consulta: "", }; + + export function DoctorRegistrationForm({ open = true, onOpenChange, @@ -98,7 +153,7 @@ export function DoctorRegistrationForm({ }: DoctorRegistrationFormProps) { const [form, setForm] = useState(initial); const [errors, setErrors] = useState>({}); - const [expanded, setExpanded] = useState({ dados: true, contato: false, endereco: false, obs: false }); + const [expanded, setExpanded] = useState({ dados: true, contato: false, endereco: false, obs: false, formacao: false, admin: false }); const [isSubmitting, setSubmitting] = useState(false); const [isSearchingCEP, setSearchingCEP] = useState(false); const [photoPreview, setPhotoPreview] = useState(null); @@ -119,6 +174,44 @@ export function DoctorRegistrationForm({ if (errors[k as string]) setErrors((e) => ({ ...e, [k]: "" })); } + + function addFormacao() { + setField("formacao_academica", [ + ...form.formacao_academica, + { instituicao: "", curso: "", ano_conclusao: "" }, + ]); + } + + function removeFormacao(index: number) { + const newFormacao = [...form.formacao_academica]; + newFormacao.splice(index, 1); + setField("formacao_academica", newFormacao); + } + + function handleFormacaoChange(index: number, field: keyof FormacaoAcademica, value: string) { + const newFormacao = [...form.formacao_academica]; + newFormacao[index][field] = value; + setField("formacao_academica", newFormacao); + } + + function formatPhone(v: string) { + const n = v.replace(/\D/g, "").slice(0, 11); + if (n.length > 6) { + return n.replace(/(\d{2})(\d{5})(\d{0,4})/, "($1) $2-$3"); + } else if (n.length > 2) { + return n.replace(/(\d{2})(\d{0,5})/, "($1) $2"); + } + return n; + } + + function formatRG(v: string) { + v = v.replace(/\D/g, "").slice(0, 9); + v = v.replace(/(\d{2})(\d)/, "$1.$2"); + v = v.replace(/(\d{3})(\d)/, "$1.$2"); + v = v.replace(/(\d{3})(\d{1,2})$/, "$1-$2"); + return v; + } + function formatCPF(v: string) { const n = v.replace(/\D/g, "").slice(0, 11); return n.replace(/(\d{3})(\d{3})(\d{3})(\d{0,2})/, (_, a, b, c, d) => `${a}.${b}.${c}${d ? "-" + d : ""}`); @@ -273,11 +366,44 @@ export function DoctorRegistrationForm({ setField("crm", e.target.value)} className={errors.crm ? "border-destructive" : ""} /> {errors.crm &&

{errors.crm}

} +
+ + setField("estado_crm", e.target.value)} /> +
+ + +
setField("especialidade", e.target.value)} className={errors.especialidade ? "border-destructive" : ""} /> {errors.especialidade &&

{errors.especialidade}

}
+
+ + setField("rqe", e.target.value)} /> +
+
+ +
+ +
+ + setField("curriculo", e.target.files?.[0] || null)} + accept=".pdf,.doc,.docx" + /> + {form.curriculo && {form.curriculo.name}} +
@@ -294,27 +420,27 @@ export function DoctorRegistrationForm({
- setField("rg", e.target.value)} /> + setField("rg", formatRG(e.target.value))} + maxLength={12} + />
- setField("sexo", v)}> -
- - -
-
- - -
-
- - -
-
+
@@ -326,6 +452,68 @@ export function DoctorRegistrationForm({ + setExpanded((s) => ({ ...s, formacao: !s.formacao }))}> + + + + + + + Formação Acadêmica + + {expanded.formacao ? : } + + + + + + {form.formacao_academica.map((formacao, index) => ( +
+
+ + + handleFormacaoChange(index, "instituicao", e.target.value) + } + /> +
+
+ + + handleFormacaoChange(index, "curso", e.target.value) + } + /> +
+
+ + + handleFormacaoChange(index, "ano_conclusao", e.target.value) + } + /> +
+ +
+ ))} + +
+
+
+
+ setExpanded((s) => ({ ...s, contato: !s.contato }))}> @@ -345,9 +533,130 @@ export function DoctorRegistrationForm({
- setField("telefone", e.target.value)} /> + setField("telefone", formatPhone(e.target.value))} + placeholder="(XX) XXXXX-XXXX" + />
+
+
+ + setField("celular", formatPhone(e.target.value))} + placeholder="(XX) XXXXX-XXXX" + /> +
+
+ + setField("contato_emergencia", formatPhone(e.target.value))} + placeholder="(XX) XXXXX-XXXX" + /> +
+
+ + + + + + setExpanded((s) => ({ ...s, admin: !s.admin }))}> + + + + + + + Dados Administrativos e Financeiros + + {expanded.admin ? : } + + + + + +
+
+ + +
+
+ + setField("valor_consulta", e.target.value)} + placeholder="R$ 0,00" + /> +
+
+ +
+ +