3import { useState, useEffect, Suspense } from "react";
4import { useSearchParams } from "next/navigation";
5import { Icon } from '@/contexts/IconContext';
7type TabId = "advisor" | "sales" | "inventory" | "customers" | "financial" | "staff" | "operational";
9function ReportsPageContent() {
10 const searchParams = useSearchParams();
11 const source = searchParams.get('source');
13 const [activeTab, setActiveTab] = useState<TabId>(() => {
14 return source === 'advisor' ? 'advisor' : 'sales';
17 // Update active tab when source parameter changes
19 if (source === 'advisor') {
20 setActiveTab('advisor');
25 { id: "advisor" as TabId, label: "Advisor Reports", icon: "lightbulb" },
26 { id: "sales" as TabId, label: "Sales Reports", icon: "trending_up" },
27 { id: "inventory" as TabId, label: "Inventory", icon: "inventory_2" },
28 { id: "customers" as TabId, label: "Customers", icon: "people" },
29 { id: "financial" as TabId, label: "Financial", icon: "account_balance" },
30 { id: "staff" as TabId, label: "Staff Performance", icon: "badge" },
31 { id: "operational" as TabId, label: "Operational", icon: "settings" },
35 <div className="p-6 min-h-screen bg-bg">
36 <div className="mb-6">
37 <h1 className="text-3xl font-bold text-text mb-2 flex items-center gap-2">
38 <Icon name="assessment" size={32} className="text-brand" />
41 <p className="text-muted">Comprehensive reporting across all business functions</p>
45 <div className="bg-surface rounded-lg shadow-sm mb-6">
46 <div className="border-b border-border">
47 <nav className="flex space-x-2 p-2 overflow-x-auto">
51 onClick={() => setActiveTab(tab.id)}
52 className={`flex items-center gap-2 px-4 py-3 rounded-lg whitespace-nowrap transition ${
54 ? "bg-brand text-surface font-semibold"
55 : "text-muted hover:bg-surface-2"
58 <Icon name={tab.icon} className="text-xl" />
59 <span>{tab.label}</span>
67 {activeTab === "advisor" && <AdvisorReports />}
68 {activeTab === "sales" && <SalesReports />}
69 {activeTab === "inventory" && <InventoryReports />}
70 {activeTab === "customers" && <CustomerReports />}
71 {activeTab === "financial" && <FinancialReports />}
72 {activeTab === "staff" && <StaffReports />}
73 {activeTab === "operational" && <OperationalReports />}
80function AdvisorReports() {
82 { name: "Possible Duplicate Customers", desc: "Identify potential duplicate customer records", path: "/pages/reports/advisor/duplicate-customers" },
83 { name: "Products Priced Low", desc: "Products with pricing below cost or threshold", path: "/pages/reports/advisor/products-priced-low" },
84 { name: "Duplicate PLU Codes", desc: "Products with identical PLU numbers", path: "/pages/reports/advisor/duplicate-plu" },
85 { name: "Duplicate Product Descriptions", desc: "Products with identical descriptions", path: "/pages/reports/advisor/duplicate-descriptions" },
86 { name: "Spelling Issues", desc: "Potential spelling errors in product names", path: "/pages/reports/advisor/spelling-issues" },
87 { name: "Missing Product Information", desc: "Products with incomplete details", path: "/pages/reports/advisor/missing-info" },
88 { name: "Inactive Products", desc: "Products with no recent sales activity", path: "/pages/reports/advisor/inactive-products" },
89 { name: "Stock Level Issues", desc: "Products with incorrect or negative stock", path: "/pages/reports/advisor/stock-issues" },
90 { name: "Customer Data Quality", desc: "Customers with missing or invalid information", path: "/pages/reports/advisor/customer-data-quality" },
91 { name: "Price Inconsistencies", desc: "Products with unusual price variations", path: "/pages/products/price-changes" },
92 { name: "Supplier Data Issues", desc: "Suppliers with missing or outdated information", path: "/pages/reports/advisor/supplier-issues" },
93 { name: "Security Recommendations", desc: "System security and access suggestions", path: "/pages/reports/advisor/security-recommendations" },
98 <div className="mb-6">
99 <div className="flex items-center gap-3 mb-3">
100 <Icon name="lightbulb" size={24} className="text-warning" />
101 <h2 className="text-2xl font-bold text-text">Advisor Reports</h2>
103 <p className="text-muted">
104 Automated insights and recommendations from your business data. These reports are generated
105 by the Advisor system which continuously analyzes your data for potential issues,
106 inconsistencies, and opportunities for improvement.
110 <div className="bg-info/10 border border-info/30 rounded-lg p-4 mb-6">
111 <div className="flex items-start gap-3">
112 <Icon name="info" size={20} className="text-info flex-shrink-0 mt-0.5" />
114 <p className="text-sm text-text mb-2">
115 <strong>From Advisor Page:</strong> Click on any report below to view detailed information.
116 To customize which categories are analyzed, visit the{' '}
117 <a href="/advisor" className="text-brand hover:underline">
121 <p className="text-sm text-muted">
122 The Advisor continuously monitors your business data across products, customers,
123 inventory, and operations to help you maintain data quality and identify issues early.
129 <ReportGrid reports={reports} />
134function SalesReports() {
136 { name: "Daily Sales Summary", desc: "Sales totals by day with trends", path: "/pages/reports/sales-reports" },
137 { name: "Sales by Store", desc: "Compare performance across locations", path: "/pages/reports/sales-reports/sales-by-store" },
138 { name: "Sales by Product", desc: "Top selling products and categories", path: "/pages/reports/sales-reports" },
139 { name: "Sales by Staff Member", desc: "Individual staff performance", path: "/pages/reports/sales-reports/sales-by-teller" },
140 { name: "Sales with Discounts", desc: "Analyze discount usage and impact", path: "/pages/reports/sales-reports/sales-with-discounts" },
141 { name: "Hourly Sales Analysis", desc: "Peak trading hours identification", path: "/pages/reports/sales-reports" },
142 { name: "Sales by Payment Type", desc: "Payment method breakdown", path: "/pages/reports/sales-reports/payment-list" },
143 { name: "Basket Size Analysis", desc: "Average transaction values", path: "/pages/reports/sales-reports/basket-sizes" },
144 { name: "Sales KPI Dashboard", desc: "Key performance indicators", path: "/pages/reports/sales-reports/sales-kpi" },
145 { name: "Lost Sales Report", desc: "Track refused or cancelled sales", path: "/pages/reports/sales-reports/lost-sales" },
148 return <ReportGrid reports={reports} />;
151function InventoryReports() {
153 { name: "Stock Levels Overview", desc: "Current stock across all locations", path: "/pages/products" },
154 { name: "Low Stock Alert", desc: "Items below reorder point", path: "/pages/products" },
155 { name: "Stock Movement", desc: "Product velocity and turnover", path: "/pages/products" },
156 { name: "Dead Stock Analysis", desc: "Slow-moving and obsolete items", path: "/pages/products" },
157 { name: "Shrinkage Report", desc: "Stock loss and discrepancies", path: "/pages/products/stocktake" },
158 { name: "Reorder Recommendations", desc: "Suggested purchase orders", path: "/purchase-orders" },
159 { name: "Stock Valuation", desc: "Total inventory value by location", path: "/pages/products" },
160 { name: "Supplier Performance", desc: "Delivery times and quality metrics", path: "/pages/suppliers" },
161 { name: "Price Changes History", desc: "Track pricing adjustments", path: "/pages/products/price-changes" },
164 return <ReportGrid reports={reports} />;
167function CustomerReports() {
169 { name: "Customer Database", desc: "Complete customer listing", path: "/pages/customers" },
170 { name: "Top Customers", desc: "Highest value customers by spend", path: "/pages/reports/sales-reports/sales-by-customer" },
171 { name: "Customer Lifetime Value", desc: "Long-term customer worth analysis", path: "/pages/customers" },
172 { name: "New vs Returning", desc: "Customer acquisition and retention", path: "/pages/customers" },
173 { name: "Loyalty Program Analysis", desc: "Points, rewards, and redemption", path: "/pages/customers/loyalty" },
174 { name: "Customer Segmentation", desc: "Group customers by behavior", path: "/pages/customers" },
175 { name: "Aged Debtors", desc: "Outstanding customer accounts", path: "/pages/customers/customer-accounts/aged-debtors" },
176 { name: "Customer Purchase History", desc: "Individual buying patterns", path: "/pages/customers" },
177 { name: "Lapsed Customers", desc: "Inactive customer identification", path: "/pages/customers" },
180 return <ReportGrid reports={reports} />;
183function FinancialReports() {
185 { name: "Daily Takings", desc: "Cash, card, and total receipts", path: "/pages/sales/end-of-day" },
186 { name: "Monthly P&L", desc: "Profit and loss statement", path: "/pages/reports/analytics" },
187 { name: "Gross Margin Analysis", desc: "Product and category profitability", path: "/pages/reports/analytics" },
188 { name: "GST/Tax Summary", desc: "Tax collected and payable", path: "/pages/reports/analytics" },
189 { name: "Account Sales", desc: "Credit account transactions", path: "/pages/reports/sales-reports/sales-by-account" },
190 { name: "Payment Reconciliation", desc: "Match payments to deposits", path: "/pages/reports/sales-reports/payment-list" },
191 { name: "Refunds & Returns", desc: "Track product returns", path: "/pages/reports/sales-reports" },
192 { name: "Franchise Royalties", desc: "Franchise fee calculations", path: "/pages/reports/franchise-report" },
193 { name: "Cost of Goods Sold", desc: "COGS by period", path: "/pages/reports/analytics" },
194 { name: "Banking Summary", desc: "Deposits and cash flow", path: "/pages/sales/end-of-day" },
197 return <ReportGrid reports={reports} />;
200function StaffReports() {
202 { name: "Sales by Staff Member", desc: "Individual performance metrics", path: "/pages/reports/sales-reports/sales-by-teller" },
203 { name: "Staff Hours Report", desc: "Time tracking and scheduling", path: "/pages/settings/staff" },
204 { name: "Staff Productivity", desc: "Sales per hour worked", path: "/pages/reports/sales-reports/sales-by-teller" },
205 { name: "Staff Activity Log", desc: "Login times and transactions", path: "/audit" },
206 { name: "Commission Report", desc: "Sales commission calculations", path: "/pages/reports/sales-reports/sales-by-teller" },
207 { name: "Void & Discount Analysis", desc: "Staff discount and void usage", path: "/pages/reports/sales-reports/sales-with-discounts" },
208 { name: "Training Compliance", desc: "Staff training status", path: "/pages/settings/staff" },
209 { name: "Performance Reviews", desc: "KPIs and targets", path: "/pages/settings/staff" },
212 return <ReportGrid reports={reports} />;
215function OperationalReports() {
217 { name: "System Health Monitor", desc: "Server and database status", path: "/pages/operations/monitoring" },
218 { name: "Transaction Log", desc: "Complete audit trail", path: "/audit" },
219 { name: "End of Day Reports", desc: "Daily closeout summaries", path: "/pages/sales/end-of-day" },
220 { name: "Till Reconciliation", desc: "Cash drawer accuracy", path: "/pages/sales/end-of-day" },
221 { name: "Sale Processing Errors", desc: "Failed or edited transactions", path: "/pages/reports/sales-reports/edited-sales" },
222 { name: "Gift Card Activity", desc: "Gift card sales and redemptions", path: "/prepay" },
223 { name: "Layby Report", desc: "Layby payments and completions", path: "/pages/reports/sales-reports/layby" },
224 { name: "Open Quotations", desc: "Pending customer quotes", path: "/pages/reports/sales-reports/open-quotations" },
225 { name: "Store Comparison", desc: "Multi-location performance", path: "/pages/reports/sales-reports/sales-by-store" },
226 { name: "API Usage Statistics", desc: "System integration activity", path: "/api" },
229 return <ReportGrid reports={reports} />;
232function ReportGrid({ reports }: { reports: Array<{ name: string; desc: string; path: string }> }) {
234 <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
235 {reports.map((report, idx) => (
239 className="group relative block bg-gradient-to-br from-surface to-surface-2 border border-border rounded-xl p-5 hover:shadow-xl hover:scale-[1.02] hover:border-brand/50 hover:from-brand/5 hover:to-brand/10 transition-all duration-300 overflow-hidden"
241 <div className="absolute inset-0 bg-gradient-to-br from-brand/0 to-brand/0 group-hover:from-brand/5 group-hover:to-brand/10 transition-all duration-300"></div>
242 <div className="relative z-10">
243 <h3 className="text-lg font-semibold text-text mb-1 group-hover:text-brand transition-colors duration-200">
246 <p className="text-sm text-muted">{report.desc}</p>
254export default function ReportsPage() {
256 <Suspense fallback={<div className="flex items-center justify-center min-h-screen">Loading...</div>}>
257 <ReportsPageContent />