nyuchimzizi
Mzizi — an open-architecture project of the Bundu Foundation, operated and developed by Nyuchi. Built on the Five African Minerals palette.
Built by Nyuchi Africav4.0.39
Transaction history row for the Mukoko wallet. Displays transaction type (send/receive/purchase/reward), amount with MIT currency formatting, counterparty, status, and timestamp. Maps to wallet.transaction table. Used in wallet history, payment confirmations, and financial reporting.
No interactive demo is registered for this component yet — the source is shown directly.
"use client"
// ── INFRASTRUCTURE HARNESS (auto-wired) ──
// Every brand component participates in observability, motion, a11y,
// and health monitoring via the harness. Zero manual config.
import { useNyuchiHarness } from "@/lib/harness"
import * as React from "react"
import { ArrowUpRight, ArrowDownLeft, ShoppingBag, Gift, Repeat, Clock, Check, X } from "@/lib/icons"
import { cn } from "@/lib/utils"
type TransactionType = "send" | "receive" | "purchase" | "reward" | "swap"
type TransactionStatus = "pending" | "completed" | "failed" | "cancelled"
const typeConfig: Record<TransactionType, { icon: React.ComponentType<{ className?: string }>; color: string; sign: string }> = {
send: { icon: ArrowUpRight, color: "var(--status-error, #FF5252)", sign: "-" },
receive: { icon: ArrowDownLeft, color: "var(--status-success, #64FFDA)", sign: "+" },
purchase: { icon: ShoppingBag, color: "var(--color-cobalt,#00B0FF)", sign: "-" },
reward: { icon: Gift, color: "var(--color-gold,#FFD740)", sign: "+" },
swap: { icon: Repeat, color: "var(--color-tanzanite,#B388FF)", sign: "" },
}
const statusConfig: Record<TransactionStatus, { icon: React.ComponentType<{ className?: string }>; color: string }> = {
pending: { icon: Clock, color: "var(--status-warning, #FFD740)" },
completed: { icon: Check, color: "var(--status-success, #64FFDA)" },
failed: { icon: X, color: "var(--status-error, #FF5252)" },
cancelled: { icon: X, color: "var(--status-neutral, #6B6B66)" },
}
interface NyuchiTransactionRowProps {
type: TransactionType
amount: number
currency?: string
counterparty?: string
description?: string
status?: TransactionStatus
timestamp: string | Date
onClick?: () => void
className?: string
}
function NyuchiTransactionRow({ loading = false,
type, amount, currency = "MIT", counterparty, description,
status = "completed", timestamp, onClick, className,
}: NyuchiTransactionRowProps) {
const { log, motion, LiveRegion } = useNyuchiHarness("transaction-row")
const animStyle = React.useMemo(() => motion.prefersReduced ? {} : { animation: `nyuchi-fade-slide-up ${motion.enterDuration}ms ${motion.enterEasing} both` }, [motion])
if (loading) return (<div data-slot="nyuchi-transaction-row" data-portal="https://design.nyuchi.com/components/nyuchi-transaction-row" data-loading role="listitem" className="animate-pulse flex items-center gap-3 py-3"><div className="size-10 shrink-0 rounded-full bg-muted" /><div className="flex-1 space-y-1.5"><div className="h-3.5 w-1/3 rounded bg-muted" /><div className="h-2.5 w-1/4 rounded bg-muted" /></div><div className="h-4 w-16 rounded bg-muted" /></div>)
if (loading) return (<div data-slot="nyuchi-transaction-row" data-loading role="listitem" className="animate-pulse flex items-center gap-3 py-3 px-4"><div className="size-10 shrink-0 rounded-full bg-muted" /><div className="flex-1 space-y-1.5"><div className="h-3.5 w-1/3 rounded bg-muted" /><div className="h-2.5 w-1/4 rounded bg-muted" /></div><div className="h-4 w-16 rounded bg-muted" /></div>)
const tc = typeConfig[type]
const sc = statusConfig[status]
const Icon = tc.icon
const time = typeof timestamp === "string" ? timestamp : timestamp.toLocaleDateString()
return (
<div data-slot="nyuchi-transaction-row" role="listitem" onClick={onClick}
className={cn("flex items-center gap-3 px-4 py-3", onClick && "cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary,#00B0FF)] hover:bg-foreground/[0.02] transition-colors", className)}>
<div className="flex size-10 shrink-0 items-center justify-center rounded-full"
style={{ backgroundColor: `color-mix(in srgb, ${tc.color} 12%, transparent)` }}>
<Icon className="size-5" style={{ color: tc.color }} />
</div>
<div className="min-w-0 flex-1">
<div className="text-sm font-medium text-foreground">{description || counterparty || type}</div>
<div className="mt-0.5 flex items-center gap-2 text-xs text-muted-foreground">
<span>{time}</span>
{status !== "completed" && (
<span className="flex items-center gap-0.5 capitalize" style={{ color: sc.color }}>
<sc.icon className="size-3" />{status}
</span>
)}
</div>
</div>
<span className={cn("text-sm font-semibold tabular-nums")} style={{ color: tc.color }}>
{tc.sign}{amount.toLocaleString()} {currency}
</span>
</div>
)
}
export { NyuchiTransactionRow }
export type { NyuchiTransactionRowProps, TransactionType, TransactionStatus }
The variants, sizes, and props surfaced by the registry. Each is sourced from the Supabase component_docs table.
Hit the registry API live and see the JSON the shadcn CLI consumes when it installs this component.
/api/v1/ui/nyuchi-transaction-rownpx shadcn@latest add https://mzizi.dev/api/v1/ui/nyuchi-transaction-rowcomponents/mukoko/mukoko-transaction-row.tsx