"use client" import { useState, useEffect } from "react" import OrderStats from "./order-stats" import QuickActions from "./quick-actions" import RecentActivity from "./recent-activity" import { WidgetSettings } from "./widget-settings" import { WidgetSettingsModal } from "./widget-settings-modal" import { DashboardEditor } from "./dashboard-editor" import { DraggableWidget } from "./draggable-widget" import { CommandPalette } from "./command-palette" import RevenueWidget from "./revenue-widget" import LowStockWidget from "./low-stock-widget" import RecentCustomersWidget from "./recent-customers-widget" import { ProductPeek } from "./product-peek" import PendingChatsWidget from "./pending-chats-widget" import { getGreeting } from "@/lib/utils/general" import { statsConfig } from "@/config/dashboard" import { getRandomQuote } from "@/config/quotes" import type { OrderStatsData } from "@/lib/types" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card" import { ShoppingCart, RefreshCcw, ArrowRight } from "lucide-react" import { Button } from "@/components/common/button" import { useToast } from "@/components/common/use-toast" import { Skeleton } from "@/components/common/skeleton" import { clientFetch } from "@/lib/api" import { motion } from "framer-motion" import Link from "next/link" import { useWidgetLayout } from "@/lib/hooks/useWidgetLayout" import type { TopProduct, WidgetConfig } from "@/lib/types/dashboard" interface ContentProps { username: string orderStats: OrderStatsData } // TopProduct interface moved to @/lib/types/dashboard export default function Content({ username, orderStats }: ContentProps) { const [greeting, setGreeting] = useState(""); const [topProducts, setTopProducts] = useState([]); const [loading, setLoading] = useState(true); const [errorQuery, setErrorQuery] = useState(false); const [selectedProductId, setSelectedProductId] = useState(null); const [isProductPeekOpen, setIsProductPeekOpen] = useState(false); const [trends, setTrends] = useState([]); const handleProductPeek = (id: string) => { setSelectedProductId(id); setIsProductPeekOpen(true); }; const { toast } = useToast(); const { widgets, toggleWidget, moveWidget, reorderWidgets, resetLayout, isWidgetVisible, updateWidgetSettings } = useWidgetLayout(); const [configuredWidget, setConfiguredWidget] = useState(null); // Initialize with a default quote to match server-side rendering, then randomize on client const [randomQuote, setRandomQuote] = useState({ text: "Loading wisdom...", author: "..." }); useEffect(() => { // Determine quote on client-side to avoid hydration mismatch setRandomQuote(getRandomQuote()); }, []); const fetchTopProducts = async () => { try { setLoading(true); const data = await clientFetch('/orders/top-products'); setTopProducts(data); } catch (err) { console.error("Error fetching top products:", err); setErrorQuery(true); } finally { setLoading(false); } }; const fetchTrends = async () => { try { const data = await clientFetch('/analytics/revenue-trends?period=30'); if (Array.isArray(data)) { setTrends(data); } } catch (err) { console.error("Error fetching trends:", err); } }; const handleRetry = () => { fetchTopProducts(); }; const renderWidget = (widget: WidgetConfig) => { switch (widget.id) { case "quick-actions": return (

Quick Actions

); case "overview": return (

Overview

{statsConfig.map((stat, index) => { const colors = ["#8884d8", "#10b981", "#3b82f6", "#f59e0b"]; const val = Number(orderStats[stat.key as keyof OrderStatsData]) || 0; // Map real trend data if available, otherwise fallback to empty (or subtle random if just started) let trendData = trends.map(t => ({ value: stat.key === "revenue" ? t.revenue : t.orders })).slice(-12); // Last 12 points // Fallback for demo/new stores if no trends yet if (trendData.length === 0) { trendData = Array.from({ length: 12 }, (_, i) => ({ value: Math.max(0, val * (0.8 + Math.random() * 0.4 + (i / 20))) })); } return ( ); })}
); case "recent-activity": return (

Recent Activity

); case "top-products": return (

Top Performing Listings

Top Performing Listings Your products with the highest sales volume
{errorQuery && ( )}
{loading ? (
{[...Array(5)].map((_, i) => (
))}
) : errorQuery ? (
Failed to load product insights
) : topProducts.length === 0 ? (

Begin your sales journey

Your top performing listings will materialize here as you receive orders.

) : (
{topProducts.map((product, index) => ( handleProductPeek(product.id)} >
{!product.image && ( )}

{product.name}

{product.currentStock ?? 0} Stock
{product.count} Sold
))}
)}
); case "revenue-chart": return ; case "low-stock": return ; case "recent-customers": return ; case "pending-chats": return ; default: return null; } }; useEffect(() => { setGreeting(getGreeting()); fetchTopProducts(); fetchTrends(); }, []); return (

{greeting}, {username}!

"{randomQuote.text}" — {randomQuote.author}

setConfiguredWidget(widget)} />
{ }} onReorder={reorderWidgets} onReset={resetLayout} >
{widgets.map((widget) => { if (!widget.visible) return null; return ( setConfiguredWidget(widget)} onToggleVisibility={() => toggleWidget(widget.id)} > {renderWidget(widget)} ); })}
{/* Widget Settings Modal */} !open && setConfiguredWidget(null)} onSave={(widgetId, settings) => { updateWidgetSettings(widgetId, settings); }} />
); }