import React, { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Link } from 'react-router-dom'; import { useStore } from '../src/context/StoreContext'; type Tab = 'dashboard' | 'shop' | 'editorial' | 'orders'; type Section = { id: string; type: 'text' | 'image'; content: string; }; // Mock Data Types type Product = { id?: number; title: string; price: number; image: string; images: string[]; description?: string; details?: string[] }; type Article = { id?: number; title: string; date: string; image: string; sections: Section[]; category?: string; isFeatured?: boolean }; const Admin: React.FC = () => { const [activeTab, setActiveTab] = useState('dashboard'); // Modal State const [isModalOpen, setIsModalOpen] = useState(false); const [modalMode, setModalMode] = useState<'add' | 'edit'>('add'); const [editType, setEditType] = useState<'shop' | 'editorial' | null>(null); const [productForm, setProductForm] = useState({ id: '', title: '', price: 0, image: '', images: [], details: [] }); const [articleForm, setArticleForm] = useState
({ id: '', title: '', date: '', image: '', sections: [], isFeatured: false }); const [pendingSectionId, setPendingSectionId] = useState(null); const fileInputRef = React.useRef(null); const galleryInputRef = React.useRef(null); // Handlers const openAddModal = (type: 'shop' | 'editorial') => { setEditType(type); setModalMode('add'); // Reset forms setProductForm({ title: '', price: 0, image: '', images: [], details: [] }); setArticleForm({ title: '', date: new Date().toLocaleDateString('en-US', { month: 'short', day: '2-digit' }), image: '', sections: [], isFeatured: false }); setIsModalOpen(true); }; const openEditModal = (type: 'shop' | 'editorial', item: any) => { setEditType(type); setModalMode('edit'); if (type === 'shop') { setProductForm({ ...item, images: item.images || [], details: item.details || [] }); } else { setArticleForm({ ...item, sections: item.sections || [], isFeatured: !!item.isFeatured }); } setIsModalOpen(true); }; const addSection = (type: 'text' | 'image') => { setArticleForm(prev => ({ ...prev, sections: [...prev.sections, { id: Math.random().toString(), type, content: '' }] })); }; const updateSection = (id: string, content: string) => { setArticleForm(prev => ({ ...prev, sections: prev.sections.map(s => s.id === id ? { ...s, content } : s) })); }; const removeSection = (id: string) => { setArticleForm(prev => ({ ...prev, sections: prev.sections.filter(s => s.id !== id) })); }; const handleImageUpload = (e: React.ChangeEvent, isGallery: boolean = false) => { const files = e.target.files; if (files && files[0]) { const reader = new FileReader(); reader.onload = (event) => { const url = event.target?.result as string; if (pendingSectionId) { setArticleForm(prev => ({ ...prev, sections: prev.sections.map(s => s.id === pendingSectionId ? { ...s, content: url } : s) })); setPendingSectionId(null); } else if (isGallery) { // For gallery we handle multiple if needed, but let's stick to simple one at a time for base64 setProductForm(prev => ({ ...prev, images: [...prev.images, url] })); } else { if (editType === 'shop') { setProductForm(prev => ({ ...prev, image: url })); } else { setArticleForm(prev => ({ ...prev, image: url })); } } }; reader.readAsDataURL(files[0]); } }; const { products, articles, orders, fetchOrders, updateOrderStatus, addProduct, updateProduct, deleteProduct, addArticle, updateArticle, deleteArticle } = useStore(); const [selectedOrder, setSelectedOrder] = useState(null); React.useEffect(() => { if (activeTab === 'orders') { fetchOrders(); } }, [activeTab]); const handleSave = async () => { try { if (editType === 'shop') { const newProduct = { ...productForm, id: modalMode === 'add' ? undefined : productForm.id, slug: productForm.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]/g, ''), number: '01', images: productForm.images.includes(productForm.image) ? productForm.images : [productForm.image, ...productForm.images.filter(img => img !== productForm.image)], aspectRatio: 'aspect-[4/5]', details: productForm.details || [] }; if (modalMode === 'add') { await addProduct(newProduct as any); } else { await updateProduct(newProduct as any); } } else { const newArticle = { ...articleForm, id: modalMode === 'add' ? undefined : articleForm.id, slug: articleForm.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]/g, ''), category: articleForm.category || 'Studio Life', description: articleForm.sections.find(s => s.type === 'text')?.content?.substring(0, 150) || 'New article...', isFeatured: articleForm.isFeatured }; if (modalMode === 'add') { await addArticle(newArticle as any); } else { await updateArticle(newArticle as any); } } alert('Saved successfully!'); setIsModalOpen(false); } catch (err) { console.error('Save failed:', err); alert('Failed to save. Please make sure the server is running.'); } }; return (
{isModalOpen && (
setIsModalOpen(false)} className="absolute inset-0 bg-black/40 backdrop-blur-sm" /> {/* Modal Header */}
{modalMode === 'add' ? 'Create New' : 'Editing'}

{editType === 'shop' ? (modalMode === 'add' ? 'Product' : productForm.title) : (modalMode === 'add' ? 'Article' : articleForm.title)}

{editType === 'shop' ? (
setProductForm({ ...productForm, title: e.target.value })} className="w-full bg-stone-50 dark:bg-black border border-stone-200 dark:border-stone-800 p-4 text-lg focus:outline-none focus:border-stone-400 rounded-sm" placeholder="e.g. Speckled Vase" />
setProductForm({ ...productForm, price: parseFloat(e.target.value) })} className="w-full bg-stone-50 dark:bg-black border border-stone-200 dark:border-stone-800 p-4 text-lg focus:outline-none focus:border-stone-400 rounded-sm" placeholder="0.00" />