From 0832c0f9e5fe17d577cab806b3b1eb93140faf94 Mon Sep 17 00:00:00 2001 From: belisards Date: Sun, 3 May 2026 16:32:19 -0300 Subject: [PATCH] feat(admin): guests CRUD UI with copy-link --- app/admin/guests/page.tsx | 97 +++++++++++++++++++++++++++++++++++++++ app/admin/page.tsx | 6 +++ 2 files changed, 103 insertions(+) create mode 100644 app/admin/guests/page.tsx diff --git a/app/admin/guests/page.tsx b/app/admin/guests/page.tsx new file mode 100644 index 0000000..63963e9 --- /dev/null +++ b/app/admin/guests/page.tsx @@ -0,0 +1,97 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import AdminGuard from '@/components/admin-guard'; +import { guestsApi, type Guest } from '@/lib/api'; + +export default function AdminGuestsPage() { + return ( + + + + ); +} + +function GuestsManager() { + const [guests, setGuests] = useState([]); + const [name, setName] = useState(''); + const [busy, setBusy] = useState(false); + const [err, setErr] = useState(''); + + const load = async () => setGuests(await guestsApi.list()); + useEffect(() => { load(); }, []); + + const linkFor = (g: Guest) => { + const base = typeof window === 'undefined' ? '' : window.location.origin; + return `${base}/?usr=${g.id}`; + }; + + const onCreate = async (e: React.FormEvent) => { + e.preventDefault(); + setErr(''); + if (!name.trim()) return; + setBusy(true); + try { + await guestsApi.create(name.trim()); + setName(''); + await load(); + } catch (e: any) { + setErr(e.message || 'Erro ao criar'); + } finally { + setBusy(false); + } + }; + + const onRename = async (g: Guest) => { + const next = prompt('Novo nome', g.name); + if (!next || next.trim() === g.name) return; + await guestsApi.rename(g.id, next.trim()); + await load(); + }; + + const onDelete = async (g: Guest) => { + if (!confirm(`Excluir o convidado ${g.name}? As reservas dele(a) ficarão sem dono.`)) return; + await guestsApi.delete(g.id); + await load(); + }; + + const onCopy = async (g: Guest) => { + await navigator.clipboard.writeText(linkFor(g)); + }; + + return ( +
+

Convidados

+ +
+ setName(e.target.value)} + placeholder="Nome do convidado" + className="flex-1 border rounded px-3 py-2" + /> + +
+ {err &&
{err}
} + +
    + {guests.map((g) => ( +
  • +
    +
    {g.name}
    +
    {linkFor(g)}
    +
    +
    + + + +
    +
  • + ))} + {guests.length === 0 &&
  • Nenhum convidado ainda
  • } +
+
+ ); +} diff --git a/app/admin/page.tsx b/app/admin/page.tsx index 381ea9d..747bc53 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -154,6 +154,12 @@ function AdminPageContent() { > View Public Site + + Convidados +