"use client"; import { useState, useTransition } from "react"; import { Copy, Plus, Trash2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { createInviteCode, deleteInviteCode } from "../actions"; type InviteCode = { id: string; code: string; maxUses: number; uses: number; expiresAt: string | null; createdAt: string; creator: { name: string | null }; }; export function InviteManager({ inviteCodes, appUrl, }: { inviteCodes: InviteCode[]; appUrl: string; }) { const [maxUses, setMaxUses] = useState(1); const [expiresInDays, setExpiresInDays] = useState(7); const [noExpiry, setNoExpiry] = useState(false); const [isPending, startTransition] = useTransition(); const [copiedId, setCopiedId] = useState(null); function handleCreate() { startTransition(async () => { await createInviteCode({ maxUses, expiresInDays: noExpiry ? null : expiresInDays, }); }); } function handleDelete(id: string) { startTransition(async () => { await deleteInviteCode(id); }); } function copyLink(code: string, id: string) { const url = `${appUrl}/register?code=${code}`; navigator.clipboard.writeText(url); setCopiedId(id); setTimeout(() => setCopiedId(null), 2000); } function getStatus(invite: InviteCode) { if (invite.uses >= invite.maxUses) return "used"; if (invite.expiresAt && new Date(invite.expiresAt) < new Date()) return "expired"; return "active"; } return (
Create Invite Code Generate a new invite code to share with someone
setMaxUses(Number(e.target.value))} className="w-24" />
setExpiresInDays(Number(e.target.value))} disabled={noExpiry} className="w-24" />
setNoExpiry(e.target.checked)} className="h-4 w-4" />
Invite Codes {inviteCodes.length} invite code{inviteCodes.length !== 1 ? "s" : ""} created {inviteCodes.length === 0 ? (

No invite codes yet. Create one above.

) : ( Code Status Uses Expires Created Actions {inviteCodes.map((invite) => { const status = getStatus(invite); return ( {invite.code} {status} {invite.uses} / {invite.maxUses} {invite.expiresAt ? new Date(invite.expiresAt).toLocaleDateString() : "Never"} {new Date(invite.createdAt).toLocaleDateString()}
); })}
)}
); }