diff --git a/web/client/src/components/SettingsPanel.jsx b/web/client/src/components/SettingsPanel.jsx new file mode 100644 index 0000000..abf780f --- /dev/null +++ b/web/client/src/components/SettingsPanel.jsx @@ -0,0 +1,145 @@ +import React, { useState, useCallback } from 'react'; +import { useInventoryStore } from '../store/inventoryStore'; +import './SettingsPanel.css'; + +function SettingsPanel({ isOpen, onClose }) { + const droppers = useInventoryStore((state) => state.inventory.droppers) || []; + const dropperNicknames = useInventoryStore((state) => state.dropperNicknames) || {}; + const setDropperNickname = useInventoryStore((state) => state.setDropperNickname); + + const [editingDropper, setEditingDropper] = useState(null); + const [editValue, setEditValue] = useState(''); + const [saving, setSaving] = useState(false); + + const startEditing = useCallback((dropperName) => { + setEditingDropper(dropperName); + setEditValue(dropperNicknames[dropperName] || ''); + }, [dropperNicknames]); + + const saveNickname = useCallback(async () => { + if (!editingDropper) return; + setSaving(true); + await setDropperNickname(editingDropper, editValue); + setSaving(false); + setEditingDropper(null); + setEditValue(''); + }, [editingDropper, editValue, setDropperNickname]); + + const removeNickname = useCallback(async (dropperName) => { + setSaving(true); + await setDropperNickname(dropperName, ''); + setSaving(false); + }, [setDropperNickname]); + + const handleKeyDown = useCallback((e) => { + if (e.key === 'Enter') saveNickname(); + if (e.key === 'Escape') { + setEditingDropper(null); + setEditValue(''); + } + }, [saveNickname]); + + if (!isOpen) return null; + + return ( +
+ Give your dispensers friendly names so they're easier to identify. +
+ + {droppers.length === 0 ? ( +