189 lines
6.8 KiB
TypeScript
189 lines
6.8 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Input } from "@/components/ui/input"
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
|
import {
|
|
Search,
|
|
Plus,
|
|
MoreHorizontal,
|
|
Eye,
|
|
Edit,
|
|
Trash2,
|
|
ArrowLeft,
|
|
} from "lucide-react"
|
|
import { DoctorRegistrationForm } from "@/components/forms/doctor-registration-form"
|
|
import { getMedicos, DoctorFormData } from "@/lib/api"
|
|
|
|
export default function MedicosPage() {
|
|
const [searchTerm, setSearchTerm] = useState("")
|
|
const [medicos, setMedicos] = useState<DoctorFormData[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [showDoctorForm, setShowDoctorForm] = useState(false)
|
|
const [editingDoctor, setEditingDoctor] = useState<DoctorFormData | null>(null)
|
|
|
|
async function fetchMedicos() {
|
|
try {
|
|
setLoading(true)
|
|
const data = await getMedicos()
|
|
setMedicos(data)
|
|
} catch (error) {
|
|
console.error("Erro ao buscar médicos:", error)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
fetchMedicos()
|
|
}, [])
|
|
|
|
const filteredMedicos = medicos.filter((medico) =>
|
|
medico.nome.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
(medico.crm && medico.crm.toLowerCase().includes(searchTerm.toLowerCase())) ||
|
|
(medico.especialidade && medico.especialidade.toLowerCase().includes(searchTerm.toLowerCase()))
|
|
)
|
|
|
|
const handleViewDetails = (doctorId: number) => {
|
|
console.log("[v0] Ver detalhes do médico:", doctorId)
|
|
}
|
|
|
|
const handleEditDoctor = (doctor: DoctorFormData) => {
|
|
setEditingDoctor(doctor)
|
|
setShowDoctorForm(true)
|
|
}
|
|
|
|
const handleDeleteDoctor = (doctorId: number) => {
|
|
setMedicos(medicos.filter(m => m.id !== doctorId))
|
|
}
|
|
|
|
const handleAddDoctor = () => {
|
|
setEditingDoctor(null)
|
|
setShowDoctorForm(true)
|
|
}
|
|
|
|
const handleFormClose = () => {
|
|
setShowDoctorForm(false)
|
|
setEditingDoctor(null)
|
|
fetchMedicos() // Recarrega os dados após fechar o formulário
|
|
}
|
|
|
|
if (showDoctorForm) {
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center gap-4">
|
|
<Button variant="ghost" onClick={handleFormClose} className="p-2">
|
|
<ArrowLeft className="h-4 w-4" />
|
|
</Button>
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-foreground">
|
|
{editingDoctor ? "Editar Médico" : "Cadastrar Novo Médico"}
|
|
</h1>
|
|
<p className="text-muted-foreground">
|
|
{editingDoctor ? "Atualize as informações do médico" : "Preencha os dados do novo médico"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<DoctorRegistrationForm doctorData={editingDoctor} onClose={handleFormClose} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-foreground">Médicos</h1>
|
|
<p className="text-muted-foreground">Gerencie os médicos da clínica</p>
|
|
</div>
|
|
<Button className="bg-primary hover:bg-primary/90" onClick={handleAddDoctor}>
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
Adicionar Médico
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-4 items-center">
|
|
<div className="relative flex-1 min-w-64">
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4" />
|
|
<Input
|
|
placeholder="Buscar por nome, CRM ou especialidade"
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
className="pl-10"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="border rounded-lg">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Nome</TableHead>
|
|
<TableHead>CRM</TableHead>
|
|
<TableHead>Especialidade</TableHead>
|
|
<TableHead>Celular</TableHead>
|
|
<TableHead>E-mail</TableHead>
|
|
<TableHead className="w-[100px]">Ações</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{loading ? (
|
|
<TableRow>
|
|
<TableCell colSpan={6} className="text-center">Carregando...</TableCell>
|
|
</TableRow>
|
|
) : filteredMedicos.map((medico) => (
|
|
<TableRow key={medico.id}>
|
|
<TableCell className="font-medium">
|
|
<div className="flex items-center gap-2">
|
|
<div className="w-8 h-8 bg-muted rounded-full flex items-center justify-center">
|
|
<span className="text-xs font-medium">{medico.nome.charAt(0).toUpperCase()}</span>
|
|
</div>
|
|
<button onClick={() => handleViewDetails(medico.id!)} className="hover:text-primary cursor-pointer">
|
|
{medico.nome}
|
|
</button>
|
|
</div>
|
|
</TableCell>
|
|
<TableCell>{medico.crm} - {medico.crmUf}</TableCell>
|
|
<TableCell>{medico.especialidade}</TableCell>
|
|
<TableCell>{medico.celular}</TableCell>
|
|
<TableCell>{medico.email}</TableCell>
|
|
<TableCell>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<button className="h-8 w-8 p-0 flex items-center justify-center rounded-md hover:bg-accent">
|
|
<span className="sr-only">Abrir menu</span>
|
|
<MoreHorizontal className="h-4 w-4" />
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem onClick={() => handleViewDetails(medico.id!)}>
|
|
<Eye className="mr-2 h-4 w-4" />
|
|
Ver detalhes
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={() => handleEditDoctor(medico)}>
|
|
<Edit className="mr-2 h-4 w-4" />
|
|
Editar
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={() => handleDeleteDoctor(medico.id!)} className="text-destructive">
|
|
<Trash2 className="mr-2 h-4 w-4" />
|
|
Excluir
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
|
|
<div className="text-sm text-muted-foreground">
|
|
Mostrando {filteredMedicos.length} de {medicos.length} médicos
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|