import { Info } from "lucide-react"; import { BrandLookupMentionTrendCard } from "@/client/features/ai-search/components/BrandLookupMentionTrendCard"; import { BrandLookupShareOfVoice } from "@/client/features/ai-search/components/BrandLookupShareOfVoice"; import { CitationTabsCard } from "@/client/features/ai-search/components/BrandLookupCitationsCard"; import { formatCount, formatPlatformLabel, PLATFORM_DOT_CLASS, } from "@/client/features/ai-search/platformLabels"; import type { BrandLookupResult } from "@/types/schemas/ai-search"; type Props = { result: BrandLookupResult; projectId: string; }; type PlatformRow = BrandLookupResult["perPlatform"][number]; type MetricKey = "mentions" | "aiSearchVolume"; export function BrandLookupResults({ result, projectId }: Props) { if (!result.hasData) { const erroredPlatforms = result.perPlatform.filter( (p) => p.status === "error", ); const allPlatformsErrored = erroredPlatforms.length === result.perPlatform.length && result.perPlatform.length > 0; if (allPlatformsErrored) { return (
AI mention data is temporarily unavailable for{" "} {result.resolvedTarget}. Please try again shortly.
); } return (
No AI mentions found for {result.resolvedTarget}.
{erroredPlatforms.length > 0 ? (

Note:{" "} {erroredPlatforms .map((p) => formatPlatformLabel(p.platform)) .join(" and ")}{" "} {erroredPlatforms.length === 1 ? "was" : "were"} unavailable — some mentions may be missing.

) : null}
); } const hasTrendData = result.monthlyVolume.length > 0; const sov = result.shareOfVoice; return (
{/* One shared grid so the cards align by construction: stats left, trend right, Share of Voice flowing into the next free half-width cell — whichever of trend/SoV is absent, the rest stay column-aligned. A lone stats card keeps full width instead of half a grid. */}
{hasTrendData ? : null} {sov ? : null}
); } function BrandHeader({ result }: { result: BrandLookupResult }) { return (

{result.resolvedTarget}

{result.detectedTargetType}

Updated {formatRelative(result.fetchedAt)}

); } function StatsCard({ result }: { result: BrandLookupResult }) { return (
); } function StatBlock({ label, tooltip, value, perPlatform, metric, }: { label: string; tooltip: string; value: number | null; perPlatform: PlatformRow[]; metric: MetricKey; }) { return (

{label}

{formatCount(value)}

{perPlatform.map((row) => ( ))}
); } function PlatformStatRow({ row, metric, }: { row: PlatformRow; metric: MetricKey; }) { const value = row.status === "error" ? null : row[metric]; return (
{formatPlatformLabel(row.platform)} {row.platform === "chat_gpt" ? ( ) : null} {row.status === "error" ? ( unavailable ) : null} {formatCount(value)}
); } function MentionTrendCard({ result }: { result: BrandLookupResult }) { return (

Mention trend (last 12 months)

); } function formatRelative(iso: string): string { const date = new Date(iso); if (Number.isNaN(date.getTime())) return "just now"; const diffMs = Date.now() - date.getTime(); const diffMin = Math.floor(diffMs / 60_000); if (diffMin < 1) return "just now"; if (diffMin < 60) return `${diffMin}m ago`; const diffHr = Math.floor(diffMin / 60); if (diffHr < 24) return `${diffHr}h ago`; const diffDay = Math.floor(diffHr / 24); return `${diffDay}d ago`; }