diff --git a/src/app/(main)/report/ReportSelectionDashboard.tsx b/src/app/(main)/report/ReportSelectionDashboard.tsx new file mode 100644 index 0000000..3e1ff3d --- /dev/null +++ b/src/app/(main)/report/ReportSelectionDashboard.tsx @@ -0,0 +1,188 @@ +"use client"; + +import React from "react"; +import { + Box, + Card, + CardContent, + Grid, + Typography, +} from "@mui/material"; +import Inventory2OutlinedIcon from "@mui/icons-material/Inventory2Outlined"; +import MonetizationOnOutlinedIcon from "@mui/icons-material/MonetizationOnOutlined"; +import LayersOutlinedIcon from "@mui/icons-material/LayersOutlined"; +import SearchOutlinedIcon from "@mui/icons-material/SearchOutlined"; +import LocalShippingOutlinedIcon from "@mui/icons-material/LocalShippingOutlined"; +import OutboundOutlinedIcon from "@mui/icons-material/OutboundOutlined"; +import BarChartOutlinedIcon from "@mui/icons-material/BarChartOutlined"; +import PieChartOutlineOutlinedIcon from "@mui/icons-material/PieChartOutlineOutlined"; +import type { SvgIconComponent } from "@mui/icons-material"; +import { REPORTS } from "@/config/reportConfig"; +import { REPORT_CATEGORIES, type ReportCategoryConfig } from "./reportCategories"; + +const REPORT_ICON_MAP: Record = { + "rep-011": Inventory2OutlinedIcon, + "rep-007": MonetizationOnOutlinedIcon, + "rep-012": LayersOutlinedIcon, + "rep-010": SearchOutlinedIcon, + "rep-004": LocalShippingOutlinedIcon, + "rep-014": LocalShippingOutlinedIcon, + "rep-008": OutboundOutlinedIcon, + "rep-009": OutboundOutlinedIcon, + "rep-013": LocalShippingOutlinedIcon, + "rep-006": BarChartOutlinedIcon, + "rep-005": PieChartOutlineOutlinedIcon, +}; + +const reportById = Object.fromEntries(REPORTS.map((r) => [r.id, r])); + +interface ReportSelectionDashboardProps { + selectedReportId: string; + onSelectReport: (reportId: string) => void; +} + +function ReportCard({ + reportId, + title, + accent, + selected, + onClick, +}: { + reportId: string; + title: string; + accent: string; + selected: boolean; + onClick: () => void; +}) { + const Icon = REPORT_ICON_MAP[reportId] ?? Inventory2OutlinedIcon; + + return ( + + + + + + {title} + + + ); +} + +function CategoryColumn({ + category, + selectedReportId, + onSelectReport, +}: { + category: ReportCategoryConfig; + selectedReportId: string; + onSelectReport: (reportId: string) => void; +}) { + const reports = category.reportIds + .map((id) => reportById[id]) + .filter(Boolean); + + return ( + + + + {category.title} + + + + + {reports.map((report) => ( + + onSelectReport(report.id)} + /> + + ))} + + + + ); +} + +export default function ReportSelectionDashboard({ + selectedReportId, + onSelectReport, +}: ReportSelectionDashboardProps) { + return ( + + + + {REPORT_CATEGORIES.map((category) => ( + + + + ))} + + + + ); +} diff --git a/src/app/(main)/report/page.tsx b/src/app/(main)/report/page.tsx index 7d025f9..cf16570 100644 --- a/src/app/(main)/report/page.tsx +++ b/src/app/(main)/report/page.tsx @@ -24,6 +24,7 @@ import { REPORTS, ReportDefinition } from '@/config/reportConfig'; import { NEXT_PUBLIC_API_URL } from '@/config/api'; import { clientAuthFetch } from '@/app/utils/clientAuthFetch'; import SemiFGProductionAnalysisReport from './SemiFGProductionAnalysisReport'; +import ReportSelectionDashboard from './ReportSelectionDashboard'; import { fetchSemiFGItemCodes, fetchSemiFGItemCodesWithCategory @@ -66,9 +67,10 @@ export default function ReportPage() { REPORTS.find((r) => r.id === selectedReportId), [selectedReportId]); - const handleReportChange = (event: React.ChangeEvent) => { - setSelectedReportId(event.target.value); - setCriteria({}); // Clear criteria when switching reports + const handleSelectReport = (reportId: string) => { + if (reportId === selectedReportId) return; + setSelectedReportId(reportId); + setCriteria({}); }; const handleFieldChange = (name: string, value: string | string[]) => { @@ -368,32 +370,15 @@ export default function ReportPage() { }; return ( - + 報告管理 - - - - - 選擇報告 - - - {REPORTS.map((report) => ( - - {report.title} - - ))} - - - + + {currentReport && ( diff --git a/src/app/(main)/report/reportCategories.ts b/src/app/(main)/report/reportCategories.ts new file mode 100644 index 0000000..b869064 --- /dev/null +++ b/src/app/(main)/report/reportCategories.ts @@ -0,0 +1,38 @@ +export type ReportCategoryId = "inventory" | "inbound-outbound" | "production"; + +export interface ReportCategoryConfig { + id: ReportCategoryId; + title: string; + headerBg: string; + bodyBg: string; + accent: string; + reportIds: string[]; +} + +/** Display order and grouping for the report management dashboard. */ +export const REPORT_CATEGORIES: ReportCategoryConfig[] = [ + { + id: "inventory", + title: "庫存管理", + headerBg: "#b8e0b8", + bodyBg: "#eef8ee", + accent: "#2e7d32", + reportIds: ["rep-011", "rep-007", "rep-012", "rep-010"], + }, + { + id: "inbound-outbound", + title: "出入倉作業", + headerBg: "#b3d4f0", + bodyBg: "#eef5fc", + accent: "#1565c0", + reportIds: ["rep-004", "rep-014", "rep-008", "rep-009", "rep-013"], + }, + { + id: "production", + title: "生產與趨勢", + headerBg: "#f5d4a8", + bodyBg: "#fdf6ec", + accent: "#e65100", + reportIds: ["rep-006", "rep-005"], + }, +];