diff --git a/src/components/nostr/kinds/TrustedAssertionDetailRenderer.tsx b/src/components/nostr/kinds/TrustedAssertionDetailRenderer.tsx index 3aa81a8..5fa5dd8 100644 --- a/src/components/nostr/kinds/TrustedAssertionDetailRenderer.tsx +++ b/src/components/nostr/kinds/TrustedAssertionDetailRenderer.tsx @@ -17,40 +17,36 @@ import { } from "@/lib/nip73-helpers"; import { formatTimestamp } from "@/hooks/useLocale"; import { ShieldCheck, User, FileText, Hash } from "lucide-react"; +import { Progress } from "@/components/ui/progress"; import { cn } from "@/lib/utils"; +function rankColor(rank: number) { + if (rank >= 70) return { indicator: "bg-green-600", text: "text-green-600" }; + if (rank >= 40) + return { indicator: "bg-yellow-600", text: "text-yellow-600" }; + return { indicator: "bg-red-600", text: "text-red-600" }; +} + /** - * Color-coded rank bar with label + * Color-coded rank bar with label, using Progress component */ function RankBar({ rank }: { rank: number }) { const clamped = Math.min(100, Math.max(0, rank)); - const color = - clamped >= 70 - ? "bg-green-600" - : clamped >= 40 - ? "bg-yellow-600" - : "bg-red-600"; - const textColor = - clamped >= 70 - ? "text-green-600" - : clamped >= 40 - ? "text-yellow-600" - : "text-red-600"; + const { indicator, text } = rankColor(clamped); return (
Rank
-
-
-
+ {rank}/100 @@ -66,14 +62,23 @@ function RankBar({ rank }: { rank: number }) { function MetricRow({ label, value, + unit, }: { label: string; value: string | number; + unit?: string; }) { return (
{label} - {value} + + {value} + {unit && ( + + {unit} + + )} +
); } @@ -149,8 +154,10 @@ function SubjectHeader({ function UserMetrics({ event }: { event: NostrEvent }) { const data = getUserAssertionData(event); + type Metric = { label: string; value: string | number; unit?: string }; + // Activity section - const activity: { label: string; value: string | number }[] = []; + const activity: Metric[] = []; if (data.postCount !== undefined) activity.push({ label: "Posts", value: data.postCount.toLocaleString() }); if (data.replyCount !== undefined) @@ -180,16 +187,18 @@ function UserMetrics({ event }: { event: NostrEvent }) { }); // Zaps section - const zaps: { label: string; value: string | number }[] = []; + const zaps: Metric[] = []; if (data.zapAmountReceived !== undefined) zaps.push({ label: "Received", - value: `${data.zapAmountReceived.toLocaleString()} sats`, + value: data.zapAmountReceived.toLocaleString(), + unit: "sats", }); if (data.zapAmountSent !== undefined) zaps.push({ label: "Sent", - value: `${data.zapAmountSent.toLocaleString()} sats`, + value: data.zapAmountSent.toLocaleString(), + unit: "sats", }); if (data.zapCountReceived !== undefined) zaps.push({ @@ -204,16 +213,18 @@ function UserMetrics({ event }: { event: NostrEvent }) { if (data.zapAvgAmountDayReceived !== undefined) zaps.push({ label: "Avg/Day In", - value: `${data.zapAvgAmountDayReceived.toLocaleString()} sats`, + value: data.zapAvgAmountDayReceived.toLocaleString(), + unit: "sats", }); if (data.zapAvgAmountDaySent !== undefined) zaps.push({ label: "Avg/Day Out", - value: `${data.zapAvgAmountDaySent.toLocaleString()} sats`, + value: data.zapAvgAmountDaySent.toLocaleString(), + unit: "sats", }); // Moderation section - const moderation: { label: string; value: string | number }[] = []; + const moderation: Metric[] = []; if (data.reportsReceived !== undefined) moderation.push({ label: "Reports Received", @@ -231,7 +242,12 @@ function UserMetrics({ event }: { event: NostrEvent }) {
Activity {activity.map((m) => ( - + ))}
)} @@ -240,7 +256,12 @@ function UserMetrics({ event }: { event: NostrEvent }) {
Zaps {zaps.map((m) => ( - + ))}
)} @@ -249,7 +270,12 @@ function UserMetrics({ event }: { event: NostrEvent }) {
Moderation {moderation.map((m) => ( - + ))}
)} @@ -280,7 +306,8 @@ function UserMetrics({ event }: { event: NostrEvent }) { function EventMetrics({ event }: { event: NostrEvent }) { const data = getEventAssertionData(event); - const metrics: { label: string; value: string | number }[] = []; + const metrics: { label: string; value: string | number; unit?: string }[] = + []; if (data.commentCount !== undefined) metrics.push({ label: "Comments", @@ -303,7 +330,8 @@ function EventMetrics({ event }: { event: NostrEvent }) { if (data.zapAmount !== undefined) metrics.push({ label: "Zap Amount", - value: `${data.zapAmount.toLocaleString()} sats`, + value: data.zapAmount.toLocaleString(), + unit: "sats", }); if (metrics.length === 0) return null; @@ -325,7 +353,8 @@ function ExternalMetrics({ event }: { event: NostrEvent }) { const data = getExternalAssertionData(event); const types = getExternalAssertionTypes(event); - const metrics: { label: string; value: string | number }[] = []; + const metrics: { label: string; value: string | number; unit?: string }[] = + []; if (data.commentCount !== undefined) metrics.push({ label: "Comments", @@ -362,7 +391,12 @@ function ExternalMetrics({ event }: { event: NostrEvent }) {
Engagement {metrics.map((m) => ( - + ))}
)} diff --git a/src/components/nostr/kinds/TrustedAssertionRenderer.tsx b/src/components/nostr/kinds/TrustedAssertionRenderer.tsx index e9cfb77..011ea45 100644 --- a/src/components/nostr/kinds/TrustedAssertionRenderer.tsx +++ b/src/components/nostr/kinds/TrustedAssertionRenderer.tsx @@ -16,35 +16,31 @@ import { ASSERTION_KIND_LABELS, ASSERTION_TAG_LABELS, } from "@/lib/nip85-helpers"; +import { Progress } from "@/components/ui/progress"; import { cn } from "@/lib/utils"; +function rankColor(rank: number) { + if (rank >= 70) return { indicator: "bg-green-600", text: "text-green-600" }; + if (rank >= 40) + return { indicator: "bg-yellow-600", text: "text-yellow-600" }; + return { indicator: "bg-red-600", text: "text-red-600" }; +} + /** - * Color-coded rank bar: green (>=70), yellow (40-69), red (<40) + * Color-coded rank bar using Progress component */ function RankBar({ rank }: { rank: number }) { const clamped = Math.min(100, Math.max(0, rank)); - const color = - clamped >= 70 - ? "bg-green-600" - : clamped >= 40 - ? "bg-yellow-600" - : "bg-red-600"; - const textColor = - clamped >= 70 - ? "text-green-600" - : clamped >= 40 - ? "text-yellow-600" - : "text-red-600"; + const { indicator, text } = rankColor(clamped); return (
-
-
-
- + + {rank}
@@ -126,7 +122,7 @@ function MetricsPreview({ const tags = getAssertionTags(event); const rankTag = tags.find((t) => t.name === "rank"); - let summaryMetrics: { label: string; value: string }[] = []; + let summaryMetrics: { label: string; value: string; unit?: string }[] = []; if (event.kind === 30382) { const data = getUserAssertionData(event); @@ -143,7 +139,8 @@ function MetricsPreview({ if (data.zapAmountReceived !== undefined) summaryMetrics.push({ label: "Zaps In", - value: `${data.zapAmountReceived.toLocaleString()} sats`, + value: data.zapAmountReceived.toLocaleString(), + unit: "sats", }); } else if (event.kind === 30383 || event.kind === 30384) { const data = getEventAssertionData(event); @@ -160,7 +157,8 @@ function MetricsPreview({ if (data.zapAmount !== undefined) summaryMetrics.push({ label: "Zaps", - value: `${data.zapAmount.toLocaleString()} sats`, + value: data.zapAmount.toLocaleString(), + unit: "sats", }); } else if (event.kind === 30385) { const data = getExternalAssertionData(event); @@ -199,7 +197,10 @@ function MetricsPreview({
{summaryMetrics.map((m) => ( - {m.value}{" "} + {m.value} + {m.unit && ( + {m.unit} + )}{" "} {m.label} ))} diff --git a/src/components/ui/progress.tsx b/src/components/ui/progress.tsx index 882affb..924c179 100644 --- a/src/components/ui/progress.tsx +++ b/src/components/ui/progress.tsx @@ -5,8 +5,10 @@ import { cn } from "@/lib/utils"; const Progress = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, value, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { + indicatorClassName?: string; + } +>(({ className, value, indicatorClassName, ...props }, ref) => (