Added blog style pages for more descriptive sidequests and increased bottom padding to stop page from touching
This commit is contained in:
@@ -8,6 +8,7 @@ import About from './pages/About';
|
||||
import WorkExperience from './pages/WorkExperience';
|
||||
import Projects from './pages/Projects';
|
||||
import Skills from './pages/Skills';
|
||||
import SidequestDetail from './pages/SidequestDetail';
|
||||
|
||||
|
||||
function ScrollToTop() {
|
||||
@@ -41,6 +42,7 @@ function App() {
|
||||
<Route path="/work-experience" element={<WorkExperience />} />
|
||||
<Route path="/projects" element={<Projects />} />
|
||||
<Route path="/skills" element={<Skills />} />
|
||||
<Route path="/sidequest/:id" element={<SidequestDetail />} />
|
||||
|
||||
</Routes>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { motion, Variants } from "framer-motion";
|
||||
import "../styles/components/cards.css";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export interface Project {
|
||||
id: number;
|
||||
@@ -11,6 +12,12 @@ export interface Project {
|
||||
demo?: string;
|
||||
repo?: string;
|
||||
};
|
||||
hasDetails?: boolean;
|
||||
detailContent?: {
|
||||
longDescription: string;
|
||||
challenges: string;
|
||||
learnings: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface ProjectCardProps {
|
||||
@@ -57,6 +64,11 @@ export default function ProjectCard({ project, variants }: ProjectCardProps) {
|
||||
GitHub <span>↗</span>
|
||||
</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>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ const FEATURED_PROJECTS: Project[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const SIDEQUESTS: Project[] = [
|
||||
export const SIDEQUESTS: Project[] = [
|
||||
{
|
||||
id: 101, // Different ID range for sidequests
|
||||
title: "Experimental Shader",
|
||||
@@ -26,6 +26,12 @@ const SIDEQUESTS: Project[] = [
|
||||
image: "https://placehold.co/600x400/1a1a1a/cccccc?text=Shader+Experiment", // Placeholder image
|
||||
links: {
|
||||
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
|
||||
links: {
|
||||
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() {
|
||||
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="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">
|
||||
{/* Featured Projects Section */}
|
||||
<motion.div
|
||||
|
||||
116
src/pages/SidequestDetail.tsx
Normal file
116
src/pages/SidequestDetail.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user