implemented react syntax highlighter
This commit is contained in:
@@ -17,6 +17,7 @@ export interface Project {
|
||||
longDescription: string;
|
||||
challenges: string;
|
||||
learnings: string;
|
||||
codeSnippet?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -30,25 +30,21 @@ export const SIDEQUESTS: Project[] = [
|
||||
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.",
|
||||
codeSnippet: `\`\`\`glsl
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
float a = random(i);
|
||||
float b = random(i + vec2(1.0, 0.0));
|
||||
float c = random(i + vec2(0.0, 1.0));
|
||||
float d = random(i + vec2(1.0, 1.0));
|
||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||
return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
|
||||
}
|
||||
\`\`\``,
|
||||
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."
|
||||
}
|
||||
},
|
||||
{
|
||||
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"
|
||||
},
|
||||
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."
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,8 +1,85 @@
|
||||
import { useParams, Link } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
||||
import { SIDEQUESTS } from "./Projects";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const RichTextRenderer = ({ content }: { content: string }) => {
|
||||
if (!content) return null;
|
||||
|
||||
const parts = content.split(/```/);
|
||||
|
||||
return (
|
||||
<div className="rich-text-content">
|
||||
{parts.map((part, index) => {
|
||||
if (index % 2 === 1) {
|
||||
// Code block
|
||||
const firstLineBreak = part.indexOf('\n');
|
||||
const language = part.slice(0, firstLineBreak).trim();
|
||||
const code = part.slice(firstLineBreak + 1).trim();
|
||||
|
||||
return (
|
||||
<div key={index} style={{
|
||||
margin: '30px 0',
|
||||
borderRadius: '12px',
|
||||
overflow: 'hidden',
|
||||
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||||
background: '#1e1e1e', // Match VS Code dark background roughly or stay transparent if needed
|
||||
boxShadow: '0 10px 30px rgba(0,0,0,0.3)'
|
||||
}}>
|
||||
{/* Window Header */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '12px 16px',
|
||||
background: 'rgba(255, 255, 255, 0.05)',
|
||||
borderBottom: '1px solid rgba(255, 255, 255, 0.05)'
|
||||
}}>
|
||||
<div style={{ display: 'flex', gap: '8px', marginRight: 'auto' }}>
|
||||
<div style={{ width: '12px', height: '12px', borderRadius: '50%', background: '#ff5f56' }}></div>
|
||||
<div style={{ width: '12px', height: '12px', borderRadius: '50%', background: '#ffbd2e' }}></div>
|
||||
<div style={{ width: '12px', height: '12px', borderRadius: '50%', background: '#27c93f' }}></div>
|
||||
</div>
|
||||
<span style={{
|
||||
fontSize: '12px',
|
||||
color: 'rgba(255, 255, 255, 0.5)',
|
||||
fontFamily: 'monospace',
|
||||
textTransform: 'uppercase',
|
||||
marginTop: '2px'
|
||||
}}>
|
||||
{language || 'text'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<SyntaxHighlighter
|
||||
language={language || 'text'}
|
||||
style={vscDarkPlus}
|
||||
customStyle={{
|
||||
margin: 0,
|
||||
borderRadius: '0 0 12px 12px', // Only round bottom
|
||||
fontSize: '14px',
|
||||
background: 'transparent', // Let container bg show or stick to theme
|
||||
padding: '20px'
|
||||
}}
|
||||
>
|
||||
{code}
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Regular text (split by newlines for paragraph handling)
|
||||
return (
|
||||
<span key={index} style={{ whiteSpace: 'pre-wrap' }}>
|
||||
{part}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function SidequestDetail() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const project = SIDEQUESTS.find(p => p.id === Number(id));
|
||||
@@ -73,26 +150,32 @@ export default function SidequestDetail() {
|
||||
}}>
|
||||
<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>
|
||||
<div style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
|
||||
<RichTextRenderer content={project.detailContent?.longDescription || project.description} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{project.detailContent?.codeSnippet && (
|
||||
<div style={{ marginBottom: "30px" }}>
|
||||
<RichTextRenderer content={project.detailContent.codeSnippet} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{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>
|
||||
<div style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
|
||||
<RichTextRenderer content={project.detailContent.challenges} />
|
||||
</div>
|
||||
</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>
|
||||
<div style={{ color: "rgba(255,255,255,0.8)", lineHeight: "1.7" }}>
|
||||
<RichTextRenderer content={project.detailContent.learnings} />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user