"use client"; import React, { useState } from "react"; import { Box, Grid, Paper, Typography, Button, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tabs, Tab // ← Added for tabs } from "@mui/material"; import { FileDownload, Print, SettingsEthernet, Lan, Router } from "@mui/icons-material"; import dayjs from "dayjs"; import { NEXT_PUBLIC_API_URL } from "@/config/api"; // Simple TabPanel component for conditional rendering interface TabPanelProps { children?: React.ReactNode; index: number; value: number; } function TabPanel(props: TabPanelProps) { const { children, value, index, ...other } = props; return ( ); } export default function TestingPage() { // Tab state const [tabValue, setTabValue] = useState(0); const handleTabChange = (event: React.SyntheticEvent, newValue: number) => { setTabValue(newValue); }; // --- 1. TSC Section States --- const [tscConfig, setTscConfig] = useState({ ip: '192.168.1.100', port: '9100' }); const [tscItems, setTscItems] = useState([ { id: 1, itemCode: 'FG-001', itemName: 'Yellow Curry Sauce', lotNo: 'LOT-TSC-01', expiryDate: '2025-12-01' }, { id: 2, itemCode: 'FG-002', itemName: 'Red Curry Paste', lotNo: 'LOT-TSC-02', expiryDate: '2025-12-05' }, ]); // --- 2. DataFlex Section States --- const [dfConfig, setDfConfig] = useState({ ip: '192.168.1.101', port: '9100' }); const [dfItems, setDfItems] = useState([ { id: 1, itemCode: 'DF-101', itemName: 'Instant Noodle A', lotNo: 'LOT-DF-01', expiryDate: '2026-01-10' }, { id: 2, itemCode: 'DF-102', itemName: 'Instant Noodle B', lotNo: 'LOT-DF-02', expiryDate: '2026-01-15' }, ]); // --- 3. OnPack Section States --- const [isPrinterModalOpen, setIsPrinterModalOpen] = useState(false); const [printerFormData, setPrinterFormData] = useState({ itemCode: '', lotNo: '', expiryDate: dayjs().format('YYYY-MM-DD'), productName: '' }); // --- 4. Laser Section States --- const [laserConfig, setLaserConfig] = useState({ ip: '192.168.1.102', port: '8080' }); const [laserItems, setLaserItems] = useState([ { id: 1, templateId: 'JOB_001', lotNo: 'L-LASER-01', expiryDate: '2025-12-31', power: '50' }, ]); // --- 5. HANS600S-M Section States --- const [hansConfig, setHansConfig] = useState({ ip: '192.168.76.10', port: '45678' }); const [hansItems, setHansItems] = useState([ { id: 1, textChannel3: 'SN-HANS-001-20260117', // channel 3 (e.g. serial / text1) textChannel4: 'BATCH-HK-TEST-OK', // channel 4 (e.g. batch / text2) text3ObjectName: 'Text3', // EZCAD object name for channel 3 text4ObjectName: 'Text4' // EZCAD object name for channel 4 }, ]); // Generic handler for inline table edits const handleItemChange = (setter: any, id: number, field: string, value: string) => { setter((prev: any[]) => prev.map(item => item.id === id ? { ...item, [field]: value } : item )); }; // --- API CALLS --- // TSC Print (Section 1) const handleTscPrint = async (row: any) => { const token = localStorage.getItem("accessToken"); const payload = { ...row, printerIp: tscConfig.ip, printerPort: tscConfig.port }; try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/print-tsc`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) alert(`TSC Print Command Sent for ${row.itemCode}!`); else alert("TSC Print Failed"); } catch (e) { console.error("TSC Error:", e); } }; // DataFlex Print (Section 2) const handleDfPrint = async (row: any) => { const token = localStorage.getItem("accessToken"); const payload = { ...row, printerIp: dfConfig.ip, printerPort: dfConfig.port }; try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/print-dataflex`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) alert(`DataFlex Print Command Sent for ${row.itemCode}!`); else alert("DataFlex Print Failed"); } catch (e) { console.error("DataFlex Error:", e); } }; // OnPack Zip Download (Section 3) const handleDownloadPrintJob = async () => { const token = localStorage.getItem("accessToken"); const params = new URLSearchParams(printerFormData); try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/get-printer6?${params.toString()}`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) throw new Error('Download failed'); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `${printerFormData.lotNo || 'OnPack'}.zip`); document.body.appendChild(link); link.click(); link.remove(); window.URL.revokeObjectURL(url); setIsPrinterModalOpen(false); } catch (e) { console.error("OnPack Error:", e); } }; // Laser Print (Section 4 - original) const handleLaserPrint = async (row: any) => { const token = localStorage.getItem("accessToken"); const payload = { ...row, printerIp: laserConfig.ip, printerPort: laserConfig.port }; try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/print-laser`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) alert(`Laser Command Sent: ${row.templateId}`); } catch (e) { console.error(e); } }; const handleLaserPreview = async (row: any) => { const token = localStorage.getItem("accessToken"); const payload = { ...row, printerIp: laserConfig.ip, printerPort: parseInt(laserConfig.port) }; try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/preview-laser`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) alert("Red light preview active!"); } catch (e) { console.error("Preview Error:", e); } }; // HANS600S-M TCP Print (Section 5) const handleHansPrint = async (row: any) => { const token = localStorage.getItem("accessToken"); const payload = { printerIp: hansConfig.ip, printerPort: hansConfig.port, textChannel3: row.textChannel3, textChannel4: row.textChannel4, text3ObjectName: row.text3ObjectName, text4ObjectName: row.text4ObjectName }; try { const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/print-laser-tcp`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.text(); if (response.ok) { alert(`HANS600S-M Mark Success: ${result}`); } else { alert(`HANS600S-M Failed: ${result}`); } } catch (e) { console.error("HANS600S-M Error:", e); alert("HANS600S-M Connection Error"); } }; // Layout Helper const Section = ({ title, children }: { title: string, children?: React.ReactNode }) => ( {title} {children || Waiting for implementation...} ); return ( Printer Testing
setTscConfig({...tscConfig, ip: e.target.value})} /> setTscConfig({...tscConfig, port: e.target.value})} /> Code Name Lot Expiry Action {tscItems.map(row => ( handleItemChange(setTscItems, row.id, 'itemCode', e.target.value)} /> handleItemChange(setTscItems, row.id, 'itemName', e.target.value)} /> handleItemChange(setTscItems, row.id, 'lotNo', e.target.value)} /> handleItemChange(setTscItems, row.id, 'expiryDate', e.target.value)} /> ))}
setDfConfig({...dfConfig, ip: e.target.value})} /> setDfConfig({...dfConfig, port: e.target.value})} /> Code Name Lot Expiry Action {dfItems.map(row => ( handleItemChange(setDfItems, row.id, 'itemCode', e.target.value)} /> handleItemChange(setDfItems, row.id, 'itemName', e.target.value)} /> handleItemChange(setDfItems, row.id, 'lotNo', e.target.value)} /> handleItemChange(setDfItems, row.id, 'expiryDate', e.target.value)} /> ))}
Calls /plastic/get-printer6 to generate CoLOS .job bundle.
setLaserConfig({...laserConfig, ip: e.target.value})} /> setLaserConfig({...laserConfig, port: e.target.value})} /> Template Lot Exp Pwr% Action {laserItems.map(row => ( handleItemChange(setLaserItems, row.id, 'templateId', e.target.value)} /> handleItemChange(setLaserItems, row.id, 'lotNo', e.target.value)} /> handleItemChange(setLaserItems, row.id, 'expiryDate', e.target.value)} /> handleItemChange(setLaserItems, row.id, 'power', e.target.value)} /> ))}
Note: HANS Laser requires pre-saved templates on the controller.
setHansConfig({...hansConfig, ip: e.target.value})} /> setHansConfig({...hansConfig, port: e.target.value})} /> Ch3 Text (SN) Ch4 Text (Batch) Obj3 Name Obj4 Name Action {hansItems.map(row => ( handleItemChange(setHansItems, row.id, 'textChannel3', e.target.value)} sx={{ minWidth: 180 }} /> handleItemChange(setHansItems, row.id, 'textChannel4', e.target.value)} sx={{ minWidth: 140 }} /> handleItemChange(setHansItems, row.id, 'text3ObjectName', e.target.value)} size="small" /> handleItemChange(setHansItems, row.id, 'text4ObjectName', e.target.value)} size="small" /> ))}
TCP Push to EZCAD3 (Ch3/Ch4 via E3_SetTextObject) | IP:192.168.76.10:45678 | Backend: /print-laser-tcp
{/* Dialog for OnPack */} setIsPrinterModalOpen(false)} fullWidth maxWidth="sm"> OnPack Printer Job Details setPrinterFormData({ ...printerFormData, itemCode: e.target.value })} /> setPrinterFormData({ ...printerFormData, lotNo: e.target.value })} /> setPrinterFormData({ ...printerFormData, productName: e.target.value })} /> setPrinterFormData({ ...printerFormData, expiryDate: e.target.value })} />
); }