fix: add array guards to all frontend components consuming API responses
Prevents "M.forEach is not a function" crashes when API returns error objects or unexpected shapes instead of arrays. Guards all useQuery consumers with Array.isArray checks and safe defaults for object props. Files fixed: DeadlineList, AppointmentList, TenantSwitcher, DeadlineTrafficLights, UpcomingTimeline, CaseOverviewGrid, AISummaryCard, TeamSettings, and all page-level components (dashboard, cases, fristen, termine, ai/extract).
This commit is contained in:
@@ -9,7 +9,9 @@ interface Props {
|
||||
|
||||
function generateSummary(data: DashboardData): string {
|
||||
const parts: string[] = [];
|
||||
const { deadline_summary: ds, case_summary: cs, upcoming_deadlines: ud } = data;
|
||||
const ds = data.deadline_summary ?? { overdue_count: 0, due_this_week: 0, due_next_week: 0, ok_count: 0 };
|
||||
const cs = data.case_summary ?? { active_count: 0, new_this_month: 0, closed_count: 0 };
|
||||
const ud = Array.isArray(data.upcoming_deadlines) ? data.upcoming_deadlines : [];
|
||||
|
||||
// Deadline urgency
|
||||
if (ds.overdue_count > 0) {
|
||||
|
||||
@@ -8,24 +8,25 @@ interface Props {
|
||||
}
|
||||
|
||||
export function CaseOverviewGrid({ data }: Props) {
|
||||
const safe = data ?? { active_count: 0, new_this_month: 0, closed_count: 0 };
|
||||
const items = [
|
||||
{
|
||||
label: "Aktive Akten",
|
||||
value: data.active_count,
|
||||
value: safe.active_count ?? 0,
|
||||
icon: FolderOpen,
|
||||
color: "text-blue-600",
|
||||
bg: "bg-blue-50",
|
||||
},
|
||||
{
|
||||
label: "Neu (Monat)",
|
||||
value: data.new_this_month,
|
||||
value: safe.new_this_month ?? 0,
|
||||
icon: FolderPlus,
|
||||
color: "text-violet-600",
|
||||
bg: "bg-violet-50",
|
||||
},
|
||||
{
|
||||
label: "Abgeschlossen",
|
||||
value: data.closed_count,
|
||||
value: safe.closed_count ?? 0,
|
||||
icon: Archive,
|
||||
color: "text-neutral-500",
|
||||
bg: "bg-neutral-50",
|
||||
|
||||
@@ -31,24 +31,25 @@ interface Props {
|
||||
}
|
||||
|
||||
export function DeadlineTrafficLights({ data, onFilter }: Props) {
|
||||
const safe = data ?? { overdue_count: 0, due_this_week: 0, due_next_week: 0, ok_count: 0 };
|
||||
const cards = [
|
||||
{
|
||||
key: "overdue" as const,
|
||||
label: "Überfällig",
|
||||
count: data.overdue_count,
|
||||
count: safe.overdue_count ?? 0,
|
||||
icon: AlertTriangle,
|
||||
bg: "bg-red-50",
|
||||
border: "border-red-200",
|
||||
iconColor: "text-red-500",
|
||||
countColor: "text-red-700",
|
||||
labelColor: "text-red-600",
|
||||
ring: data.overdue_count > 0 ? "ring-2 ring-red-300 ring-offset-1" : "",
|
||||
pulse: data.overdue_count > 0,
|
||||
ring: (safe.overdue_count ?? 0) > 0 ? "ring-2 ring-red-300 ring-offset-1" : "",
|
||||
pulse: (safe.overdue_count ?? 0) > 0,
|
||||
},
|
||||
{
|
||||
key: "this_week" as const,
|
||||
label: "Diese Woche",
|
||||
count: data.due_this_week,
|
||||
count: safe.due_this_week ?? 0,
|
||||
icon: Clock,
|
||||
bg: "bg-amber-50",
|
||||
border: "border-amber-200",
|
||||
@@ -61,7 +62,7 @@ export function DeadlineTrafficLights({ data, onFilter }: Props) {
|
||||
{
|
||||
key: "ok" as const,
|
||||
label: "Im Zeitplan",
|
||||
count: data.ok_count + data.due_next_week,
|
||||
count: (safe.ok_count ?? 0) + (safe.due_next_week ?? 0),
|
||||
icon: CheckCircle,
|
||||
bg: "bg-emerald-50",
|
||||
border: "border-emerald-200",
|
||||
|
||||
@@ -21,13 +21,16 @@ function formatDayLabel(date: Date): string {
|
||||
}
|
||||
|
||||
export function UpcomingTimeline({ deadlines, appointments }: Props) {
|
||||
const safeDeadlines = Array.isArray(deadlines) ? deadlines : [];
|
||||
const safeAppointments = Array.isArray(appointments) ? appointments : [];
|
||||
|
||||
const items: TimelineItem[] = [
|
||||
...deadlines.map((d) => ({
|
||||
...safeDeadlines.map((d) => ({
|
||||
type: "deadline" as const,
|
||||
date: parseISO(d.due_date),
|
||||
data: d,
|
||||
})),
|
||||
...appointments.map((a) => ({
|
||||
...safeAppointments.map((a) => ({
|
||||
type: "appointment" as const,
|
||||
date: parseISO(a.start_at),
|
||||
data: a,
|
||||
|
||||
Reference in New Issue
Block a user