first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import Link from 'next/link';
|
||||
import { AdminShell } from '@/components/admin/AdminShell';
|
||||
import { EDITABLE_SECTIONS } from '@/lib/content/sections';
|
||||
import { sectionStatus } from '@/lib/db/store';
|
||||
import { passwordConfigured } from '@/lib/auth/session';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
function timeAgo(ts: number): string {
|
||||
const s = Math.floor((Date.now() - ts) / 1000);
|
||||
if (s < 60) return 'just now';
|
||||
const m = Math.floor(s / 60);
|
||||
if (m < 60) return `${m}m ago`;
|
||||
const h = Math.floor(m / 60);
|
||||
if (h < 24) return `${h}h ago`;
|
||||
return `${Math.floor(h / 24)}d ago`;
|
||||
}
|
||||
|
||||
export default function AdminDashboard() {
|
||||
const status = sectionStatus();
|
||||
const usingDefaultPassword = !process.env.ADMIN_PASSWORD && passwordConfigured();
|
||||
const edited = Object.keys(status).length;
|
||||
|
||||
return (
|
||||
<AdminShell>
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-2xl font-bold text-white">Dashboard</h1>
|
||||
<p className="mt-1 text-sm text-slate-400">
|
||||
Edit every section of the site. {edited > 0 ? `${edited} section${edited > 1 ? 's' : ''} customized.` : 'All sections are at their defaults.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{usingDefaultPassword && (
|
||||
<div className="mb-6 rounded-xl border border-magenta/30 bg-magenta/5 p-4 text-sm text-magenta">
|
||||
<strong>Heads up:</strong> no <code className="font-mono">ADMIN_PASSWORD</code> is set, so the dev default
|
||||
(<code className="font-mono">admin</code>) is in use. Set one in your environment before going live.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
{EDITABLE_SECTIONS.map((s) => {
|
||||
const edited = status[s.key];
|
||||
return (
|
||||
<Link
|
||||
key={s.key}
|
||||
href={`/admin/sections/${s.key}`}
|
||||
className="group rounded-xl border border-white/8 bg-white/[0.02] p-5 transition-colors hover:border-electric/30 hover:bg-electric/[0.03]"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="font-semibold text-white group-hover:text-electric">
|
||||
{s.label.en}
|
||||
<span className="ms-2 font-fa text-sm font-normal text-slate-500">
|
||||
{s.label.fa}
|
||||
</span>
|
||||
</h2>
|
||||
{edited ? (
|
||||
<span className="rounded-full border border-emerald/30 bg-emerald/5 px-2 py-0.5 font-mono text-[0.6rem] uppercase tracking-wider text-emerald">
|
||||
edited · {timeAgo(edited)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="rounded-full border border-white/10 px-2 py-0.5 font-mono text-[0.6rem] uppercase tracking-wider text-slate-500">
|
||||
default
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-2 text-sm text-slate-400">{s.desc.en}</p>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-3 grid gap-3 sm:grid-cols-2">
|
||||
<Link
|
||||
href="/admin/posts"
|
||||
className="group rounded-xl border border-violet/20 bg-violet/[0.03] p-5 transition-colors hover:border-violet/40 hover:bg-violet/[0.06]"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="font-semibold text-white group-hover:text-violet">
|
||||
Journal articles
|
||||
<span className="ms-2 font-fa text-sm font-normal text-slate-500">مقالات</span>
|
||||
</h2>
|
||||
<span className="font-mono text-[0.65rem] uppercase tracking-wider text-violet">
|
||||
bodies →
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-2 text-sm text-slate-400">
|
||||
Edit the full bilingual body of each blog post (lead + content blocks).
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</AdminShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user