38334-vm/frontend/src/pages/projects.tsx
2026-02-10 06:21:03 +00:00

261 lines
12 KiB
TypeScript

import React, { useState } from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import BaseButton from '../components/BaseButton';
import LayoutGuest from '../layouts/Guest';
import BaseIcon from '../components/BaseIcon';
import {
mdiChevronRight,
mdiMenu,
mdiClose,
mdiTwitter,
mdiLinkedin,
mdiGithub,
mdiArrowLeft
} from '@mdi/js';
import { getPageTitle } from '../config';
export default function ProjectsPage() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const allProjects = [
{
title: 'The Future of Web3 Infrastructure',
type: 'Strategic Blog Post',
desc: 'A deep dive into the evolving landscape of decentralized infrastructure and its impact on SaaS.',
url: 'https://docs.google.com/document/d/1example1',
image: null
},
{
title: 'Modern SaaS Architecture Guide',
type: 'White Paper',
desc: 'Comprehensive guide on building scalable, cloud-native SaaS applications for the modern enterprise.',
url: 'https://docs.google.com/document/d/1example2',
image: null
},
{
title: 'Cloud-Native Deployment API Docs',
type: 'Documentation',
desc: 'Technical reference documentation for a multi-cloud deployment engine using Kubernetes.',
url: 'https://docs.google.com/document/d/1example3',
image: null
},
{
title: 'Developer Experience Report 2026',
type: 'Case Study',
desc: 'An analytical report on the current state of DX and how it influences tool adoption.',
url: 'https://docs.google.com/document/d/1example4',
image: null
},
{
title: 'Understanding Serverless Security',
type: 'Technical Article',
desc: 'Exploring common vulnerabilities in serverless architectures and best practices for mitigation.',
url: 'https://docs.google.com/document/d/1example5',
image: null
},
{
title: 'Next-Gen DevOps Handbook',
type: 'E-Book',
desc: 'A 50-page guide covering CI/CD, observability, and infrastructure as code for high-growth startups.',
url: 'https://docs.google.com/document/d/1example6',
image: null
},
{
title: 'Kafka vs. RabbitMQ: Choosing the Right Message Broker',
type: 'Technical Comparison',
desc: 'Detailed architectural comparison for distributed systems engineering teams.',
url: 'https://docs.google.com/document/d/1example7',
image: null
},
{
title: 'Building a Design System from Scratch',
type: 'Documentation',
desc: 'Internal documentation for a fintech startup scaling their front-end engineering team.',
url: 'https://docs.google.com/document/d/1example8',
image: null
},
{
title: 'AI-Driven Content Strategy for SaaS',
type: 'Case Study',
desc: 'How we implemented a hybrid AI-human content workflow to triple organic traffic.',
url: 'https://docs.google.com/document/d/1example9',
image: null
}
];
const navLinks = [
{ label: 'About', href: '/#about' },
{ label: 'Services', href: '/#services' },
{ label: 'Portfolio', href: '/projects' },
{ label: 'Contact', href: '/#contact' }
];
return (
<div className="bg-[#0B0B0B] text-white font-sans selection:bg-[#D4AF37] selection:text-black min-h-screen">
<Head>
<title>{getPageTitle('Portfolio | Blackness Studio')}</title>
<meta name="description" content="Explore the full portfolio of Blackness Studio - Premium technical writing, documentation, and content strategy." />
</Head>
{/* Navigation */}
<nav className="fixed top-0 w-full z-50 bg-[#0B0B0B]/90 backdrop-blur-md border-b border-white/10">
<div className="container mx-auto px-6 h-20 flex items-center justify-between">
<Link href="/" className="text-xl md:text-2xl font-bold tracking-tighter">
BLACKNESS<span className="text-[#D4AF37]">STUDIO</span>
</Link>
{/* Desktop Links */}
<div className="hidden md:flex space-x-8 text-sm font-medium uppercase tracking-widest">
{navLinks.map((link) => (
<Link key={link.label} href={link.href} className={`hover:text-[#D4AF37] transition-colors ${link.href === '/projects' ? 'text-[#D4AF37]' : ''}`}>
{link.label}
</Link>
))}
</div>
<div className="hidden md:flex">
<BaseButton
href="https://www.fiverr.com/s/gDL8yVE"
label="Hire on Fiverr"
color="white"
className="!text-black !bg-[#D4AF37] border-none hover:scale-105 transition-transform"
/>
</div>
{/* Mobile Menu Toggle */}
<button
className="md:hidden text-white"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
aria-label="Toggle Menu"
>
<BaseIcon path={isMobileMenuOpen ? mdiClose : mdiMenu} size={32} />
</button>
</div>
{/* Mobile Menu Dropdown */}
<div className={`md:hidden absolute top-20 left-0 w-full bg-[#0B0B0B] border-b border-white/10 transition-all duration-300 ease-in-out ${isMobileMenuOpen ? 'opacity-100 visible h-auto' : 'opacity-0 invisible h-0'} overflow-hidden`}>
<div className="flex flex-col p-6 space-y-6 text-center uppercase tracking-widest font-medium text-sm">
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href}
className={`hover:text-[#D4AF37] transition-colors py-2 ${link.href === '/projects' ? 'text-[#D4AF37]' : ''}`}
onClick={() => setIsMobileMenuOpen(false)}
>
{link.label}
</Link>
))}
<div className="pt-4">
<BaseButton
href="https://www.fiverr.com/s/gDL8yVE"
label="Hire on Fiverr"
className="!text-black !bg-[#D4AF37] border-none w-full justify-center"
/>
</div>
</div>
</div>
</nav>
{/* Hero Section */}
<section className="pt-40 pb-20 px-6">
<div className="container mx-auto">
<div className="flex flex-col md:flex-row md:items-end justify-between mb-12 space-y-4 md:space-y-0">
<div>
<Link href="/" className="inline-flex items-center text-[#D4AF37] text-sm font-bold uppercase tracking-widest mb-6 hover:translate-x-[-4px] transition-transform">
<BaseIcon path={mdiArrowLeft} w="w-5" h="h-5" className="mr-2" /> Back to Home
</Link>
<h1 className="text-4xl md:text-7xl font-black tracking-tighter">
PORTFOLIO
</h1>
</div>
<p className="text-gray-400 max-w-md text-sm md:text-base font-light">
A comprehensive collection of my technical writing, strategic blog posts, and developer documentation.
</p>
</div>
<div className="h-px bg-gradient-to-r from-[#D4AF37] to-transparent w-full mb-20 opacity-30"></div>
{/* Projects Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-12">
{allProjects.map((project, idx) => (
<div key={idx} className="group flex flex-col bg-[#1A1A1A] border border-white/5 rounded-[40px] overflow-hidden hover:border-[#D4AF37]/30 transition-all">
<div className="aspect-video bg-[#0B0B0B] relative overflow-hidden flex items-center justify-center p-8">
{project.image ? (
<img src={project.image} alt={project.title} className="object-cover w-full h-full group-hover:scale-105 transition-transform duration-700" />
) : (
<div className="text-[#D4AF37]/10 font-black text-6xl select-none tracking-tighter">
BS
</div>
)}
<div className="absolute inset-0 bg-[#D4AF37]/5 opacity-0 group-hover:opacity-100 transition-opacity"></div>
</div>
<div className="p-8 md:p-10 flex flex-col flex-grow">
<span className="text-[#D4AF37] text-[10px] md:text-xs uppercase tracking-[0.3em] font-black mb-4 block">
{project.type}
</span>
<h2 className="text-xl md:text-2xl font-bold mb-4 leading-tight group-hover:text-[#D4AF37] transition-colors">
{project.title}
</h2>
<p className="text-gray-400 text-sm md:text-base leading-relaxed mb-8 flex-grow">
{project.desc}
</p>
<BaseButton
href={project.url}
label="View Project"
className="!bg-transparent !text-[#D4AF37] !border-[#D4AF37]/50 hover:!bg-[#D4AF37] hover:!text-black !rounded-full py-3 text-xs font-black uppercase tracking-widest transition-all w-full md:w-auto"
/>
</div>
</div>
))}
</div>
</div>
</section>
{/* CTA Section */}
<section className="py-20 md:py-32 bg-[#0B0B0B] border-t border-white/5">
<div className="container mx-auto px-6 text-center">
<h3 className="text-3xl md:text-5xl font-black mb-8 tracking-tighter">READY TO START YOUR PROJECT?</h3>
<BaseButton
href="https://www.fiverr.com/s/gDL8yVE"
label="Hire Me on Fiverr"
className="!bg-[#D4AF37] !text-black !border-none px-12 py-5 text-lg md:text-xl font-black uppercase tracking-widest hover:scale-105 transition-transform"
/>
</div>
</section>
{/* Footer */}
<footer className="py-12 border-t border-white/5 bg-[#0B0B0B]">
<div className="container mx-auto px-6">
<div className="flex flex-col md:flex-row justify-between items-center space-y-10 md:space-y-0">
<Link href="/" className="text-xl font-black tracking-tighter">
BLACKNESS<span className="text-[#D4AF37]">STUDIO</span>
</Link>
<div className="flex space-x-6">
<a href="#" className="text-gray-500 hover:text-white transition-colors" aria-label="Twitter">
<BaseIcon path={mdiTwitter} size={20} />
</a>
<a href="#" className="text-gray-500 hover:text-white transition-colors" aria-label="LinkedIn">
<BaseIcon path={mdiLinkedin} size={20} />
</a>
<a href="#" className="text-gray-500 hover:text-white transition-colors" aria-label="GitHub">
<BaseIcon path={mdiGithub} size={20} />
</a>
</div>
<div className="flex flex-wrap justify-center gap-6 md:gap-8 text-[10px] md:text-xs uppercase tracking-widest text-gray-600 font-bold">
<Link href="/privacy-policy" className="hover:text-white transition-colors">Privacy Policy</Link>
<Link href="/terms-of-use" className="hover:text-white transition-colors">Terms of Use</Link>
</div>
</div>
<div className="text-center mt-12 text-[10px] text-gray-700 uppercase tracking-[0.4em] md:tracking-[0.5em] font-medium leading-relaxed">
&copy; 2026 BLACKNESS STUDIO. ALL RIGHTS RESERVED.
</div>
</div>
</footer>
</div>
);
}
ProjectsPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};