diff --git a/app/cv/page.tsx b/app/cv/page.tsx
new file mode 100644
index 0000000..6c0529a
--- /dev/null
+++ b/app/cv/page.tsx
@@ -0,0 +1,270 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import React from 'react';
+
+interface Job {
+ title: string;
+ organization: string;
+ startDate: string;
+ endDate?: string;
+ location: string;
+ description: string;
+}
+
+interface Education {
+ degree: string;
+ institution: string;
+ startDate: string;
+ endDate?: string;
+ location: string;
+ description: string;
+}
+
+interface Publication {
+ title: string;
+ date: string;
+ authors: string[];
+ url: string;
+}
+
+const CvPage = async () => {
+ const workPath = path.join(process.cwd(), 'app/data/cv/work-experience.json');
+ const educationPath = path.join(
+ process.cwd(),
+ 'app/data/cv/educational-experience.json',
+ );
+ const publicationsPath = path.join(
+ process.cwd(),
+ 'app/data/cv/publications.json',
+ );
+
+ const workExperience: Job[] = JSON.parse(await fs.readFile(workPath, 'utf8'));
+ const educationalExperience: Education[] = JSON.parse(
+ await fs.readFile(educationPath, 'utf8'),
+ );
+ const publications: Publication[] = JSON.parse(
+ await fs.readFile(publicationsPath, 'utf8'),
+ );
+
+ const parseDate = (dateStr: string): Date => {
+ if (dateStr.toLowerCase() === 'present') {
+ return new Date(); // Current date for ongoing entries
+ }
+ return new Date(dateStr);
+ };
+
+ const calculateSpanInYears = (startDate: Date, endDate: Date): number => {
+ const startYear = startDate.getFullYear();
+ const endYear = Math.min(endDate.getFullYear(), new Date().getFullYear());
+ return endYear - startYear + 1;
+ };
+
+ const combinedItems = [
+ ...workExperience.map((job) => ({
+ type: 'work',
+ startDate: parseDate(job.startDate),
+ endDate: parseDate(job.endDate || 'Present'),
+ data: job,
+ })),
+ ...educationalExperience.map((edu) => ({
+ type: 'education',
+ startDate: parseDate(edu.startDate),
+ endDate: parseDate(edu.endDate || 'Present'),
+ data: edu,
+ })),
+ ...publications.map((pub) => ({
+ type: 'publication',
+ startDate: parseDate(pub.date),
+ endDate: parseDate(pub.date),
+ data: pub,
+ })),
+ ];
+
+ const earliestYear = Math.min(
+ ...combinedItems.map((item) => item.startDate.getFullYear()),
+ );
+ const latestYear = Math.max(
+ ...combinedItems.map((item) => item.endDate.getFullYear()),
+ );
+
+ const allYears = [];
+ for (let year = latestYear; year >= earliestYear; year--) {
+ allYears.push(year);
+ }
+
+ const getItemsForYear = (year: number) => {
+ return combinedItems.filter(
+ (item) =>
+ item.startDate.getFullYear() <= year &&
+ item.endDate.getFullYear() >= year,
+ );
+ };
+
+ // Track already rendered work and education items to avoid repeating
+ const renderedWorkItems = new Set();
+ const renderedEducationItems = new Set();
+
+ return (
+
+
+
Curriculum Vitae
+
+
+
+
Year
+ Work
+ Education
+ Publications
+
+
+ {allYears.map((year) => {
+ const itemsForYear = getItemsForYear(year);
+
+ return (
+
+
+ {/* Work Experience Column (spanning multiple years) */}
+
+ {itemsForYear
+ .filter((item) => item.type === 'work')
+ .map((item) => {
+ const spanInYears = calculateSpanInYears(
+ item.startDate,
+ item.endDate,
+ );
+
+ if (
+ item.startDate.getFullYear() === year &&
+ !renderedWorkItems.has(item)
+ ) {
+ renderedWorkItems.add(item);
+ return (
+
+
+ {(item.data as Job).title} at{' '}
+ {(item.data as Job).organization}
+
+
+ {item.startDate.getFullYear()} -{' '}
+ {item.endDate.getFullYear() ===
+ new Date().getFullYear()
+ ? 'Present'
+ : item.endDate.getFullYear()}{' '}
+ | {(item.data as Job).location}
+
+
+ {(item.data as Job).description}
+
+
+ );
+ } else {
+ return null; // Prevent rendering in non-start years
+ }
+ })}
+
+
+ {/* Educational Experience Column (spanning multiple years) */}
+
+ {itemsForYear
+ .filter((item) => item.type === 'education')
+ .map((item) => {
+ const spanInYears = calculateSpanInYears(
+ item.startDate,
+ item.endDate,
+ );
+
+ if (
+ item.startDate.getFullYear() === year &&
+ !renderedEducationItems.has(item)
+ ) {
+ renderedEducationItems.add(item);
+ return (
+
+
+ {(item.data as Education).degree} at{' '}
+ {(item.data as Education).institution}
+
+
+ {item.startDate.getFullYear()} -{' '}
+ {item.endDate.getFullYear() ===
+ new Date().getFullYear()
+ ? 'Present'
+ : item.endDate.getFullYear()}{' '}
+ | {(item.data as Education).location}
+
+
+ {(item.data as Education).description}
+
+
+ );
+ } else {
+ return null; // Prevent rendering in non-start years
+ }
+ })}
+
+
+ {/* Publications Column (single row) */}
+
+ {itemsForYear
+ .filter((item) => item.type === 'publication')
+ .map((item) => (
+
+
+ {(item.data as Publication).title}
+
+
+ {(item.data as Publication).date} |{' '}
+ {(item.data as Publication).authors.join(', ')}
+
+
+ View Publication
+
+
+ ))}
+
+
+ );
+ })}
+
+
+
+ );
+};
+
+export default CvPage;
diff --git a/app/data/content.ts b/app/data/content.ts
index 40dd89b..761a8ea 100644
--- a/app/data/content.ts
+++ b/app/data/content.ts
@@ -22,6 +22,7 @@ import webDevelopment from '../images/services/web-development.png';
export const navLinks = [
{ name: 'Featured Projects', href: '/#project' },
{ name: 'Services', href: '/#service' },
+ { name: 'CV', href: 'cv' },
] as const;
export const heroSectionData = {
diff --git a/app/data/cv/educational-experience.json b/app/data/cv/educational-experience.json
new file mode 100644
index 0000000..d6961d2
--- /dev/null
+++ b/app/data/cv/educational-experience.json
@@ -0,0 +1,26 @@
+[
+ {
+ "degree": "Ph.D. in Prehistory and Historical Archaeology",
+ "institution": "University of Vienna",
+ "startDate": "March 2019",
+ "endDate": "Present",
+ "description": "Doctoral studies focusing on prehistoric and historical archaeological research.",
+ "location": "Vienna, Austria"
+ },
+ {
+ "degree": "M.Sc. in Landscape Archaeology",
+ "institution": "Hochschule für Technik und Wirtschaft / Freie Universität",
+ "startDate": "April 2016",
+ "endDate": "June 2018",
+ "description": "Master thesis on ancient archaeological sites using modern field archaeology methods.",
+ "location": "Berlin, Germany"
+ },
+ {
+ "degree": "B.A. in Conservation & Restoration / Field Archaeology",
+ "institution": "Hochschule für Technik und Wirtschaft",
+ "startDate": "October 2012",
+ "endDate": "March 2016",
+ "description": "Focus on field archaeology and excavation techniques.",
+ "location": "Berlin, Germany"
+ }
+]
diff --git a/app/data/cv/publications.json b/app/data/cv/publications.json
new file mode 100644
index 0000000..1d2dc3a
--- /dev/null
+++ b/app/data/cv/publications.json
@@ -0,0 +1,270 @@
+[
+ {
+ "title": "Different Folks, Different Strokes",
+ "authors": [
+ "Merrill, Samuel",
+ "Verhoeven, Geert",
+ "Wild, Benjamin",
+ "Schlegel, Jona"
+ ],
+ "date": "May 2023",
+ "url": "https://doi.org/10.48619/indigo.v0i0.701",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Towards a Graffiti Thesaurus",
+ "authors": [
+ "Schlegel, Jona",
+ "Carloni, Massimiliano",
+ "Wogrin, Stefan",
+ "Verhoeven, Geert"
+ ],
+ "date": "May 2022",
+ "url": "https://doi.org/10.5281/zenodo.6578470",
+ "type": "Journal article",
+ "journal": "Zenodo"
+ },
+ {
+ "title": "Finding Listeners for Walls That Speak",
+ "authors": [
+ "Verhoeven, Geert",
+ "Schlegel, Jona",
+ "Wild, Benjamin",
+ "Wogrin, Stefan",
+ "Carloni, Massimiliano"
+ ],
+ "date": "May 2023",
+ "url": "https://doi.org/10.48619/indigo.v0i0.699",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Facing a Chameleon – How Project INDIGO Discovers and Records New Graffiti",
+ "authors": [
+ "Verhoeven, Geert",
+ "Schlegel, Jona",
+ "Wild, Benjamin",
+ "Wogrin, Stefan",
+ "Carloni, Massimiliano"
+ ],
+ "date": "May 2023",
+ "url": "https://doi.org/10.48619/indigo.v0i0.703",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Project INDIGO – Document, Disseminate & Analyse a Graffiti-Scape",
+ "authors": [
+ "Verhoeven, Geert",
+ "Schlegel, Jona",
+ "Wild, Benjamin",
+ "Wieser, Martin",
+ "Pfeifer, Norbert",
+ "Wogrin, Stefan"
+ ],
+ "date": "February 2022",
+ "url": "https://doi.org/10.5194/isprs-archives-XLVI-2-W1-2022-513-2022",
+ "type": "Conference paper",
+ "conference": "The International Archives of the Photogrammetry, Remote Sensing and Spatial Information Sciences"
+ },
+ {
+ "title": "Prospecting the UNESCO World Heritage Site of Müstair (Switzerland)",
+ "authors": [
+ "Schlegel, Jona",
+ "Verhoeven, Geert",
+ "Cassitti, Patrick ",
+ "Hinterleitner, Alois",
+ "Löcker, Klaus",
+ "Schiel, Hannes",
+ "Walser, Christoph",
+ "Reitmaier, Thomas",
+ "Neubauer, Wolfgang"
+ ],
+ "date": "June 2021",
+ "url": "https://doi.org/10.3390/rs13132515",
+ "type": "Journal article",
+ "journal": "Remote Sensing"
+ },
+ {
+ "title": "Pliska – Integrated Geophysical Prospection of the First Early Medieval Bulgarian Capital",
+ "authors": [
+ "Filzwieser, Roland",
+ "Schlegel, Jona",
+ "Aladzhov, Andrey",
+ "Hinterleitner, Alois",
+ "Doneus, Nives",
+ "Schiel, Hannes",
+ "Dimitrov, Janko",
+ "Gamon, Martin",
+ "Daim, Falko",
+ "Neubauer, Wolfgang"
+ ],
+ "date": "December 2019",
+ "url": "https://www.semanticscholar.org/paper/Pliska-%E2%80%93-integrated-geophysical-prospection-of-the-Filzwieser-Aladzhov/ddfbb46fdab2c85a2814045b64816c1a1919e669",
+ "type": "Journal article",
+ "journal": "Semantics Scholar"
+ },
+ {
+ "title": "AUTOGRAF—AUTomated Orthorectification of GRAFfiti Photos",
+ "authors": [
+ "Wild, Benjamin",
+ "Verhoeven, Geert",
+ "Wieser, Martin",
+ "Ressl, Camillo",
+ "Schlegel, Jona",
+ "Wogrin, Stefan",
+ "Otepka-Schremmer, Johannes",
+ "Pfeifer, Norbert"
+ ],
+ "date": "December 2022",
+ "url": "https://doi.org/10.3390/heritage5040156",
+ "type": "Journal article",
+ "journal": "Heritage"
+ },
+ {
+ "title": "‘Imagine Being a Racist’: goINDIGO 2022’s «Ethics & Legality in Graffiti (Research)» Discussion Round",
+ "authors": [
+ "Wild, Benjamin",
+ "Verhoeven, Geert",
+ "Pfeifer, Norbert",
+ "Bonadio, Enrico",
+ "DEADBEAT HERO",
+ "JANER ONE",
+ "Carloni, Massimiliano",
+ "Ricci, Chiara",
+ "Schlegel, Jona"
+ ],
+ "date": "May 2023",
+ "url": "https://doi.org/10.48619/indigo.v0i0.702",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Making a Mark – Towards a Graffiti Thesaurus",
+ "authors": [
+ "Schlegel, Jona",
+ "Massimiliano Carloni",
+ "Wogrin, Stefan",
+ "Graf, Ann M.",
+ "Verhoeven, Geert"
+ ],
+ "date": "May 2023",
+ "url": "https://doi.org/10.48619/indigo.v0i0.710",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Towards an automated analysis of geophysical archaeological prospection data",
+ "authors": ["Schlegel, Jona"],
+ "date": "November 2020",
+ "url": "",
+ "type": "Conference paper",
+ "conference": "CHNT25 Conference"
+ },
+ {
+ "title": "CrowdSlide – a mobile web application for building a database of gravitational mass movements using volunteer field reports",
+ "authors": ["Schlegel, Jona", " Grass, Annemarie", "Fuchs, Florian"],
+ "date": "May 2020",
+ "url": "https://doi.org/10.5194/egusphere-egu2020-16503",
+ "type": "Conference paper",
+ "conference": "EGU General Assembly Conference Abstracts"
+ },
+ {
+ "title": "Entdeckung und Erkundung des antiken Stadtgrundrisses von Seleukeia Sidera, Türkei – Ein erster Überblick",
+ "authors": ["Schlegel, Jona", "Schenk, Thomas"],
+ "date": "April 2018",
+ "url": "",
+ "type": "Conference abstract",
+ "conference": "Verband für Grabungstechnik und Feldarchäologie e.V."
+ },
+ {
+ "title": "Recreating an ancient marketplace with geophysical and topographical data",
+ "authors": ["Gillikin, Kelly", "Schlegel, Jona"],
+ "date": "March 2018",
+ "url": "",
+ "type": "Conference abstract",
+ "conference": "CAA 2018"
+ },
+ {
+ "title": "Grabungstechnik Praktische Archäologie",
+ "authors": ["Schlegel, Jona"],
+ "date": "June 2014",
+ "url": "",
+ "type": "Other",
+ "publisher": "Online Lehre Plus HTW Berlin"
+ },
+ {
+ "title": "Dem Donaukanal-Chamäleon auf der Spur",
+ "authors": ["Wild, Benjamin", "Schlegel, Jona"],
+ "date": "March 2023",
+ "url": "https://www.derstandard.de/story/2000144976673/dem-donaukanal-chamaeleon-auf-der-spur",
+ "type": "Article",
+ "publisher": "Der Standard"
+ },
+ {
+ "title": "disseminate | analyse | understand graffiti-scapes. Proceedings of the goINDIGO2023 international graffiti symposium",
+ "authors": [
+ "Verhoeven, Geert",
+ "Schlegel, Jona",
+ "Wild, Benjamin",
+ "Wogrin, Stefan"
+ ],
+ "date": "September 2024",
+ "url": "https://doi.org/10.5281/zenodo.13786065",
+ "type": "Proceedings",
+ "publisher": "Zenodo"
+ },
+ {
+ "title": "Dissipating and Unravelling Bits of Graffiti Bytes",
+ "authors": [
+ "Verhoeven, Geert",
+ "Schlegel, Jona",
+ "Wild, Benjamin",
+ "Wogrin, Stefan"
+ ],
+ "date": "September 2024",
+ "url": "https://doi.org/10.5281/zenodo.13786065",
+ "type": "Proceedings",
+ "conference": "goINDIGO 2023"
+ },
+ {
+ "title": "Decoding the Walls – Urban Graffiti Layers Through Digital Processing",
+ "authors": [
+ "Schlegel, Jona",
+ "Verhoeven, Geert",
+ "Wild, Benjamin",
+ "Wogrin, Stefan"
+ ],
+ "date": "September 2024",
+ "url": "https://journals.ap2.pt/index.php/indigo/article/view/975",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Graffiti on the Urban Fringe – A Geospatial Analysis",
+ "authors": [
+ "Schlegel, Jona",
+ "Verhoeven, Geert",
+ "Wild, Benjamin",
+ "Wogrin, Stefan"
+ ],
+ "date": "September 2024",
+ "url": "https://journals.ap2.pt/index.php/indigo/article/view/971",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ },
+ {
+ "title": "Graffiti as Cultural Markers – From Ancient Sites to Modern Walls",
+ "authors": [
+ "Schlegel, Jona",
+ "Verhoeven, Geert",
+ "Wild, Benjamin",
+ "Wogrin, Stefan"
+ ],
+ "date": "September 2024",
+ "url": "https://journals.ap2.pt/index.php/indigo/article/view/981",
+ "type": "Journal article",
+ "journal": "INDIGO Journal"
+ }
+]
diff --git a/app/data/cv/work-experience.json b/app/data/cv/work-experience.json
new file mode 100644
index 0000000..dc3241a
--- /dev/null
+++ b/app/data/cv/work-experience.json
@@ -0,0 +1,34 @@
+[
+ {
+ "title": "Freelancer",
+ "organization": "archaeoINK",
+ "startDate": "January 2024",
+ "endDate": "Present",
+ "description": "Providing services in scientific communication, including web development (consulting and execution), illustration, knowledge management, database structures (CIDOC CRM), and controlled vocabulary for archaeological data sharing.",
+ "location": "Vienna, Austria"
+ },
+ {
+ "title": "Researcher",
+ "organization": "Ludwig Boltzmann Institute for Archaeological Prospection and Virtual Archaeology",
+ "startDate": "May 2018",
+ "endDate": "September 2023",
+ "description": "Specialised in ground-penetrating radar (GPR) surveys, magnetic motorised surveying, data interpretation using GIS, and project management across multiple international sites.",
+ "location": "Vienna, Austria"
+ },
+ {
+ "title": "Student Assistant",
+ "organization": "Hochschule für Technik und Wirtschaft",
+ "startDate": "November 2017",
+ "endDate": "December 2017",
+ "description": "Involved in post-processing and interpretation of geophysical data from the Seleukia Sidera project, Turkey.",
+ "location": "Berlin, Germany"
+ },
+ {
+ "title": "Intern",
+ "organization": "Ludwig Boltzmann Institute for Archaeological Prospection and Virtual Archaeology",
+ "startDate": "April 2017",
+ "endDate": "June 2017",
+ "description": "Worked on magnetic and ground-penetrating radar data processing and the reconstruction of archaeological sites in Herforst, Germany.",
+ "location": "Vienna, Austria"
+ }
+]