import React, { useState, useEffect } from "react"; import { base44 } from "@/api/base44Client"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Settings, GripVertical, X, Plus, Eye, EyeOff, Info, Save, RotateCcw, Sparkles } from "lucide-react"; import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd"; import { useToast } from "@/components/ui/use-toast"; import { motion, AnimatePresence } from "framer-motion"; export default function DashboardCustomizer({ user, availableWidgets = [], currentLayout = [], onLayoutChange, dashboardType = "default" // admin, client, vendor, operator, etc }) { const [isOpen, setIsOpen] = useState(false); const [showHowItWorks, setShowHowItWorks] = useState(false); const [visibleWidgets, setVisibleWidgets] = useState([]); const [hiddenWidgets, setHiddenWidgets] = useState([]); const [hasChanges, setHasChanges] = useState(false); const { toast } = useToast(); const queryClient = useQueryClient(); // Initialize widgets from user's saved layout or defaults useEffect(() => { const layoutKey = `dashboard_layout_${dashboardType}`; const savedLayout = user?.[layoutKey]; if (savedLayout?.widgets && savedLayout.widgets.length > 0) { const savedVisible = savedLayout.widgets .map(id => availableWidgets.find(w => w.id === id)) .filter(Boolean); setVisibleWidgets(savedVisible); const savedHidden = savedLayout.hidden_widgets || []; const hiddenWidgetsList = availableWidgets.filter(w => savedHidden.includes(w.id) ); setHiddenWidgets(hiddenWidgetsList); } else { // Default: all widgets visible in provided order setVisibleWidgets(availableWidgets); setHiddenWidgets([]); } }, [user, availableWidgets, isOpen, dashboardType]); // Save layout mutation const saveLayoutMutation = useMutation({ mutationFn: async (layoutData) => { const layoutKey = `dashboard_layout_${dashboardType}`; await base44.auth.updateMe({ [layoutKey]: layoutData }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['current-user'] }); queryClient.invalidateQueries({ queryKey: ['current-user-layout'] }); queryClient.invalidateQueries({ queryKey: ['current-user-client'] }); queryClient.invalidateQueries({ queryKey: ['current-user-vendor'] }); queryClient.invalidateQueries({ queryKey: ['current-user-operator'] }); toast({ title: "✅ Layout Saved", description: "Your dashboard layout has been updated", }); setHasChanges(false); if (onLayoutChange) { onLayoutChange(visibleWidgets); } setTimeout(() => { setIsOpen(false); }, 500); }, onError: () => { toast({ title: "❌ Save Failed", description: "Could not save your layout. Please try again.", variant: "destructive", }); } }); const handleDragEnd = (result) => { if (!result.destination) return; const { source, destination } = result; if (source.droppableId === "visible" && destination.droppableId === "visible") { const items = Array.from(visibleWidgets); const [reorderedItem] = items.splice(source.index, 1); items.splice(destination.index, 0, reorderedItem); setVisibleWidgets(items); setHasChanges(true); } }; const handleHideWidget = (widget) => { setVisibleWidgets(visibleWidgets.filter(w => w.id !== widget.id)); setHiddenWidgets([...hiddenWidgets, widget]); setHasChanges(true); }; const handleShowWidget = (widget) => { setHiddenWidgets(hiddenWidgets.filter(w => w.id !== widget.id)); setVisibleWidgets([...visibleWidgets, widget]); setHasChanges(true); }; const handleSave = () => { const layoutData = { widgets: visibleWidgets.map(w => w.id), hidden_widgets: hiddenWidgets.map(w => w.id), layout_version: "2.0" }; saveLayoutMutation.mutate(layoutData); }; const handleReset = () => { setVisibleWidgets(availableWidgets); setHiddenWidgets([]); setHasChanges(true); }; const handleOpenCustomizer = () => { setIsOpen(true); setShowHowItWorks(true); setHasChanges(false); }; const handleClose = () => { if (hasChanges) { if (window.confirm("You have unsaved changes. Are you sure you want to close?")) { setIsOpen(false); setHasChanges(false); } } else { setIsOpen(false); } }; return ( <> {/* Customize Button */} {/* Customizer Dialog */} Customize Your Dashboard Personalize your workspace by adding, removing, and reordering widgets {/* How It Works Banner */} {showHowItWorks && (

How it works

Drag widgets to reorder them

Hide widgets you don't need

Show hidden widgets to bring them back

)}
{/* Visible Widgets */}

Visible Widgets ({visibleWidgets.length})

{(provided, snapshot) => (
{visibleWidgets.length === 0 ? (

No visible widgets

Add widgets from the hidden section below!

) : ( visibleWidgets.map((widget, index) => ( {(provided, snapshot) => (

{widget.title}

{widget.description}

{widget.category}
)}
)) )} {provided.placeholder}
)}
{/* Hidden Widgets */} {hiddenWidgets.length > 0 && (

Hidden Widgets ({hiddenWidgets.length}) Click + to add

{hiddenWidgets.map((widget) => (

{widget.title}

{widget.description}

))}
)} {/* All Hidden Message */} {hiddenWidgets.length === 0 && visibleWidgets.length === availableWidgets.length && (

All widgets are visible on your dashboard!

)}
{/* Actions */}
{hasChanges && ( Unsaved Changes )}
); }