This portfolio website was built to document engineering projects and provide a central place to share technical work. It uses a data-driven architecture where each project is defined in a structured TypeScript file, making it easy to add new content.
The site uses a modern web stack with Next.js for routing and static generation, TypeScript for type safety, and Tailwind CSS for styling.
1// Each project is a typed object
2export interface Project {
3 title: string;
4 subtitle?: string;
5 media: string;
6 tags?: string[];
7 section: Section[];
8}The architecture follows a data-driven approach where each project is defined as a structured TypeScript object. This separation of content from presentation allows for easy updates and ensures consistency across all project pages.
1src/app/
2├── components/
3│ ├── data/projects/ # Project content files
4│ ├── project/ # Page components
5│ ├── resume/ # Resume components
6│ └── shared/ # Reusable UI components
7├── projects/
8│ ├── page.tsx # Project gallery
9│ └── [projectTitle]/ # Dynamic routes
10└── resume/Dynamic routing with Next.js allows each project to have its own URL (e.g., /projects/multi-robot-frontier-exploration) while sharing a common page template. The project data is fetched based on the URL slug and rendered using reusable section components.
Rather than using a traditional CMS or database, the site employs a content-as-code approach. Each project is a TypeScript file exporting a structured object that defines all content blocks: text, images, videos, code snippets, and math equations.
1// Adding a new project = creating a new file
2export const myProject: Project = {
3 title: "Project Name",
4 media: "/media/videos/demo.mp4",
5 section: [
6 {
7 title: "Overview",
8 navRef: "overview",
9 content: [
10 { type: "text", content: "Description..." },
11 { type: "image", content: "/media/images/fig.png" },
12 ],
13 },
14 ],
15};The UI uses a dark theme with responsive layouts built using Tailwind's breakpoint utilities.
1// Responsive grid: 1 column on mobile, 3 on desktop
2<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
3 {projects.map((project) => (
4 <ProjectCard key={project.title} {...project} />
5 ))}
6</div>The site leverages Next.js features for performance: static generation, automatic image optimization, and code splitting.
Key challenges addressed during development:
Potential future additions:
The data-driven architecture makes it straightforward to add new projects—each one is just a new TypeScript file following the same structure. All project pages use the same component system shown here.