Added blog style pages for more descriptive sidequests and increased bottom padding to stop page from touching

This commit is contained in:
2026-01-12 20:37:18 -06:00
parent 65fbec3e33
commit 91683d1767
4 changed files with 144 additions and 2 deletions

View File

@@ -8,6 +8,7 @@ import About from './pages/About';
import WorkExperience from './pages/WorkExperience'; import WorkExperience from './pages/WorkExperience';
import Projects from './pages/Projects'; import Projects from './pages/Projects';
import Skills from './pages/Skills'; import Skills from './pages/Skills';
import SidequestDetail from './pages/SidequestDetail';
function ScrollToTop() { function ScrollToTop() {
@@ -41,6 +42,7 @@ function App() {
<Route path="/work-experience" element={<WorkExperience />} /> <Route path="/work-experience" element={<WorkExperience />} />
<Route path="/projects" element={<Projects />} /> <Route path="/projects" element={<Projects />} />
<Route path="/skills" element={<Skills />} /> <Route path="/skills" element={<Skills />} />
<Route path="/sidequest/:id" element={<SidequestDetail />} />
</Routes> </Routes>
<div> <div>

View File

@@ -1,5 +1,6 @@
import { motion, Variants } from "framer-motion"; import { motion, Variants } from "framer-motion";
import "../styles/components/cards.css"; import "../styles/components/cards.css";
import { Link } from "react-router-dom";
export interface Project { export interface Project {
id: number; id: number;
@@ -11,6 +12,12 @@ export interface Project {
demo?: string; demo?: string;
repo?: string; repo?: string;
}; };
hasDetails?: boolean;
detailContent?: {
longDescription: string;
challenges: string;
learnings: string;
};
} }
interface ProjectCardProps { interface ProjectCardProps {
@@ -57,6 +64,11 @@ export default function ProjectCard({ project, variants }: ProjectCardProps) {
GitHub <span></span> GitHub <span></span>
</a> </a>
)} )}
{project.hasDetails && (
<Link to={`/sidequest/${project.id}`} className="project-link" style={{ background: "rgba(255, 255, 255, 0.15)", border: "1px solid rgba(255, 255, 255, 0.3)" }}>
Read More <span></span>
</Link>
)}
</div> </div>
</motion.div> </motion.div>
); );

View File

@@ -17,7 +17,7 @@ const FEATURED_PROJECTS: Project[] = [
}, },
]; ];
const SIDEQUESTS: Project[] = [ export const SIDEQUESTS: Project[] = [
{ {
id: 101, // Different ID range for sidequests id: 101, // Different ID range for sidequests
title: "Experimental Shader", title: "Experimental Shader",
@@ -26,6 +26,12 @@ const SIDEQUESTS: Project[] = [
image: "https://placehold.co/600x400/1a1a1a/cccccc?text=Shader+Experiment", // Placeholder image image: "https://placehold.co/600x400/1a1a1a/cccccc?text=Shader+Experiment", // Placeholder image
links: { links: {
repo: "https://github.com/Bayda77/sidequests", // Placeholder link repo: "https://github.com/Bayda77/sidequests", // Placeholder link
},
hasDetails: true,
detailContent: {
longDescription: "This project started as a deep dive into the world of fragment shaders. I wanted to understand how to create organic-looking textures without relying on image assets. Using Perlin noise and fractional Brownian motion (fBm), I created a dynamic, shifting terrain that reacts to time and mouse input.",
challenges: "One of the biggest challenges was optimizing the GLSL code to run smoothly on lower-end devices. Mathematical operations in the fragment shader can get expensive quickly.",
learnings: "I gained a much deeper understanding of the graphics pipeline, vector math, and how to think about visuals in terms of mathematical functions rather than pixels."
} }
}, },
{ {
@@ -36,6 +42,12 @@ const SIDEQUESTS: Project[] = [
image: "https://placehold.co/600x400/2a2a2a/dddddd?text=CLI+Tool", // Placeholder image: "https://placehold.co/600x400/2a2a2a/dddddd?text=CLI+Tool", // Placeholder
links: { links: {
repo: "https://github.com/Bayda77/cli-tools" repo: "https://github.com/Bayda77/cli-tools"
},
hasDetails: true,
detailContent: {
longDescription: "I built this CLI tool to automate repetitive tasks in my development workflow, such as scaffolding new project directories, managing git branches, and cleaning up temporary files. Written in Rust for blazingly fast execution.",
challenges: "Learning Rust's ownership model was a steep learning curve. Fighting the borrow checker was frustrating at first, but it eventually taught me to write much safer memory management code.",
learnings: "I learned how to build robust command-line interfaces with Clap, how to handle system I/O efficiently, and the benefits of compiled languages for system tools."
} }
} }
]; ];
@@ -66,7 +78,7 @@ const cardVariants: Variants = {
export default function Projects() { export default function Projects() {
return ( return (
<div style={{ position: "relative", width: "100%", minHeight: "100vh" }}> <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="mainContentBlock" style={{ width: "100%", minWidth: "100vw", maxWidth: "100vw", paddingTop: "20px", paddingBottom: "100px", boxSizing: "border-box", display: "flex", justifyContent: "center", position: "relative", zIndex: 1 }}>
<div className="projects-container"> <div className="projects-container">
{/* Featured Projects Section */} {/* Featured Projects Section */}
<motion.div <motion.div

View File

@@ -0,0 +1,116 @@
import { useParams, Link } from "react-router-dom";
import { motion } from "framer-motion";
import { SIDEQUESTS } from "./Projects";
import { useEffect } from "react";
export default function SidequestDetail() {
const { id } = useParams<{ id: string }>();
const project = SIDEQUESTS.find(p => p.id === Number(id));
useEffect(() => {
window.scrollTo(0, 0);
}, []);
if (!project) {
return (
<div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column", color: "white" }}>
<h2>Sidequest not found</h2>
<Link to="/projects" style={{ color: "rgba(255,255,255,0.7)", marginTop: "20px" }}>Back to Projects</Link>
</div>
);
}
return (
<div className="mainContentBlock" style={{ minWidth: "66vw", display: "flex", justifyContent: "center", paddingTop: "40px" }}>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
style={{ width: "100%", maxWidth: "800px", padding: "0 20px" }}
>
<Link to="/projects" style={{ display: "inline-flex", alignItems: "center", color: "rgba(255,255,255,0.6)", textDecoration: "none", marginBottom: "30px" }}>
Back to Projects
</Link>
<div style={{ marginBottom: "40px" }}>
<h1 style={{ fontSize: "2.5rem", marginBottom: "10px", color: "white" }}>{project.title}</h1>
<div style={{ display: "flex", flexWrap: "wrap", gap: "10px", marginBottom: "20px" }}>
{project.techStack.map(tech => (
<span key={tech} style={{
background: "rgba(255,255,255,0.1)",
padding: "4px 12px",
borderRadius: "15px",
fontSize: "0.85rem",
color: "rgba(255,255,255,0.9)"
}}>
{tech}
</span>
))}
</div>
</div>
<div style={{
width: "100%",
height: "400px",
borderRadius: "16px",
overflow: "hidden",
marginBottom: "40px",
boxShadow: "0 10px 30px rgba(0,0,0,0.3)"
}}>
<img
src={project.image}
alt={project.title}
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
</div>
<div style={{
background: "rgba(255, 255, 255, 0.05)",
backdropFilter: "blur(10px)",
borderRadius: "16px",
padding: "40px",
border: "1px solid rgba(255, 255, 255, 0.1)"
}}>
<section style={{ marginBottom: "30px" }}>
<h2 style={{ color: "white", fontSize: "1.5rem", marginBottom: "15px" }}>Overview</h2>
<p style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
{project.detailContent?.longDescription || project.description}
</p>
</section>
{project.detailContent?.challenges && (
<section style={{ marginBottom: "30px" }}>
<h2 style={{ color: "white", fontSize: "1.5rem", marginBottom: "15px" }}>Challenges</h2>
<p style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
{project.detailContent.challenges}
</p>
</section>
)}
{project.detailContent?.learnings && (
<section>
<h2 style={{ color: "white", fontSize: "1.5rem", marginBottom: "15px" }}>Learnings</h2>
<p style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
{project.detailContent.learnings}
</p>
</section>
)}
<div style={{ marginTop: "40px", paddingTop: "20px", borderTop: "1px solid rgba(255,255,255,0.1)", display: "flex", gap: "20px" }}>
{project.links.demo && (
<a href={project.links.demo} target="_blank" rel="noopener noreferrer" style={{ color: "white", textDecoration: "underline" }}>
Live Demo
</a>
)}
{project.links.repo && (
<a href={project.links.repo} target="_blank" rel="noopener noreferrer" style={{ color: "white", textDecoration: "underline" }}>
View Code
</a>
)}
</div>
</div>
<div style={{ height: "100px" }}></div>
</motion.div>
</div>
);
}