Compare commits
No commits in common. "913fd6ad64727eff21dfe4479fc9ab9835529ea6" and "e53d7fb96e4b7fa9ae70fdfa7ea2a7a40c154dfb" have entirely different histories.
913fd6ad64
...
e53d7fb96e
@ -1,39 +1,40 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
import { MoreHorizontal, Plus, Search, Edit, Trash2, ArrowLeft, Eye } from "lucide-react";
|
import { MoreHorizontal, Plus, Search, Edit, Trash2, ArrowLeft, Eye } from "lucide-react";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { DoctorRegistrationForm } from "@/components/forms/doctor-registration-form";
|
import { DoctorRegistrationForm, Medico } from "@/components/forms/doctor-registration-form";
|
||||||
|
|
||||||
// >>> IMPORTES DA API <<<
|
// Mock data for doctors
|
||||||
import { listarMedicos, excluirMedico, Medico } from "@/lib/api";
|
const initialDoctors: Medico[] = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
nome: "Dr. João Silva",
|
||||||
|
especialidade: "Cardiologia",
|
||||||
|
crm: "12345-SP",
|
||||||
|
email: "joao.silva@example.com",
|
||||||
|
telefone: "(11) 99999-1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
nome: "Dra. Maria Oliveira",
|
||||||
|
especialidade: "Pediatria",
|
||||||
|
crm: "54321-RJ",
|
||||||
|
email: "maria.oliveira@example.com",
|
||||||
|
telefone: "(21) 98888-5678",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default function DoutoresPage() {
|
export default function DoutoresPage() {
|
||||||
const [doctors, setDoctors] = useState<Medico[]>([]);
|
const [doctors, setDoctors] = useState<Medico[]>(initialDoctors);
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [showForm, setShowForm] = useState(false);
|
const [showForm, setShowForm] = useState(false);
|
||||||
const [editingId, setEditingId] = useState<string | null>(null);
|
const [editingId, setEditingId] = useState<string | null>(null);
|
||||||
|
|
||||||
// Carrega da API
|
|
||||||
async function load() {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const list = await listarMedicos({ limit: 50 });
|
|
||||||
setDoctors(list ?? []);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
load();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
if (!search.trim()) return doctors;
|
if (!search.trim()) return doctors;
|
||||||
const q = search.toLowerCase();
|
const q = search.toLowerCase();
|
||||||
@ -55,17 +56,26 @@ export default function DoutoresPage() {
|
|||||||
setShowForm(true);
|
setShowForm(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Excluir via API e recarregar
|
function handleDelete(id: string) {
|
||||||
async function handleDelete(id: string) {
|
|
||||||
if (!confirm("Excluir este médico?")) return;
|
if (!confirm("Excluir este médico?")) return;
|
||||||
await excluirMedico(id);
|
setDoctors((prev) => prev.filter((x) => String(x.id) !== String(id)));
|
||||||
await load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Após salvar/criar/editar no form, fecha e recarrega
|
function handleSaved(medico: Medico) {
|
||||||
async function handleSaved() {
|
const saved = medico;
|
||||||
|
setDoctors((prev) => {
|
||||||
|
// Se não houver ID, é um novo médico
|
||||||
|
if (!saved.id) {
|
||||||
|
return [{ ...saved, id: String(Date.now()) }, ...prev];
|
||||||
|
}
|
||||||
|
// Se houver ID, é uma edição
|
||||||
|
const i = prev.findIndex((x) => String(x.id) === String(saved.id));
|
||||||
|
if (i < 0) return [{ ...saved, id: String(Date.now()) }, ...prev]; // Caso não encontre, adiciona
|
||||||
|
const clone = [...prev];
|
||||||
|
clone[i] = saved;
|
||||||
|
return clone;
|
||||||
|
});
|
||||||
setShowForm(false);
|
setShowForm(false);
|
||||||
await load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showForm) {
|
if (showForm) {
|
||||||
@ -107,7 +117,7 @@ export default function DoutoresPage() {
|
|||||||
onChange={(e) => setSearch(e.target.value)}
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button onClick={handleAdd} disabled={loading}>
|
<Button onClick={handleAdd}>
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
<Plus className="mr-2 h-4 w-4" />
|
||||||
Novo Médico
|
Novo Médico
|
||||||
</Button>
|
</Button>
|
||||||
@ -126,13 +136,7 @@ export default function DoutoresPage() {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{loading ? (
|
{filtered.length > 0 ? (
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={5} className="text-center text-muted-foreground">
|
|
||||||
Carregando…
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
) : filtered.length > 0 ? (
|
|
||||||
filtered.map((doctor) => (
|
filtered.map((doctor) => (
|
||||||
<TableRow key={doctor.id}>
|
<TableRow key={doctor.id}>
|
||||||
<TableCell className="font-medium">{doctor.nome}</TableCell>
|
<TableCell className="font-medium">{doctor.nome}</TableCell>
|
||||||
@ -182,9 +186,7 @@ export default function DoutoresPage() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm text-muted-foreground">
|
<div className="text-sm text-muted-foreground">Mostrando {filtered.length} de {doctors.length}</div>
|
||||||
Mostrando {filtered.length} de {doctors.length}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -13,18 +13,6 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/u
|
|||||||
import { AlertCircle, ChevronDown, ChevronUp, FileImage, Loader2, Save, Upload, User, X, XCircle, Trash2 } from "lucide-react";
|
import { AlertCircle, ChevronDown, ChevronUp, FileImage, Loader2, Save, Upload, User, X, XCircle, Trash2 } from "lucide-react";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
|
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
|
||||||
import {
|
|
||||||
criarMedico,
|
|
||||||
atualizarMedico,
|
|
||||||
buscarMedicoPorId,
|
|
||||||
uploadFotoMedico,
|
|
||||||
listarAnexosMedico,
|
|
||||||
adicionarAnexoMedico,
|
|
||||||
removerAnexoMedico,
|
|
||||||
MedicoInput,
|
|
||||||
} from "@/lib/api";
|
|
||||||
|
|
||||||
import { buscarCepAPI } from "@/lib/api"; // use o seu já existente
|
|
||||||
|
|
||||||
// Mock data and types since API is not used for now
|
// Mock data and types since API is not used for now
|
||||||
|
|
||||||
@ -173,57 +161,13 @@ export function DoctorRegistrationForm({
|
|||||||
|
|
||||||
const title = useMemo(() => (mode === "create" ? "Cadastro de Médico" : "Editar Médico"), [mode]);
|
const title = useMemo(() => (mode === "create" ? "Cadastro de Médico" : "Editar Médico"), [mode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let alive = true;
|
// Data loading logic would go here in a real scenario
|
||||||
async function load() {
|
|
||||||
if (mode === "edit" && doctorId) {
|
if (mode === "edit" && doctorId) {
|
||||||
const medico = await buscarMedicoPorId(doctorId);
|
console.log("Loading doctor data for ID:", doctorId);
|
||||||
if (!alive) return;
|
// Example: setForm(loadedDoctorData);
|
||||||
// mapeia API -> estado do formulário
|
|
||||||
setForm({
|
|
||||||
photo: null,
|
|
||||||
nome: medico.nome ?? "",
|
|
||||||
nome_social: medico.nome_social ?? "",
|
|
||||||
crm: medico.crm ?? "",
|
|
||||||
estado_crm: medico.estado_crm ?? "",
|
|
||||||
rqe: medico.rqe ?? "",
|
|
||||||
formacao_academica: medico.formacao_academica ?? [],
|
|
||||||
curriculo: null, // se a API devolver URL, você pode exibir ao lado
|
|
||||||
especialidade: medico.especialidade ?? "",
|
|
||||||
cpf: medico.cpf ?? "",
|
|
||||||
rg: medico.rg ?? "",
|
|
||||||
sexo: medico.sexo ?? "",
|
|
||||||
data_nascimento: medico.data_nascimento ?? "",
|
|
||||||
email: medico.email ?? "",
|
|
||||||
telefone: medico.telefone ?? "",
|
|
||||||
celular: medico.celular ?? "",
|
|
||||||
contato_emergencia: medico.contato_emergencia ?? "",
|
|
||||||
cep: "",
|
|
||||||
logradouro: "",
|
|
||||||
numero: "",
|
|
||||||
complemento: "",
|
|
||||||
bairro: "",
|
|
||||||
cidade: "",
|
|
||||||
estado: "",
|
|
||||||
observacoes: medico.observacoes ?? "",
|
|
||||||
anexos: [],
|
|
||||||
tipo_vinculo: medico.tipo_vinculo ?? "",
|
|
||||||
dados_bancarios: medico.dados_bancarios ?? { banco: "", agencia: "", conta: "", tipo_conta: "" },
|
|
||||||
agenda_horario: medico.agenda_horario ?? "",
|
|
||||||
valor_consulta: medico.valor_consulta ? String(medico.valor_consulta) : "",
|
|
||||||
});
|
|
||||||
|
|
||||||
// (Opcional) listar anexos que já existem no servidor
|
|
||||||
try {
|
|
||||||
const list = await listarAnexosMedico(doctorId);
|
|
||||||
setServerAnexos(list ?? []);
|
|
||||||
} catch {}
|
|
||||||
}
|
}
|
||||||
}
|
}, [mode, doctorId]);
|
||||||
load();
|
|
||||||
return () => { alive = false; };
|
|
||||||
}, [mode, doctorId]);
|
|
||||||
|
|
||||||
|
|
||||||
function setField<T extends keyof FormData>(k: T, v: FormData[T]) {
|
function setField<T extends keyof FormData>(k: T, v: FormData[T]) {
|
||||||
setForm((s) => ({ ...s, [k]: v }));
|
setForm((s) => ({ ...s, [k]: v }));
|
||||||
@ -281,26 +225,27 @@ export function DoctorRegistrationForm({
|
|||||||
return n.replace(/(\d{5})(\d{0,3})/, (_, a, b) => `${a}${b ? "-" + b : ""}`);
|
return n.replace(/(\d{5})(\d{0,3})/, (_, a, b) => `${a}${b ? "-" + b : ""}`);
|
||||||
}
|
}
|
||||||
async function fillFromCEP(cep: string) {
|
async function fillFromCEP(cep: string) {
|
||||||
const clean = cep.replace(/\D/g, "");
|
const clean = cep.replace(/\D/g, "");
|
||||||
if (clean.length !== 8) return;
|
if (clean.length !== 8) return;
|
||||||
setSearchingCEP(true);
|
setSearchingCEP(true);
|
||||||
try {
|
try {
|
||||||
const res = await buscarCepAPI(clean);
|
// Mocking API call
|
||||||
if (res && !res.erro) {
|
console.log("Searching CEP:", clean);
|
||||||
setField("logradouro", res.logradouro ?? "");
|
// In a real app: const res = await buscarCepAPI(clean);
|
||||||
setField("bairro", res.bairro ?? "");
|
// Mock response:
|
||||||
setField("cidade", res.localidade ?? "");
|
const res = { logradouro: "Rua Fictícia", bairro: "Bairro dos Sonhos", localidade: "Cidade Exemplo", uf: "EX" };
|
||||||
setField("estado", res.uf ?? "");
|
if (res) {
|
||||||
} else {
|
setField("logradouro", res.logradouro ?? "");
|
||||||
setErrors((e) => ({ ...e, cep: "CEP não encontrado" }));
|
setField("bairro", res.bairro ?? "");
|
||||||
|
setField("cidade", res.localidade ?? "");
|
||||||
|
setField("estado", res.uf ?? "");
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
setErrors((e) => ({ ...e, cep: "Erro ao buscar CEP" }));
|
||||||
|
} finally {
|
||||||
|
setSearchingCEP(false);
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
setErrors((e) => ({ ...e, cep: "Erro ao buscar CEP" }));
|
|
||||||
} finally {
|
|
||||||
setSearchingCEP(false);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function validateLocal(): boolean {
|
function validateLocal(): boolean {
|
||||||
const e: Record<string, string> = {};
|
const e: Record<string, string> = {};
|
||||||
@ -313,75 +258,25 @@ export function DoctorRegistrationForm({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit(ev: React.FormEvent) {
|
async function handleSubmit(ev: React.FormEvent) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (!validateLocal()) return;
|
if (!validateLocal()) return;
|
||||||
|
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
setErrors((e) => ({ ...e, submit: "" }));
|
console.log("Submitting form with data:", form);
|
||||||
|
|
||||||
try {
|
// Simulate API call
|
||||||
// monta o payload esperado pela API
|
setTimeout(() => {
|
||||||
const payload: MedicoInput = {
|
setSubmitting(false);
|
||||||
nome: form.nome,
|
const savedData: Medico = {
|
||||||
nome_social: form.nome_social || null,
|
id: doctorId ? String(doctorId) : String(Date.now()),
|
||||||
cpf: form.cpf || null,
|
...form,
|
||||||
rg: form.rg || null,
|
};
|
||||||
sexo: form.sexo || null,
|
onSaved?.(savedData);
|
||||||
data_nascimento: form.data_nascimento || null,
|
alert(mode === "create" ? "Médico cadastrado com sucesso! (simulado)" : "Médico atualizado com sucesso! (simulado)");
|
||||||
telefone: form.telefone || null,
|
if (inline) onClose?.();
|
||||||
celular: form.celular || null,
|
else onOpenChange?.(false);
|
||||||
contato_emergencia: form.contato_emergencia || null,
|
}, 1000);
|
||||||
email: form.email || null,
|
|
||||||
crm: form.crm,
|
|
||||||
estado_crm: form.estado_crm || null,
|
|
||||||
rqe: form.rqe || null,
|
|
||||||
formacao_academica: form.formacao_academica ?? [],
|
|
||||||
curriculo_url: null, // se quiser, suba arquivo do currículo num endpoint próprio e salve a URL aqui
|
|
||||||
especialidade: form.especialidade,
|
|
||||||
observacoes: form.observacoes || null,
|
|
||||||
tipo_vinculo: form.tipo_vinculo || null,
|
|
||||||
dados_bancarios: form.dados_bancarios ?? null,
|
|
||||||
agenda_horario: form.agenda_horario || null,
|
|
||||||
valor_consulta: form.valor_consulta || null,
|
|
||||||
};
|
|
||||||
|
|
||||||
// cria ou atualiza
|
|
||||||
const saved = mode === "create"
|
|
||||||
? await criarMedico(payload)
|
|
||||||
: await atualizarMedico(doctorId as number, payload);
|
|
||||||
|
|
||||||
const medicoId = saved.id;
|
|
||||||
|
|
||||||
// foto (opcional)
|
|
||||||
if (form.photo) {
|
|
||||||
try {
|
|
||||||
await uploadFotoMedico(medicoId, form.photo);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Falha ao enviar foto:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// anexos locais (opcional)
|
|
||||||
if (form.anexos?.length) {
|
|
||||||
for (const f of form.anexos) {
|
|
||||||
try {
|
|
||||||
await adicionarAnexoMedico(medicoId, f);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Falha ao enviar anexo:", f.name, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSaved?.(saved);
|
|
||||||
if (inline) onClose?.();
|
|
||||||
else onOpenChange?.(false);
|
|
||||||
} catch (err: any) {
|
|
||||||
setErrors((e) => ({ ...e, submit: err?.message || "Erro ao salvar médico" }));
|
|
||||||
} finally {
|
|
||||||
setSubmitting(false);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function handlePhoto(e: React.ChangeEvent<HTMLInputElement>) {
|
function handlePhoto(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
const f = e.target.files?.[0];
|
const f = e.target.files?.[0];
|
||||||
|
|||||||
@ -61,10 +61,8 @@ export type PacienteInput = {
|
|||||||
|
|
||||||
|
|
||||||
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? "https://mock.apidog.com/m1/1053378-0-default";
|
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? "https://mock.apidog.com/m1/1053378-0-default";
|
||||||
const MEDICOS_BASE = process.env.NEXT_PUBLIC_MEDICOS_BASE_PATH ?? "/medicos";
|
|
||||||
|
|
||||||
export const PATHS = {
|
const PATHS = {
|
||||||
// Pacientes (já existia)
|
|
||||||
pacientes: "/pacientes",
|
pacientes: "/pacientes",
|
||||||
pacienteId: (id: string | number) => `/pacientes/${id}`,
|
pacienteId: (id: string | number) => `/pacientes/${id}`,
|
||||||
foto: (id: string | number) => `/pacientes/${id}/foto`,
|
foto: (id: string | number) => `/pacientes/${id}/foto`,
|
||||||
@ -72,16 +70,8 @@ export const PATHS = {
|
|||||||
anexoId: (id: string | number, anexoId: string | number) => `/pacientes/${id}/anexos/${anexoId}`,
|
anexoId: (id: string | number, anexoId: string | number) => `/pacientes/${id}/anexos/${anexoId}`,
|
||||||
validarCPF: "/pacientes/validar-cpf",
|
validarCPF: "/pacientes/validar-cpf",
|
||||||
cep: (cep: string) => `/utils/cep/${cep}`,
|
cep: (cep: string) => `/utils/cep/${cep}`,
|
||||||
|
|
||||||
// Médicos (APONTANDO PARA PACIENTES por enquanto)
|
|
||||||
medicos: MEDICOS_BASE,
|
|
||||||
medicoId: (id: string | number) => `${MEDICOS_BASE}/${id}`,
|
|
||||||
medicoFoto: (id: string | number) => `${MEDICOS_BASE}/${id}/foto`,
|
|
||||||
medicoAnexos: (id: string | number) => `${MEDICOS_BASE}/${id}/anexos`,
|
|
||||||
medicoAnexoId: (id: string | number, anexoId: string | number) => `${MEDICOS_BASE}/${id}/anexos/${anexoId}`,
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
||||||
function headers(kind: "json" | "form" = "json"): Record<string, string> {
|
function headers(kind: "json" | "form" = "json"): Record<string, string> {
|
||||||
const h: Record<string, string> = {};
|
const h: Record<string, string> = {};
|
||||||
const token = process.env.NEXT_PUBLIC_API_TOKEN?.trim();
|
const token = process.env.NEXT_PUBLIC_API_TOKEN?.trim();
|
||||||
@ -105,22 +95,17 @@ async function parse<T>(res: Response): Promise<T> {
|
|||||||
try {
|
try {
|
||||||
json = await res.json();
|
json = await res.json();
|
||||||
} catch {
|
} catch {
|
||||||
// ignora erro de parse vazio
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
// 🔴 ADICIONE ESSA LINHA AQUI:
|
|
||||||
console.error("[API ERROR]", res.url, res.status, json);
|
|
||||||
|
|
||||||
const code = json?.apidogError?.code ?? res.status;
|
const code = json?.apidogError?.code ?? res.status;
|
||||||
const msg = json?.apidogError?.message ?? res.statusText;
|
const msg = json?.apidogError?.message ?? res.statusText;
|
||||||
throw new Error(`${code}: ${msg}`);
|
throw new Error(`${code}: ${msg}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (json?.data ?? json) as T;
|
return (json?.data ?? json) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Pacientes (CRUD)
|
// Pacientes (CRUD)
|
||||||
//
|
//
|
||||||
@ -265,150 +250,3 @@ export async function buscarCepAPI(cep: string): Promise<{ logradouro?: string;
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// >>> ADICIONE (ou mova) ESTES TIPOS <<<
|
|
||||||
export type FormacaoAcademica = {
|
|
||||||
instituicao: string;
|
|
||||||
curso: string;
|
|
||||||
ano_conclusao: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DadosBancarios = {
|
|
||||||
banco: string;
|
|
||||||
agencia: string;
|
|
||||||
conta: string;
|
|
||||||
tipo_conta: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Medico = {
|
|
||||||
id: string;
|
|
||||||
nome?: string;
|
|
||||||
nome_social?: string | null;
|
|
||||||
cpf?: string;
|
|
||||||
rg?: string | null;
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MedicoInput = {
|
|
||||||
nome: string;
|
|
||||||
nome_social?: string | null;
|
|
||||||
cpf?: string | null;
|
|
||||||
rg?: string | null;
|
|
||||||
sexo?: string | null;
|
|
||||||
data_nascimento?: string | null;
|
|
||||||
telefone?: string | null;
|
|
||||||
celular?: string | null;
|
|
||||||
contato_emergencia?: string | null;
|
|
||||||
email?: string | null;
|
|
||||||
crm: string;
|
|
||||||
estado_crm?: string | null;
|
|
||||||
rqe?: string | null;
|
|
||||||
formacao_academica?: FormacaoAcademica[];
|
|
||||||
curriculo_url?: string | null;
|
|
||||||
especialidade: string;
|
|
||||||
observacoes?: string | null;
|
|
||||||
tipo_vinculo?: string | null;
|
|
||||||
dados_bancarios?: DadosBancarios | null;
|
|
||||||
agenda_horario?: string | null;
|
|
||||||
valor_consulta?: number | string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// MÉDICOS (CRUD)
|
|
||||||
//
|
|
||||||
// ======= MÉDICOS (forçando usar rotas de PACIENTES no mock) =======
|
|
||||||
|
|
||||||
export async function listarMedicos(params?: { page?: number; limit?: number; q?: string }): Promise<Medico[]> {
|
|
||||||
const query = new URLSearchParams();
|
|
||||||
if (params?.page) query.set("page", String(params.page));
|
|
||||||
if (params?.limit) query.set("limit", String(params.limit));
|
|
||||||
if (params?.q) query.set("q", params.q);
|
|
||||||
|
|
||||||
// FORÇA /pacientes
|
|
||||||
const url = `${API_BASE}/pacientes${query.toString() ? `?${query.toString()}` : ""}`;
|
|
||||||
const res = await fetch(url, { method: "GET", headers: headers("json") });
|
|
||||||
const data = await parse<ApiOk<Medico[]>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function buscarMedicoPorId(id: string | number): Promise<Medico> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "GET", headers: headers("json") });
|
|
||||||
const data = await parse<ApiOk<Medico>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function criarMedico(input: MedicoInput): Promise<Medico> {
|
|
||||||
const url = `${API_BASE}/pacientes`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "POST", headers: headers("json"), body: JSON.stringify(input) });
|
|
||||||
const data = await parse<ApiOk<Medico>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function atualizarMedico(id: string | number, input: MedicoInput): Promise<Medico> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "PUT", headers: headers("json"), body: JSON.stringify(input) });
|
|
||||||
const data = await parse<ApiOk<Medico>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function excluirMedico(id: string | number): Promise<void> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "DELETE", headers: headers("json") });
|
|
||||||
await parse<any>(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function uploadFotoMedico(id: string | number, file: File): Promise<{ foto_url?: string; thumbnail_url?: string }> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}/foto`; // FORÇA /pacientes
|
|
||||||
const fd = new FormData();
|
|
||||||
fd.append("foto", file);
|
|
||||||
const res = await fetch(url, { method: "POST", headers: headers("form"), body: fd });
|
|
||||||
const data = await parse<ApiOk<{ foto_url?: string; thumbnail_url?: string }>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function removerFotoMedico(id: string | number): Promise<void> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}/foto`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "DELETE", headers: headers("json") });
|
|
||||||
await parse<any>(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listarAnexosMedico(id: string | number): Promise<any[]> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}/anexos`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "GET", headers: headers("json") });
|
|
||||||
const data = await parse<ApiOk<any[]>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function adicionarAnexoMedico(id: string | number, file: File): Promise<any> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}/anexos`; // FORÇA /pacientes
|
|
||||||
const fd = new FormData();
|
|
||||||
fd.append("arquivo", file);
|
|
||||||
const res = await fetch(url, { method: "POST", headers: headers("form"), body: fd });
|
|
||||||
const data = await parse<ApiOk<any>>(res);
|
|
||||||
return (data as any)?.data ?? (data as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function removerAnexoMedico(id: string | number, anexoId: string | number): Promise<void> {
|
|
||||||
const url = `${API_BASE}/pacientes/${id}/anexos/${anexoId}`; // FORÇA /pacientes
|
|
||||||
const res = await fetch(url, { method: "DELETE", headers: headers("json") });
|
|
||||||
await parse<any>(res);
|
|
||||||
}
|
|
||||||
// ======= FIM: médicos usando rotas de pacientes =======
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user