Add delete action to invitations and UI improvements

Introduces a delete button for unused invitations in InvitationsListCard, allowing admins to remove invites. Also improves layout and spacing in the invitations card, formats order totals with currency in RecentOrdersCard, and hides several unused cards in the admin page as requested.
This commit is contained in:
NotII
2025-10-15 17:53:01 +01:00
parent e7c06e4352
commit 2808ce6919
3 changed files with 26 additions and 45 deletions

View File

@@ -16,6 +16,15 @@ export default function InvitationsListCard() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
async function deleteInvite(id: string) {
try {
await fetchClient(`/admin/invitations/${id}`, { method: 'DELETE' });
setInvites(prev => prev.filter(i => i._id !== id));
} catch (e: any) {
setError(e?.message || 'Failed to delete invitation');
}
}
useEffect(() => {
let mounted = true;
(async () => {
@@ -47,8 +56,8 @@ export default function InvitationsListCard() {
{invites.map((inv) => {
const expired = new Date(inv.expiresAt).getTime() < Date.now();
return (
<div key={inv._id} className="rounded border border-border/50 p-3 text-sm flex items-center justify-between">
<div className="space-y-1">
<div key={inv._id} className="rounded border border-border/50 p-3 text-sm flex items-center justify-between gap-3">
<div className="space-y-1 min-w-0">
<div>
Code: <span className="font-mono px-1.5 py-0.5 rounded bg-muted">{inv.code}</span>
</div>
@@ -56,9 +65,19 @@ export default function InvitationsListCard() {
Created: {new Date(inv.createdAt).toLocaleString()} · Expires: {new Date(inv.expiresAt).toLocaleString()}
</div>
</div>
<span className={`text-xs px-2 py-0.5 rounded ${inv.isUsed ? 'bg-emerald-500/15 text-emerald-400' : expired ? 'bg-rose-500/15 text-rose-400' : 'bg-amber-500/15 text-amber-400'}`}>
{inv.isUsed ? 'Used' : expired ? 'Expired' : 'Active'}
</span>
<div className="flex items-center gap-2 shrink-0">
<span className={`text-xs px-2 py-0.5 rounded ${inv.isUsed ? 'bg-emerald-500/15 text-emerald-400' : expired ? 'bg-rose-500/15 text-rose-400' : 'bg-amber-500/15 text-amber-400'}`}>
{inv.isUsed ? 'Used' : expired ? 'Expired' : 'Active'}
</span>
{!inv.isUsed && (
<button
onClick={() => deleteInvite(inv._id)}
className="text-xs px-2 py-1 rounded border border-border hover:bg-muted/40"
>
Delete
</button>
)}
</div>
</div>
);
})}