Mejorar tema oscuro, añadir dropdownmenu en laboratorios, unificar estilos de botones a outline
This commit is contained in:
+8
-4
@@ -13,6 +13,7 @@ import { EditIngreso } from '@/sections/EditIngreso';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ThemeProvider } from '@/contexts/ThemeContext';
|
||||
import { Toaster } from '@/components/ui/sonner';
|
||||
|
||||
function AppContent() {
|
||||
const store = useHospitalStore();
|
||||
@@ -127,7 +128,7 @@ function AppContent() {
|
||||
if (!internacion || !paciente) {
|
||||
return (
|
||||
<div className="p-4 text-center">
|
||||
<p className="text-gray-500">Internación no encontrada</p>
|
||||
<p className="text-gray-500 dark:text-gray-400">Internación no encontrada</p>
|
||||
<Button onClick={() => store.setVista('internaciones')}>Volver a Internaciones</Button>
|
||||
</div>
|
||||
);
|
||||
@@ -160,7 +161,7 @@ function AppContent() {
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'nuevoingreso':
|
||||
case 'nuevoingreso':
|
||||
return (
|
||||
<NuevoIngreso
|
||||
pacientes={store.pacientes}
|
||||
@@ -178,7 +179,7 @@ case 'nuevoingreso':
|
||||
if (!internacion || !paciente) {
|
||||
return (
|
||||
<div className="p-4 text-center">
|
||||
<p className="text-gray-500">Internación no encontrada</p>
|
||||
<p className="text-gray-500 dark:text-gray-400">Internación no encontrada</p>
|
||||
<Button onClick={() => store.setVista('internaciones')}>Volver a Internaciones</Button>
|
||||
</div>
|
||||
);
|
||||
@@ -197,6 +198,7 @@ case 'nuevoingreso':
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -210,8 +212,10 @@ case 'nuevoingreso':
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThemeProvider>
|
||||
// @ts-expect-error - next-themes types mismatch
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<AppContent />
|
||||
<Toaster position="top-right" />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,40 +1,19 @@
|
||||
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
|
||||
|
||||
interface ThemeContextType {
|
||||
isDarkMode: boolean;
|
||||
toggleDarkMode: () => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
||||
import { ThemeProvider as NextThemesProvider, useTheme as useNextTheme } from 'next-themes';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
const [isDarkMode, setIsDarkMode] = useState(() => {
|
||||
const saved = localStorage.getItem('darkMode');
|
||||
return saved ? JSON.parse(saved) : false;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('darkMode', JSON.stringify(isDarkMode));
|
||||
if (isDarkMode) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
}, [isDarkMode]);
|
||||
|
||||
const toggleDarkMode = () => setIsDarkMode((prev: boolean) => !prev);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ isDarkMode, toggleDarkMode }}>
|
||||
<NextThemesProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
</NextThemesProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useTheme() {
|
||||
const context = useContext(ThemeContext);
|
||||
if (!context) {
|
||||
throw new Error('useTheme must be used within ThemeProvider');
|
||||
}
|
||||
return context;
|
||||
const { theme, setTheme } = useNextTheme();
|
||||
const isDarkMode = theme === 'dark';
|
||||
const toggleDarkMode = () => setTheme(theme === 'dark' ? 'light' : 'dark');
|
||||
return { isDarkMode, toggleDarkMode, theme, setTheme };
|
||||
}
|
||||
|
||||
export { NextThemesProvider };
|
||||
@@ -184,7 +184,7 @@ export function Cultivos({
|
||||
</div>
|
||||
<Dialog open={dialogoNuevoAbierto} onOpenChange={setDialogoNuevoAbierto}>
|
||||
<DialogTrigger asChild>
|
||||
<Button onClick={resetFormularioNuevo} className="w-full sm:w-auto">
|
||||
<Button variant="outline" onClick={resetFormularioNuevo} className="w-full sm:w-auto">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Nuevo Cultivo
|
||||
</Button>
|
||||
@@ -230,7 +230,7 @@ export function Cultivos({
|
||||
return p ? `${p.apellido}, ${p.nombre} - DNI: ${p.dni}` : '';
|
||||
})()}
|
||||
</Badge>
|
||||
<Button size="sm" variant="ghost" onClick={() => setPacienteSeleccionado('')}>Cambiar</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => setPacienteSeleccionado('')}>Cambiar</Button>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
@@ -269,7 +269,7 @@ export function Cultivos({
|
||||
</div>
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button variant="outline" onClick={() => setDialogoNuevoAbierto(false)}><X className="h-4 w-4 mr-2" />Cancelar</Button>
|
||||
<Button onClick={handleAgregar} disabled={!pacienteSeleccionado || !fechaToma || !tipoMuestra}>
|
||||
<Button variant="outline" onClick={handleAgregar} disabled={!pacienteSeleccionado || !fechaToma || !tipoMuestra}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Guardar
|
||||
</Button>
|
||||
@@ -310,7 +310,7 @@ export function Cultivos({
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button onClick={handleParcial} disabled={!germen}>
|
||||
<Button variant="outline" onClick={handleParcial} disabled={!germen}>
|
||||
<Save className="h-4 w-4 mr-2" />
|
||||
Guardar Parcial
|
||||
</Button>
|
||||
@@ -368,7 +368,7 @@ export function Cultivos({
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button onClick={handleDefinitivo} disabled={estadoResultado === 'Positivo' && !germen}>
|
||||
<Button variant="outline" onClick={handleDefinitivo} disabled={estadoResultado === 'Positivo' && !germen}>
|
||||
<Save className="h-4 w-4 mr-2" />
|
||||
Guardar Definitivo
|
||||
</Button>
|
||||
@@ -452,11 +452,11 @@ export function Cultivos({
|
||||
<div className="flex flex-wrap items-center gap-1 sm:gap-2 ml-auto sm:ml-0">
|
||||
{onActualizarCultivo && cultivo.estado === 'NAF/Pendiente' && (
|
||||
<>
|
||||
<Button size="sm" className="text-xs px-2 py-1" onClick={() => abrirParcial(cultivo)}>
|
||||
<Button size="sm" variant="outline" className="text-xs px-2 py-1" onClick={() => abrirParcial(cultivo)}>
|
||||
<AlertCircle className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
||||
<span className="hidden sm:inline">Parcial</span>
|
||||
</Button>
|
||||
<Button size="sm" variant="default" className="text-xs px-2 py-1" onClick={() => abrirDefinitivo(cultivo)}>
|
||||
<Button size="sm" variant="outline" className="text-xs px-2 py-1" onClick={() => abrirDefinitivo(cultivo)}>
|
||||
<CheckCircle2 className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
||||
<span className="hidden sm:inline">Definitivo</span>
|
||||
</Button>
|
||||
@@ -468,7 +468,7 @@ export function Cultivos({
|
||||
<Pencil className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
||||
<span className="hidden sm:inline">Editar</span>
|
||||
</Button>
|
||||
<Button size="sm" variant="default" className="text-xs px-2 py-1" onClick={() => abrirDefinitivo(cultivo)}>
|
||||
<Button size="sm" variant="outline" className="text-xs px-2 py-1" onClick={() => abrirDefinitivo(cultivo)}>
|
||||
<CheckCircle2 className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
||||
<span className="hidden sm:inline">Definitivo</span>
|
||||
</Button>
|
||||
@@ -479,7 +479,7 @@ export function Cultivos({
|
||||
<Pencil className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||
</Button>
|
||||
)}
|
||||
<Button size="sm" variant="ghost" className="text-red-600 text-xs px-2 py-1" onClick={() => onEliminarCultivo(cultivo.id)}>
|
||||
<Button size="sm" variant="outline" className="text-red-600 text-xs px-2 py-1" onClick={() => onEliminarCultivo(cultivo.id)}>
|
||||
<Trash2 className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -82,7 +82,7 @@ export function EditIngreso({
|
||||
|
||||
return (
|
||||
<div className="space-y-6 dark:text-white">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="ghost" size="icon" onClick={onVolver}>
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
@@ -95,7 +95,7 @@ export function EditIngreso({
|
||||
<p className="text-gray-500 dark:text-gray-400">Modificar datos de internación</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex gap-2 ml-auto sm:ml-0">
|
||||
<Button variant="outline" onClick={() => onVolver()}>
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Cancelar
|
||||
@@ -120,13 +120,13 @@ export function EditIngreso({
|
||||
{selectedPaciente ? (
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Badge variant="outline" className="bg-primary/10 text-primary border-primary/30">
|
||||
<Badge variant="outline" className="bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-300">
|
||||
{selectedPaciente?.apellido}, {selectedPaciente?.nombre}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="bg-primary/10 text-primary border-primary/30">
|
||||
{selectedPaciente?.fechaNacimiento ? calcularEdad(selectedPaciente.fechaNacimiento) + ' años' : ''}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="bg-primary/10 text-primary border-primary/30">
|
||||
<Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-200">
|
||||
DNI: {selectedPaciente?.dni}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -192,7 +192,7 @@ export function Evoluciones({
|
||||
</div>
|
||||
<Dialog open={dialogoAbierto} onOpenChange={setDialogoAbierto}>
|
||||
<DialogTrigger asChild>
|
||||
<Button onClick={resetFormulario}>
|
||||
<Button variant="outline" onClick={resetFormulario}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Nueva Evolución
|
||||
</Button>
|
||||
@@ -390,7 +390,7 @@ export function Evoluciones({
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
onClick={handleGuardar}
|
||||
disabled={!medico || (!evolucionEditando && !pacienteSeleccionado)}
|
||||
>
|
||||
@@ -462,10 +462,9 @@ export function Evoluciones({
|
||||
<Pencil className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
<Button variant="outline"
|
||||
size="sm"
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
className="text-red-600"
|
||||
onClick={() => onEliminarEvolucion(evolucion.id)}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
|
||||
@@ -22,7 +22,11 @@ import {
|
||||
Wind,
|
||||
Droplets,
|
||||
Save,
|
||||
X
|
||||
X,
|
||||
MoreHorizontal,
|
||||
Edit,
|
||||
ClipboardList,
|
||||
TrendingUp
|
||||
} from 'lucide-react';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
@@ -33,6 +37,8 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import type { Laboratorio, AcidoBase, Cultivo, Paciente, ResultadoLaboratorio, Internacion, Evolucion, Cama } from '@/types';
|
||||
import { formatDateDDMMYYYY } from '@/lib/utils';
|
||||
|
||||
@@ -212,7 +218,7 @@ export function HistoriaClinica({
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-900">Historia Clínica</h1>
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white flex items-center gap-2"><ClipboardList className="h-6 w-6" />Historia Clínica</h1>
|
||||
<p className="text-gray-500">
|
||||
Cama: {cama?.numero || 'N/A'} | {paciente.apellido}, {paciente.nombre} | {paciente.fechaNacimiento ? calcularEdad(paciente.fechaNacimiento) + ' años' : ''} | DNI: {paciente.dni}
|
||||
</p>
|
||||
@@ -534,6 +540,8 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
}) {
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [obsDialog, setObsDialog] = useState(false);
|
||||
const [evolDialog, setEvolDialog] = useState(false);
|
||||
const [selectedLab, setSelectedLab] = useState<Laboratorio | null>(null);
|
||||
const [edit, setEdit] = useState<Laboratorio | null>(null);
|
||||
const [obsLab, setObsLab] = useState<Laboratorio | null>(null);
|
||||
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
||||
@@ -556,6 +564,23 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
const [tp, setTp] = useState('');
|
||||
const [kptt, setKptt] = useState('');
|
||||
const [rin, setRin] = useState('');
|
||||
const [parametroEvolucion, setParametroEvolucion] = useState('');
|
||||
|
||||
const parametrosLaboratorio = [
|
||||
'Hematocrito', 'Hemoglobina', 'Leucocitos', 'Plaquetas',
|
||||
'Glucemia', 'Urea', 'Creatinina',
|
||||
'Sodio', 'Potasio', 'Cloro',
|
||||
'Bilirrubina Total', 'Bilirrubina Directa', 'GOT', 'GPT',
|
||||
'Tiempo de Protrombina', 'KPTT', 'INR'
|
||||
];
|
||||
|
||||
const datosEvolucion = lab
|
||||
.filter(l => l.resultados.some(r => r.parametro === parametroEvolucion))
|
||||
.sort((a, b) => new Date(a.fecha).getTime() - new Date(b.fecha).getTime())
|
||||
.map(l => {
|
||||
const r = l.resultados.find(r => r.parametro === parametroEvolucion);
|
||||
return { fecha: l.fecha, valor: r ? parseFloat(String(r.valor)) : null };
|
||||
});
|
||||
|
||||
const getEstadoColor = (estado: ResultadoLaboratorio['estado']) => {
|
||||
switch (estado) {
|
||||
@@ -657,8 +682,11 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Laboratorio</Button>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Laboratorio</Button>
|
||||
<Button variant="outline" onClick={() => { setSelectedLab(lab[0] || null); setParametroEvolucion('Hematocrito'); setEvolDialog(true); }}><TrendingUp className="h-4 w-4 mr-2" />Evolución</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog open={dialog} onOpenChange={setDialog}>
|
||||
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
@@ -725,7 +753,7 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm text-gray-500">{obsLab?.fecha}</p>
|
||||
<p className="text-sm text-gray-500">{obsLab?.tipo}</p>
|
||||
<div className="bg-gray-50 p-3 rounded-lg border border-gray-200">
|
||||
<div className="bg-gray-50 p-3 rounded-lg border border-gray-200 dark:bg-gray-800 dark:border-gray-700">
|
||||
<p className="whitespace-pre-wrap">{obsLab?.observaciones}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -733,6 +761,64 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={evolDialog} onOpenChange={setEvolDialog}>
|
||||
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<TrendingUp className="h-5 w-5" />
|
||||
Evolución de Laboratorio
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label>Parámetro a visualizar</Label>
|
||||
<Select value={parametroEvolucion} onValueChange={setParametroEvolucion}>
|
||||
<SelectTrigger><SelectValue placeholder="Seleccionar parámetro" /></SelectTrigger>
|
||||
<SelectContent>
|
||||
{parametrosLaboratorio.map(p => (
|
||||
<SelectItem key={p} value={p}>{p}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
{parametroEvolucion && datosEvolucion.length > 0 && (
|
||||
<div className="h-64 bg-muted/30 rounded-lg p-4">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart data={datosEvolucion}>
|
||||
<CartesianGrid strokeDasharray="3 3" className="opacity-30" />
|
||||
<XAxis dataKey="fecha" tick={{ fontSize: 12 }} />
|
||||
<YAxis tick={{ fontSize: 12 }} domain={['auto', 'auto']} />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'hsl(var(--card))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
borderRadius: '8px'
|
||||
}}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="valor"
|
||||
stroke="hsl(var(--primary))"
|
||||
strokeWidth={2}
|
||||
dot={{ fill: 'hsl(var(--primary))', r: 4 }}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
)}
|
||||
{parametroEvolucion && datosEvolucion.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-400">
|
||||
<TrendingUp className="h-12 w-12 mx-auto mb-2 opacity-50" />
|
||||
<p>No hay datos para este parámetro</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
<Button onClick={() => setEvolDialog(false)}>Cerrar</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{labs.length === 0 ? <div className="text-center py-8 text-gray-400"><FlaskConical className="h-12 w-12 mx-auto mb-2 opacity-50" /><p>No hay laboratorios</p></div> :
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
@@ -756,7 +842,7 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
<TableHead>TP</TableHead>
|
||||
<TableHead>KPTT</TableHead>
|
||||
<TableHead>RIN</TableHead>
|
||||
<TableHead></TableHead>
|
||||
<TableHead>Acciones</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -781,11 +867,27 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
|
||||
<TableCell className={getValorStyle(l, 'KPTT')}>{getValor(l, 'KPTT')}</TableCell>
|
||||
<TableCell className={getValorStyle(l, 'INR')}>{getValor(l, 'INR')}</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-1">
|
||||
{l.observaciones && <Button size="sm" variant="ghost" onClick={() => { setObsLab(l); setObsDialog(true); }}><ChevronRight className="h-4 w-4" /></Button>}
|
||||
<Button size="sm" variant="ghost" onClick={() => loadEdit(l)}><Pencil className="h-4 w-4" /></Button>
|
||||
<Button size="sm" variant="ghost" className="text-red-600" onClick={() => del(l.id)}><Trash2 className="h-4 w-4" /></Button>
|
||||
</div>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="sm" variant="ghost" className="h-8 w-8 p-0">
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => loadEdit(l)}>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Editar
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => del(l.id)} className="text-red-600">
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Eliminar
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => { setObsLab(l); setObsDialog(true); }}>
|
||||
<ClipboardList className="mr-2 h-4 w-4" />
|
||||
Ver Observaciones
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
@@ -893,8 +995,8 @@ function SeccionEvoluciones({ evos, internacionId, add, update, del }: {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Evolución</Button>
|
||||
<div className="flex">
|
||||
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Evolución</Button>
|
||||
</div>
|
||||
<Dialog open={dialog} onOpenChange={setDialog}>
|
||||
<DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto">
|
||||
@@ -1037,8 +1139,8 @@ function SeccionAcidosBase({ ab, patientId, add, del }: {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Gasometría</Button>
|
||||
<div className="flex">
|
||||
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nueva Gasometría</Button>
|
||||
</div>
|
||||
<Dialog open={dialog} onOpenChange={setDialog}>
|
||||
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
@@ -1212,8 +1314,8 @@ const resetRes = () => {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Cultivo</Button>
|
||||
<div className="flex">
|
||||
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}><Plus className="h-4 w-4 mr-2" />Nuevo Cultivo</Button>
|
||||
</div>
|
||||
<Dialog open={dialog} onOpenChange={setDialog}>
|
||||
<DialogContent className="sm:max-w-lg">
|
||||
@@ -1242,7 +1344,7 @@ const resetRes = () => {
|
||||
</div>
|
||||
<div><Label>Observaciones</Label><textarea className="w-full p-2 border rounded-md text-sm min-h-[60px]" value={observaciones} onChange={e => setObservaciones(e.target.value)} /></div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => setDialog(false)}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button onClick={handle}><Plus className="h-4 w-4 mr-2" />Guardar</Button></div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => setDialog(false)}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button variant="outline" onClick={handle}><Plus className="h-4 w-4 mr-2" />Guardar</Button></div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -1259,7 +1361,7 @@ const resetRes = () => {
|
||||
<div><Label>Sensible a:</Label><Input value={sensible} onChange={e => setSensible(e.target.value)} placeholder="Ej: Amikacina, Vancomicina" /></div>
|
||||
<div><Label>Resistente a:</Label><Input value={resistente} onChange={e => setResistente(e.target.value)} placeholder="Ej: Oxacilina" /></div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => { resetRes(); setResDialog(false); }}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button onClick={handleParcial} disabled={!germen}><Save className="h-4 w-4 mr-2" />Guardar Parcial</Button></div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => { resetRes(); setResDialog(false); }}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button variant="outline" onClick={handleParcial} disabled={!germen}><Save className="h-4 w-4 mr-2" />Guardar Parcial</Button></div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -1288,7 +1390,7 @@ const resetRes = () => {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => { resetRes(); setEditDialog(false); }}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button onClick={handleDefinitivo} disabled={estadoResultado === 'Positivo' && !germen}><Save className="h-4 w-4 mr-2" />Guardar Definitivo</Button></div>
|
||||
<div className="flex justify-end gap-2 mt-4"><Button variant="outline" onClick={() => { resetRes(); setEditDialog(false); }}><X className="h-4 w-4 mr-2" />Cancelar</Button><Button variant="outline" onClick={handleDefinitivo} disabled={estadoResultado === 'Positivo' && !germen}><Save className="h-4 w-4 mr-2" />Guardar Definitivo</Button></div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -1312,18 +1414,18 @@ const resetRes = () => {
|
||||
<div className="flex items-center gap-2">
|
||||
{c.estado === 'NAF/Pendiente' && (
|
||||
<>
|
||||
<Button size="sm" onClick={() => openParcial(c)}><AlertCircle className="h-4 w-4 mr-1" />Parcial</Button>
|
||||
<Button size="sm" variant="default" onClick={() => { openDefinitivo(c); setIsParcialMode(false); }}><CheckCircle2 className="h-4 w-4 mr-1" />Definitivo</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => openParcial(c)}><AlertCircle className="h-4 w-4 mr-1" />Parcial</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => { openDefinitivo(c); setIsParcialMode(false); }}><CheckCircle2 className="h-4 w-4 mr-1" />Definitivo</Button>
|
||||
</>
|
||||
)}
|
||||
{c.estado === 'Parcial' && (
|
||||
<>
|
||||
<Button size="sm" variant="outline" onClick={() => openParcial(c)}><Pencil className="h-4 w-4 mr-1" />Editar Parcial</Button>
|
||||
<Button size="sm" variant="default" onClick={() => openDefinitivo(c)}><CheckCircle2 className="h-4 w-4 mr-1" />Definitivo</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => openDefinitivo(c)}><CheckCircle2 className="h-4 w-4 mr-1" />Definitivo</Button>
|
||||
</>
|
||||
)}
|
||||
{(c.estado === 'Positivo' || c.estado === 'Negativo') && <Button size="sm" variant="outline" onClick={() => openDefinitivo(c)}><Pencil className="h-4 w-4" /></Button>}
|
||||
<Button size="sm" variant="ghost" className="text-red-600" onClick={() => del(c.id)}><Trash2 /></Button>
|
||||
<Button size="sm" variant="outline" className="text-red-600" onClick={() => del(c.id)}><Trash2 /></Button>
|
||||
</div>
|
||||
</div>
|
||||
{c.protocolo && <p className="text-xs text-gray-500">Protocolo: {c.protocolo}</p>}
|
||||
|
||||
@@ -145,7 +145,7 @@ export function Internaciones({
|
||||
</div>
|
||||
<Dialog open={dialogoNuevaAbierto} onOpenChange={setDialogoNuevaAbierto}>
|
||||
<DialogTrigger asChild>
|
||||
<Button onClick={() => onNuevoIngreso ? onNuevoIngreso() : setDialogoNuevaAbierto(true)}>
|
||||
<Button variant="outline" onClick={() => onNuevoIngreso ? onNuevoIngreso() : setDialogoNuevaAbierto(true)}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Nuevo Ingreso
|
||||
</Button>
|
||||
@@ -202,7 +202,7 @@ export function Internaciones({
|
||||
return p ? `${p.apellido}, ${p.nombre} — DNI: ${p.dni}` : '';
|
||||
})()}
|
||||
</Badge>
|
||||
<Button size="sm" variant="ghost" onClick={() => setPacienteSeleccionado('')}>Cambiar</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => setPacienteSeleccionado('')}>Cambiar</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -257,7 +257,7 @@ export function Internaciones({
|
||||
placeholder="Nombre del médico ingresante"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
className="w-full"
|
||||
onClick={handleIniciarInternacion}
|
||||
disabled={!pacienteSeleccionado || !camaSeleccionada || !motivoConsulta || !enfermedadActual || !medicoIngresante}
|
||||
@@ -424,7 +424,7 @@ export function Internaciones({
|
||||
placeholder="Ingrese el diagnóstico de egreso..."
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
className="w-full"
|
||||
onClick={handleFinalizarInternacion}
|
||||
disabled={!fechaEgreso || !diagnosticoEgreso || !motivoEgreso}
|
||||
@@ -437,7 +437,7 @@ export function Internaciones({
|
||||
</Dialog>
|
||||
)}
|
||||
|
||||
<Button onClick={() => { if (typeof onVerHC === 'function') onVerHC(internacion.id); }}>Ver HC</Button>
|
||||
<Button variant="outline" onClick={() => { if (typeof onVerHC === 'function') onVerHC(internacion.id); }}>Ver HC</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
@@ -188,14 +188,14 @@ return (
|
||||
{camas.filter(c => c.estado === 'Ocupada').length} Ocupadas
|
||||
</Badge>
|
||||
<div className="ml-4 flex items-center gap-2 flex-wrap sm:flex-nowrap">
|
||||
<Button onClick={() => {
|
||||
<Button variant="outline" onClick={() => {
|
||||
setEditingAreaId(null);
|
||||
setAreaNombre('');
|
||||
setAreaDialogOpen(true);
|
||||
}} className="text-xs px-2 py-1 sm:text-sm sm:px-4 sm:py-2">
|
||||
Administrar Áreas
|
||||
</Button>
|
||||
<Button onClick={() => {
|
||||
<Button variant="outline" onClick={() => {
|
||||
setEditingBed(null);
|
||||
setBedNumero('');
|
||||
setBedTipo('General');
|
||||
@@ -327,7 +327,7 @@ return (
|
||||
{cama.estado === 'Disponible' && (
|
||||
<Dialog open={dialogoAbierto} onOpenChange={setDialogoAbierto}>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
className="w-full"
|
||||
onClick={() => {
|
||||
setCamaSeleccionada(cama);
|
||||
@@ -398,7 +398,7 @@ return (
|
||||
placeholder="Nombre del médico..."
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
className="w-full"
|
||||
onClick={handleOcuparCama}
|
||||
disabled={!pacienteSeleccionado || !diagnostico || !enfermedadActual || !medico}
|
||||
@@ -491,7 +491,7 @@ return (
|
||||
<Button size="sm" variant="outline" onClick={() => setAreaDialogOpen(false)}>
|
||||
<X className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button size="sm" onClick={() => {
|
||||
<Button size="sm" variant="outline" onClick={() => {
|
||||
if (!areaNombre.trim()) return alert('Nombre requerido');
|
||||
if (editingAreaId) onActualizarArea(editingAreaId, { nombre: areaNombre });
|
||||
else onAgregarArea({ nombre: areaNombre });
|
||||
@@ -507,10 +507,10 @@ return (
|
||||
<div key={a.id} className="flex items-center justify-between">
|
||||
<div>{a.nombre}</div>
|
||||
<div className="flex gap-1">
|
||||
<Button size="sm" variant="ghost" onClick={() => { setEditingAreaId(a.id); setAreaNombre(a.nombre); }}>
|
||||
<Button size="sm" variant="outline" onClick={() => { setEditingAreaId(a.id); setAreaNombre(a.nombre); }}>
|
||||
<Edit2 className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button size="sm" variant="ghost" className="text-red-600" onClick={() => { if (confirm('Eliminar área?')) onEliminarArea(a.id); }}>
|
||||
<Button size="sm" variant="outline" className="text-red-600" onClick={() => { if (confirm('Eliminar área?')) onEliminarArea(a.id); }}>
|
||||
<Trash className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
@@ -568,8 +568,8 @@ return (
|
||||
Eliminar
|
||||
</Button>
|
||||
)}
|
||||
<Button onClick={() => setBedDialogOpen(false)}><X className="h-4 w-4 mr-2" />Cancelar</Button>
|
||||
<Button onClick={() => {
|
||||
<Button variant="outline" onClick={() => setBedDialogOpen(false)}><X className="h-4 w-4 mr-2" />Cancelar</Button>
|
||||
<Button variant="outline" onClick={() => {
|
||||
if (!bedNumero.trim()) return alert('Número requerido');
|
||||
if (editingBed) {
|
||||
onActualizarCama(editingBed.id, { numero: bedNumero, tipo: bedTipo, areaId: bedAreaId });
|
||||
|
||||
@@ -147,7 +147,7 @@ export function Pacientes({
|
||||
</div>
|
||||
<Dialog open={dialogoAbierto} onOpenChange={setDialogoAbierto}>
|
||||
<DialogTrigger asChild>
|
||||
<Button onClick={resetFormulario}>
|
||||
<Button variant="outline" onClick={resetFormulario}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Nuevo Paciente
|
||||
</Button>
|
||||
@@ -299,7 +299,7 @@ export function Pacientes({
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button
|
||||
<Button variant="outline"
|
||||
onClick={handleGuardar}
|
||||
disabled={!nombre || !apellido || !dni || !fechaNacimiento}
|
||||
>
|
||||
@@ -441,7 +441,7 @@ export function Pacientes({
|
||||
{busqueda ? 'No se encontraron pacientes con esa búsqueda' : 'No hay pacientes registrados'}
|
||||
</p>
|
||||
{!busqueda && (
|
||||
<Button className="mt-4" onClick={() => setDialogoAbierto(true)}>
|
||||
<Button variant="outline" className="mt-4" onClick={() => setDialogoAbierto(true)}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Agregar primer paciente
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user