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
Universal branded review card with trust-verified reviewer badge, star rating, review text, and helpful vote. Used across all domains where user reviews exist: Places (business reviews), BushTrade (seller reviews), Novels (book reviews), Health (provider reviews), Nhimbe (event reviews). The reviewer verification tier is always visible — Ubuntu principle: trust is earned and displayed.
View the full component source code below.
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { useNyuchiHarness } from "@/lib/harness"
/* ═══════════════════════════════════════════════════════════════
NYUCHI REVIEW CARD — Universal Brand Component (Pre-Wired)
Branded review display used across all domains with reviews.
Reviewer verification tier is always visible — trust matters.
Dynamic mineral accent via --brand-accent.
✅ HARNESS ✅ TOKENS ✅ STRICT MINERAL RULES ✅ TOUCH 48px+
═══════════════════════════════════════════════════════════════ */
interface NyuchiReviewCardProps {
/** Reviewer name */
reviewer: string
/** Reviewer avatar */
avatarUrl?: string
/** Verification tier (0-4) */
verificationTier?: 0 | 1 | 2 | 3 | 4
/** Star rating (1-5) */
rating: number
/** Review text */
text: string
/** Review date */
date?: string
/** Helpful vote count */
helpfulCount?: number
/** Whether current user found this helpful */
markedHelpful?: boolean
/** Helpful vote handler */
onHelpful?: () => void
/** Report handler */
onReport?: () => void
className?: string
}
const tierBadge = ["", "🟤", "🔵", "🟡", "🟣"] as const
export function NyuchiReviewCard({ loading = false,
reviewer, avatarUrl, verificationTier = 0, rating, text, date,
helpfulCount, markedHelpful, onHelpful, onReport, className,
}: NyuchiReviewCardProps) {
const { log, motion, LiveRegion } = useNyuchiHarness("review-card")
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-review-card" data-portal="https://design.nyuchi.com/components/nyuchi-review-card" data-loading role="article" className="animate-pulse rounded-[var(--radius-lg,14px)] bg-card p-4 ring-1 ring-foreground/10 space-y-3"><div className="flex items-center gap-2.5"><div className="size-9 rounded-full bg-muted" /><div className="flex-1 space-y-1"><div className="h-3 w-1/4 rounded bg-muted" /><div className="h-2.5 w-16 rounded bg-muted" /></div><div className="flex gap-0.5">{Array.from({length:5}).map((_,i)=>(<div key={i} className="size-3 rounded bg-muted" />))}</div></div><div className="h-3 w-full rounded bg-muted" /><div className="h-3 w-3/4 rounded bg-muted" /></div>)
return (
<div data-slot="nyuchi-review-card" role="article" className={cn("bg-card rounded-[var(--radius-lg,14px)] border border-border p-4 space-y-3", className)}>
{/* Reviewer + rating */}
<div className="flex items-start justify-between gap-2">
<div className="flex items-center gap-2.5">
<div className="size-9 shrink-0 rounded-full bg-muted flex items-center justify-center text-xs font-bold text-muted-foreground overflow-hidden">
{avatarUrl ? <img src={avatarUrl} alt={reviewer} className="size-full object-cover" /> : reviewer.charAt(0).toUpperCase()}
</div>
<div>
<div className="flex items-center gap-1">
<p className="text-sm font-medium text-foreground">{reviewer}</p>
{verificationTier > 0 && <span className="text-xs">{tierBadge[verificationTier]}</span>}
</div>
{date && <p className="text-[10px] text-muted-foreground">{date}</p>}
</div>
</div>
{/* Stars */}
<div className="flex items-center gap-0.5 text-sm">
{Array.from({ length: 5 }).map((_, i) => (
<span key={i} className={i < rating ? "text-[var(--color-gold,#FFD740)]" : "text-muted-foreground/20"}>★</span>
))}
</div>
</div>
{/* Review text */}
<p className="text-sm text-foreground leading-relaxed">{text}</p>
{/* Actions */}
<div className="flex items-center justify-between pt-1">
{onHelpful && (
<button onClick={onHelpful} className={cn("flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[11px] font-medium transition-colors", markedHelpful ? "bg-[var(--brand-accent,var(--color-malachite,#64FFDA))]/10 text-[var(--brand-accent,var(--color-malachite,#64FFDA))]" : "text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary,#00B0FF)] min-h-[48px] hover:bg-muted")}>
👍 Helpful{helpfulCount ? ` (${helpfulCount})` : ""}
</button>
)}
{onReport && (
<button onClick={onReport} className="text-[10px] text-muted-foreground hover:text-foreground transition-colors">Report</button>
)}
</div>
</div>
)
}
npx shadcn@latest add https://mzizi.dev/api/v1/ui/nyuchi-review-cardFetch this component's metadata and source code from the registry API.
/api/v1/ui/nyuchi-review-card