|
- import React, { useState } from 'react';
- import {
- Box,
- Paper,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Typography,
- Chip,
- Card,
- CardContent,
- } from '@mui/material';
- import {
- useReactTable,
- getCoreRowModel,
- createColumnHelper,
- flexRender,
- } from '@tanstack/react-table';
- import DescriptionIcon from '@mui/icons-material/Description';
- import CheckCircleIcon from '@mui/icons-material/CheckCircle';
- import CancelIcon from '@mui/icons-material/Cancel';
- import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
-
- interface QCReport {
- id: string;
- productName: string;
- isQualified: boolean;
- remarks: string;
- reportDate: string;
- batchNumber: string;
- inspector: string;
- testResults: string;
- specifications: string;
- }
-
- interface QCReportFormProps {
- reports: QCReport[];
- }
-
- function QCReportForm({ reports }: QCReportFormProps): JSX.Element {
- const [selectedReport, setSelectedReport] = useState<QCReport | null>(null);
-
- const handleReportClick = (report: QCReport): void => {
- setSelectedReport(report);
- };
-
- const getQualifiedStatus = (isQualified: boolean) => {
- return isQualified ? (
- <Chip
- icon={<CheckCircleIcon />}
- label="合格"
- color="success"
- size="small"
- sx={{ fontWeight: 'medium' }}
- />
- ) : (
- <Chip
- icon={<CancelIcon />}
- label="不合格"
- color="error"
- size="small"
- sx={{ fontWeight: 'medium' }}
- />
- );
- };
-
- const columnHelper = createColumnHelper<QCReport>();
-
- const columns = [
- // columnHelper.accessor('productName', {
- // header: '產品',
- // cell: info => (
- // <Typography variant="body2" fontWeight="medium">
- // {info.getValue()}
- // </Typography>
- // ),
- // }),
- columnHelper.accessor('isQualified', {
- header: '合格',
- cell: info => getQualifiedStatus(info.getValue()),
- }),
- columnHelper.accessor('remarks', {
- header: '備註',
- cell: info => (
- <Typography
- variant="body2"
- color="text.secondary"
- sx={{ maxWidth: '200px', overflow: 'hidden', textOverflow: 'ellipsis' }}
- >
- {info.getValue()}
- </Typography>
- ),
- }),
- columnHelper.accessor('reportDate', {
- header: '上報日期',
- cell: info => (
- <Typography variant="body2" color="text.secondary">
- {info.getValue()}
- </Typography>
- ),
- }),
- ];
-
- const table = useReactTable({
- data: reports,
- columns,
- getCoreRowModel: getCoreRowModel(),
- });
-
- return (
- <Box sx={{ maxWidth: '1200px', mx: 'auto', p: 3 }}>
- {/* Title */}
- {/* <Box sx={{ mb: 4 }}>
- <Typography variant="h5" fontWeight="bold" color="text.primary">
- 品質控制上報系統
- </Typography>
- <Typography variant="body2" color="text.secondary">
- 品質檢測結果上報與管理
- </Typography>
- </Box> */}
-
- {/* <Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', lg: '2fr 1fr' }, gap: 3 }}> */}
- <Box sx={{ display: 'grid' }}>
- {/* Table Section */}
- <Box>
- <Typography variant="h6" fontWeight="medium" sx={{ mb: 2 }}>
- 上報資料
- </Typography>
- <TableContainer component={Paper} elevation={2}>
- <Table>
- <TableHead sx={{ bgcolor: 'grey.50' }}>
- {table.getHeaderGroups().map(headerGroup => (
- <TableRow key={headerGroup.id}>
- {headerGroup.headers.map(header => (
- <TableCell
- key={header.id}
- sx={{
- fontSize: '0.75rem',
- fontWeight: 'medium',
- color: 'text.secondary',
- textTransform: 'uppercase',
- py: 2,
- px: 3,
- }}
- >
- {header.isPlaceholder
- ? null
- : flexRender(header.column.columnDef.header, header.getContext())}
- </TableCell>
- ))}
- </TableRow>
- ))}
- </TableHead>
- <TableBody>
- {table.getRowModel().rows.map(row => (
- <TableRow
- key={row.id}
- onClick={() => handleReportClick(row.original)}
- sx={{
- cursor: 'pointer',
- '&:hover': { bgcolor: 'grey.50' },
- bgcolor: selectedReport?.id === row.original.id ? 'primary.light' : 'inherit',
- transition: 'background-color 0.15s',
- }}
- >
- {row.getVisibleCells().map(cell => (
- <TableCell key={cell.id} sx={{ py: 2, px: 3 }}>
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
- </TableCell>
- ))}
- </TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
- </Box>
-
- {/* Details Section */}
- {/* <Box>
- <Typography variant="h6" fontWeight="medium" sx={{ mb: 2 }}>
- 詳細資訊
- </Typography>
- <Card elevation={2} sx={{ minHeight: '300px', bgcolor: 'grey.50' }}>
- <CardContent>
- {selectedReport ? (
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
- <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, color: 'primary.main', mb: 2 }}>
- <DescriptionIcon />
- <Typography variant="subtitle1" fontWeight="medium">
- 上報詳情
- </Typography>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium">
- 產品名稱:
- </Typography>
- <Typography variant="body2">{selectedReport.productName}</Typography>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium">
- 檢測結果:
- </Typography>
- <Box sx={{ mt: 1 }}>{getQualifiedStatus(selectedReport.isQualified)}</Box>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium">
- 批次號碼:
- </Typography>
- <Typography variant="body2">{selectedReport.batchNumber}</Typography>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium">
- 檢驗員:
- </Typography>
- <Typography variant="body2">{selectedReport.inspector}</Typography>
- </Box>
-
- <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
- <CalendarTodayIcon fontSize="small" sx={{ color: 'text.secondary' }} />
- <Typography variant="body2">
- 上報日期:{selectedReport.reportDate}
- </Typography>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium" sx={{ mb: 1 }}>
- 檢測規格:
- </Typography>
- <Paper sx={{ p: 1, bgcolor: 'background.paper' }}>
- <Typography variant="body2">{selectedReport.specifications}</Typography>
- </Paper>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium" sx={{ mb: 1 }}>
- 檢測結果詳情:
- </Typography>
- <Paper sx={{ p: 1, bgcolor: 'background.paper' }}>
- <Typography variant="body2">{selectedReport.testResults}</Typography>
- </Paper>
- </Box>
-
- <Box>
- <Typography variant="body2" color="text.secondary" fontWeight="medium" sx={{ mb: 1 }}>
- 備註 (REMARKS):
- </Typography>
- <Paper sx={{ p: 1, bgcolor: 'background.paper' }}>
- <Typography variant="body2">{selectedReport.remarks}</Typography>
- </Paper>
- </Box>
- </Box>
- ) : (
- <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
- <Typography variant="body2" color="text.secondary">
- 請點擊表格中的記錄來查看詳細資訊
- </Typography>
- </Box>
- )}
- </CardContent>
- </Card>
- </Box> */}
- </Box>
- </Box>
- );
- }
-
- // Dummy data
- const dummyReports = [
- // {
- // id: '1',
- // productName: '智慧手機 Pro Max',
- // isQualified: true,
- // remarks: '所有檢測項目均符合標準規格',
- // reportDate: '2024-08-07',
- // batchNumber: 'SPM-240807-001',
- // inspector: '張品質',
- // testResults: '外觀檢查:無瑕疵,功能測試:100%通過,性能測試:符合標準',
- // specifications: '螢幕解析度≥1080p,電池續航≥24小時,防水等級IPX7',
- // },
- {
- id: '2',
- productName: '無線藍牙耳機',
- isQualified: false,
- remarks: '包裝有破損',
- reportDate: '2024-08-06',
- batchNumber: 'WBE-240806-002',
- inspector: '李測試',
- testResults: '音質測試:左右聲道音量差異>3dB,不符合標準',
- specifications: '頻響範圍20Hz-20kHz,左右聲道音量差≤1dB,電池續航≥8小時',
- },
- {
- id: '3',
- productName: '筆記型電腦',
- isQualified: true,
- remarks: '經檢查,無損壞',
- reportDate: '2024-08-05',
- batchNumber: 'NB-240805-003',
- inspector: '王檢驗',
- testResults: '溫度測試:CPU最高溫度75°C,性能測試:符合預期',
- specifications: 'CPU溫度≤85°C,開機時間≤30秒,電池續航≥6小時',
- },
- // {
- // id: '4',
- // productName: '智慧手錶',
- // isQualified: false,
- // remarks: '防水測試未通過,密封性能不足',
- // reportDate: '2024-08-04',
- // batchNumber: 'SW-240804-004',
- // inspector: '劉品管',
- // testResults: '防水測試:IPX5等級測試失敗,發現進水現象',
- // specifications: '防水等級≥IPX7,電池續航≥48小時,心率監測精度≥95%',
- // },
- // {
- // id: '5',
- // productName: '平板電腦',
- // isQualified: true,
- // remarks: '觸控靈敏度優良,顯示效果佳',
- // reportDate: '2024-08-03',
- // batchNumber: 'TB-240803-005',
- // inspector: '陳測試',
- // testResults: '觸控測試:反應時間<10ms,顯示測試:色彩準確度98%',
- // specifications: '螢幕尺寸10.1吋,解析度2K,觸控反應時間≤15ms',
- // },
- ];
-
- // Main component
- const EscalationLog: React.FC = () => {
- return <QCReportForm reports={dummyReports} />;
- };
-
- export default EscalationLog;
|