'use client' import { useState, useEffect, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { customerService } from '@/src/services/api'; import { Customer, Sale } from '@/src/types/sales'; import { AdminSidebar } from '@/src/components/AdminSidebar'; interface CustomerWithSales extends Customer { sales?: Sale[]; total_purchases?: number; } export default function CustomersManagement() { const router = useRouter(); const [customers, setCustomers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [searchTerm, setSearchTerm] = useState(''); const [expandedCustomerId, setExpandedCustomerId] = useState(null); const [expandedSales, setExpandedSales] = useState([]); const [loadingSales, setLoadingSales] = useState(false); const [editingCustomer, setEditingCustomer] = useState(null); const [editForm, setEditForm] = useState>({}); const [saving, setSaving] = useState(false); const [darkMode, setDarkMode] = useState(false); const [mounted, setMounted] = useState(false); // Initialize dark mode useEffect(() => { setMounted(true); const saved = localStorage.getItem('darkMode'); if (saved !== null) { setDarkMode(JSON.parse(saved)); } else { setDarkMode(true); } }, []); useEffect(() => { if (!mounted) return; localStorage.setItem('darkMode', JSON.stringify(darkMode)); if (darkMode) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } }, [darkMode, mounted]); // Check authentication useEffect(() => { if (!mounted) return; const token = localStorage.getItem('authToken'); const expiry = localStorage.getItem('tokenExpiry'); if (!token || !expiry || Date.now() > parseInt(expiry)) { window.location.href = '/upadaj'; } }, [mounted]); // Fetch customers const fetchCustomers = useCallback(async () => { try { setLoading(true); const data = await customerService.getAll(); setCustomers(data); } catch (err) { setError('Greska pri ucitavanju kupaca'); console.error('Fetch error:', err); } finally { setLoading(false); } }, []); useEffect(() => { fetchCustomers(); }, [fetchCustomers]); // Search customers const filteredCustomers = customers.filter((customer) => { if (!searchTerm) return true; const term = searchTerm.toLowerCase(); return ( customer.name.toLowerCase().includes(term) || (customer.phone && customer.phone.toLowerCase().includes(term)) || (customer.city && customer.city.toLowerCase().includes(term)) ); }); // Toggle expanded row to show purchase history const handleToggleExpand = async (customerId: string) => { if (expandedCustomerId === customerId) { setExpandedCustomerId(null); setExpandedSales([]); return; } setExpandedCustomerId(customerId); setLoadingSales(true); try { const data = await customerService.getById(customerId); setExpandedSales(data.sales || []); } catch (err) { console.error('Error fetching customer sales:', err); setExpandedSales([]); } finally { setLoadingSales(false); } }; // Edit customer const handleStartEdit = (customer: Customer) => { setEditingCustomer(customer); setEditForm({ name: customer.name, phone: customer.phone || '', city: customer.city || '', notes: customer.notes || '', }); }; const handleCancelEdit = () => { setEditingCustomer(null); setEditForm({}); }; const handleSaveEdit = async () => { if (!editingCustomer) return; setSaving(true); try { await customerService.update(editingCustomer.id, editForm); setEditingCustomer(null); setEditForm({}); await fetchCustomers(); } catch (err) { setError('Greska pri cuvanju izmena'); console.error('Save error:', err); } finally { setSaving(false); } }; const handleLogout = () => { localStorage.removeItem('authToken'); localStorage.removeItem('tokenExpiry'); router.push('/upadaj'); }; const formatDate = (dateStr?: string) => { if (!dateStr) return '-'; return new Date(dateStr).toLocaleDateString('sr-Latn-RS', { day: '2-digit', month: '2-digit', year: 'numeric', }); }; const formatCurrency = (amount: number) => { return new Intl.NumberFormat('sr-Latn-RS', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0, }).format(amount) + ' RSD'; }; if (loading) { return (
Ucitavanje...
); } return (
{/* Main Content */}
Filamenteka

Upravljanje kupcima

{mounted && ( )}
{error && (
{error}
)} {/* Search bar */}
setSearchTerm(e.target.value)} className="w-full max-w-md px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Customer count */}

Ukupno kupaca: {filteredCustomers.length}

{/* Customer table */}
{filteredCustomers.length === 0 ? ( ) : ( filteredCustomers.map((customer) => ( <> {editingCustomer?.id === customer.id ? ( <>
Ime Telefon Grad Beleske Datum registracije Akcije
{searchTerm ? 'Nema rezultata pretrage' : 'Nema registrovanih kupaca'}
setEditForm({ ...editForm, name: e.target.value }) } className="w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white text-sm" /> setEditForm({ ...editForm, phone: e.target.value }) } className="w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white text-sm" /> setEditForm({ ...editForm, city: e.target.value }) } className="w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white text-sm" />