mirror of
https://github.com/soconnor0919/personal-website.git
synced 2025-12-12 23:04:43 -05:00
Add experience page and improve CV data structure
- Add /experience page with research, teaching, professional, and leadership sections, technical skills, awards, conferences, and coursework - Refactor data.ts to include structured Experience, Education, Award types - Update homepage to show research interests, education, experience highlights, awards, and improved quick links - Improve card layouts and text wrapping for consistency - Add "Experience" to navigation and breadcrumbs - Enhance projects and publications pages for better readability and layout - Update global styles for card and grid alignment
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
title = {A Web-Based Wizard-of-Oz Platform for Collaborative and Reproducible Human-Robot Interaction Research},
|
||||
author = {Sean O'Connor and L. Felipe Perrone},
|
||||
year = {2025},
|
||||
booktitle = {34th IEEE International Conference on Robot and Human Interactive Communication},
|
||||
booktitle = {2025 34th IEEE International Conference on Robot and Human Interactive Communication (RO-MAN)},
|
||||
address = {Eindhoven, The Netherlands},
|
||||
abstract = {Human-robot interaction (HRI) research plays a pivotal role in shaping how robots communicate and collaborate with humans. However, conducting HRI studies can be challenging, particularly those employing the Wizard-of-Oz (WoZ) technique. WoZ user studies can have technical and methodological complexities that may render the results irreproducible. We propose to address these challenges with HRIStudio, a modular web-based platform designed to streamline the design, the execution, and the analysis of WoZ experiments. HRIStudio offers an intuitive interface for experiment creation, real-time control and monitoring during experimental runs, and comprehensive data logging and playback tools for analysis and reproducibility. By lowering technical barriers, promoting collaboration, and offering methodological guidelines, HRIStudio aims to make human-centered robotics research easier and empower researchers to develop scientifically rigorous user studies.},
|
||||
url = {https://soconnor.dev/api/publications/ROMAN25_0574_FI.pdf},
|
||||
@@ -14,7 +14,7 @@
|
||||
title = {HRIStudio: A Framework for Wizard-of-Oz Experiments in Human-Robot Interaction Studies (Late Breaking Report)},
|
||||
author = {Sean O'Connor and L. Felipe Perrone},
|
||||
year = {2024},
|
||||
organization = {33rd IEEE International Conference on Robot and Human Interactive Communication},
|
||||
booktitle = {2024 33rd IEEE International Conference on Robot and Human Interactive Communication (RO-MAN)},
|
||||
address = {Pasadena, CA, USA},
|
||||
abstract = {Human-robot interaction (HRI) research plays a pivotal role in shaping how robots communicate and collaborate with humans. However, conducting HRI studies, particularly those employing the Wizard-of-Oz (WoZ) technique, can be challenging. WoZ user studies can have complexities at the technical and methodological levels that may render the results irreproducible. We propose to address these challenges with HRIStudio, a novel web-based platform designed to streamline the design, execution, and analysis of WoZ experiments. HRIStudio offers an intuitive interface for experiment creation, real-time control and monitoring during experimental runs, and comprehensive data logging and playback tools for analysis and reproducibility. By lowering technical barriers, promoting collaboration, and offering methodological guidelines, HRIStudio aims to make human-centered robotics research easier, and at the same time, empower researchers to develop scientifically rigorous user studies.},
|
||||
url = {https://soconnor.dev/api/publications/hristudio-lbr.pdf},
|
||||
|
||||
278
src/app/experience/page.tsx
Normal file
278
src/app/experience/page.tsx
Normal file
@@ -0,0 +1,278 @@
|
||||
import {
|
||||
FlaskConical,
|
||||
GraduationCap,
|
||||
Building,
|
||||
Users,
|
||||
Calendar,
|
||||
MapPin,
|
||||
Award,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import {
|
||||
experiences,
|
||||
awards,
|
||||
conferences,
|
||||
technicalSkills,
|
||||
relevantCoursework,
|
||||
} from "~/lib/data";
|
||||
|
||||
export default function ExperiencePage() {
|
||||
const researchExperience = experiences.filter(
|
||||
(exp) => exp.type === "research",
|
||||
);
|
||||
const teachingExperience = experiences.filter(
|
||||
(exp) => exp.type === "teaching",
|
||||
);
|
||||
const professionalExperience = experiences.filter(
|
||||
(exp) => exp.type === "professional",
|
||||
);
|
||||
const leadershipExperience = experiences.filter(
|
||||
(exp) => exp.type === "leadership",
|
||||
);
|
||||
|
||||
const getIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case "research":
|
||||
return FlaskConical;
|
||||
case "teaching":
|
||||
return GraduationCap;
|
||||
case "professional":
|
||||
return Building;
|
||||
case "leadership":
|
||||
return Users;
|
||||
default:
|
||||
return Building;
|
||||
}
|
||||
};
|
||||
|
||||
const renderExperienceSection = (
|
||||
title: string,
|
||||
experiences: typeof researchExperience,
|
||||
delay: number = 1,
|
||||
) => (
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">{title}</h2>
|
||||
<div className="space-y-6">
|
||||
{experiences.map((exp, index) => {
|
||||
const IconComponent = getIcon(exp.type);
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${Math.min(delay + index, 4)} card-hover`}
|
||||
>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-start gap-3">
|
||||
<IconComponent className="mt-1 h-6 w-6 flex-shrink-0 text-primary" />
|
||||
<div className="min-w-0 flex-1">
|
||||
<CardTitle className="break-words text-lg leading-tight">
|
||||
{exp.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="mt-1 break-words text-base font-medium">
|
||||
{exp.organization}
|
||||
</CardDescription>
|
||||
<div className="mt-2 flex flex-wrap gap-4 text-sm text-muted-foreground">
|
||||
<div className="flex items-center gap-1">
|
||||
<MapPin className="h-3 w-3" />
|
||||
{exp.location}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Calendar className="h-3 w-3" />
|
||||
{exp.period}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<ul className="space-y-3">
|
||||
{exp.description.map((item, itemIndex) => (
|
||||
<li key={itemIndex} className="flex items-start gap-3">
|
||||
<span className="mt-2 h-1.5 w-1.5 flex-shrink-0 rounded-full bg-primary" />
|
||||
<span className="break-words leading-relaxed text-muted-foreground">
|
||||
{item}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-12">
|
||||
{/* Header */}
|
||||
<section className="animate-fade-in-up prose prose-zinc dark:prose-invert max-w-none">
|
||||
<div className="flex items-start gap-3">
|
||||
<Building className="h-8 w-8 text-primary" />
|
||||
<div>
|
||||
<h1 className="mb-2 text-2xl font-bold">Experience</h1>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-2 text-lg text-muted-foreground">
|
||||
My comprehensive experience across research, teaching, professional
|
||||
development, and leadership roles.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Research Experience */}
|
||||
{renderExperienceSection("Research Experience", researchExperience, 1)}
|
||||
|
||||
{/* Teaching Experience */}
|
||||
{renderExperienceSection("Teaching Experience", teachingExperience, 2)}
|
||||
|
||||
{/* Professional Experience */}
|
||||
{renderExperienceSection(
|
||||
"Professional Experience",
|
||||
professionalExperience,
|
||||
3,
|
||||
)}
|
||||
|
||||
{/* Leadership & Activities */}
|
||||
{renderExperienceSection(
|
||||
"Leadership & Activities",
|
||||
leadershipExperience,
|
||||
4,
|
||||
)}
|
||||
|
||||
{/* Technical Skills */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Technical Skills</h2>
|
||||
<div className="grid-equal-height grid gap-6 md:grid-cols-2">
|
||||
{Object.entries(technicalSkills).map(([category, skills], index) => (
|
||||
<div
|
||||
key={category}
|
||||
className={`animate-fade-in-up-delay-${Math.min(index + 1, 4)} card-hover`}
|
||||
>
|
||||
<Card className="card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-lg">{category}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{skills.map((skill) => (
|
||||
<Badge
|
||||
key={skill}
|
||||
variant="secondary"
|
||||
className="text-xs"
|
||||
>
|
||||
{skill}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Conferences & Presentations */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Conferences & Presentations</h2>
|
||||
<div className="grid-equal-height grid gap-4 md:grid-cols-1 lg:grid-cols-2">
|
||||
{conferences.map((conf, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${Math.min(index + 1, 4)} card-hover`}
|
||||
>
|
||||
<Card className="card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="min-w-0">
|
||||
<CardTitle className="break-words text-lg leading-tight">
|
||||
{conf.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="mt-1 break-words">
|
||||
{conf.location} • {conf.date}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Award className="h-5 w-5 flex-shrink-0 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-muted-foreground">{conf.presentation}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Awards & Recognition */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Awards & Recognition</h2>
|
||||
<div className="grid-equal-height grid gap-4 md:grid-cols-2">
|
||||
{awards.map((award, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${Math.min(index + 1, 4)} card-hover`}
|
||||
>
|
||||
<Card className="card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start gap-3">
|
||||
<Award className="mt-1 h-5 w-5 flex-shrink-0 text-primary" />
|
||||
<div className="min-w-0">
|
||||
<CardTitle className="break-words text-base leading-tight">
|
||||
{award.title}
|
||||
</CardTitle>
|
||||
{award.organization && (
|
||||
<CardDescription className="mt-1 break-words">
|
||||
{award.organization} • {award.year}
|
||||
</CardDescription>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
{award.description && (
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="break-words text-sm leading-relaxed text-muted-foreground">
|
||||
{award.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Relevant Coursework */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Relevant Coursework</h2>
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<ul className="space-y-3">
|
||||
{relevantCoursework.map((course, index) => (
|
||||
<li key={index} className="flex items-start gap-3">
|
||||
<span className="mt-2 h-1.5 w-1.5 flex-shrink-0 rounded-full bg-primary" />
|
||||
<span className="break-words leading-relaxed text-muted-foreground">
|
||||
{course}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
593
src/app/page.tsx
593
src/app/page.tsx
@@ -9,6 +9,9 @@ import {
|
||||
Mail,
|
||||
ExternalLink,
|
||||
BookOpen,
|
||||
School,
|
||||
Award,
|
||||
Calendar,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
@@ -19,8 +22,23 @@ import {
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { researchInterests, education, experiences, awards } from "~/lib/data";
|
||||
|
||||
export default function HomePage() {
|
||||
const researchExperience = experiences.filter(
|
||||
(exp) => exp.type === "research",
|
||||
);
|
||||
const teachingExperience = experiences.filter(
|
||||
(exp) => exp.type === "teaching",
|
||||
);
|
||||
const professionalExperience = experiences.filter(
|
||||
(exp) => exp.type === "professional",
|
||||
);
|
||||
const leadershipExperience = experiences.filter(
|
||||
(exp) => exp.type === "leadership",
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-12">
|
||||
{/* Hero Section */}
|
||||
@@ -30,8 +48,9 @@ export default function HomePage() {
|
||||
Sean O'Connor
|
||||
</h1>
|
||||
<p className="animate-fade-in-up-delay-2 text-xl text-muted-foreground">
|
||||
Computer Science and Engineering student with experience in software
|
||||
development, robotics research, and technical leadership.
|
||||
Computer Science and Engineering student passionate about
|
||||
human-robot interaction and developing technologies that make robots
|
||||
better collaborators with humans.
|
||||
</p>
|
||||
<div className="animate-fade-in-up-delay-3 flex flex-wrap gap-4 text-sm text-muted-foreground">
|
||||
<div className="flex items-center gap-1">
|
||||
@@ -40,6 +59,16 @@ export default function HomePage() {
|
||||
sean@soconnor.dev
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Mail className="h-4 w-4" />
|
||||
<a
|
||||
href="mailto:sso005@bucknell.edu"
|
||||
className="hover:text-primary"
|
||||
>
|
||||
sso005@bucknell.edu
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<GraduationCap className="h-4 w-4" />
|
||||
Bucknell University
|
||||
@@ -66,320 +95,330 @@ export default function HomePage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Current Focus */}
|
||||
{/* Research Interests */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Current Focus</h2>
|
||||
<div className="grid-equal-height grid gap-6 md:grid-cols-2">
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<FlaskConical className="h-5 w-5" />
|
||||
<h2 className="text-2xl font-bold">Research Interests</h2>
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover">
|
||||
<CardContent className="pt-6">
|
||||
<p className="leading-relaxed text-muted-foreground">
|
||||
{researchInterests}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Education */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Education</h2>
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">
|
||||
Human-Robot Interaction Research
|
||||
{education.institution}
|
||||
</CardTitle>
|
||||
<CardDescription>{education.location}</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Developing a web-based platform for HRI experiments that
|
||||
addresses reproducibility challenges in Wizard-of-Oz studies.
|
||||
Published at IEEE RO-MAN 2024 with second publication
|
||||
forthcoming.
|
||||
<School className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3 pt-0">
|
||||
<div>
|
||||
<p className="font-medium">{education.degree}</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Expected {education.expectedGraduation}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-2">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<GraduationCap className="h-5 w-5" />
|
||||
<CardTitle className="mb-1">Academic Excellence</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Bachelor of Science in Computer Science and Engineering at
|
||||
Bucknell University. 3.86 Engineering GPA, Dean's List
|
||||
multiple semesters. Expected graduation: May 2026.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Badge variant="secondary">
|
||||
Engineering GPA: {education.gpa}
|
||||
</Badge>
|
||||
<Badge variant="outline">
|
||||
Dean's List: {education.deansListSemesters.length} semesters
|
||||
</Badge>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Experience Highlights */}
|
||||
{/* Research Experience */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Experience Highlights</h2>
|
||||
<h2 className="text-2xl font-bold">Research Experience</h2>
|
||||
<div className="space-y-6">
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">
|
||||
Software Developer - Riverhead Raceway
|
||||
</CardTitle>
|
||||
<CardDescription>Oct 2020 – Present</CardDescription>
|
||||
{researchExperience.map((exp, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${index + 1}`}
|
||||
>
|
||||
<Card className="card-hover">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">{exp.title}</CardTitle>
|
||||
<CardDescription>{exp.organization}</CardDescription>
|
||||
<CardDescription className="text-xs">
|
||||
{exp.location} • {exp.period}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<FlaskConical className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
<Building className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Transformed organizational culture by building trust in
|
||||
data-driven decision making. Revolutionized fan engagement
|
||||
through a real-time statistics platform serving 1500+
|
||||
concurrent users. Modernized entire technical infrastructure
|
||||
through containerization and automated systems.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-2">
|
||||
<Card className="card-hover">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">
|
||||
Computer Science Researcher - Bucknell University
|
||||
</CardTitle>
|
||||
<CardDescription>Jan 2023 – Present</CardDescription>
|
||||
</div>
|
||||
<FlaskConical className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Led research and authored first-author paper presented at
|
||||
international conference. Built framework that enables
|
||||
researchers to conduct experiments across different robot
|
||||
platforms without specialized programming knowledge.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-3">
|
||||
<Card className="card-hover">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">
|
||||
Teaching Assistant - Computer Science
|
||||
</CardTitle>
|
||||
<CardDescription>Jan 2024 – Present</CardDescription>
|
||||
</div>
|
||||
<Users className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Mentored 150+ students in software engineering principles,
|
||||
connecting theoretical concepts to real-world applications.
|
||||
Developed learning environments that embrace productive
|
||||
failure.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
{exp.description.map((item, itemIndex) => (
|
||||
<li key={itemIndex} className="flex items-start gap-2">
|
||||
<span className="mt-2 h-1 w-1 flex-shrink-0 rounded-full bg-muted-foreground" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Technical Skills */}
|
||||
{/* Professional Experience Highlights */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="flex items-center gap-2 text-2xl font-bold">
|
||||
<Code className="h-6 w-6" />
|
||||
Technical Skills
|
||||
<h2 className="text-2xl font-bold">
|
||||
Professional Experience Highlights
|
||||
</h2>
|
||||
<div className="space-y-6">
|
||||
{professionalExperience.slice(0, 2).map((exp, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${index + 1}`}
|
||||
>
|
||||
<Card className="card-hover">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="mb-1">{exp.title}</CardTitle>
|
||||
<CardDescription>{exp.organization}</CardDescription>
|
||||
<CardDescription className="text-xs">
|
||||
{exp.location} • {exp.period}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Building className="h-5 w-5 text-muted-foreground" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
{exp.description.slice(0, 3).map((item, itemIndex) => (
|
||||
<li key={itemIndex} className="flex items-start gap-2">
|
||||
<span className="mt-2 h-1 w-1 flex-shrink-0 rounded-full bg-muted-foreground" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Teaching Experience */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Teaching Experience</h2>
|
||||
<div className="grid-equal-height grid gap-6 md:grid-cols-2">
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">Languages & Frameworks</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Java, C/C++, Python, JavaScript/TypeScript, React, Next.js,
|
||||
PHP, SQL
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-2">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">Backend & DevOps</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
REST APIs, MySQL, PostgreSQL, Docker, Apache Web Server,
|
||||
NGINX, ROS2
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-3">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">Cloud & Infrastructure</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
AWS, GCP, Azure, Backblaze, Linux (RHEL/Debian), CI/CD
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-4">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">Development Tools</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Git, JetBrains Suite, VS Code, Cursor, Linux CLI
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
{teachingExperience.slice(0, 4).map((exp, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${index + 1}`}
|
||||
>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<GraduationCap className="h-5 w-5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<CardTitle className="mb-1 break-words text-base leading-tight">
|
||||
{exp.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="break-words text-xs">
|
||||
{exp.organization}
|
||||
</CardDescription>
|
||||
<CardDescription className="text-xs">
|
||||
{exp.period}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
{exp.description[0]}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Leadership & Activities */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="flex items-center gap-2 text-2xl font-bold">
|
||||
<Users className="h-6 w-6" />
|
||||
Leadership & Activities
|
||||
</h2>
|
||||
<h2 className="text-2xl font-bold">Leadership & Activities</h2>
|
||||
<div className="grid-equal-height grid gap-6 md:grid-cols-2">
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">
|
||||
AIChE Chem-E-Car Competition Team
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Former President, Electrical and Mechanical Team Lead
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Pioneered team's first custom hardware solution by
|
||||
designing and fabricating a microcontroller-based control
|
||||
system. Improved team dynamics by introducing agile
|
||||
development principles and structured communication protocols.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
{leadershipExperience.map((exp, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${index + 1}`}
|
||||
>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Users className="h-5 w-5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<CardTitle className="mb-1 break-words text-base leading-tight">
|
||||
{exp.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="break-words text-xs">
|
||||
{exp.organization}
|
||||
</CardDescription>
|
||||
<CardDescription className="text-xs">
|
||||
{exp.period}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<ul className="space-y-1 text-sm text-muted-foreground">
|
||||
{exp.description.slice(0, 2).map((item, itemIndex) => (
|
||||
<li key={itemIndex} className="flex items-start gap-2">
|
||||
<span className="mt-2 h-1 w-1 flex-shrink-0 rounded-full bg-muted-foreground" />
|
||||
<span className="break-words">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="animate-fade-in-up-delay-2">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">Bucknell Coffee Society</CardTitle>
|
||||
<CardDescription>Treasurer</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Co-established and launched a new campus organization,
|
||||
managing financial operations and coordinating event
|
||||
logistics.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-3">
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="mb-1">RoboLab@Bucknell</CardTitle>
|
||||
<CardDescription>Founding Member</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="text-muted-foreground">
|
||||
Led and participated in group discussions in a new lab
|
||||
bridging computer science and psychology perspectives on
|
||||
human-robot interaction, working with the complexities of
|
||||
human-robot trust, job replacement, and autonomy.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
{/* Recent Awards & Recognition */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Recent Awards & Recognition</h2>
|
||||
<div className="grid-equal-height grid gap-4 md:grid-cols-2">
|
||||
{awards.map((award, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`animate-fade-in-up-delay-${index + 1}`}
|
||||
>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Award className="h-5 w-5 flex-shrink-0" />
|
||||
<div className="min-w-0">
|
||||
<CardTitle className="mb-1 break-words text-base leading-tight">
|
||||
{award.title}
|
||||
</CardTitle>
|
||||
{award.organization && (
|
||||
<CardDescription className="break-words">
|
||||
{award.organization} • {award.year}
|
||||
</CardDescription>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
{award.description && (
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<p className="break-words text-sm leading-relaxed text-muted-foreground">
|
||||
{award.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Quick Links */}
|
||||
<section className="animate-fade-in-up space-y-6">
|
||||
<h2 className="text-2xl font-bold">Explore More</h2>
|
||||
<div className="grid-equal-height grid gap-4 md:grid-cols-3">
|
||||
<div className="grid-equal-height grid gap-6 md:grid-cols-3">
|
||||
<div className="animate-fade-in-up-delay-1">
|
||||
<Card className="card-hover card-full-height group cursor-pointer transition-colors hover:bg-accent">
|
||||
<Link href="/publications" className="block h-full p-4">
|
||||
<CardContent className="card-content-stretch p-0">
|
||||
<div className="flex h-full items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<FlaskConical className="h-6 w-6 text-primary" />
|
||||
<div>
|
||||
<div className="font-medium">Research Publications</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
IEEE conferences and ongoing research
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ArrowUpRight className="h-4 w-4 text-muted-foreground group-hover:text-primary" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Link>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Code className="h-5 w-5 flex-shrink-0" />
|
||||
<CardTitle className="mb-1 break-words">Projects</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<div className="flex h-full flex-col">
|
||||
<p className="break-words leading-relaxed text-muted-foreground">
|
||||
Explore my featured projects including HRIStudio, machine
|
||||
learning research, and web applications.
|
||||
</p>
|
||||
<Button variant="outline" asChild className="mt-auto w-full">
|
||||
<Link href="/projects">
|
||||
View Projects
|
||||
<ArrowUpRight className="ml-2 h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-2">
|
||||
<Card className="card-hover card-full-height group cursor-pointer transition-colors hover:bg-accent">
|
||||
<Link href="/projects" className="block h-full p-4">
|
||||
<CardContent className="card-content-stretch p-0">
|
||||
<div className="flex h-full items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Code className="h-6 w-6 text-primary" />
|
||||
<div>
|
||||
<div className="font-medium">Projects</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
Software development and research work
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ArrowUpRight className="h-4 w-4 text-muted-foreground group-hover:text-primary" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Link>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<BookOpen className="h-5 w-5 flex-shrink-0" />
|
||||
<CardTitle className="mb-1 break-words">
|
||||
Publications
|
||||
</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<div className="flex h-full flex-col">
|
||||
<p className="break-words leading-relaxed text-muted-foreground">
|
||||
Read my peer-reviewed publications in human-robot
|
||||
interaction research.
|
||||
</p>
|
||||
<Button variant="outline" asChild className="mt-auto w-full">
|
||||
<Link href="/publications">
|
||||
View Publications
|
||||
<ArrowUpRight className="ml-2 h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="animate-fade-in-up-delay-3">
|
||||
<Card className="card-hover card-full-height group cursor-pointer transition-colors hover:bg-accent">
|
||||
<Link href="/cv" className="block h-full p-4">
|
||||
<CardContent className="card-content-stretch p-0">
|
||||
<div className="flex h-full items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<GraduationCap className="h-6 w-6 text-primary" />
|
||||
<div>
|
||||
<div className="font-medium">Curriculum Vitae</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
Complete academic and professional record
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ArrowUpRight className="h-4 w-4 text-muted-foreground group-hover:text-primary" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Link>
|
||||
<Card className="card-hover card-full-height">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<ExternalLink className="h-5 w-5 flex-shrink-0" />
|
||||
<CardTitle className="mb-1 break-words">
|
||||
Complete CV
|
||||
</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="card-content-stretch pt-0">
|
||||
<div className="flex h-full flex-col">
|
||||
<p className="break-words leading-relaxed text-muted-foreground">
|
||||
View my complete academic and professional curriculum vitae.
|
||||
</p>
|
||||
<Button variant="outline" asChild className="mt-auto w-full">
|
||||
<Link href="/cv">
|
||||
View CV
|
||||
<ArrowUpRight className="ml-2 h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -79,23 +79,27 @@ export default function ProjectsPage() {
|
||||
<div className="card-content-stretch flex flex-1 flex-col p-6">
|
||||
<div className="flex-1 space-y-4">
|
||||
<div>
|
||||
<CardTitle className="text-xl">
|
||||
<CardTitle className="break-words text-xl leading-tight">
|
||||
{project.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="mt-2 text-base">
|
||||
<CardDescription className="mt-2 break-words text-base leading-relaxed">
|
||||
{project.description}
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground">
|
||||
<p className="break-words leading-relaxed text-muted-foreground">
|
||||
{project.longDescription}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="mt-6 flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{project.tags.map((tag) => (
|
||||
<Badge key={tag} variant="secondary">
|
||||
<Badge
|
||||
key={tag}
|
||||
variant="secondary"
|
||||
className="break-words"
|
||||
>
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
@@ -219,34 +223,32 @@ export default function ProjectsPage() {
|
||||
)}
|
||||
|
||||
<div className="flex flex-1 flex-col p-6">
|
||||
<div className="flex-1">
|
||||
<div className="flex flex-1 flex-col">
|
||||
<CardHeader className="p-0">
|
||||
<div>
|
||||
<CardTitle className="text-lg">
|
||||
<CardTitle className="break-words text-lg leading-tight">
|
||||
{project.title}
|
||||
</CardTitle>
|
||||
</div>
|
||||
<CardDescription className="mt-2">
|
||||
<CardDescription className="mt-2 break-words leading-relaxed">
|
||||
{project.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</div>
|
||||
|
||||
<CardContent className="p-0 pt-4">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<CardContent className="flex flex-1 flex-col p-0 pt-4">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{project.tags.map((tag) => (
|
||||
<Badge
|
||||
key={tag}
|
||||
variant="secondary"
|
||||
className="text-xs"
|
||||
className="break-words text-xs"
|
||||
>
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<div className="mt-auto flex gap-2 pt-4">
|
||||
{project.link && project.link.startsWith("/") && (
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -314,8 +316,8 @@ export default function ProjectsPage() {
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</CardContent>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -114,27 +114,29 @@ export default function PublicationsPage() {
|
||||
>
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
||||
<CardTitle>{pub.title}</CardTitle>
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
|
||||
<CardTitle className="break-words leading-tight">
|
||||
{pub.title}
|
||||
</CardTitle>
|
||||
{pub.paperUrl && (
|
||||
<Link
|
||||
href={pub.paperUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-muted-foreground hover:text-primary sm:flex-shrink-0"
|
||||
className="flex-shrink-0 text-muted-foreground hover:text-primary"
|
||||
>
|
||||
<ArrowUpRight className="h-5 w-5" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<CardDescription className="text-base">
|
||||
<CardDescription className="break-words text-base leading-relaxed">
|
||||
{pub.authors.join(", ")}
|
||||
</CardDescription>
|
||||
<CardDescription className="text-sm">
|
||||
<CardDescription className="break-words text-sm">
|
||||
{pub.venue} ({pub.year})
|
||||
</CardDescription>
|
||||
{pub.address && (
|
||||
<CardDescription className="text-sm text-muted-foreground">
|
||||
<CardDescription className="break-words text-sm text-muted-foreground">
|
||||
{pub.address}
|
||||
</CardDescription>
|
||||
)}
|
||||
@@ -148,7 +150,7 @@ export default function PublicationsPage() {
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
{pub.abstract && (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
<p className="break-words text-sm leading-relaxed text-muted-foreground">
|
||||
{pub.abstract}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import {
|
||||
BookOpenText,
|
||||
Briefcase,
|
||||
FileText,
|
||||
FolderGit2,
|
||||
Home,
|
||||
@@ -19,6 +20,7 @@ const navItems = [
|
||||
{ href: "/articles", label: "Articles", icon: Newspaper },
|
||||
{ href: "/projects", label: "Projects", icon: FolderGit2 },
|
||||
{ href: "/publications", label: "Publications", icon: BookOpenText },
|
||||
{ href: "/experience", label: "Experience", icon: Briefcase },
|
||||
{ href: "/travel", label: "Travel", icon: Plane },
|
||||
{ href: "/cv", label: "CV", icon: FileText },
|
||||
];
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
Plane,
|
||||
FileText,
|
||||
Accessibility,
|
||||
Briefcase,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
Breadcrumb,
|
||||
@@ -74,6 +75,10 @@ export function PageBreadcrumb() {
|
||||
icon = <FileText className="mr-1 h-3.5 w-3.5" />;
|
||||
label = "CV";
|
||||
break;
|
||||
case "experience":
|
||||
icon = <Briefcase className="mr-1 h-3.5 w-3.5" />;
|
||||
label = "Experience";
|
||||
break;
|
||||
case "latex-intro":
|
||||
icon = <BookOpenText className="mr-1 h-3.5 w-3.5" />;
|
||||
label = "LaTeX Tutorial";
|
||||
|
||||
440
src/lib/data.ts
440
src/lib/data.ts
@@ -14,6 +14,44 @@ export interface Project {
|
||||
featured: boolean;
|
||||
}
|
||||
|
||||
export interface Publication {
|
||||
title: string;
|
||||
authors: string[];
|
||||
venue: string;
|
||||
year: number;
|
||||
type: "conference" | "journal" | "workshop" | "thesis";
|
||||
abstract?: string;
|
||||
paperUrl?: string;
|
||||
doi?: string;
|
||||
address?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface Experience {
|
||||
title: string;
|
||||
organization: string;
|
||||
location: string;
|
||||
period: string;
|
||||
description: string[];
|
||||
type: "research" | "teaching" | "professional" | "leadership";
|
||||
}
|
||||
|
||||
export interface Education {
|
||||
institution: string;
|
||||
location: string;
|
||||
degree: string;
|
||||
expectedGraduation: string;
|
||||
gpa: string;
|
||||
deansListSemesters: string[];
|
||||
}
|
||||
|
||||
export interface Award {
|
||||
title: string;
|
||||
organization?: string;
|
||||
year: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const name = [
|
||||
{
|
||||
first: "Sean",
|
||||
@@ -21,7 +59,26 @@ export const name = [
|
||||
},
|
||||
];
|
||||
|
||||
export const description = "Personal website and portfolio";
|
||||
export const description =
|
||||
"Computer Science and Engineering student passionate about human-robot interaction and developing technologies that make robots better collaborators with humans.";
|
||||
|
||||
export const researchInterests =
|
||||
"I'm passionate about human-robot interaction and developing technologies that make robots better collaborators with humans. My work focuses on creating reproducible research methodologies, particularly through Wizard-of-Oz experiments, and building platforms that lower barriers for HRI researchers. I'm especially interested in how we can make robot behaviors more trustworthy and explainable, and how to design effective frameworks for studying human-robot collaboration across different contexts and applications.";
|
||||
|
||||
export const education: Education = {
|
||||
institution: "Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
degree: "Bachelor of Science in Computer Science and Engineering",
|
||||
expectedGraduation: "May 2026",
|
||||
gpa: "3.86/4.0",
|
||||
deansListSemesters: [
|
||||
"Fall 2022",
|
||||
"Fall 2023",
|
||||
"Spring 2024",
|
||||
"Fall 2024",
|
||||
"Spring 2025",
|
||||
],
|
||||
};
|
||||
|
||||
export const location = [
|
||||
{
|
||||
@@ -91,7 +148,263 @@ export const articles = [
|
||||
"RoboLab provides an environment for scholarly and creative conversations.",
|
||||
source: "the Bucknell College of Engineering Report 2024",
|
||||
},
|
||||
// Add more articles as needed
|
||||
];
|
||||
|
||||
export const experiences: Experience[] = [
|
||||
{
|
||||
title: "Lead Researcher - HRIStudio Platform Development",
|
||||
organization: "Human-Robot Interaction Research, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Jan 2023 – Present",
|
||||
description: [
|
||||
"Developing HRIStudio, a novel web-based platform addressing reproducibility challenges in Wizard-of-Oz HRI studies, with two first-author publications at IEEE RO-MAN 2024 and 2025",
|
||||
"Designed modular architecture enabling cross-platform robot control without specialized programming knowledge, lowering technical barriers for HRI researchers across disciplines",
|
||||
"Implemented comprehensive data logging and playback capabilities for experimental analysis, supporting rigorous scientific methodology in human-robot interaction studies",
|
||||
"Conducted literature review identifying key challenges in WoZ methodology reproducibility, informing platform design decisions and feature prioritization",
|
||||
],
|
||||
type: "research",
|
||||
},
|
||||
{
|
||||
title:
|
||||
"Computer Science Research Assistant - Chemical Engineering Department",
|
||||
organization:
|
||||
"Interdisciplinary Research Collaboration, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Aug 2023 – May 2025",
|
||||
description: [
|
||||
"Developed automated data collection and analysis tools for environmental research, processing real-time sensor data streams for atmospheric and water quality monitoring",
|
||||
"Built custom Python pipelines integrating multiple data sources, enabling researchers to identify patterns in environmental data that informed conference presentations",
|
||||
"Bridged computer science expertise with domain-specific research needs, demonstrating ability to collaborate across disciplines",
|
||||
],
|
||||
type: "research",
|
||||
},
|
||||
{
|
||||
title: "Founding Member and Research Participant",
|
||||
organization: "RoboLab@Bucknell",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Sep 2023 - Present",
|
||||
description: [
|
||||
"Participate in weekly research seminars exploring human-robot trust, automation bias, and ethical implications of autonomous systems",
|
||||
"Contribute to discussions on experimental design for HRI studies, bringing technical perspective to psychological research questions",
|
||||
],
|
||||
type: "research",
|
||||
},
|
||||
{
|
||||
title: "Teaching Assistant - Software Engineering & Design",
|
||||
organization: "Computer Science Department, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Jan 2024 - Present",
|
||||
description: [
|
||||
"Mentor 150+ students in software engineering principles, design patterns, and collaborative development practices",
|
||||
"Developed automated testing frameworks with personalized feedback, improving learning outcomes while streamlining assessment processes",
|
||||
"Created supplementary materials connecting theoretical concepts to real-world applications, drawing from industry experience",
|
||||
"Hold regular office hours and code review sessions, fostering deep understanding of software architecture principles",
|
||||
],
|
||||
type: "teaching",
|
||||
},
|
||||
{
|
||||
title: "Computer Science Tutor",
|
||||
organization: "Engineering Study Spot, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Aug 2024 - Dec 2024",
|
||||
description: [
|
||||
"Provided one-on-one tutoring across the entire computer science curriculum, from introductory programming to advanced algorithms",
|
||||
"Developed personalized learning strategies for students with diverse backgrounds and learning styles",
|
||||
],
|
||||
type: "teaching",
|
||||
},
|
||||
{
|
||||
title: "Teaching Assistant - Engineering Design Experience",
|
||||
organization: "Engineering Department, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Aug 2023 - Dec 2023",
|
||||
description: [
|
||||
"Guided 40+ engineering students through Arduino programming and breadboard circuit design",
|
||||
"Supervised hands-on laboratory sessions involving microcontroller programming and sensor integration",
|
||||
"Facilitated discussions on engineering ethics and the societal implications of embedded system design",
|
||||
],
|
||||
type: "teaching",
|
||||
},
|
||||
{
|
||||
title: "Teaching Assistant - Experimental Physics Laboratory",
|
||||
organization: "Physics Department, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Aug 2023 - May 2024",
|
||||
description: [
|
||||
"Instructed 100+ students in experimental design, data analysis, and scientific writing",
|
||||
"Emphasized connection between theoretical physics principles and experimental validation",
|
||||
"Guided students through error analysis and uncertainty quantification in experimental measurements",
|
||||
],
|
||||
type: "teaching",
|
||||
},
|
||||
{
|
||||
title: "Software Developer",
|
||||
organization: "Riverhead Raceway",
|
||||
location: "Riverhead, NY",
|
||||
period: "Oct 2020 – Present",
|
||||
description: [
|
||||
"Architected and deployed production systems handling 250k+ monthly users and $100,000+ in payment processing",
|
||||
"Led digital transformation initiative, replacing legacy paper-based systems with modern web applications",
|
||||
"Implemented CI/CD pipelines, containerization, and infrastructure as code using Docker and GitHub Actions",
|
||||
"Developed RESTful APIs and microservices architecture for scalable, maintainable systems",
|
||||
],
|
||||
type: "professional",
|
||||
},
|
||||
{
|
||||
title: "IT Administrator",
|
||||
organization: "Riverhead Raceway",
|
||||
location: "Riverhead, NY",
|
||||
period: "Oct 2020 - Apr 2024",
|
||||
description: [
|
||||
"Modernized IT infrastructure from consumer to enterprise-grade systems, improving uptime to 99.9%",
|
||||
"Implemented comprehensive backup and disaster recovery protocols protecting critical business data",
|
||||
"Automated system administration tasks using PowerShell and Bash scripting",
|
||||
],
|
||||
type: "professional",
|
||||
},
|
||||
{
|
||||
title: "Information Technology Intern",
|
||||
organization: "Miller Place School District",
|
||||
location: "Miller Place, NY",
|
||||
period: "Sep 2020 - May 2022",
|
||||
description: [
|
||||
"Supported 1000+ students and faculty during COVID-19 transition to remote learning",
|
||||
"Deployed and maintained educational technology platforms and troubleshooted hardware/software issues",
|
||||
],
|
||||
type: "professional",
|
||||
},
|
||||
{
|
||||
title: "Former President, Current Electrical/Mechanical Team Lead",
|
||||
organization: "AIChE Chem-E-Car Competition Team, Bucknell University",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Jan 2023 – Present",
|
||||
description: [
|
||||
"Led 15-member interdisciplinary team in designing autonomous chemical-powered vehicles for national competition",
|
||||
"Introduced agile development methodologies and version control practices to hardware development process",
|
||||
"Mentored junior members in embedded systems programming and control theory",
|
||||
],
|
||||
type: "leadership",
|
||||
},
|
||||
{
|
||||
title: "Co-Founder and Treasurer",
|
||||
organization: "Bucknell Coffee Society",
|
||||
location: "Lewisburg, PA",
|
||||
period: "Oct 2023 – Present",
|
||||
description: [
|
||||
"Co-established campus organization promoting coffee education and community building",
|
||||
"Manage $5,000+ annual budget, coordinate events, and maintain vendor relationships",
|
||||
"Organized educational workshops on coffee science, brewing techniques, and sustainability",
|
||||
],
|
||||
type: "leadership",
|
||||
},
|
||||
];
|
||||
|
||||
export const awards: Award[] = [
|
||||
{
|
||||
title: "Dean's List (5 semesters)",
|
||||
organization: "Bucknell University",
|
||||
year: 2024,
|
||||
description: "Fall 2022, Fall 2023, Spring 2024, Fall 2024, Spring 2025",
|
||||
},
|
||||
{
|
||||
title: "AIChE Mid-Atlantic Chem-E-Car Competition",
|
||||
organization: "AIChE",
|
||||
year: 2024,
|
||||
description: "2nd Place",
|
||||
},
|
||||
];
|
||||
|
||||
export const conferences = [
|
||||
{
|
||||
title: "IEEE RO-MAN 2025",
|
||||
location: "Eindhoven, The Netherlands",
|
||||
date: "Aug 2025",
|
||||
presentation:
|
||||
"A Web-Based Wizard-of-Oz Platform for Collaborative and Reproducible Human-Robot Interaction Research",
|
||||
},
|
||||
{
|
||||
title: "IEEE RO-MAN 2024",
|
||||
location: "Pasadena, CA",
|
||||
date: "Aug 2024",
|
||||
presentation:
|
||||
"HRIStudio: A Framework for Wizard-of-Oz Experiments in HRI Studies (Late Breaking Report)",
|
||||
},
|
||||
{
|
||||
title: "AIChE Annual Student Conference",
|
||||
location: "San Diego, CA",
|
||||
date: "Oct 2024",
|
||||
presentation:
|
||||
"Chem-E-Car Performance Competition with autonomous hydrogen fuel cell vehicle",
|
||||
},
|
||||
{
|
||||
title: "AIChE Mid-Atlantic Regional Conference",
|
||||
location: "UMBC, Baltimore, MD",
|
||||
date: "Apr 2024",
|
||||
presentation: "Chem-E-Car Performance Competition - 2nd Place overall",
|
||||
},
|
||||
];
|
||||
|
||||
export const technicalSkills = {
|
||||
"Programming Languages": [
|
||||
"Python",
|
||||
"C/C++",
|
||||
"JavaScript/TypeScript",
|
||||
"Java",
|
||||
"MATLAB",
|
||||
"SQL",
|
||||
"Bash",
|
||||
"LaTeX",
|
||||
],
|
||||
"Robotics & HRI": [
|
||||
"ROS/ROS2",
|
||||
"Gazebo",
|
||||
"NAO/Pepper SDK",
|
||||
"WebSockets",
|
||||
"Robot Operating System (ROS)",
|
||||
],
|
||||
"Machine Learning & AI": [
|
||||
"PyTorch",
|
||||
"TensorFlow",
|
||||
"scikit-learn",
|
||||
"LightGBM",
|
||||
"XGBoost",
|
||||
"OpenCV",
|
||||
"pandas",
|
||||
"numpy",
|
||||
"Jupyter",
|
||||
],
|
||||
"Research Tools": [
|
||||
"Git/GitHub",
|
||||
"Docker",
|
||||
"Statistical Analysis (R)",
|
||||
"Experimental Design",
|
||||
"Data Visualization",
|
||||
],
|
||||
"Web & Systems": [
|
||||
"React",
|
||||
"Node.js",
|
||||
"Next.js",
|
||||
"REST APIs",
|
||||
"PostgreSQL",
|
||||
"Linux",
|
||||
"Cloud Computing",
|
||||
"Distributed Systems",
|
||||
],
|
||||
"Hardware/Embedded": [
|
||||
"Arduino",
|
||||
"Raspberry Pi",
|
||||
"I2C/SPI",
|
||||
"Sensor Integration",
|
||||
"Real-time Systems",
|
||||
],
|
||||
};
|
||||
|
||||
export const relevantCoursework = [
|
||||
"Artificial Intelligence & Data Science: Data Mining, Algorithm Design & Analysis",
|
||||
"Systems & Software Engineering: Software Engineering & Design, Computer Systems, Operating Systems Design, Programming Language Design",
|
||||
"Research & Analysis: Research Methods in Computer Science, Probability & Statistics, Experimental Design",
|
||||
"Mathematics & Theory: Linear Algebra, Discrete Mathematics",
|
||||
"Networks & Security: Computer Networks & Security",
|
||||
];
|
||||
|
||||
export const projects: Project[] = [
|
||||
@@ -100,14 +413,84 @@ export const projects: Project[] = [
|
||||
description:
|
||||
"A modular web-based experimental platform for human-robot interaction studies using the Wizard of Oz experimental paradigm.",
|
||||
longDescription:
|
||||
"Engineered a comprehensive platform that enables researchers to conduct human-robot interaction experiments without requiring extensive programming knowledge. The system integrates with ROS2 and provides a user-friendly interface for experiment design and execution.",
|
||||
tags: ["ROS2", "React", "TypeScript", "C++", "Python"],
|
||||
"Architected full-stack web application for managing HRI experiments with real-time robot control interfaces. Implemented WebSocket-based bidirectional communication protocols for low-latency robot teleoperation. Designed RESTful API leveraging Robot Operating System with JSON-defined plugins for extensibility across multiple robot platforms. Created comprehensive logging system capturing interaction data, timestamps, and experimental conditions for reproducibility. Technologies: Next.js, React, TypeScript, Node.js, WebSockets, PostgreSQL, Docker.",
|
||||
tags: [
|
||||
"ROS2",
|
||||
"React",
|
||||
"TypeScript",
|
||||
"C++",
|
||||
"Python",
|
||||
"WebSockets",
|
||||
"Next.js",
|
||||
"PostgreSQL",
|
||||
"Docker",
|
||||
],
|
||||
gitLink: "https://github.com/soconnor0919/hristudio",
|
||||
image: "/hristudio_laptop.png",
|
||||
imageAlt:
|
||||
"Screenshot of HRIStudio application showing the robot control dashboard on a laptop",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Autonomous Vehicle Control System - Chem-E-Car Competition",
|
||||
description:
|
||||
"Custom microcontroller-based control system for hydrogen fuel cell regulation and reaction monitoring.",
|
||||
longDescription:
|
||||
"Designed embedded control system for autonomous hydrogen fuel cell-powered vehicle using finite state machine architecture. Implemented real-time sensor fusion combining spectrometer readings and power monitoring with calculated stopping algorithms. Developed PlatformIO-based build system with hardware abstraction layer for testing and simulation. Achieved precise distance control (±10cm) through chemical reaction timing at AIChE National Competition. Technologies: C++, Arduino, PlatformIO, I2C/SPI protocols, finite state machines.",
|
||||
tags: [
|
||||
"C++",
|
||||
"Embedded Systems",
|
||||
"Hardware Design",
|
||||
"Arduino",
|
||||
"PlatformIO",
|
||||
"I2C/SPI",
|
||||
],
|
||||
gitLink: "https://github.com/soconnor0919/national_fa24",
|
||||
image: "/car.png",
|
||||
imageAlt:
|
||||
"Photo of the Chem-E-Car with custom control system hardware visible, showing the microcontroller and sensor connections",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Formula One Performance Prediction Using Machine Learning",
|
||||
description:
|
||||
"Machine learning project analyzing Formula One race data to predict lap times based on weather conditions and track characteristics.",
|
||||
longDescription:
|
||||
"Developed ensemble machine learning models (LightGBM, XGBoost, Random Forest) to predict F1 lap times with high accuracy. Engineered features from weather data, track characteristics, and historical performance using domain knowledge. Implemented cross-validation and hyperparameter optimization for model evaluation across multiple racing circuits. Analyzed feature importance to understand factors influencing racing performance. Technologies: Python, LightGBM, XGBoost, Random Forest, pandas, scikit-learn, FastF1 API.",
|
||||
tags: [
|
||||
"Python",
|
||||
"Machine Learning",
|
||||
"Data Science",
|
||||
"LightGBM",
|
||||
"XGBoost",
|
||||
"Random Forest",
|
||||
"FastF1",
|
||||
"Jupyter",
|
||||
],
|
||||
gitLink: "https://github.com/soconnor0919/f1-race-prediction",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Real-time Racing Statistics Platform",
|
||||
description:
|
||||
"A comprehensive web platform for Riverhead Raceway, a local motorsports track in New York, serving 1500+ concurrent users during race events.",
|
||||
longDescription:
|
||||
"Built production system serving 1500+ concurrent users and 250k+ monthly visitors. Implemented WebSocket-based real-time data streaming with automatic reconnection and state synchronization. Designed responsive UI with accessibility features meeting WCAG 2.1 AA standards. Optimized database queries reducing page load times by 60% through intelligent caching and indexing. Technologies: Next.js, TypeScript, PostgreSQL, Docker, DigitalOcean.",
|
||||
tags: [
|
||||
"Next.js",
|
||||
"TypeScript",
|
||||
"PostgreSQL",
|
||||
"Drizzle ORM",
|
||||
"Auth.js",
|
||||
"Tailwind CSS",
|
||||
"WebSockets",
|
||||
"Docker",
|
||||
],
|
||||
websiteLink: "https://riverheadraceway.com",
|
||||
image: "/images/racehub.png",
|
||||
imageAlt: "Screenshot of the RaceHub Next platform",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "BeenVoice - Professional Invoicing Platform",
|
||||
description:
|
||||
@@ -166,55 +549,6 @@ export const projects: Project[] = [
|
||||
"Decorative thumbnail showing the project title 'Getting Started with LaTeX'",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "RaceHub Next - Motorsports Track Management Platform",
|
||||
description:
|
||||
"A comprehensive web platform for Riverhead Raceway, a local motorsports track in New York, serving 1500+ concurrent users during race events.",
|
||||
longDescription:
|
||||
"The platform combines a public website for fans to access event schedules, race results, and competitor information with a sophisticated content management system for track staff. Features include automated email newsletters reaching thousands of subscribers, real-time race data management across multiple racing divisions, championship standings tracking, and mobile-responsive design for on-site access. The system centralizes all track operations from event scheduling to competitor management, replacing a legacy system while maintaining critical functionality for one of Long Island's premier racing venues",
|
||||
tags: [
|
||||
"Next.js",
|
||||
"TypeScript",
|
||||
"PostgreSQL",
|
||||
"Drizzle ORM",
|
||||
"Auth.js",
|
||||
"Tailwind CSS",
|
||||
],
|
||||
websiteLink: "https://riverheadraceway.com",
|
||||
image: "/images/racehub.png",
|
||||
imageAlt: "Screenshot of the RaceHub Next platform",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Formula One Lap Time Prediction",
|
||||
description:
|
||||
"Machine learning project analyzing Formula One race data to predict lap times based on weather conditions and track characteristics.",
|
||||
longDescription:
|
||||
"A comprehensive data mining project that analyzes Formula One race data to predict lap times using machine learning models. Achieved significant success with varying models by incorporating weather conditions, track characteristics, and tire degradation metrics. Data sourced from FastF1 API with analysis covering multiple tracks and racing conditions.",
|
||||
tags: [
|
||||
"Python",
|
||||
"Machine Learning",
|
||||
"Data Science",
|
||||
"LightGBM",
|
||||
"FastF1",
|
||||
"Jupyter",
|
||||
],
|
||||
gitLink: "https://github.com/soconnor0919/f1-race-prediction",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Chem-E-Car Control System",
|
||||
description:
|
||||
"Custom microcontroller-based control system for hydrogen fuel cell regulation and reaction monitoring.",
|
||||
longDescription:
|
||||
"Pioneered the team's first custom hardware solution, implementing a finite state machine architecture that integrates spectrometer readings, relay control, and LED feedback for real-time reaction monitoring.",
|
||||
tags: ["C++", "Embedded Systems", "Hardware Design"],
|
||||
gitLink: "https://github.com/soconnor0919/national_fa24",
|
||||
image: "/car.png",
|
||||
imageAlt:
|
||||
"Photo of the Chem-E-Car with custom control system hardware visible, showing the microcontroller and sensor connections",
|
||||
featured: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const travel = [
|
||||
|
||||
@@ -267,6 +267,100 @@ body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Ensure buttons align to bottom of cards */
|
||||
.card-button-bottom {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* Card layout improvements for consistent button positioning */
|
||||
.card-full-height {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-full-height .card-header {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-full-height .card-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.card-full-height .card-footer {
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* Text wrapping and overflow utilities */
|
||||
.break-words {
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.text-truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Ensure flex items don't shrink below content size */
|
||||
.flex-shrink-0 {
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* Better line height for readability */
|
||||
.leading-relaxed {
|
||||
line-height: 1.625;
|
||||
}
|
||||
|
||||
.leading-tight {
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
/* Prevent layout shifts with min-width */
|
||||
.min-w-0 {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Consistent spacing for list items */
|
||||
.list-spacing li + li {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
/* Button positioning in card layouts */
|
||||
.mt-auto {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* Grid layout improvements */
|
||||
.grid-equal-height {
|
||||
display: grid;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
/* Enhanced card content distribution */
|
||||
.card-with-button {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-with-button .card-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-with-button .card-actions {
|
||||
margin-top: auto;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
|
||||
Reference in New Issue
Block a user