import React, { useState, useEffect } from 'react'; import { Button, Input, Card, notification, Space, Typography, Alert, Row, Col } from 'antd'; import { ReadOutlined, EditOutlined, DeleteOutlined, WifiOutlined } from '@ant-design/icons'; import mqtt from 'mqtt'; import dayjs from 'dayjs'; const { Title, Text } = Typography; const { TextArea } = Input; function App() { const [lockNo, setLockNo] = useState('1'); const [startTime, setStartTime] = useState(dayjs().format('YYYY-MM-DDTHH:mm')); const [endTime, setEndTime] = useState( dayjs().add(1, 'day').set('hour', 12).set('minute', 0).format('YYYY-MM-DDTHH:mm') ); const [isConnected, setIsConnected] = useState(false); const [connectionError, setConnectionError] = useState(''); const [client, setClient] = useState(null); const [receivedMessages, setReceivedMessages] = useState('No messages received yet'); // MQTT connection options const mqttOptions = { host: `${import.meta.env.VITE_MQTT_SERVER}`, // host: 'mosquitto-apotek-2', port: Number(`${import.meta.env.VITE_MQTT_PORT}`), // protocol: "mqtt", username: 'morekmorekmorek', password: 'morek888', // connectTimeout: 5000, // reconnectPeriod: 5000, }; // Update end time when start time changes useEffect(() => { const start = dayjs(startTime); const newEndTime = start.add(1, 'day').set('hour', 12).set('minute', 0).set('second', 0); setEndTime(newEndTime.format('YYYY-MM-DDTHH:mm')); }, [startTime]); // Connect to MQTT broker - and keep connection alive useEffect(() => { let mqttClient; const connectToMqtt = () => { try { const connectUrl = `mqtt://${mqttOptions.host}:${mqttOptions.port}`; console.log('Attempting to connect to:', connectUrl); mqttClient = mqtt.connect(connectUrl, { username: mqttOptions.username, password: mqttOptions.password, clientId: 'mqttjs_' + Math.random().toString(16).substring(2, 8), connectTimeout: mqttOptions.connectTimeout, reconnectPeriod: mqttOptions.reconnectPeriod, clean: false, keepalive: 30, }); setClient(mqttClient); mqttClient.on('connect', () => { console.log('Connected to MQTT broker'); setIsConnected(true); setConnectionError(''); notification.success({ message: 'MQTT Connected', description: 'Successfully connected to MQTT broker', duration: 2, }); mqttClient.subscribe('hotel1/pc1', (err) => { if (err) { console.error('Subscription error:', err); } else { console.log('Subscribed to topic: hotel1/pc1'); } }); }); mqttClient.on('error', (err) => { console.error('MQTT connection error:', err); setConnectionError(err.message); setIsConnected(false); }); mqttClient.on('close', () => { console.log('MQTT connection closed'); setIsConnected(false); }); mqttClient.on('reconnect', () => { console.log('Attempting to reconnect to MQTT broker'); setIsConnected(false); setConnectionError('Reconnecting...'); }); mqttClient.on('offline', () => { console.log('MQTT client is offline'); setIsConnected(false); setConnectionError('Offline - attempting to reconnect'); }); mqttClient.on('message', (topic, message) => { console.log('Received message:', topic, message.toString()); const newMessage = `[${new Date().toLocaleTimeString()}] ${topic}: ${message.toString()}\n`; setReceivedMessages(prev => prev === 'No messages received yet' ? newMessage : prev + newMessage); }); } catch (err) { console.error('Failed to initialize MQTT client:', err); setConnectionError(err.message); setTimeout(connectToMqtt, 5000); } }; connectToMqtt(); }, []); const handleStartTimeChange = (e) => { const newStartTime = e.target.value; setStartTime(newStartTime); }; const handleEndTimeChange = (e) => { const newEndTime = e.target.value; const start = dayjs(startTime); const end = dayjs(newEndTime); if (end.isBefore(start)) { notification.error({ message: 'Invalid End Time', description: 'End time cannot be before start time', duration: 3, }); return; } setEndTime(newEndTime); }; // Format datetime to YYYY-MM-DD HH:mm:ss const formatDateTime = (dateTimeString) => { return dayjs(dateTimeString).format('YYYY-MM-DD HH:mm:ss'); }; const handleRead = () => { if (client && isConnected) { const payload = JSON.stringify({ cmd: "cek_kartu" }); client.publish('hotel1/pc1', payload); notification.info({ message: 'Read Command Sent', description: `Published: ${payload}`, duration: 2, }); } else { notification.warning({ message: 'Not Connected', description: 'Cannot publish message - not connected to MQTT', duration: 2, }); } }; const handleWrite = () => { if (client && isConnected) { if (!lockNo || !startTime || !endTime) { notification.error({ message: 'Validation Error', description: 'Please fill in all fields', duration: 2, }); return; } const start = dayjs(startTime); const end = dayjs(endTime); if (end.isBefore(start)) { notification.error({ message: 'Validation Error', description: 'End time must be after start time', duration: 2, }); return; } // Format the datetime values before sending const formattedStartTime = formatDateTime(startTime); const formattedEndTime = formatDateTime(endTime); const payload = JSON.stringify({ cmd: "tulis_kartu", lock_no: parseInt(lockNo), start_time: formattedStartTime, end_time: formattedEndTime }); client.publish('hotel1/pc1', payload); notification.info({ message: 'Write Command Sent', description: `Published: ${payload}`, duration: 2, }); } else { notification.warning({ message: 'Not Connected', description: 'Cannot publish message - not connected to MQTT', duration: 2, }); } }; const handleDelete = () => { if (client && isConnected) { const payload = JSON.stringify({ cmd: "hapus_kartu" }); client.publish('hotel1/pc1', payload); notification.info({ message: 'Delete Command Sent', description: `Published: ${payload}`, duration: 2, }); } else { notification.warning({ message: 'Not Connected', description: 'Cannot publish message - not connected to MQTT', duration: 2, }); } }; const clearMessages = () => { setReceivedMessages('No messages received yet'); }; const disconnectMqtt = () => { if (client) { client.end(false, () => { console.log('Manually disconnected from MQTT'); setIsConnected(false); setConnectionError('Manually disconnected'); }); } }; const reconnectMqtt = () => { if (client) { client.reconnect(); } }; // Calculate min and max values for datetime inputs const minEndTime = startTime; const maxStartTime = endTime; return (