"use client"; import type { ComponentType, ReactNode } from "react"; import { useCallback, useMemo, useRef, useState } from "react"; import { Responsive, WidthProvider } from "react-grid-layout/legacy"; import type { DashboardGridWidget, DashboardLayoutItem } from "@/lib/dashboard-layout"; export type DashboardGridProps = { widgets: DashboardGridWidget[]; editMode: boolean; activeMenuWidgetId?: string | null; renderWidget: (widget: DashboardGridWidget) => ReactNode; onLayoutChange: (layout: DashboardLayoutItem[]) => void; }; const ResponsiveGridLayout = WidthProvider(Responsive) as ComponentType; const BREAKPOINTS = { lg: 1200, md: 900, sm: 600, xs: 0 }; const COLS = { lg: 48, md: 24, sm: 12, xs: 6 }; function clamp(value: number, min: number, max: number): number { return Math.max(min, Math.min(max, value)); } function getWidgetMinimumSize(widget: DashboardGridWidget): { minW: number; minH: number } { if (widget.type === "search") { return { minW: 8, minH: 5 }; } if (widget.type === "clock") { return { minW: 4, minH: 4 }; } if (widget.type === "calendar") { return { minW: 8, minH: 6 }; } if (widget.type === "calculator") { return { minW: 8, minH: 6 }; } if (widget.type === "note") { return { minW: 4, minH: 5 }; } return { minW: 4, minH: 4 }; } function widgetsToLayout(widgets: DashboardGridWidget[]): DashboardLayoutItem[] { return widgets.map((widget) => { const minimumSize = getWidgetMinimumSize(widget); const width = clamp(widget.w, minimumSize.minW, 48); const height = clamp(widget.h, minimumSize.minH, 180); const x = clamp(widget.x, 0, 48 - width); const y = clamp(widget.y, 0, 10000); return { i: widget.id, x, y, w: width, h: height, minW: minimumSize.minW, minH: minimumSize.minH, maxW: 48, maxH: 180 }; }); } function normalizeLayout(layout: readonly DashboardLayoutItem[]): DashboardLayoutItem[] { return layout.map((item) => ({ i: String(item.i), x: Number.isFinite(item.x) ? item.x : 0, y: Number.isFinite(item.y) ? item.y : 0, w: Number.isFinite(item.w) ? item.w : 1, h: Number.isFinite(item.h) ? item.h : 1, minW: item.minW, minH: item.minH, maxW: item.maxW, maxH: item.maxH })); } export default function DashboardGrid({ widgets, editMode, activeMenuWidgetId = null, renderWidget, onLayoutChange }: DashboardGridProps) { const [currentBreakpoint, setCurrentBreakpoint] = useState("lg"); const breakpointRef = useRef("lg"); const isDesktop = currentBreakpoint === "lg"; const layouts = useMemo(() => ({ lg: widgetsToLayout(widgets) }), [widgets]); const handleBreakpointChange = useCallback((breakpoint: string) => { breakpointRef.current = breakpoint; setCurrentBreakpoint(breakpoint); }, []); const handleLayoutChange = useCallback((layout: DashboardLayoutItem[]) => { if (breakpointRef.current === "lg") { onLayoutChange(normalizeLayout(layout)); } }, [onLayoutChange]); return (
{widgets.length === 0 ? (

Keine Widgets aktiv

Schalte den Bearbeitungsmodus ein und füge Widgets hinzu.

) : null} {widgets.length > 0 ? ( {widgets.map((widget) => (
{renderWidget(widget)}
))}
) : null}
); }