Organize/components/profile/blocked-link-requests.tsx

91 lines
2.9 KiB
TypeScript

"use client";
import { useState } from "react";
import { toast } from "sonner";
import { Loader2, ShieldCheck } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { AccountAvatar } from "@/components/profile/account-avatar";
import { unblockAccountLinkRequests } from "@/lib/actions/account-links";
import type { BlockedRequesterDTO } from "@/types/profile";
/**
* Accounts this account blocked from sending link requests (via "Deny and
* Block Account Link"). Lifting a block lets that account request again --
* the block is permanent for them otherwise, so it must be reversible
* here.
*/
export function BlockedLinkRequests({ blocks }: { blocks: BlockedRequesterDTO[] }) {
const [busyId, setBusyId] = useState<string | null>(null);
async function handleAllow(block: BlockedRequesterDTO) {
if (busyId) return;
setBusyId(block.blockId);
try {
const result = await unblockAccountLinkRequests(block.blockId);
if (result?.error) {
toast.error(result.error);
return;
}
toast.success(`${block.email} can send link requests to you again.`);
} catch {
toast.error("Couldn't allow requests from that account. Try again.");
} finally {
setBusyId(null);
}
}
return (
<Card>
<CardHeader>
<CardTitle>Blocked Account Link Requests</CardTitle>
<CardDescription>
These accounts can&apos;t send link requests to this one.
</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-3">
{blocks.map((block) => {
const busy = busyId === block.blockId;
return (
<div
key={block.blockId}
className="flex items-center justify-between gap-3 rounded-lg border p-3"
>
<div className="flex min-w-0 flex-1 items-center gap-3">
<AccountAvatar account={block} sizeClass="size-9" />
<div className="min-w-0">
<p className="truncate text-sm font-medium">{block.email}</p>
<p className="truncate text-xs text-muted-foreground">
{block.name ? `${block.name} · ` : ""}
blocked {block.blockedAtLabel}
</p>
</div>
</div>
<Button
variant="outline"
size="sm"
onClick={() => handleAllow(block)}
disabled={busyId !== null}
>
{busy ? (
<Loader2 className="size-3.5 animate-spin" />
) : (
<ShieldCheck className="size-3.5" />
)}
Allow requests
</Button>
</div>
);
})}
</CardContent>
</Card>
);
}