import React, { useState, useEffect } from 'react'; import { Layers, Package, Search, Plus, Edit2, Trash2, X, Check } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; // Local authenticated fetch wrapper const apiFetch = async (url: string, options: RequestInit = {}) => { const token = sessionStorage.getItem('counterToken'); const headers = { 'Content-Type': 'application/json', ...(options.headers || {}), ...(token ? { 'Authorization': `Bearer ${token}` } : {}) }; const response = await fetch(url, { ...options, headers }); if (response.status === 401 || response.status === 403) { sessionStorage.removeItem('isCounterLoggedIn'); sessionStorage.removeItem('counterToken'); window.location.href = '/login'; } return response; }; const Categories = () => { const [categories, setCategories] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [currentCategory, setCurrentCategory] = useState(null); const fetchCategories = async () => { setLoading(true); try { const host = window.location.hostname; const response = await apiFetch(`http://${host}:8080/api/base-items`); const data = await response.json(); setCategories(Array.isArray(data) ? data : (data.content || [])); } catch (error) { console.error('Error fetching categories:', error); } finally { setLoading(false); } }; useEffect(() => { fetchCategories(); }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const host = window.location.hostname; const url = currentCategory?.id ? `http://${host}:8080/api/base-items/${currentCategory.id}` : `http://${host}:8080/api/base-items`; const method = currentCategory?.id ? 'PUT' : 'POST'; try { const response = await apiFetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(currentCategory) }); if (response.ok) { setIsModalOpen(false); fetchCategories(); } } catch (error) { console.error('Error saving category:', error); } }; const filteredCategories = categories.filter(cat => cat.name.toLowerCase().includes(searchTerm.toLowerCase()) ); return (

Food Categories

Manage your menu structure

c.active).length} color="bg-primary/5 text-primary" />
setSearchTerm(e.target.value)} className="w-full bg-slate-50 border border-slate-100/50 rounded-2xl py-6 pl-16 pr-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all shadow-inner" />
{loading ? (
) : filteredCategories.map((cat) => (

{cat.name}

{cat.active ? 'Active' : 'Inactive'}

))}
{/* CRUD Modal */} {isModalOpen && (
setIsModalOpen(false)} className="absolute inset-0 bg-slate-900/60 backdrop-blur-md" />

{currentCategory?.id ? 'Edit Category' : 'New Category'}

Configure category properties

setCurrentCategory({...currentCategory, name: e.target.value})} className="w-full bg-slate-50 border border-slate-100 rounded-2xl py-5 px-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all" placeholder="e.g. FAST FOOD" />