Skip to content

Commit

Permalink
Merge pull request #3 from jonaschlegel/adjust-the-cv-timeline-styling
Browse files Browse the repository at this point in the history
Create a mobile friendly CV page version
  • Loading branch information
jonaschlegel authored Oct 12, 2024
2 parents 7925571 + b7e0b2a commit eedc021
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 46 deletions.
171 changes: 171 additions & 0 deletions app/components/CvTabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
'use client';
import React, { useState } from 'react';

interface Job {
id: string;
title: string;
organization: string;
startDate: string;
endDate?: string;
location: string;
description: string;
url?: string;
}

interface Education {
id: string;
degree: string;
institution: string;
startDate: string;
endDate?: string;
location: string;
description: string;
url?: string;
}

interface Publication {
id: string;
title: string;
type: string;
date: string;
authors: string[];
url?: string;
}

interface CvTabsProps {
workEntries: { id: string; data: Job }[];
educationEntries: { id: string; data: Education }[];
publications: Publication[];
}

const CvTabs: React.FC<CvTabsProps> = ({
workEntries,
educationEntries,
publications,
}) => {
const [activeTab, setActiveTab] = useState<
'work' | 'education' | 'publications'
>('work');

return (
<div>
<div className="flex justify-around mb-4">
<button
className={`px-4 py-2 ${activeTab === 'work' ? 'border-b-2 border-primary-accent font-bold' : ''}`}
onClick={() => setActiveTab('work')}
>
Work
</button>
<button
className={`px-4 py-2 ${activeTab === 'education' ? 'border-b-2 border-primary-accent font-bold' : ''}`}
onClick={() => setActiveTab('education')}
>
Education
</button>
<button
className={`px-4 py-2 ${activeTab === 'publications' ? 'border-b-2 border-primary-accent font-bold' : ''}`}
onClick={() => setActiveTab('publications')}
>
Publications
</button>
</div>

{/* Work Tab */}
{activeTab === 'work' && (
<div>
{workEntries.map((entry) => (
<div
key={`mobile-work-${entry.id}`}
className="mb-4 p-4 rounded-lg shadow bg-gray-50"
>
<h3 className="font-semibold text-gray-900 text-sm">
{entry.data.title} at {entry.data.organization}
</h3>
<p className="text-xs text-gray-700">
{entry.data.startDate} - {entry.data.endDate || 'Present'} |{' '}
{entry.data.location}
</p>
<p className="text-gray-700">{entry.data.description}</p>
{entry.data.url && (
<a
href={entry.data.url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Project or Institution
</a>
)}
</div>
))}
</div>
)}

{/* Education Tab */}
{activeTab === 'education' && (
<div>
{educationEntries.map((entry) => (
<div
key={`mobile-education-${entry.id}`}
className="mb-4 p-4 rounded-lg shadow bg-gray-50"
>
<h3 className="font-semibold text-gray-900 text-sm">
{entry.data.degree} at {entry.data.institution}
</h3>
<p className="text-xs text-gray-700 my-2">
{entry.data.startDate} - {entry.data.endDate || 'Present'} |{' '}
{entry.data.location}
{entry.data.endDate || 'Present'} | {entry.data.location}
</p>
<div className="text-gray-700">{entry.data.description}</div>
{entry.data.url && (
<a
href={entry.data.url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Department
</a>
)}
</div>
))}
</div>
)}

{/* Publications Tab */}
{activeTab === 'publications' && (
<div>
{publications.map((pub) => (
<div
key={`mobile-publication-${pub.id}`}
className="mb-4 p-4 rounded-lg shadow bg-gray-50"
>
<h3 className="font-semibold text-gray-900 text-sm">
{pub.title}
</h3>
<div className="text-xs uppercase my-2 text-gray-700">
{pub.type}
</div>
<div className="text-xs text-gray-700">
{pub.date} | {pub.authors.join(', ')}
</div>
{pub.url && (
<a
href={pub.url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Publication
</a>
)}
</div>
))}
</div>
)}
</div>
);
};

export default CvTabs;
125 changes: 79 additions & 46 deletions app/cv/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import React from 'react';
import CvTabs from '../components/CvTabs';

interface Job {
id: string;
title: string;
organization: string;
startDate: string;
Expand All @@ -14,6 +16,7 @@ interface Job {
}

interface Education {
id: string;
degree: string;
institution: string;
startDate: string;
Expand All @@ -24,6 +27,7 @@ interface Education {
}

interface Publication {
id: string;
title: string;
type: string;
date: string;
Expand Down Expand Up @@ -189,9 +193,24 @@ const CvPage = async () => {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 className="mb-8">Curriculum Vitae</h1>

{/* Grid container */}
{/* Mobile Tabs */}
<div className="block md:hidden">
<CvTabs
workEntries={workEntries.map((entry) => ({
id: entry.id,
data: entry.data as Job,
}))}
educationEntries={educationEntries.map((entry) => ({
id: entry.id,
data: entry.data as Education,
}))}
publications={publications}
/>
</div>

{/* Desktop version with grid */}
<div
className="grid gap-1"
className="hidden md:grid gap-1"
style={{
gridTemplateColumns: '100px 1fr 1fr 1fr',
gridTemplateRows: `repeat(${currentRow - 1}, auto)`,
Expand Down Expand Up @@ -240,28 +259,35 @@ const CvPage = async () => {
}}
className="p-2 rounded-lg shadow bg-gray-50"
>
<h3 className="font-semibold text-gray-900 text-sm">
{(entry.data as Job).title} at{' '}
{(entry.data as Job).organization}
</h3>
<p className="text-xs text-gray-700">
{(entry.data as Job).startDate} -{' '}
{(entry.data as Job).endDate || 'Present'} |{' '}
{(entry.data as Job).location}
</p>
<p className="text-gray-700">
{(entry.data as Job).description}
</p>
{entry.data.url && (
<a
href={(entry.data as Job).url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Project or Institution
</a>
)}
<div
style={{
position: 'sticky',
top: '10px',
}}
>
<h3 className="font-semibold text-gray-900 text-sm">
{(entry.data as Job).title} at{' '}
{(entry.data as Job).organization}
</h3>
<p className="text-xs text-gray-700">
{(entry.data as Job).startDate} -{' '}
{(entry.data as Job).endDate || 'Present'} |{' '}
{(entry.data as Job).location}
</p>
<p className="text-gray-700">
{(entry.data as Job).description}
</p>
{entry.data.url && (
<a
href={(entry.data as Job).url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Project or Institution
</a>
)}
</div>
</div>
);
})}
Expand All @@ -288,28 +314,35 @@ const CvPage = async () => {
}}
className="p-2 rounded-lg shadow bg-gray-50"
>
<h3 className="font-semibold text-gray-900 text-sm">
{(entry.data as Education).degree} at{' '}
{(entry.data as Education).institution}
</h3>
<p className="text-xs text-gray-700 my-2">
{(entry.data as Education).startDate} -{' '}
{(entry.data as Education).endDate || 'Present'} |{' '}
{(entry.data as Education).location}
</p>
<p className="text-gray-700">
{(entry.data as Education).description}
</p>
{entry.data.url && (
<a
href={(entry.data as Education).url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Department
</a>
)}
<div
style={{
position: 'sticky',
top: '10px',
}}
>
<h3 className="font-semibold text-gray-900 text-sm">
{(entry.data as Education).degree} at{' '}
{(entry.data as Education).institution}
</h3>
<p className="text-xs text-gray-700 my-2">
{(entry.data as Education).startDate} -{' '}
{(entry.data as Education).endDate || 'Present'} |{' '}
{(entry.data as Education).location}
</p>
<p className="text-gray-700">
{(entry.data as Education).description}
</p>
{entry.data.url && (
<a
href={(entry.data as Education).url}
className="text-primary-accent underline text-xs"
target="_blank"
rel="noopener noreferrer"
>
View Department
</a>
)}
</div>
</div>
);
})}
Expand Down

0 comments on commit eedc021

Please sign in to comment.