mirror of
https://github.com/soconnor0919/personal-website.git
synced 2026-02-05 08:16:31 -05:00
Initial commit
This commit is contained in:
14
src/app/api/cv/route.ts
Normal file
14
src/app/api/cv/route.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const cvPath = path.join(process.cwd(), 'cv.tex');
|
||||
const cvContent = await fs.readFile(cvPath, 'utf8');
|
||||
|
||||
return NextResponse.json({ content: cvContent });
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: 'Failed to load CV' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
26
src/app/cv/page.tsx
Normal file
26
src/app/cv/page.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
'use client';
|
||||
|
||||
export default function CVPage() {
|
||||
return (
|
||||
<div className="bg-white shadow-sm rounded-lg overflow-hidden">
|
||||
<object
|
||||
data="/cv.pdf"
|
||||
type="application/pdf"
|
||||
className="w-full h-[calc(100vh-8rem)]"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center p-8">
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Your browser doesn't support PDF preview.
|
||||
</p>
|
||||
<a
|
||||
href="/cv.pdf"
|
||||
download
|
||||
className="mt-4 inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"
|
||||
>
|
||||
Download PDF
|
||||
</a>
|
||||
</div>
|
||||
</object>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
src/app/layout.tsx
Normal file
28
src/app/layout.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { inter } from "~/lib/fonts"
|
||||
import "~/styles/globals.css"
|
||||
import { Navigation } from "~/components/Navigation"
|
||||
import { Sidebar } from "~/components/Sidebar"
|
||||
|
||||
export const metadata = {
|
||||
title: "Sean O'Connor",
|
||||
description: "Personal website and portfolio",
|
||||
icons: [{ rel: "icon", url: "/favicon.ico" }],
|
||||
}
|
||||
|
||||
export default function RootLayout({ children }: React.PropsWithChildren) {
|
||||
return (
|
||||
<html lang="en" className={inter.className}>
|
||||
<body className="font-sans bg-background text-foreground min-h-screen">
|
||||
<Navigation />
|
||||
<div className="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex flex-col lg:flex-row lg:gap-12 py-8">
|
||||
<Sidebar />
|
||||
<main className="flex-1">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
114
src/app/page.tsx
Normal file
114
src/app/page.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "~/components/ui/card";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import Link from "next/link";
|
||||
import { ArrowUpRight, Code, FlaskConical, Users } from 'lucide-react';
|
||||
import { projects } from "~/lib/data";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<div className="space-y-12">
|
||||
{/* About Section */}
|
||||
<section className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">About Me</h1>
|
||||
<p className="text-lg text-muted-foreground mt-2">
|
||||
I'm a Computer Science and Engineering student at Bucknell University, passionate about robotics,
|
||||
software development, and human-computer interaction. With a strong foundation in both academic
|
||||
research and practical development, I bridge the gap between theoretical concepts and real-world applications.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Code className="h-5 w-5" />
|
||||
<CardTitle>Technical Expertise</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>Full-stack development with modern frameworks (React, Next.js, Node.js)</li>
|
||||
<li>Robotics development using ROS2 and C++</li>
|
||||
<li>Systems programming and architecture design</li>
|
||||
<li>Database design and optimization (SQL, PostgreSQL)</li>
|
||||
<li>Cloud infrastructure and DevOps (AWS, Docker)</li>
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<FlaskConical className="h-5 w-5" />
|
||||
<CardTitle>Research Focus</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>Human-Robot Interaction studies and experimental design</li>
|
||||
<li>Published researcher at IEEE RO-MAN 2024</li>
|
||||
<li>Development of experimental platforms for HRI research</li>
|
||||
<li>Integration of robotics in chemical engineering research</li>
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Users className="h-5 w-5" />
|
||||
<CardTitle>Leadership</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<ul className="list-disc pl-5 space-y-2">
|
||||
<li>President of AIChE Chem-E-Car Competition Team</li>
|
||||
<li>Treasurer of Bucknell Coffee Society</li>
|
||||
<li>Teaching Assistant for Computer Science courses</li>
|
||||
<li>Founding member of RoboLab@Bucknell</li>
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</section>
|
||||
|
||||
{/* Featured Projects Section */}
|
||||
<section className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-2xl font-bold">Featured Projects</h2>
|
||||
<Link
|
||||
href="/projects"
|
||||
className="text-sm text-muted-foreground hover:text-primary flex items-center gap-1"
|
||||
>
|
||||
View all projects
|
||||
<ArrowUpRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="space-y-6">
|
||||
{projects
|
||||
.filter(project => project.featured)
|
||||
.slice(0, 2)
|
||||
.map((project, index) => (
|
||||
<Card key={index}>
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle>{project.title}</CardTitle>
|
||||
{project.link && (
|
||||
<Link
|
||||
href={project.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-muted-foreground hover:text-primary"
|
||||
>
|
||||
<ArrowUpRight className="h-5 w-5" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<CardDescription className="text-base">{project.description}</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
72
src/app/projects/page.tsx
Normal file
72
src/app/projects/page.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "~/components/ui/card";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import Link from "next/link";
|
||||
import { ArrowUpRight } from "lucide-react";
|
||||
import { projects } from "~/lib/data";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function ProjectsPage() {
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<section className="prose prose-zinc dark:prose-invert max-w-none">
|
||||
<h1 className="text-2xl font-bold">Featured Projects</h1>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
A selection of my academic and professional projects, focusing on robotics,
|
||||
web development, and embedded systems.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="space-y-6">
|
||||
{projects.map((project, index) => (
|
||||
<Card key={index}>
|
||||
<div className="flex flex-col lg:flex-row lg:items-center">
|
||||
<div className="flex-1">
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle>{project.title}</CardTitle>
|
||||
{project.link && (
|
||||
<Link
|
||||
href={project.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-muted-foreground hover:text-primary"
|
||||
>
|
||||
<ArrowUpRight className="h-5 w-5" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<CardDescription className="text-base">{project.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{project.longDescription}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{project.tags.map((tag) => (
|
||||
<Badge key={tag} variant="secondary">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</div>
|
||||
|
||||
{project.image && (
|
||||
<div className="px-6 pb-6 lg:py-6 lg:w-1/3">
|
||||
<div className="relative aspect-[4/3] w-full overflow-hidden rounded-lg">
|
||||
<Image
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user