"use client"; import { useState, useEffect } from "react"; import { motion } from 'framer-motion'; import { ExternalLink, Github, Calendar, ArrowLeft, Search } from 'lucide-react'; import Link from 'next/link'; interface Project { id: number; title: string; description: string; content: string; tags: string[]; featured: boolean; category: string; date: string; github?: string; live?: string; imageUrl?: string; } const ProjectsPage = () => { const [projects, setProjects] = useState([]); const [filteredProjects, setFilteredProjects] = useState([]); const [categories, setCategories] = useState(["All"]); const [selectedCategory, setSelectedCategory] = useState("All"); const [searchQuery, setSearchQuery] = useState(""); const [mounted, setMounted] = useState(false); // Load projects from API useEffect(() => { const loadProjects = async () => { try { const response = await fetch('/api/projects?published=true'); if (response.ok) { const data = await response.json(); const loadedProjects = data.projects || []; setProjects(loadedProjects); // Extract unique categories const uniqueCategories = ["All", ...Array.from(new Set(loadedProjects.map((p: Project) => p.category))) as string[]]; setCategories(uniqueCategories); } } catch (error) { if (process.env.NODE_ENV === 'development') { console.error('Error loading projects:', error); } } }; loadProjects(); setMounted(true); }, []); // Filter projects useEffect(() => { let result = projects; if (selectedCategory !== "All") { result = result.filter(project => project.category === selectedCategory); } if (searchQuery) { const query = searchQuery.toLowerCase(); result = result.filter(project => project.title.toLowerCase().includes(query) || project.description.toLowerCase().includes(query) || project.tags.some(tag => tag.toLowerCase().includes(query)) ); } setFilteredProjects(result); }, [projects, selectedCategory, searchQuery]); if (!mounted) { return null; } return (
{/* Header */} Back to Home

My Projects

Explore my portfolio of projects, from web applications to mobile apps. Each project showcases different skills and technologies.

{/* Filters & Search */} {/* Categories */}
{categories.map((category) => ( ))}
{/* Search */}
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-white border border-stone-200 rounded-full text-stone-800 placeholder:text-stone-400 focus:outline-none focus:ring-2 focus:ring-stone-200 focus:border-stone-400 transition-all" />
{/* Projects Grid */}
{filteredProjects.map((project, index) => ( {/* Image / Fallback / Cover Area */}
{project.imageUrl ? ( <> {project.title}
) : (
{project.title.charAt(0)}
)} {/* Texture/Grain Overlay */}
{/* Animated Shine Effect */}
{project.featured && (
Featured
)} {/* Overlay Links */}
{project.github && ( e.stopPropagation()} > )} {project.live && !project.title.toLowerCase().includes('kernel panic') && ( e.stopPropagation()} > )}
{/* Stretched Link covering the whole card (including image area) */}

{project.title}

{new Date(project.date).getFullYear()}

{project.description}

{project.tags.slice(0, 4).map((tag) => ( {tag} ))} {project.tags.length > 4 && ( + {project.tags.length - 4} )}
{project.github && ( e.stopPropagation()} > )} {project.live && !project.title.toLowerCase().includes('kernel panic') && ( e.stopPropagation()} > )}
))}
{filteredProjects.length === 0 && (

No projects found matching your criteria.

)}
); }; export default ProjectsPage;