import { useState } from 'react'; import { AlertTriangle, Flag } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { ReportDialog } from '@/components/ReportDialog'; import { useTrustBucket } from '@/hooks/useTrustBucket'; import { useUserReports } from '@/hooks/useUserReports'; import { useBatchTrustScores } from '@/hooks/useBatchTrustScores'; import { useMuteUser } from '@/hooks/useMuteUser'; import { FLAGGED_REPORTERS_THRESHOLD } from '@/lib/trustLadder'; import { useTranslation } from '@/contexts/language'; import { cn } from '@/lib/utils'; interface TrustFlaggedNoticeProps { pubkey: string; targetTitle?: string; className?: string; } /** * A safety notice for a flagged counterparty (seller, coach, organiser). It is * informational, not an automatic takedown: it shows that trusted people * reported the account, breaks the reporters down by the viewer's own network, * and offers Report / Dismiss. Dismissal is session-only — a safety signal * reappears on the next visit rather than staying hidden forever. */ export function TrustFlaggedNotice({ pubkey, targetTitle, className }: TrustFlaggedNoticeProps) { const { t } = useTranslation(); const { bucket, assertion } = useTrustBucket(pubkey); const { reporterPubkeys, reporterCount } = useUserReports(pubkey); const { data: scores } = useBatchTrustScores(reporterPubkeys); const [dismissed, setDismissed] = useState(false); const [reportOpen, setReportOpen] = useState(false); const muteUser = useMuteUser(); const flagged = bucket === 'flagged' || reporterCount >= FLAGGED_REPORTERS_THRESHOLD; if (!flagged || dismissed) return null; let follow = 0; let network = 0; let other = 0; for (const pk of reporterPubkeys) { const score = scores?.get(pk); if (score !== undefined && score >= 90) follow += 1; else if (score === 60) network += 1; else other += 1; } const trustedCount = assertion?.reporters ?? reporterCount; return (

{t('walletUi.trust.flaggedNoticeTitle')}

{t('walletUi.trust.flaggedNoticeDesc')}

{trustedCount > 0 && (

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

)} {(follow > 0 || network > 0 || other > 0) && (
{follow > 0 && ( )} {network > 0 && ( )} {other > 0 && ( )}
)}
); } function Chip({ label }: { label: string }) { return ( {label} ); }