"use client"; import { Suspense, useEffect, useState } from "react"; import { useSearchParams } from "next/navigation"; import { useLanguage } from "@/lib/i18n-context"; interface AnalyticsPoint { label: string; value: number; } interface DashboardOrder { id: string; product: string; sku: string; customer: string; location: string; date: string; amount: number; status: string; } interface SellerDashboardPayload { metrics: { totalProducts: number; soldProducts: number; refundProducts: number; internationalProducts: number; localProducts: number; }; analytics: AnalyticsPoint[]; recentOrders: DashboardOrder[]; } interface ProductSearchRow { id: string; name: string; market?: string | null; state?: string | null; status?: string | null; totalStock?: number | null; } interface WarehouseSearchRow { id: string; name: string | null; address: string | null; city: string | null; province: string | null; country: string | null; warehouseType: string | null; } function getToken() { if (typeof window === "undefined") return ""; return sessionStorage.getItem("token") || localStorage.getItem("token") || ""; } function formatCurrency(value: number) { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 2, }).format(value || 0); } function statusColor(status: string) { const normalized = status.toLowerCase(); if (normalized.includes("ship")) return "text-secondary bg-secondary/10"; if (normalized.includes("deliver")) return "text-tertiary bg-tertiary/10"; if (normalized.includes("cancel") || normalized.includes("reject")) return "text-error bg-error/10"; return "text-primary bg-primary/10"; } function DashboardContent() { const searchParams = useSearchParams(); const { t } = useLanguage(); const d = t.dashboard.overview; const [data, setData] = useState(null); const [productResults, setProductResults] = useState([]); const [warehouseResults, setWarehouseResults] = useState([]); const [searchLoading, setSearchLoading] = useState(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); useEffect(() => { async function load() { setLoading(true); setError(""); try { const res = await fetch("/api/dashboard/seller", { headers: { "x-auth-token": getToken() }, }); const result = await res.json(); if (!res.ok) { throw new Error(result?.responseDesc || result?.error || "Failed to load dashboard"); } setData(result); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load dashboard"); } finally { setLoading(false); } } load(); }, []); const analytics = data?.analytics || []; const maxAnalytics = Math.max(...analytics.map((item) => item.value), 1); const rawDashboardQuery = (searchParams.get("q") || "").trim(); const dashboardQuery = rawDashboardQuery.toLowerCase(); const filteredOrders = (data?.recentOrders || []).filter((order) => { if (!dashboardQuery) { return true; } return [ order.product, order.sku, order.customer, order.location, order.date, order.status, String(order.amount), ] .join(" ") .toLowerCase() .includes(dashboardQuery); }); const totalRevenue = filteredOrders.reduce((sum, item) => sum + item.amount, 0); const totalOrders = filteredOrders.length; useEffect(() => { async function loadSearchResults() { if (!dashboardQuery) { setProductResults([]); setWarehouseResults([]); setSearchLoading(false); return; } setSearchLoading(true); try { const [productsRes, warehousesRes] = await Promise.all([ fetch("/api/products?page=1&size=100", { headers: { "x-auth-token": getToken() }, }), fetch("/api/products/warehouses?page=1&size=100", { headers: { "x-auth-token": getToken() }, }), ]); const [productsResult, warehousesResult] = await Promise.all([ productsRes.json().catch(() => ({})), warehousesRes.json().catch(() => ({})), ]); const products: ProductSearchRow[] = Array.isArray(productsResult?.rows) ? productsResult.rows : Array.isArray(productsResult?.data?.rows) ? productsResult.data.rows : []; const warehouses: WarehouseSearchRow[] = Array.isArray(warehousesResult?.rows) ? warehousesResult.rows : Array.isArray(warehousesResult?.data) ? warehousesResult.data : []; setProductResults( products.filter((item) => [item.name, item.market, item.state, item.status, String(item.totalStock ?? "")] .join(" ") .toLowerCase() .includes(dashboardQuery) ) ); setWarehouseResults( warehouses.filter((item) => [ item.name || "", item.address || "", item.city || "", item.province || "", item.country || "", item.warehouseType || "", ] .join(" ") .toLowerCase() .includes(dashboardQuery) ) ); } catch { setProductResults([]); setWarehouseResults([]); } finally { setSearchLoading(false); } } loadSearchResults(); }, [dashboardQuery]); return (

{d.title}

{d.subtitle}

{dashboardQuery ? (

Dashboard Search

Hasil pencarian untuk "{rawDashboardQuery}"

{searchLoading ? "Mencari data..." : `${filteredOrders.length} order, ${productResults.length} produk, ${warehouseResults.length} warehouse`}

Orders

{filteredOrders.slice(0, 4).map((order) => (

{order.product}

{order.customer} · {order.location}

))} {!searchLoading && filteredOrders.length === 0 ? (

Tidak ada order yang cocok.

) : null}

Products

Lihat semua
{productResults.slice(0, 4).map((product) => (

{product.name}

{product.market || product.state || product.status || "Produk"}

))} {!searchLoading && productResults.length === 0 ? (

Tidak ada produk yang cocok.

) : null}

Warehouses

Lihat semua
{warehouseResults.slice(0, 4).map((warehouse) => (

{warehouse.name || "Tanpa nama"}

{[warehouse.city, warehouse.province, warehouse.country].filter(Boolean).join(", ") || warehouse.address || "Warehouse"}

))} {!searchLoading && warehouseResults.length === 0 ? (

Tidak ada warehouse yang cocok.

) : null}
) : null}

{d.totalProducts}

{loading ? "—" : (data?.metrics.totalProducts ?? 0).toLocaleString("en-US")}

trending_up {loading ? "Loading..." : `${data?.metrics.internationalProducts ?? 0} international`}

{d.totalBuyers}

{loading ? "—" : (data?.metrics.soldProducts ?? 0).toLocaleString("en-US")}

group {loading ? "Loading..." : `${data?.metrics.localProducts ?? 0} local`}

{d.refunds}

{loading ? "—" : (data?.metrics.refundProducts ?? 0).toLocaleString("en-US")}

history {loading ? "Loading..." : `${totalOrders} recent orders`}

{d.ordersAnalytics}

{d.ordersSubtitle}

{d.last30Days}
{loading ? (
Loading analytics...
) : analytics.length === 0 ? (
No analytics available
) : ( analytics.map((item, i) => (
)) )}
{(analytics.length ? analytics : [{ label: `${d.wk} 1`, value: 0 }]).slice(0, 4).map((item) => ( {item.label} ))}

{d.earnings}

{loading ? "—" : formatCurrency(totalRevenue)} {d.grossRevenue}
{[ { color: "bg-primary", label: d.directSales, value: `${data?.metrics.totalProducts ?? 0}` }, { color: "bg-secondary", label: d.retailPartners, value: `${data?.metrics.soldProducts ?? 0}` }, { color: "bg-tertiary", label: d.affiliates, value: `${data?.metrics.refundProducts ?? 0}` }, ].map((item) => (
{item.label}
{item.value}
))}

{d.recentOrders}

{dashboardQuery ? (

Menampilkan hasil pencarian untuk "{searchParams.get("q")}"

) : null}
{filteredOrders.map((order) => ( ))} {!loading && !error && filteredOrders.length === 0 ? ( ) : null}
{d.productDetails} {d.customer} {d.transactionDate} {d.amount} {d.status} {d.action}
inventory_2

{order.product}

SKU: {order.sku || "—"}

{order.customer}

{order.location}

{order.date} {formatCurrency(order.amount)} {order.status}
{dashboardQuery ? "Tidak ada order yang cocok dengan pencarian Anda." : "No recent orders available."}
{error ? (
{error}
) : null}
); } export default function DashboardPage() { return ( ); }