126 lines
4.7 KiB
TypeScript
126 lines
4.7 KiB
TypeScript
import { motion, Variants } from "framer-motion";
|
|
import FullPageImage from "../components/fullPageImage";
|
|
import ProjectCard, { Project } from "../components/ProjectCard";
|
|
|
|
const FEATURED_PROJECTS: Project[] = [
|
|
{
|
|
id: 1,
|
|
title: "Digital Resume",
|
|
description: "A fully responsive, glassmorphic portfolio site built to showcase my skills and experience. Features animated page transitions, typing effects, and a dynamic map component.",
|
|
techStack: ["React", "TypeScript", "Framer Motion", "Vite"],
|
|
image: "/digitCode.jpg",
|
|
links: {
|
|
repo: "https://github.com/Bayda77/resume-site",
|
|
demo: "https://portfolio.sashabayda.ca"
|
|
}
|
|
},
|
|
];
|
|
|
|
const SIDEQUESTS: Project[] = [
|
|
{
|
|
id: 101, // Different ID range for sidequests
|
|
title: "Experimental Shader",
|
|
description: "A WebGL shader experiment creating procedural textures and animations. Exploring noise functions and light interactions.",
|
|
techStack: ["WebGL", "GLSL", "React Three Fiber"],
|
|
image: "https://placehold.co/600x400/1a1a1a/cccccc?text=Shader+Experiment", // Placeholder image
|
|
links: {
|
|
repo: "https://github.com/Bayda77/sidequests", // Placeholder link
|
|
}
|
|
},
|
|
{
|
|
id: 102,
|
|
title: "CLI Tool",
|
|
description: "A command-line utility for automating daily workflows and file management tasks.",
|
|
techStack: ["Rust", "Clap"],
|
|
image: "https://placehold.co/600x400/2a2a2a/dddddd?text=CLI+Tool", // Placeholder
|
|
links: {
|
|
repo: "https://github.com/Bayda77/cli-tools"
|
|
}
|
|
}
|
|
];
|
|
|
|
const containerVariants: Variants = {
|
|
hidden: { opacity: 0 },
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.15
|
|
}
|
|
}
|
|
};
|
|
|
|
const cardVariants: Variants = {
|
|
hidden: { y: 50, opacity: 0 },
|
|
visible: {
|
|
y: 0,
|
|
opacity: 1,
|
|
transition: {
|
|
type: "spring",
|
|
stiffness: 100,
|
|
damping: 12
|
|
}
|
|
}
|
|
};
|
|
|
|
export default function Projects() {
|
|
return (
|
|
<div style={{ position: "relative", width: "100%", minHeight: "100vh" }}>
|
|
<div className="mainContentBlock" style={{ width: "100%", minWidth: "100vw", maxWidth: "100vw", paddingTop: "20px", paddingBottom: "10px", boxSizing: "border-box", display: "flex", justifyContent: "center", position: "relative", zIndex: 1 }}>
|
|
<div className="projects-container">
|
|
{/* Featured Projects Section */}
|
|
<motion.div
|
|
initial="hidden"
|
|
animate="visible"
|
|
variants={containerVariants}
|
|
>
|
|
<motion.h1
|
|
className="projects-title"
|
|
initial={{ y: -30, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8, ease: "easeOut" }}
|
|
>
|
|
Featured Projects
|
|
</motion.h1>
|
|
|
|
<div className="projects-grid">
|
|
{FEATURED_PROJECTS.map((project) => (
|
|
<ProjectCard key={project.id} project={project} variants={cardVariants} />
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
|
|
|
|
{/* Sidequests Section */}
|
|
<motion.div
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true, amount: 0.1 }}
|
|
variants={containerVariants}
|
|
style={{ marginTop: "80px" }}
|
|
>
|
|
<motion.h2
|
|
className="projects-title" // Reusing title style for consistency, maybe smaller?
|
|
style={{ fontSize: "clamp(24px, 4vw, 40px)", marginBottom: "30px" }}
|
|
variants={cardVariants}
|
|
>
|
|
Sidequests
|
|
</motion.h2>
|
|
|
|
<div className="projects-grid">
|
|
{SIDEQUESTS.map((project) => (
|
|
<ProjectCard key={project.id} project={project} variants={cardVariants} />
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
<FullPageImage
|
|
src="/20251111_224823.jpg"
|
|
alt="projects background"
|
|
credit="Sasha Bayda"
|
|
isFixed={true}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|