import { useState } from 'react'; import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query'; import { Plug, Power, PowerOff, Loader2, Trash2, Settings2, Thermometer, Clock, Wifi, WifiOff, Edit2, Bell, Calendar } from 'lucide-react'; import { api } from '../api/client'; import type { SmartPlug, SmartPlugUpdate } from '../api/client'; import { Card, CardContent } from './Card'; import { Button } from './Button'; import { ConfirmModal } from './ConfirmModal'; interface SmartPlugCardProps { plug: SmartPlug; onEdit: (plug: SmartPlug) => void; } export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) { const queryClient = useQueryClient(); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [showPowerOnConfirm, setShowPowerOnConfirm] = useState(false); const [showPowerOffConfirm, setShowPowerOffConfirm] = useState(false); const [isExpanded, setIsExpanded] = useState(false); // Fetch current status const { data: status, isLoading: statusLoading, refetch: refetchStatus } = useQuery({ queryKey: ['smart-plug-status', plug.id], queryFn: () => api.getSmartPlugStatus(plug.id), refetchInterval: 30000, // Refresh every 30 seconds }); // Fetch printers for linking const { data: printers } = useQuery({ queryKey: ['printers'], queryFn: api.getPrinters, }); const linkedPrinter = printers?.find(p => p.id === plug.printer_id); // Control mutation const controlMutation = useMutation({ mutationFn: (action: 'on' | 'off' | 'toggle') => api.controlSmartPlug(plug.id, action), onSuccess: () => { refetchStatus(); }, }); // Update mutation const updateMutation = useMutation({ mutationFn: (data: SmartPlugUpdate) => api.updateSmartPlug(plug.id, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['smart-plugs'] }); // Also invalidate printer-specific smart plug queries to keep PrintersPage in sync if (plug.printer_id) { queryClient.invalidateQueries({ queryKey: ['smartPlugByPrinter', plug.printer_id] }); } }, }); // Delete mutation const deleteMutation = useMutation({ mutationFn: () => api.deleteSmartPlug(plug.id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['smart-plugs'] }); }, }); const isOn = status?.state === 'ON'; const isReachable = status?.reachable ?? false; const isPending = controlMutation.isPending; return ( <> {/* Header Row */}

{plug.name}

{plug.ip_address}

{/* Status indicator */}
{statusLoading ? ( ) : isReachable ? (
{status?.state || 'Unknown'}
) : (
Offline
)}
{/* Linked Printer */} {linkedPrinter && (
Linked to: {linkedPrinter.name}
)} {/* Feature Badges */} {(plug.power_alert_enabled || plug.schedule_enabled) && (
{plug.power_alert_enabled && ( Alerts )} {plug.schedule_enabled && ( {plug.schedule_on_time && plug.schedule_off_time ? `${plug.schedule_on_time} - ${plug.schedule_off_time}` : plug.schedule_on_time ? `On ${plug.schedule_on_time}` : `Off ${plug.schedule_off_time}`} )}
)} {/* Quick Controls */}
{/* Toggle Settings Panel */} {/* Expanded Settings */} {isExpanded && (
{/* Enabled Toggle */}

Enabled

Enable automation for this plug

{/* Auto On */}

Auto On

Turn on when print starts

{/* Auto Off */}

Auto Off

Turn off when print completes (one-shot)

{/* Delay Mode */} {plug.auto_off && (

Turn Off Delay Mode

{plug.off_delay_mode === 'time' ? (
updateMutation.mutate({ off_delay_minutes: parseInt(e.target.value) || 5 })} className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white text-sm focus:border-bambu-green focus:outline-none" />
) : (
updateMutation.mutate({ off_temp_threshold: parseInt(e.target.value) || 70 })} className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white text-sm focus:border-bambu-green focus:outline-none" />

Turns off when nozzle cools below this temperature

)}
)} {/* Action Buttons */}
)}
{/* Delete Confirmation */} {showDeleteConfirm && ( { deleteMutation.mutate(); setShowDeleteConfirm(false); }} onCancel={() => setShowDeleteConfirm(false)} /> )} {/* Power On Confirmation */} {showPowerOnConfirm && ( { controlMutation.mutate('on'); setShowPowerOnConfirm(false); }} onCancel={() => setShowPowerOnConfirm(false)} /> )} {/* Power Off Confirmation */} {showPowerOffConfirm && ( { controlMutation.mutate('off'); setShowPowerOffConfirm(false); }} onCancel={() => setShowPowerOffConfirm(false)} /> )} ); }