'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import AdminGuard from '@/components/admin-guard'; import { authApi, wishlistsApi, itemsApi, settingsApi, type Wishlist, type Item, type Settings, } from '@/lib/api'; import Header from '@/components/header'; import Link from 'next/link'; import ItemCard from '@/components/admin/ItemCard'; import ItemForm from '@/components/admin/ItemForm'; import ImageUpload from '@/components/image-upload'; import RichTextEditor from '@/components/RichTextEditor'; export default function AdminPage() { return ( ); } function AdminPageContent() { const router = useRouter(); // Single wishlist state const [wishlist, setWishlist] = useState(null); const [items, setItems] = useState([]); const [isLoading, setIsLoading] = useState(true); // Settings const [settings, setSettings] = useState({ siteTitle: 'Wishlist', homepageSubtext: '', }); // Unified config edit state const [isEditingWishlist, setIsEditingWishlist] = useState(false); const [editForm, setEditForm] = useState({ name: '', slug: '', description: '', preferences: '', imageUrl: '', isPublic: true, siteTitle: '', homepageSubtext: '', }); const [editError, setEditError] = useState(''); const [isWishlistImageUploading, setIsWishlistImageUploading] = useState(false); // Item management state const [editingItemId, setEditingItemId] = useState(null); const [showAddItemForm, setShowAddItemForm] = useState(false); const [newItemError, setNewItemError] = useState(''); const logout = async () => { await authApi.logout(); router.push('/'); }; useEffect(() => { fetchData(); }, []); const fetchData = async () => { try { const [lists, settingsData] = await Promise.all([ wishlistsApi.getAll(), settingsApi.getSettings(), ]); setSettings(settingsData); if (lists.length > 0) { const w = lists[0]; setWishlist(w); const itemsData = await itemsApi.getAll(w.id); setItems(itemsData.sort((a, b) => a.sortOrder - b.sortOrder)); } } catch (error) { console.error('Failed to fetch data:', error); } finally { setIsLoading(false); } }; const refreshItems = async () => { if (!wishlist) return; const itemsData = await itemsApi.getAll(wishlist.id); setItems(itemsData.sort((a, b) => a.sortOrder - b.sortOrder)); }; // Wishlist edit handlers const startEditingWishlist = () => { if (!wishlist) return; setEditForm({ name: wishlist.name, slug: wishlist.slug, description: wishlist.description || '', preferences: wishlist.preferences || '', imageUrl: wishlist.imageUrl || '', isPublic: wishlist.isPublic, siteTitle: settings.siteTitle, homepageSubtext: settings.homepageSubtext, }); setEditError(''); setIsEditingWishlist(true); }; const handleUpdateWishlist = async (e: React.FormEvent) => { e.preventDefault(); if (!wishlist) return; setEditError(''); try { const { siteTitle, homepageSubtext, ...wishlistFields } = editForm; const [updated] = await Promise.all([ wishlistsApi.update(wishlist.id, wishlistFields), settingsApi.updateSettings({ siteTitle, homepageSubtext }), ]); setWishlist(updated); setSettings({ siteTitle, homepageSubtext }); setIsEditingWishlist(false); } catch (error: any) { setEditError(error.message || 'Failed to update settings'); } }; // Item handlers const handleCreateItem = async (itemData: Partial) => { if (!wishlist) return; setNewItemError(''); try { await itemsApi.create(wishlist.id, itemData); setShowAddItemForm(false); await refreshItems(); } catch (error: any) { setNewItemError(error.message || 'Failed to create item'); throw error; } }; const handleUpdateItem = async (itemData: Partial) => { if (!editingItemId) return; try { await itemsApi.update(editingItemId, itemData); setEditingItemId(null); await refreshItems(); } catch (error: any) { alert(error.message || 'Failed to update item'); throw error; } }; const handleDeleteItem = async (itemId: string) => { if (!confirm('Tem certeza que deseja excluir este item?')) return; try { await itemsApi.delete(itemId); await refreshItems(); } catch { alert('Failed to delete item'); } }; const handleMoveItemUp = async (itemId: string) => { const currentIndex = items.findIndex((item) => item.id === itemId); if (currentIndex <= 0) return; try { await itemsApi.reorder(itemId, currentIndex - 1); await refreshItems(); } catch (error: any) { alert(error?.message || 'Failed to reorder item'); } }; const handleMoveItemDown = async (itemId: string) => { const currentIndex = items.findIndex((item) => item.id === itemId); if (currentIndex === -1 || currentIndex === items.length - 1) return; try { await itemsApi.reorder(itemId, currentIndex + 1); await refreshItems(); } catch (error: any) { alert(error?.message || 'Failed to reorder item'); } }; const editingItem = items.find((item) => item.id === editingItemId); return ( Reservas Convidados Logout > } /> {isLoading ? ( Carregando... ) : ( <> {/* Unified Settings & Wishlist Config */} {wishlist && ( Configurações {!isEditingWishlist && ( Editar )} {isEditingWishlist ? ( {editError && ( {editError} )} Título do site * setEditForm((prev) => ({ ...prev, siteTitle: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white" /> Nome da lista * setEditForm((prev) => ({ ...prev, name: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white" /> Mensagem de boas-vindas setEditForm((prev) => ({ ...prev, homepageSubtext: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white" rows={2} /> Descrição da lista setEditForm((prev) => ({ ...prev, description: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white" rows={2} /> Preferências setEditForm((prev) => ({ ...prev, preferences: html }))} placeholder="Interesses e preferências gerais..." /> setEditForm((prev) => ({ ...prev, imageUrl: url }))} onUploadStateChange={setIsWishlistImageUploading} type="wishlist" label="Imagem da Lista" /> setIsEditingWishlist(false)} className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer" > Cancelar {isWishlistImageUploading ? 'Enviando...' : 'Salvar'} ) : ( {wishlist.imageUrl && ( )} Título do site {settings.siteTitle} Nome da lista {wishlist.name} {settings.homepageSubtext && ( Mensagem de boas-vindas {settings.homepageSubtext} )} {wishlist.description && ( Descrição {wishlist.description} )} )} )} {/* Items Section */} {wishlist && ( Itens ({items.length}) { setShowAddItemForm(true); setNewItemError(''); }} className="inline-flex items-center px-6 py-3 border border-transparent text-base font-semibold rounded-lg text-white bg-indigo-600 hover:bg-indigo-700 shadow-md hover:shadow-lg transition-all cursor-pointer" > + Adicionar Item {/* Add Item Form */} {showAddItemForm && ( { setShowAddItemForm(false); setNewItemError(''); }} error={newItemError} /> )} {items.length === 0 && !showAddItemForm ? ( Nenhum item ainda { setShowAddItemForm(true); setNewItemError(''); }} className="inline-flex items-center px-6 py-3 border border-transparent text-base font-semibold rounded-lg text-white bg-indigo-600 hover:bg-indigo-700 shadow-md hover:shadow-lg transition-all cursor-pointer" > Adicionar Primeiro Item ) : ( {items.map((item, index) => ( {editingItemId === item.id ? ( setEditingItemId(null)} /> ) : ( setEditingItemId(item.id)} onDelete={() => handleDeleteItem(item.id)} onMoveUp={() => handleMoveItemUp(item.id)} onMoveDown={() => handleMoveItemDown(item.id)} isFirst={index === 0} isLast={index === items.length - 1} /> )} ))} )} )} {!wishlist && !isLoading && ( Nenhuma lista encontrada no banco de dados. )} > )} ); }
Carregando...
Título do site
{settings.siteTitle}
Nome da lista
{wishlist.name}
Mensagem de boas-vindas
{settings.homepageSubtext}
Descrição
{wishlist.description}
Nenhum item ainda
Nenhuma lista encontrada no banco de dados.