Files
git-website-engine-control-…/src/components/ThemeTab.tsx
T

188 lines
7.4 KiB
TypeScript

import React, { useState } from "react";
import {
Palette,
Folder,
FileCode,
CheckCircle2,
RefreshCw,
Layout,
Layers,
ShieldCheck,
Code,
} from "lucide-react";
import { ThemeConfig } from "../types";
interface ThemeTabProps {
theme: ThemeConfig;
onValidateTheme: () => Promise<void>;
}
export const ThemeTab: React.FC<ThemeTabProps> = ({
theme,
onValidateTheme,
}) => {
const [isValidating, setIsValidating] = useState(false);
const [statusMsg, setStatusMsg] = useState<string | null>(null);
const handleValidate = async () => {
setIsValidating(true);
await onValidateTheme();
setStatusMsg(
"Theme /.theme validated successfully. All required templates, CSS resets, and package supports are valid.",
);
setIsValidating(false);
};
return (
<div className="space-y-6">
{/* HEADER */}
<div className="bg-[#111111] rounded-sm border border-[#1F1F1F] p-6 shadow-xs flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<div className="flex items-center space-x-2">
<h1 className="text-xl font-serif italic text-white">
Theme Management
</h1>
<span className="px-2.5 py-0.5 rounded-xs text-[10px] uppercase font-bold tracking-widest bg-[#C5A059]/10 text-[#C5A059] border border-[#C5A059]/30">
PRD AC-10 Standard Location: /.theme
</span>
</div>
<p className="text-xs text-neutral-400 mt-1">
Loads active theme from{" "}
<code className="text-[#C5A059] font-mono">/.theme</code>, validates{" "}
<code className="text-neutral-300 font-mono">theme.yaml</code>,
templates, assets, and supported package layouts.
</p>
</div>
<button
onClick={handleValidate}
disabled={isValidating}
className="px-4 py-2 bg-[#C5A059] hover:bg-[#b38f4a] text-black font-semibold rounded-sm text-xs transition-all flex items-center space-x-1.5 uppercase tracking-wider"
>
<RefreshCw
className={`w-3.5 h-3.5 ${isValidating ? "animate-spin" : ""}`}
/>
<span>
{isValidating ? "Validating Theme..." : "Validate Theme Manifest"}
</span>
</button>
</div>
{statusMsg && (
<div className="p-4 bg-emerald-950/40 border border-emerald-500/20 rounded-sm text-xs text-emerald-400 flex items-center space-x-2">
<CheckCircle2 className="w-4 h-4 text-emerald-400 shrink-0" />
<span>{statusMsg}</span>
</div>
)}
{/* THEME STRUCTURE GRID */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* LEFT COLUMN: THEME METADATA & MANIFEST (5 COLS) */}
<div className="lg:col-span-5 bg-[#111111] rounded-sm border border-[#1F1F1F] p-6 shadow-xs space-y-4">
<div className="flex items-center justify-between border-b border-[#1F1F1F] pb-3">
<div className="flex items-center space-x-2">
<Palette className="w-5 h-5 text-[#C5A059]" />
<h2 className="text-base font-bold text-white">{theme.name}</h2>
</div>
<span className="px-2.5 py-0.5 bg-[#1A1A1A] text-neutral-300 rounded-xs font-mono text-xs font-semibold border border-[#262626]">
v{theme.version}
</span>
</div>
<div className="space-y-3 text-xs">
<div className="p-3 bg-[#0A0A0A] rounded-sm border border-[#1F1F1F] space-y-1 font-mono">
<span className="text-[10px] text-neutral-500 font-bold uppercase tracking-widest block">
Theme Root Location
</span>
<span className="text-[#C5A059] font-bold text-xs">
{theme.path}
</span>
</div>
<div className="p-3 bg-[#0A0A0A] rounded-sm border border-[#1F1F1F] space-y-1 font-mono">
<span className="text-[10px] text-neutral-500 font-bold uppercase tracking-widest block">
Theme ID
</span>
<span className="text-white font-semibold">{theme.id}</span>
</div>
<div className="p-3 bg-[#0A0A0A] rounded-sm border border-[#1F1F1F] space-y-2">
<span className="text-[10px] text-neutral-500 font-bold uppercase tracking-widest block font-mono">
Supported Style Packages ({theme.supportsPackages.length})
</span>
<div className="flex flex-wrap gap-1.5">
{theme.supportsPackages.map((pkg) => (
<span
key={pkg}
className="px-2 py-0.5 bg-[#1A1A1A] text-[#C5A059] border border-[#2A2A2A] rounded-xs font-mono text-[10px]"
>
builtin:{pkg}
</span>
))}
</div>
</div>
</div>
</div>
{/* RIGHT COLUMN: TEMPLATES & ASSETS INSPECTOR (7 COLS) */}
<div className="lg:col-span-7 bg-[#111111] rounded-sm border border-[#1F1F1F] p-6 shadow-xs space-y-6">
<h2 className="text-base font-bold text-white">
Theme Assets & Templates Catalog
</h2>
{/* TEMPLATES LIST */}
<div className="space-y-2">
<span className="text-[10px] font-bold text-neutral-500 uppercase tracking-widest block">
Required Templates
</span>
<div className="bg-[#0A0A0A] rounded-sm p-4 text-neutral-200 font-mono text-xs space-y-2 border border-[#1F1F1F]">
{Object.entries(theme.templates).map(([key, val]) => (
<div
key={key}
className="flex items-center justify-between py-1 border-b border-[#1A1A1A] last:border-0"
>
<span className="text-[#C5A059] font-semibold">{key}</span>
<span className="text-neutral-400 text-[11px]">{val}</span>
</div>
))}
</div>
</div>
{/* STYLES & SCRIPTS */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 text-xs font-mono">
<div className="p-3.5 bg-[#0A0A0A] border border-[#1F1F1F] rounded-sm space-y-1.5">
<span className="font-bold text-neutral-400 uppercase tracking-widest text-[10px] block">
CSS Style Assets
</span>
{theme.styles.map((s) => (
<div
key={s}
className="text-neutral-300 text-[11px] flex items-center space-x-1.5"
>
<span className="w-1.5 h-1.5 rounded-full bg-[#C5A059]"></span>
<span>{s}</span>
</div>
))}
</div>
<div className="p-3.5 bg-[#0A0A0A] border border-[#1F1F1F] rounded-sm space-y-1.5">
<span className="font-bold text-neutral-400 uppercase tracking-widest text-[10px] block">
JS Script Assets
</span>
{theme.scripts.map((s) => (
<div
key={s}
className="text-neutral-300 text-[11px] flex items-center space-x-1.5"
>
<span className="w-1.5 h-1.5 rounded-full bg-amber-500"></span>
<span>{s}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
);
};