portfolio/components/ForgeUI copy.tsx
2026-02-03 13:56:34 +01:00

132 lines
5.3 KiB
TypeScript

"use client";
import Image from "next/image";
import { History, ExternalLink, Cpu } from "lucide-react";
import { ForgeProject } from "@/types";
export default function ForgeUI({ project }: { project: ForgeProject }) {
return (
<div className="bg-neutral-900/40 border border-neutral-800 rounded-3xl p-8 pt-0 mb-12 overflow-hidden">
{/* Upper Section: Hero Area */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
<div className="lg:col-span-8 flex flex-col justify-center">
<div className="flex flex-wrap justify-between items-start gap-6 mb-6">
<div>
<h2 className="text-4xl font-bold text-white mb-4 tracking-tighter">
{project.projectName}
</h2>
<div className="flex flex-wrap items-center gap-3">
{/* Version Badge */}
<span className="px-3 py-1 bg-orange-500/10 border border-orange-500/20 text-orange-500 text-[10px] font-bold uppercase tracking-widest rounded-full">
{project.currentVersion}
</span>
{/* Engine Tag */}
<span className="px-3 py-1 bg-neutral-800 text-neutral-400 text-[10px] font-bold uppercase tracking-widest rounded-full flex items-center gap-2">
<Cpu size={12} /> {project.engine}
</span>
{/* Status Indicator (Now part of the tag row) */}
<div className="flex items-center gap-2 text-[9px] font-mono text-green-500/60 ml-1">
<span className="relative flex h-1.5 w-1.5">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
<span className="relative inline-flex rounded-full h-1.5 w-1.5 bg-green-500"></span>
</span>
ACTIVE STREAM
</div>
</div>
</div>
{project.externalLink && (
<a
href={project.externalLink}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 text-xs font-bold text-white bg-neutral-800 hover:bg-neutral-700 transition-colors px-4 py-2 rounded-xl shrink-0"
>
Project Details <ExternalLink size={14} />
</a>
)}
</div>
<p className="text-neutral-400 text-base leading-relaxed max-w-2xl">
{project.description}
</p>
</div>
{project.imagePath && (
<div className="lg:col-span-4 flex justify-center lg:justify-end items-center">
<div className="relative w-full aspect-square max-w-[280px] group">
<Image
src={project.imagePath}
alt={`${project.projectName} Feature`}
fill
className="object-contain drop-shadow-[0_0_40px_rgba(249,115,22,0.15)] transition-transform duration-700 group-hover:scale-110"
/>
<div className="absolute inset-0 bg-orange-500/10 blur-[80px] rounded-full -z-10 opacity-40 group-hover:opacity-60 transition-opacity" />
</div>
</div>
)}
</div>
{/* Technical Highlights */}
<div className="flex flex-wrap gap-2 mb-12">
{project.highlights.map((tag) => (
<span
key={tag}
className="text-[10px] text-neutral-600 font-mono uppercase tracking-tighter border border-neutral-800 px-3 py-1 rounded"
>
{`// ${tag}`}
</span>
))}
</div>
{/* Lower Section: Logs with Gradient Fade */}
<div className="space-y-8">
<div className="flex items-center gap-2 text-xs font-bold text-neutral-500 uppercase tracking-widest border-b border-neutral-800 pb-2">
<History size={14} /> Dev_Log
</div>
{/* This container handles the fade effect */}
<div
className="space-y-8 relative"
style={{
maskImage:
"linear-gradient(to bottom, black 60%, transparent 100%)",
WebkitMaskImage:
"linear-gradient(to bottom, black 60%, transparent 100%)",
}}
>
{project.changelog.map((entry) => (
<div
key={entry.version}
className="relative pl-8 border-l border-neutral-800"
>
<div className="absolute -left-1.5 top-1.5 w-3 h-3 bg-neutral-950 border border-neutral-700 rounded-full" />
<div className="flex items-baseline gap-4 mb-3">
<span className="text-orange-500 font-mono text-sm font-bold leading-none">
{entry.version}
</span>
<span className="text-neutral-600 font-mono text-xs leading-none">
{entry.date}
</span>
</div>
<ul className="space-y-2.5">
{entry.changes.map((change, idx) => (
<li
key={idx}
className="text-neutral-400 text-sm leading-relaxed max-w-4xl"
>
{change}
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
);
}