import { useState, useEffect, useCallback } from 'react'; import { Package, Plus, Settings as SettingsIcon } from 'lucide-react'; import type { WatchedItem, Settings } from './types'; import { getItems, getSettings } from './api/client'; import ItemCard from './components/ItemCard'; import AddItemModal from './components/AddItemModal'; import EditItemModal from './components/EditItemModal'; import SettingsModal from './components/SettingsModal'; export default function App() { const [items, setItems] = useState([]); const [settings, setSettings] = useState(null); const [loading, setLoading] = useState(true); const [connected, setConnected] = useState(null); const [showAdd, setShowAdd] = useState(false); const [editItem, setEditItem] = useState(null); const [showSettings, setShowSettings] = useState(false); const fetchItems = useCallback(async () => { try { const data = await getItems(); setItems(data); setConnected(true); } catch { setConnected(false); } finally { setLoading(false); } }, []); useEffect(() => { fetchItems(); const id = setInterval(fetchItems, 10_000); return () => clearInterval(id); }, [fetchItems]); useEffect(() => { getSettings().then(setSettings).catch(() => null); }, []); const inStock = items.filter(i => i.last_status === 'in_stock').length; const active = items.filter(i => i.is_active === 1).length; return (
{/* ── Header ── */}
UI Stock Tracker
{items.length} Tracked
{active} Active
{inStock > 0 && (
{inStock} In Stock
)}
{/* ── Main ── */}
{loading ? (
Connecting to backend…
) : connected === false ? (
⚠ Cannot reach the backend. Make sure the Docker container is running.
) : items.length === 0 ? (

Nothing tracked yet

Add a product URL from store.ui.com and the tracker will alert you the moment it comes back in stock.

) : ( <>
{items.length} item{items.length !== 1 ? 's' : ''} tracked
{items.map(item => ( ))}
)}
{/* ── Modals ── */} {showAdd && ( setShowAdd(false)} onAdded={() => { setShowAdd(false); fetchItems(); }} /> )} {editItem && ( setEditItem(null)} onSaved={() => { setEditItem(null); fetchItems(); }} /> )} {showSettings && ( setShowSettings(false)} onSaved={s => { setSettings(s); setShowSettings(false); }} /> )}
); }