"use client"; import { useState, useEffect } from "react"; import Link from "next/link"; import { useAccount } from "@/contexts/AccountContext"; type Testimonial = { id: string; user: string; role: string; quote: string; rating: number; ts?: string; submitted?: boolean; }; const SEEDS: Testimonial[] = [ { id: "t1", user: "NeonSpectre", role: "Security Researcher", quote: "Tested dozens of setups. CyberLux's per-handle vault and local ledger model is the cleanest I've seen for this type of deployment.", rating: 9 }, { id: "t2", user: "CipherQueen", role: "Privacy Advocate", quote: "The attention to OPSEC detail shows. Account bundles, per-onion identity portability, and BTC-verify flow all work as described.", rating: 9 }, { id: "t3", user: "VoidWalker", role: "Long-Time Buyer", quote: "Been using CyberLux for eight months. Every drop landed on schedule, quality matched the listing, vendor communication was clean.", rating: 10 }, { id: "t4", user: "QuantumGhost", role: "Crypto Trader", quote: "The Bitcoin deposit flow is smoother than most CEX onboarding I've done. One confirmation, txid paste, credit applied. Done.", rating: 9 }, { id: "t5", user: "DataPhantom", role: "Journalist", quote: "The local-first architecture is what kept me here. Nothing leaves the browser unless I put it in an order. That's a real commitment.", rating: 10 }, { id: "t6", user: "ShadowBroker", role: "Vendor", quote: "Setting up a stall via the exchange and barter boards is straightforward. Dispute handling in the forum works as expected.", rating: 9 }, ]; const STORAGE_KEY = "cyberlux-testimonials-v1"; function loadStored(): Testimonial[] { if (typeof window === "undefined") return []; try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return []; return JSON.parse(raw) as Testimonial[]; } catch { return []; } } function saveStored(t: Testimonial[]) { if (typeof window === "undefined") return; localStorage.setItem(STORAGE_KEY, JSON.stringify(t)); } function starBar(n: number) { return (
{Array.from({ length: 10 }).map((_, i) => (
))}
); } export default function TestimonialsPage() { const { user } = useAccount(); const [submitted, setSubmitted] = useState([]); const [hydrated, setHydrated] = useState(false); const [formQuote, setFormQuote] = useState(""); const [formRole, setFormRole] = useState(""); const [formRating, setFormRating] = useState(0); const [formHover, setFormHover] = useState(0); const [formStatus, setFormStatus] = useState<"idle" | "success" | "error">("idle"); useEffect(() => { setSubmitted(loadStored()); setHydrated(true); }, []); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!formQuote.trim() || formRating === 0) { setFormStatus("error"); return; } const t: Testimonial = { id: `u_${Date.now()}`, user: user?.username ?? "anon", role: formRole.trim() || "CyberLux user", quote: formQuote.trim(), rating: formRating, ts: new Date().toLocaleDateString(), submitted: true, }; const updated = [...submitted, t]; setSubmitted(updated); saveStored(updated); setFormQuote(""); setFormRole(""); setFormRating(0); setFormStatus("success"); setTimeout(() => setFormStatus("idle"), 3000); }; const all = [...SEEDS, ...submitted]; const avgRating = all.reduce((s, t) => s + t.rating, 0) / all.length; return (

User Testimonials

Community feedback — submit yours below

COMMUNITY VOICES

What Our Users Say

Avg Rating
{avgRating.toFixed(1)} / 10
Total Reviews
{all.length}
{submitted.length > 0 && ( <>
From this device
{submitted.length}
)}
{all.map((t) => (
{t.user.charAt(0).toUpperCase()}
{t.user}
{t.role}
{t.rating}/10
{t.submitted && ( your submission )}

"{t.quote}"

{t.ts &&

Submitted {t.ts}

}
{starBar(t.rating)}
))}

Share Your Experience

Stored locally in your browser.{" "} {user ? ( Posting as @{user.username}. ) : ( Sign in )}{" "} No server submission, no account required.

setFormRole(e.target.value)} placeholder="e.g. Buyer, Security Researcher, Vendor…" className="w-full rounded-xl border border-gray-800 bg-gray-900 px-4 py-3 text-sm text-gray-200 focus:border-cyan-700 focus:outline-none" maxLength={60} />