"use client"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { toast } from "@/components/ui/use-toast"; import { useTranslation } from "@/lib/i18n/client"; import { api } from "@/lib/trpc"; import { Check, Loader2, Mail, X } from "lucide-react"; interface Invitation { id: string; role: string; list: { name: string; icon?: string; description?: string | null; owner?: { name?: string; } | null; }; } function InvitationRow({ invitation }: { invitation: Invitation }) { const { t } = useTranslation(); const utils = api.useUtils(); const acceptInvitation = api.lists.acceptInvitation.useMutation({ onSuccess: async () => { toast({ description: t("lists.invitations.accepted"), }); await Promise.all([ utils.lists.getPendingInvitations.invalidate(), utils.lists.list.invalidate(), ]); }, onError: (error) => { toast({ variant: "destructive", description: error.message || t("lists.invitations.failed_to_accept"), }); }, }); const declineInvitation = api.lists.declineInvitation.useMutation({ onSuccess: async () => { toast({ description: t("lists.invitations.declined"), }); await utils.lists.getPendingInvitations.invalidate(); }, onError: (error) => { toast({ variant: "destructive", description: error.message || t("lists.invitations.failed_to_decline"), }); }, }); return (
{invitation.list.name} {invitation.list.icon}
{invitation.list.description && (
{invitation.list.description}
)}
{t("lists.invitations.invited_by")}{" "} {invitation.list.owner?.name || "Unknown"} {" • "} {invitation.role}
); } export function PendingInvitationsCard() { const { t } = useTranslation(); const { data: invitations, isLoading } = api.lists.getPendingInvitations.useQuery(); if (isLoading) { return null; } if (!invitations || invitations.length === 0) { return null; } return ( {t("lists.invitations.pending")} ({invitations.length}) {t("lists.invitations.description")} {invitations.map((invitation) => ( ))} ); }