| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import { Card, CardContent, CardHeader } from "@/components/ui/card";
- import { Button } from "@/components/ui/button";
- import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
- import { AppointmentStatusBadge } from "./AppointmentStatusBadge";
- import { Calendar, Clock, User, FileText } from "lucide-react";
- import { format } from "date-fns";
- import { es } from "date-fns/locale";
- import Link from "next/link";
- import type { Appointment } from "@/types/appointments";
- interface AppointmentCardProps {
- appointment: Appointment;
- userRole: "PATIENT" | "DOCTOR" | "ADMIN";
- onApprove?: (id: string) => void;
- onReject?: (id: string) => void;
- onCancel?: (id: string) => void;
- }
- export const AppointmentCard = ({
- appointment,
- userRole,
- onApprove,
- onReject,
- onCancel,
- }: AppointmentCardProps) => {
- const fecha = new Date(appointment.fechaSolicitada);
- const otherUser = userRole === "PATIENT" ? appointment.medico : appointment.paciente;
-
- return (
- <Card className="hover:shadow-md transition-shadow">
- <CardHeader className="pb-3">
- <div className="flex items-start justify-between">
- <div className="flex items-center gap-3">
- {otherUser && (
- <Avatar>
- <AvatarImage src={otherUser.profileImage || undefined} />
- <AvatarFallback>
- {otherUser.name[0]}{otherUser.lastname[0]}
- </AvatarFallback>
- </Avatar>
- )}
- <div>
- <h3 className="font-semibold text-lg">
- {otherUser
- ? `${otherUser.name} ${otherUser.lastname}`
- : userRole === "DOCTOR"
- ? "Sin asignar"
- : "Médico por asignar"}
- </h3>
- <div className="flex items-center gap-2 text-sm text-muted-foreground mt-1">
- <Calendar className="h-4 w-4" />
- <span>{format(fecha, "PPP", { locale: es })}</span>
- <Clock className="h-4 w-4 ml-2" />
- <span>{format(fecha, "p", { locale: es })}</span>
- </div>
- </div>
- </div>
- <AppointmentStatusBadge status={appointment.estado} />
- </div>
- </CardHeader>
-
- <CardContent className="space-y-3">
- <div className="flex items-start gap-2 text-sm">
- <FileText className="h-4 w-4 mt-0.5 text-muted-foreground" />
- <div>
- <p className="font-medium">Motivo de consulta:</p>
- <p className="text-muted-foreground">{appointment.motivoConsulta}</p>
- </div>
- </div>
- {appointment.motivoRechazo && (
- <div className="bg-destructive/10 p-3 rounded-md text-sm">
- <p className="font-medium text-destructive">Motivo de rechazo:</p>
- <p className="text-muted-foreground mt-1">{appointment.motivoRechazo}</p>
- </div>
- )}
- <div className="flex gap-2 pt-2">
- {userRole === "DOCTOR" && appointment.estado === "PENDIENTE" && (
- <>
- <Button
- onClick={() => onApprove?.(appointment.id)}
- className="flex-1"
- size="sm"
- >
- Aprobar
- </Button>
- <Button
- onClick={() => onReject?.(appointment.id)}
- variant="outline"
- className="flex-1"
- size="sm"
- >
- Rechazar
- </Button>
- </>
- )}
- {userRole === "PATIENT" && appointment.estado === "PENDIENTE" && (
- <Button
- onClick={() => onCancel?.(appointment.id)}
- variant="outline"
- className="flex-1"
- size="sm"
- >
- Cancelar cita
- </Button>
- )}
- {appointment.estado === "APROBADA" && (
- <Button asChild className="flex-1" size="sm">
- <Link href={`/appointments/${appointment.id}/meet`}>
- Unirse a la consulta
- </Link>
- </Button>
- )}
- <Button asChild variant="outline" size="sm">
- <Link href={`/appointments/${appointment.id}`}>
- Ver detalles
- </Link>
- </Button>
- </div>
- </CardContent>
- </Card>
- );
- };
|