import { Badge } from '@/components/ui/badge'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { CheckCircle2, HelpCircle, Flag } from 'lucide-react'; import { useTrustBucket } from '@/hooks/useTrustBucket'; import { bucketDescKey, bucketLabelKey, type TrustBucket } from '@/lib/trustLadder'; import { cn } from '@/lib/utils'; import { useTranslation } from '@/contexts/language'; interface TrustBadgeProps { pubkey: string | undefined; className?: string; showLabel?: boolean; size?: 'sm' | 'md' | 'lg'; /** * Also render the neutral "Unknown" bucket. Off by default so a card row is * not flooded with a badge on every author; surfaces with room can turn it on. */ showUnknown?: boolean; } const BUCKET_STYLE: Record< TrustBucket, { className: string; Icon: typeof CheckCircle2 } > = { verified: { className: 'border-green-500/50 text-green-400 bg-green-500/10', Icon: CheckCircle2, }, unknown: { className: 'border-gray-500/50 text-gray-400', Icon: HelpCircle, }, flagged: { className: 'border-red-500/60 text-red-400 bg-red-500/10', Icon: Flag, }, }; /** * TrustBadge shows one of three buckets for an author: * verified (someone in your network vouches), unknown (nothing said yet), or * flagged (trusted people reported them). Prefers a NIP-85 assertion, falls * back to the local web-of-trust score. Flagged always shows. */ export function TrustBadge({ pubkey, className, showLabel = true, size = 'sm', showUnknown = false, }: TrustBadgeProps) { const { t } = useTranslation(); const { bucket, assertion, directFollow, isLoading } = useTrustBucket(pubkey); if (isLoading) return null; // A direct follow (or yourself) is already known to the viewer — a "Verified" // mark there is redundant. Flagged is a safety signal and is never suppressed. if (bucket === 'verified' && directFollow) return null; if (bucket === 'unknown' && !showUnknown) return null; const { className: bucketClass, Icon } = BUCKET_STYLE[bucket]; const sizeClasses = { sm: 'text-[9px] px-1.5 py-0 h-4 gap-0.5', md: 'text-xs px-2 py-0.5 h-5 gap-1', lg: 'text-sm px-3 py-1 h-6 gap-1.5', }; const iconSizes = { sm: 'h-2.5 w-2.5', md: 'h-3 w-3', lg: 'h-4 w-4', }; return ( {showLabel && {t(bucketLabelKey(bucket))}}

{t(bucketLabelKey(bucket))}

{t(bucketDescKey(bucket))}

{bucket === 'flagged' && assertion?.reporters !== undefined && assertion.reporters > 0 && (

{t('walletUi.trust.reportedByTrusted', { count: assertion.reporters })}

)}
); }