AV: precise recolor to spec — warm dark backgrounds (#1c1815/#231d18/#26201a/#15110e) + gold #F0A623 / orange #D85A30 accents + warm text (#FBEFE0/#C9BBA8/#8a7e6e). 138 component files + 36 token swaps.
This commit is contained in:
@@ -91,7 +91,7 @@ interface StatCardProps {
|
||||
|
||||
function StatCard({ label, value, sub, accentColor, bgColor, icon, badge }: StatCardProps) {
|
||||
return (
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg p-5 flex flex-col gap-3 hover:border-[#333] transition-colors">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg p-5 flex flex-col gap-3 hover:border-[#333] transition-colors">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${bgColor}`}>
|
||||
<span className={accentColor}>{icon}</span>
|
||||
@@ -116,7 +116,7 @@ function StatCard({ label, value, sub, accentColor, bgColor, icon, badge }: Stat
|
||||
function ChartTooltip({ active, payload, label }: any) {
|
||||
if (!active || !payload?.length) return null;
|
||||
return (
|
||||
<div className="bg-[#1a1a1a] border border-[#333] rounded-lg px-3 py-2 text-xs font-body shadow-xl">
|
||||
<div className="bg-[#231d18] border border-[#333] rounded-lg px-3 py-2 text-xs font-body shadow-xl">
|
||||
{label && <p className="text-[#888] mb-1">{label}</p>}
|
||||
{payload.map((entry: any, i: number) => (
|
||||
<p key={i} style={{ color: entry.color }} className="leading-5">
|
||||
@@ -167,7 +167,7 @@ const EMPTY_STATS: ForumStats = {
|
||||
},
|
||||
};
|
||||
|
||||
const CATEGORY_COLORS = ['#ffb800', '#f59e0b', '#10b981', '#8b5cf6', '#ef4444', '#06b6d4', '#f97316', '#84cc16'];
|
||||
const CATEGORY_COLORS = ['#F0A623', '#f59e0b', '#10b981', '#8b5cf6', '#ef4444', '#06b6d4', '#f97316', '#84cc16'];
|
||||
|
||||
export default function ForumDashboardPage() {
|
||||
const { user, loading } = useAuth();
|
||||
@@ -204,7 +204,7 @@ export default function ForumDashboardPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="w-8 h-8 border-2 border-[#ffb800] border-t-transparent rounded-full animate-spin" />
|
||||
<div className="w-8 h-8 border-2 border-[#F0A623] border-t-transparent rounded-full animate-spin" />
|
||||
<p className="text-[#555] text-sm font-body">Loading forum dashboard…</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,7 +236,7 @@ export default function ForumDashboardPage() {
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={fetchStats}
|
||||
className="flex items-center gap-2 px-3 py-2 bg-[#111] border border-[#252525] rounded-lg text-xs text-[#888] hover:text-white hover:border-[#333] transition-all font-body"
|
||||
className="flex items-center gap-2 px-3 py-2 bg-[#111] border border-[#3a322b] rounded-lg text-xs text-[#888] hover:text-white hover:border-[#333] transition-all font-body"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
@@ -245,7 +245,7 @@ export default function ForumDashboardPage() {
|
||||
</button>
|
||||
<Link
|
||||
href="/admin/forum-moderation"
|
||||
className="flex items-center gap-2 px-3 py-2 bg-[#ffb800] rounded-lg text-xs text-white hover:bg-blue-500 transition-colors font-body font-semibold"
|
||||
className="flex items-center gap-2 px-3 py-2 bg-[#F0A623] rounded-lg text-xs text-white hover:bg-blue-500 transition-colors font-body font-semibold"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||
@@ -386,7 +386,7 @@ export default function ForumDashboardPage() {
|
||||
|
||||
{/* Thread Growth Chart */}
|
||||
<section className="mb-8">
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg p-6">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg p-6">
|
||||
<SectionHeader
|
||||
title="Thread Growth"
|
||||
subtitle="Weekly new threads and replies over the past 8 weeks"
|
||||
@@ -398,7 +398,7 @@ export default function ForumDashboardPage() {
|
||||
) : (
|
||||
<ResponsiveContainer width="100%" height={240}>
|
||||
<LineChart data={weeklyGrowth} margin={{ top: 5, right: 10, left: -20, bottom: 5 }}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#1a1a1a" />
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#231d18" />
|
||||
<XAxis dataKey="week" tick={{ fill: '#555', fontSize: 11 }} axisLine={false} tickLine={false} />
|
||||
<YAxis tick={{ fill: '#555', fontSize: 11 }} axisLine={false} tickLine={false} />
|
||||
<Tooltip content={<ChartTooltip />} />
|
||||
@@ -407,7 +407,7 @@ export default function ForumDashboardPage() {
|
||||
iconType="circle"
|
||||
iconSize={8}
|
||||
/>
|
||||
<Line type="monotone" dataKey="threads" stroke="#ffb800" strokeWidth={2} dot={{ fill: '#ffb800', r: 3 }} name="New Threads" />
|
||||
<Line type="monotone" dataKey="threads" stroke="#F0A623" strokeWidth={2} dot={{ fill: '#F0A623', r: 3 }} name="New Threads" />
|
||||
<Line type="monotone" dataKey="replies" stroke="#10b981" strokeWidth={2} dot={{ fill: '#10b981', r: 3 }} name="New Replies" />
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
@@ -419,33 +419,33 @@ export default function ForumDashboardPage() {
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||||
|
||||
{/* Top Categories */}
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#1a1a1a] flex items-center justify-between">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#231d18] flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-sm font-display font-bold text-white">Top Categories</h2>
|
||||
<p className="text-xs text-[#555] font-body mt-0.5">By thread count</p>
|
||||
</div>
|
||||
<Link href="/forum" className="text-xs text-[#ffb800] hover:text-blue-300 font-body transition-colors">View forum →</Link>
|
||||
<Link href="/forum" className="text-xs text-[#F0A623] hover:text-blue-300 font-body transition-colors">View forum →</Link>
|
||||
</div>
|
||||
{topCategories.length === 0 ? (
|
||||
<div className="px-5 py-10 text-center">
|
||||
<p className="text-[#555] text-sm font-body">No categories found</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="divide-y divide-[#1a1a1a]">
|
||||
<div className="divide-y divide-[#231d18]">
|
||||
{topCategories.map((cat, idx) => {
|
||||
const maxThreads = topCategories[0]?.thread_count ?? 1;
|
||||
const pct = maxThreads > 0 ? Math.round((cat.thread_count / maxThreads) * 100) : 0;
|
||||
const color = CATEGORY_COLORS[idx % CATEGORY_COLORS.length];
|
||||
return (
|
||||
<div key={cat.id} className="px-5 py-3 hover:bg-[#0d0d0d] transition-colors">
|
||||
<div key={cat.id} className="px-5 py-3 hover:bg-[#1c1815] transition-colors">
|
||||
<div className="flex items-center gap-3 mb-1.5">
|
||||
<span className="text-base leading-none">{cat.icon}</span>
|
||||
<span className="text-sm text-white font-body flex-1 truncate">{cat.name}</span>
|
||||
<span className="text-xs text-[#888] font-body font-semibold">{cat.thread_count} threads</span>
|
||||
<span className="text-xs text-[#555] font-body">{cat.post_count} posts</span>
|
||||
</div>
|
||||
<div className="h-1.5 bg-[#1a1a1a] rounded-full overflow-hidden ml-7">
|
||||
<div className="h-1.5 bg-[#231d18] rounded-full overflow-hidden ml-7">
|
||||
<div
|
||||
className="h-full rounded-full transition-all duration-500"
|
||||
style={{ width: `${pct}%`, backgroundColor: color }}
|
||||
@@ -459,8 +459,8 @@ export default function ForumDashboardPage() {
|
||||
</div>
|
||||
|
||||
{/* Active Users */}
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#1a1a1a]">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#231d18]">
|
||||
<h2 className="text-sm font-display font-bold text-white">Active Users</h2>
|
||||
<p className="text-xs text-[#555] font-body mt-0.5">Most active in the last 30 days</p>
|
||||
</div>
|
||||
@@ -469,13 +469,13 @@ export default function ForumDashboardPage() {
|
||||
<p className="text-[#555] text-sm font-body">No active users found</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="divide-y divide-[#1a1a1a]">
|
||||
<div className="divide-y divide-[#231d18]">
|
||||
{activeUsers.map((u, idx) => (
|
||||
<div key={u.author_id} className="px-5 py-3 flex items-center gap-3 hover:bg-[#0d0d0d] transition-colors">
|
||||
<div className="w-6 h-6 rounded-full bg-[#1a1a1a] flex items-center justify-center flex-shrink-0 text-xs font-bold font-body text-[#555]">
|
||||
<div key={u.author_id} className="px-5 py-3 flex items-center gap-3 hover:bg-[#1c1815] transition-colors">
|
||||
<div className="w-6 h-6 rounded-full bg-[#231d18] flex items-center justify-center flex-shrink-0 text-xs font-bold font-body text-[#555]">
|
||||
{idx + 1}
|
||||
</div>
|
||||
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-[#ffb800] to-[#8b5cf6] flex items-center justify-center flex-shrink-0">
|
||||
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-[#F0A623] to-[#8b5cf6] flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-xs font-bold text-white font-body">
|
||||
{u.author_name.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
@@ -498,14 +498,14 @@ export default function ForumDashboardPage() {
|
||||
{/* Category Bar Chart */}
|
||||
{topCategories.length > 0 && (
|
||||
<section className="mb-8">
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg p-6">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg p-6">
|
||||
<SectionHeader
|
||||
title="Category Activity"
|
||||
subtitle="Thread and post distribution across categories"
|
||||
/>
|
||||
<ResponsiveContainer width="100%" height={220}>
|
||||
<BarChart data={topCategories} margin={{ top: 5, right: 10, left: -20, bottom: 5 }}>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#1a1a1a" />
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#231d18" />
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
tick={{ fill: '#555', fontSize: 10 }}
|
||||
@@ -523,7 +523,7 @@ export default function ForumDashboardPage() {
|
||||
iconType="circle"
|
||||
iconSize={8}
|
||||
/>
|
||||
<Bar dataKey="thread_count" fill="#ffb800" radius={[3, 3, 0, 0]} name="Threads" />
|
||||
<Bar dataKey="thread_count" fill="#F0A623" radius={[3, 3, 0, 0]} name="Threads" />
|
||||
<Bar dataKey="post_count" fill="#10b981" radius={[3, 3, 0, 0]} name="Posts" />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
@@ -533,22 +533,22 @@ export default function ForumDashboardPage() {
|
||||
|
||||
{/* Moderation Stats */}
|
||||
<section className="mb-8">
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#1a1a1a] flex items-center justify-between">
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-[#231d18] flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-sm font-display font-bold text-white">Moderation Stats</h2>
|
||||
<p className="text-xs text-[#555] font-body mt-0.5">Current moderation state across all forum content</p>
|
||||
</div>
|
||||
<Link href="/admin/forum-moderation" className="text-xs text-[#ffb800] hover:text-blue-300 font-body transition-colors">Open moderation →</Link>
|
||||
<Link href="/admin/forum-moderation" className="text-xs text-[#F0A623] hover:text-blue-300 font-body transition-colors">Open moderation →</Link>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 divide-x divide-y sm:divide-y-0 divide-[#1a1a1a]">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 divide-x divide-y sm:divide-y-0 divide-[#231d18]">
|
||||
{[
|
||||
{ label: 'Flagged Threads', value: moderation.flaggedThreads, color: 'text-red-400', bg: 'bg-red-500/10' },
|
||||
{ label: 'Flagged Replies', value: moderation.flaggedReplies, color: 'text-red-400', bg: 'bg-red-500/10' },
|
||||
{ label: 'Locked Threads', value: moderation.lockedThreads, color: 'text-orange-400', bg: 'bg-orange-500/10' },
|
||||
{ label: 'Pinned Threads', value: moderation.pinnedThreads, color: 'text-yellow-400', bg: 'bg-yellow-500/10' },
|
||||
{ label: 'Featured Threads', value: moderation.featuredThreads, color: 'text-blue-400', bg: 'bg-blue-500/10' },
|
||||
{ label: 'Hidden Replies', value: moderation.hiddenReplies, color: 'text-[#888]', bg: 'bg-[#1a1a1a]' },
|
||||
{ label: 'Hidden Replies', value: moderation.hiddenReplies, color: 'text-[#888]', bg: 'bg-[#231d18]' },
|
||||
].map(({ label, value, color, bg }) => (
|
||||
<div key={label} className="px-4 py-5 flex flex-col items-center gap-1 text-center">
|
||||
<p className={`text-2xl font-bold font-display ${color}`}>{value}</p>
|
||||
|
||||
Reference in New Issue
Block a user