import { useState, useContext, useEffect, useCallback } from 'react' import axios from 'axios' import { Form, Button, message, Typography, Flex, Steps, Divider, Input, Select, Space, Descriptions, List, InputNumber, notification, Progress, Modal, Radio } from 'antd' import { SearchOutlined, SettingOutlined } from '@ant-design/icons' import PropTypes from 'prop-types' import { PrintServerContext } from '../../context/PrintServerContext' import EditIcon from '../../../Icons/EditIcon.jsx' import config from '../../../../config.js' const { Title } = Typography const initialNewPrinterForm = { moonraker: { protocol: 'ws', host: '', port: '', apiKey: '' } } const NewPrinter = ({ onOk, reset }) => { NewPrinter.propTypes = { onOk: PropTypes.func.isRequired, reset: PropTypes.bool.isRequired } const { printServer } = useContext(PrintServerContext) const [messageApi, contextHolder] = message.useMessage() const [notificationApi, notificationContextHolder] = notification.useNotification() const [newPrinterLoading, setNewPrinterLoading] = useState(false) const [currentStep, setCurrentStep] = useState(0) const [nextEnabled, setNextEnabled] = useState(false) const [newPrinterForm] = Form.useForm() const [newPrinterFormValues, setNewPrinterFormValues] = useState( initialNewPrinterForm ) const [discoveredPrinters, setDiscoveredPrinters] = useState([]) const [discovering, setDiscovering] = useState(false) const [showManualSetup, setShowManualSetup] = useState(false) const [scanPort, setScanPort] = useState(7125) const [scanProtocol, setScanProtocol] = useState('ws') const [editingHostname, setEditingHostname] = useState(null) const [hostnameInput, setHostnameInput] = useState('') const [initialized, setInitialized] = useState(false) const newPrinterFormUpdateValues = Form.useWatch([], newPrinterForm) useEffect(() => { newPrinterForm .validateFields({ validateOnly: true }) .then(() => { if (currentStep === 0) { const moonraker = newPrinterForm.getFieldValue('moonraker') setNextEnabled( !!(moonraker?.protocol && moonraker?.host && moonraker?.port) ) } else if (currentStep === 1) { const name = newPrinterForm.getFieldValue('name') setNextEnabled(!!name) } else { setNextEnabled(true) } }) .catch(() => setNextEnabled(false)) }, [newPrinterForm, newPrinterFormUpdateValues, currentStep]) const summaryItems = [ { key: 'name', label: 'Name', children: newPrinterFormValues.name }, { key: 'protocol', label: 'Protocol', children: newPrinterFormValues.moonraker?.protocol }, { key: 'host', label: 'Host', children: newPrinterFormValues.moonraker?.host }, { key: 'port', label: 'Port', children: newPrinterFormValues.moonraker?.port } ] useEffect(() => { if (reset) { newPrinterForm.resetFields() } }, [reset, newPrinterForm]) const handlePrinterSelect = (printer) => { newPrinterForm.setFieldsValue({ moonraker: { protocol: printer.protocol, host: printer.host, port: printer.port } }) setNewPrinterFormValues({ ...newPrinterFormValues, moonraker: { protocol: printer.protocol, host: printer.host, port: printer.port } }) } const handleHostnameEdit = (printer, newHostname) => { if (newHostname && newHostname.trim() !== '') { const updatedPrinter = { ...printer, host: newHostname.trim() } setDiscoveredPrinters((prev) => prev.map((p) => (p.host === printer.host ? updatedPrinter : p)) ) setEditingHostname(null) setHostnameInput('') } } const showEditHostnameDialog = (printer) => { setEditingHostname(printer.host) setHostnameInput(printer.host) } const handleNewPrinter = async () => { setNewPrinterLoading(true) try { await axios.post( `${config.backendUrl}/printers`, { ...newPrinterFormValues }, { headers: { Accept: 'application/json' }, withCredentials: true } ) onOk() } catch (error) { messageApi.error('Error adding new printer: ' + error.message) } finally { setNewPrinterLoading(false) } } const notifyScanNetworkFound = useCallback( (data) => { const newPrinter = { protocol: scanProtocol, host: data.hostname || data.ip, port: scanPort } notificationApi.info({ message: 'Printer Found', description: `Printer found: ${data.hostname || data.ip}!` }) setDiscoveredPrinters((prev) => [...prev, newPrinter]) }, [scanProtocol, scanPort, notificationApi] ) const notifyScanNetworkComplete = useCallback( (data) => { setDiscovering(false) notificationApi.destroy('network-scan') if (data == false) { messageApi.error('Error discovering printers!') } else { messageApi.success('Finished discovering printers!') } }, [messageApi, notificationApi] ) const notifyScanNetworkProgress = useCallback( (data) => { notificationApi.info({ message: 'Scanning Network', description: (