"use client" import { useState } from "react" import { useRouter } from "next/navigation" import Link from "next/link" 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Checkbox } from "@/components/ui/checkbox" import { Upload, X, ChevronDown, Save, Loader2, Home, Users, Settings, LucideIcon } from "lucide-react" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" // IMPORTANTE: Se o ManagerLayout for responsável por renderizar o cabeçalho com a barra de pesquisa, // você precisará garantir que ele seja flexível para desativá-la ou não passá-la. import ManagerLayout from "@/components/layout/DashboardLayout" import { medicosApi } from "services/medicosApi"; const UF_LIST = ["AC", "AL", "AP", "AM", "BA", "CE", "DF", "ES", "GO", "MA", "MT", "MS", "MG", "PA", "PB", "PR", "PE", "PI", "RJ", "RN", "RS", "RO", "RR", "SC", "SP", "SE", "TO"]; interface DoctorFormData { nomeCompleto: string; crm: string; crmEstado: string; cpf: string; email: string; especialidade: string; telefoneCelular: string; telefone2: string; cep: string; endereco: string; numero: string; complemento: string; bairro: string; cidade: string; estado: string; dataNascimento: string; rg: string; ativo: boolean; observacoes: string; anexos: { id: number, name: string }[]; } const apiMap: { [K in keyof DoctorFormData]: string | null } = { nomeCompleto: 'full_name', crm: 'crm', crmEstado: 'crm_uf', cpf: 'cpf', email: 'email', especialidade: 'specialty', telefoneCelular: 'phone_mobile', telefone2: 'phone2', cep: 'cep', endereco: 'street', numero: 'number', complemento: 'complement', bairro: 'neighborhood', cidade: 'city', estado: 'state', dataNascimento: 'birth_date', rg: 'rg', ativo: 'active', observacoes: null, anexos: null, }; const defaultFormData: DoctorFormData = { nomeCompleto: '', crm: '', crmEstado: '', cpf: '', email: '', especialidade: '', telefoneCelular: '', telefone2: '', cep: '', endereco: '', numero: '', complemento: '', bairro: '', cidade: '', estado: '', dataNascimento: '', rg: '', ativo: true, observacoes: '', anexos: [], }; // ---------------------------------------------------------------------- // Tipos e dados necessários para o ManagerLayout (DashboardLayout) // ---------------------------------------------------------------------- interface LayoutMenuItem { href: string; icon: LucideIcon; label: string; } interface LayoutUserProfile { name: string; secondaryText: string; avatarFallback: string; } const MANAGER_MENU_ITEMS: LayoutMenuItem[] = [ { href: "/manager/home", icon: Home, label: "Início", }, { href: "/manager/medicos", icon: Users, label: "Médicos", }, { href: "/manager/configuracoes", icon: Settings, label: "Configurações", }, ]; const MANAGER_USER_PROFILE: LayoutUserProfile = { name: "Gerente (Placeholder)", secondaryText: "gerente.placeholder@mediconnect.com", avatarFallback: "GP", }; // ---------------------------------------------------------------------- const cleanNumber = (value: string): string => value.replace(/\D/g, ''); const formatCPF = (value: string): string => { const cleaned = cleanNumber(value).substring(0, 11); return cleaned.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4'); }; const formatCEP = (value: string): string => { const cleaned = cleanNumber(value).substring(0, 8); return cleaned.replace(/(\d{5})(\d{3})/, '$1-$2'); }; const formatPhoneMobile = (value: string): string => { const cleaned = cleanNumber(value).substring(0, 11); if (cleaned.length > 10) { return cleaned.replace(/(\d{2})(\d{5})(\d{4})/, '($1) $2-$3'); } return cleaned.replace(/(\d{2})(\d{4})(\d{4})/, '($1) $2-$3'); }; // ---------------------------------------------------------------------- // COMPONENTE PRINCIPAL // ---------------------------------------------------------------------- export default function NovoMedicoPage() { const router = useRouter(); const [formData, setFormData] = useState(defaultFormData); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const [anexosOpen, setAnexosOpen] = useState(false); const handleInputChange = (key: keyof DoctorFormData, value: string | boolean | { id: number, name: string }[]) => { if (typeof value === 'string') { let maskedValue = value; if (key === 'cpf') maskedValue = formatCPF(value); if (key === 'cep') maskedValue = formatCEP(value); if (key === 'telefoneCelular' || key === 'telefone2') maskedValue = formatPhoneMobile(value); setFormData((prev) => ({ ...prev, [key]: maskedValue })); } else { setFormData((prev) => ({ ...prev, [key]: value })); } }; const adicionarAnexo = () => { const newId = Date.now(); handleInputChange('anexos', [...formData.anexos, { id: newId, name: `Documento ${formData.anexos.length + 1}` }]); } const removerAnexo = (id: number) => { handleInputChange('anexos', formData.anexos.filter((anexo) => anexo.id !== id)); } const requiredFields = [ { key: 'nomeCompleto', name: 'Nome Completo' }, { key: 'crm', name: 'CRM' }, { key: 'crmEstado', name: 'UF do CRM' }, { key: 'cpf', name: 'CPF' }, { key: 'email', name: 'E-mail' }, ] as const; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setIsSaving(true); for (const field of requiredFields) { let valueToCheck = formData[field.key]; if (!valueToCheck || String(valueToCheck).trim() === '') { setError(`O campo obrigatório "${field.name}" deve ser preenchido.`); setIsSaving(false); return; } } const finalPayload: { [key: string]: any } = {}; const formKeys = Object.keys(formData) as Array; formKeys.forEach((key) => { const apiFieldName = apiMap[key]; if (!apiFieldName) return; let value = formData[key]; if (typeof value === 'string') { let trimmedValue = value.trim(); const isOptional = !requiredFields.some(f => f.key === key); if (isOptional && trimmedValue === '') { finalPayload[apiFieldName] = null; return; } if (key === 'crmEstado' || key === 'estado') { trimmedValue = trimmedValue.toUpperCase(); } value = trimmedValue; } finalPayload[apiFieldName] = value; }); try { const response = await medicosApi.create(finalPayload); router.push("/manager/home"); } catch (e: any) { console.error("Erro ao salvar o médico:", e); let detailedError = `Erro na requisição. Verifique se o **CRM** ou **CPF** já existem ou se as **Máscaras/Datas** estão incorretas.`; if (e.message && e.message.includes("duplicate key value violates unique constraint")) { detailedError = "O CPF ou CRM informado já está cadastrado no sistema. Por favor, verifique os dados de identificação."; } else if (e.message && e.message.includes("Detalhes:")) { detailedError = e.message.split("Detalhes:")[1].trim(); } else if (e.message) { detailedError = e.message; } setError(`Erro ao cadastrar. Detalhes: ${detailedError}`); } finally { setIsSaving(false); } }; return ( {/* GARANTINDO W-FULL: O contêiner principal ocupa 100% da largura. */}

Novo Médico

Preencha os dados do novo médico para cadastro.

{error && (

Erro no Cadastro:

{error}

)}

Dados Principais e Pessoais

handleInputChange("nomeCompleto", e.target.value)} placeholder="Nome do Médico" required />
handleInputChange("crm", e.target.value)} placeholder="Ex: 123456" required />
handleInputChange("especialidade", e.target.value)} placeholder="Ex: Cardiologia" />
handleInputChange("cpf", e.target.value)} placeholder="000.000.000-00" maxLength={14} required />
handleInputChange("rg", e.target.value)} placeholder="00.000.000-0" />
handleInputChange("email", e.target.value)} placeholder="exemplo@dominio.com" required />
handleInputChange("dataNascimento", e.target.value)} />

Contato e Endereço

handleInputChange("telefoneCelular", e.target.value)} placeholder="(00) 00000-0000" maxLength={15} />
handleInputChange("telefone2", e.target.value)} placeholder="(00) 00000-0000" maxLength={15} />
handleInputChange("ativo", checked === true)} />
handleInputChange("cep", e.target.value)} placeholder="00000-000" maxLength={9} />
handleInputChange("endereco", e.target.value)} placeholder="Rua, Avenida, etc." />
handleInputChange("numero", e.target.value)} placeholder="123" />
handleInputChange("complemento", e.target.value)} placeholder="Apto, Bloco, etc." />
handleInputChange("bairro", e.target.value)} placeholder="Bairro" />
handleInputChange("estado", e.target.value)} placeholder="SP" />
handleInputChange("cidade", e.target.value)} placeholder="São Paulo" />

Outras Informações (Internas)