Files
aerzte/components/AppointmentList.tsx
T
admin 9499011a3a Termine-Tab nur offene Termine, Spalten links, Formular 60% Breite
- Termine-Tab (/) zeigt in der Liste nur noch offene (nicht erledigte)
  Termine; Überschrift entsprechend "Offene Termine"
- Spalten Arzt, Fachrichtung und Bemerkungen linksbündig (Header + Zellen)
- Eingabe-Panel (AppointmentForm) auf 60% Breite reduziert und zentriert

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 18:47:02 +02:00

135 lines
4.5 KiB
TypeScript

'use client';
import { Appointment } from '@/types/appointment';
interface AppointmentListProps {
appointments: Appointment[];
onToggleDone?: (id: string) => void;
onEdit?: (appointment: Appointment) => void;
onDelete?: (id: string) => void;
}
const weekdays = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
const formatDate = (iso: string) => {
const d = new Date(iso);
const day = String(d.getDate()).padStart(2, '0');
const m = String(d.getMonth() + 1).padStart(2, '0');
return `${day}.${m}.${d.getFullYear()}`;
};
const formatTime = (iso: string) => {
const d = new Date(iso);
const h = String(d.getHours()).padStart(2, '0');
const min = String(d.getMinutes()).padStart(2, '0');
return `${h}:${min}`;
};
const getWeekday = (iso: string) => weekdays[new Date(iso).getDay()];
export default function AppointmentList({
appointments,
onToggleDone,
onEdit,
onDelete,
}: AppointmentListProps) {
const hasActions = Boolean(onEdit || onDelete);
if (appointments.length === 0) {
return (
<div className="text-center py-8 text-gray-500">
Keine Termine vorhanden.
</div>
);
}
// Erledigte Einträge hinter die offenen schieben; innerhalb der Gruppen
// aufsteigend nach Termin sortieren.
const sorted = [...appointments].sort((a, b) => {
if (a.erledigt !== b.erledigt) return a.erledigt ? 1 : -1;
return new Date(a.termin).getTime() - new Date(b.termin).getTime();
});
return (
<div className="overflow-x-auto">
<table className="w-full border-collapse">
<thead>
<tr className="bg-[#CCCCFF] border-b-2 border-gray-400">
<th className="p-2 text-center">Erledigt</th>
<th className="p-2 text-left">Arzt</th>
<th className="p-2 text-left">Fachrichtung</th>
<th className="p-2 text-center">Datum</th>
<th className="p-2 text-center">Tag</th>
<th className="p-2 text-center">Zeit</th>
<th className="p-2 text-left">Bemerkungen</th>
{hasActions && <th className="p-2 text-center">Aktion</th>}
</tr>
</thead>
<tbody>
{sorted.map((app, index) => (
<tr
key={app.id}
onClick={onEdit ? () => onEdit(app) : undefined}
className={`border-b border-gray-300 hover:bg-gray-100 ${
onEdit ? 'cursor-pointer' : ''
} ${
app.erledigt
? 'bg-green-50 text-gray-400'
: index % 2 === 0
? 'bg-white'
: 'bg-gray-50'
}`}
>
<td
className="p-2 text-center"
onClick={(e) => e.stopPropagation()}
>
<input
type="checkbox"
className={`w-4 h-4 ${onToggleDone ? 'cursor-pointer' : ''}`}
checked={app.erledigt}
disabled={!onToggleDone}
onChange={
onToggleDone ? () => onToggleDone(app.id) : undefined
}
/>
</td>
<td className="p-2 text-left font-medium">{app.arztName}</td>
<td className="p-2 text-left">{app.arztArt || '-'}</td>
<td className="p-2 text-center">{formatDate(app.termin)}</td>
<td className="p-2 text-center">{getWeekday(app.termin)}</td>
<td className="p-2 text-center">{formatTime(app.termin)}</td>
<td className="p-2 text-left">{app.bemerkungen || '-'}</td>
{hasActions && (
<td
className="p-2 text-center"
onClick={(e) => e.stopPropagation()}
>
<div className="flex gap-2 justify-center">
{onEdit && (
<button
onClick={() => onEdit(app)}
className="text-blue-600 hover:text-blue-800 text-sm"
>
Editieren
</button>
)}
{onDelete && (
<button
onClick={() => onDelete(app.id)}
className="text-red-600 hover:text-red-800 text-sm"
>
Löschen
</button>
)}
</div>
</td>
)}
</tr>
))}
</tbody>
</table>
</div>
);
}