feat: Add Skills page, BioSection, ProjectCard, and new image assets, while refactoring the deployment workflow to build Docker images directly on my remote server.
This commit is contained in:
@@ -1,19 +1,8 @@
|
||||
import { motion, Variants } from "framer-motion";
|
||||
import FullPageImage from "../components/fullPageImage";
|
||||
import ProjectCard, { Project } from "../components/ProjectCard";
|
||||
|
||||
interface Project {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
techStack: string[];
|
||||
image: string; // Ensure these images exist in public/ or use placeholders
|
||||
links: {
|
||||
demo?: string;
|
||||
repo?: string;
|
||||
};
|
||||
}
|
||||
|
||||
const PROJECTS: Project[] = [
|
||||
const FEATURED_PROJECTS: Project[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Digital Resume",
|
||||
@@ -27,6 +16,29 @@ const PROJECTS: Project[] = [
|
||||
},
|
||||
];
|
||||
|
||||
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: {
|
||||
@@ -55,63 +67,50 @@ export default function Projects() {
|
||||
<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">
|
||||
<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>
|
||||
|
||||
{/* Featured Projects Section */}
|
||||
<motion.div
|
||||
className="projects-grid"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
variants={containerVariants}
|
||||
>
|
||||
{PROJECTS.map((project) => (
|
||||
<motion.div
|
||||
key={project.id}
|
||||
className="project-card"
|
||||
variants={cardVariants}
|
||||
whileHover={{ y: -10, transition: { duration: 0.2 } }}
|
||||
>
|
||||
<div className="project-image-container">
|
||||
<img
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
className="project-image"
|
||||
/>
|
||||
</div>
|
||||
<div className="project-header">
|
||||
<h2 className="project-name">{project.title}</h2>
|
||||
</div>
|
||||
<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="project-tech-stack">
|
||||
{project.techStack.map(tech => (
|
||||
<span key={tech} className="tech-chip">{tech}</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="projects-grid">
|
||||
{FEATURED_PROJECTS.map((project) => (
|
||||
<ProjectCard key={project.id} project={project} variants={cardVariants} />
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<p className="project-description">
|
||||
{project.description}
|
||||
</p>
|
||||
|
||||
<div className="project-links">
|
||||
{project.links.demo && (
|
||||
<a href={project.links.demo} className="project-link" target="_blank" rel="noopener noreferrer">
|
||||
Live Demo <span>→</span>
|
||||
</a>
|
||||
)}
|
||||
{project.links.repo && (
|
||||
<a href={project.links.repo} className="project-link" target="_blank" rel="noopener noreferrer">
|
||||
GitHub <span>↗</span>
|
||||
</a>
|
||||
)}
|
||||
</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>
|
||||
|
||||
Reference in New Issue
Block a user