'use client'; import { useState, useEffect } from 'react'; import Header from '@/components/Header'; import dynamic from 'next/dynamic'; import { motion, AnimatePresence } from 'framer-motion'; import { ScanLine, Plus, Search, Trash2, Edit2, Layers, MapPin, X, AlertCircle, XCircle, Box } from 'lucide-react'; const Scanner = dynamic(() => import('@yudiel/react-qr-scanner').then(mod => mod.Scanner), { ssr: false }); export default function AdminLocations() { const [locations, setLocations] = useState([]); const [warehouses, setWarehouses] = useState([]); const [selectedWarehouse, setSelectedWarehouse] = useState(''); const [newCode, setNewCode] = useState(''); const [loading, setLoading] = useState(false); const [cameraEnabled, setCameraEnabled] = useState(false); const [camError, setCamError] = useState(''); const [activeFilter, setActiveFilter] = useState('all'); const [editingId, setEditingId] = useState(null); const [editCode, setEditCode] = useState(''); const [toast, setToast] = useState({ show: false, message: '', isError: false }); const showToast = (message, isError = false) => { setToast({ show: true, message, isError }); setTimeout(() => setToast({ show: false, message: '', isError: false }), 3000); }; useEffect(() => { fetchLocations(); fetchSettings(); }, []); const fetchSettings = async () => { try { const res = await fetch('/api/settings'); if (res.ok) { const data = await res.json(); setWarehouses(data.warehouses || []); if (data.warehouses?.length > 0) { setSelectedWarehouse(data.warehouses[0].id); } } } catch (e) { console.error(e); } }; const fetchLocations = async () => { try { const res = await fetch('/api/locations'); if (res.ok) { setLocations(await res.json()); } } catch (e) { console.error(e); } }; const handleAddOrEdit = async (codeValue) => { const targetCode = editingId ? editCode : (codeValue || newCode); if (!targetCode) return; if (!selectedWarehouse) { showToast('لطفاً ابتدا انبار را انتخاب کنید', true); return; } setLoading(true); try { const method = editingId ? 'PUT' : 'POST'; const url = editingId ? `/api/locations/${editingId}` : '/api/locations'; const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: targetCode, warehouse: selectedWarehouse }) }); const data = await res.json(); if (res.ok) { showToast(editingId ? 'قفسه با موفقیت ویرایش شد' : 'قفسه با موفقیت ثبت شد!'); setNewCode(''); setEditingId(null); setEditCode(''); fetchLocations(); } else { showToast(data.error || 'خطا در ثبت قفسه', true); } } catch (e) { showToast('خطای شبکه', true); } finally { setLoading(false); setCameraEnabled(false); } }; const handleDelete = async (id) => { if (!confirm('آیا از حذف این قفسه اطمینان دارید؟')) return; try { const res = await fetch(`/api/locations/${id}`, { method: 'DELETE' }); const data = await res.json(); if (res.ok) { showToast('قفسه حذف شد'); fetchLocations(); } else { showToast(data.error || 'خطا در حذف', true); } } catch (e) { showToast('خطای شبکه', true); } }; const handleScan = (detectedCodes) => { if (detectedCodes && detectedCodes.length > 0) { const scannedValue = detectedCodes[0].rawValue; handleAddOrEdit(scannedValue); } }; const handleError = (error) => { const msg = error?.message || error?.name || ''; if (msg.includes('Requested device not found')) { setCamError('دوربینی یافت نشد.'); } else { setCamError(msg || 'خطا در دسترسی به دوربین.'); } }; const floors = [...new Set(locations.map(loc => loc.floor))].sort(); const filteredLocations = activeFilter === 'all' ? locations : locations.filter(loc => loc.floor === activeFilter); return (
ثبت، ویرایش و مدیریت قفسههای انبار