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 (
@@ -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) => (