change work -> qualifications (add education)
This commit is contained in:
parent
90fea1f2f6
commit
6ca99de358
|
|
@ -32,7 +32,7 @@ const { Content, headings } = await render(entry);
|
|||
|
||||
<!-- Main content -->
|
||||
<Container size="md">
|
||||
<article class="animate content">
|
||||
<article class="animate content prose dark:prose-invert">
|
||||
<Content />
|
||||
</article>
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ const subpath = pathname.match(/[^/]+/g);
|
|||
|
||||
<header id="header" class="fixed top-0 w-full h-16 z-50">
|
||||
<Container size="md">
|
||||
<div class="relative h-full w-full">
|
||||
<div
|
||||
class="absolute left-0 top-1/2 -translate-y-1/2 flex gap-1 font-semibold"
|
||||
class="relative h-full w-full flex flex-row justify-between items-center"
|
||||
>
|
||||
<div class="flex gap-1 font-semibold">
|
||||
<a
|
||||
href="/"
|
||||
class="flex gap-1 text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out"
|
||||
|
|
@ -34,9 +34,7 @@ const subpath = pathname.match(/[^/]+/g);
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<div>
|
||||
<nav
|
||||
class="hidden md:flex items-center justify-center text-sm gap-1"
|
||||
>
|
||||
|
|
@ -61,9 +59,7 @@ const subpath = pathname.match(/[^/]+/g);
|
|||
</nav>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="buttons absolute right-0 top-1/2 -translate-y-1/2 flex gap-1"
|
||||
>
|
||||
<div class="buttons flex gap-1">
|
||||
<a
|
||||
href="/search/"
|
||||
aria-label="Search blog posts and projects"
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ export const SITE: Site = {
|
|||
AUTHOR: "Moritz Hölting",
|
||||
};
|
||||
|
||||
// Work Page
|
||||
export const WORK: Page = {
|
||||
TITLE: "Work",
|
||||
DESCRIPTION: "Places I have worked.",
|
||||
// Qualifications Page
|
||||
export const QUALIFICATIONS: Page = {
|
||||
TITLE: "Work & Education",
|
||||
DESCRIPTION: "My work and education history.",
|
||||
};
|
||||
|
||||
// Blog Page
|
||||
|
|
@ -38,8 +38,8 @@ export const LINKS: Links = [
|
|||
HREF: "/",
|
||||
},
|
||||
{
|
||||
TEXT: "Work",
|
||||
HREF: "/work/",
|
||||
TEXT: "Qualifications",
|
||||
HREF: "/qualifications/",
|
||||
},
|
||||
{
|
||||
TEXT: "Blog",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@ const work = defineCollection({
|
|||
}),
|
||||
});
|
||||
|
||||
const education = defineCollection({
|
||||
loader: glob({ base: "./src/content/education", pattern: "**/*.{md,mdx}" }),
|
||||
schema: z.object({
|
||||
institution: z.string(),
|
||||
degree: z.string(),
|
||||
field: z.string().optional(),
|
||||
location: z.string().optional(),
|
||||
finalGrade: z.union([z.string(), z.number()]).optional(),
|
||||
dateStart: z.date(),
|
||||
dateEnd: z.union([z.date(), z.string()]),
|
||||
}),
|
||||
});
|
||||
|
||||
const blog = defineCollection({
|
||||
loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
|
||||
schema: z.object({
|
||||
|
|
@ -36,4 +49,4 @@ const projects = defineCollection({
|
|||
}),
|
||||
});
|
||||
|
||||
export const collections = { work, blog, projects };
|
||||
export const collections = { work, education, blog, projects };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
institution: "Brede Gymnasium"
|
||||
degree: "Abitur"
|
||||
dateStart: 2014-08-01
|
||||
dateEnd: 2022-06-30
|
||||
---
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
institution: "Paderborn University"
|
||||
degree: "Bachelor of Science"
|
||||
field: "Computer Science"
|
||||
dateStart: 2022-10-01
|
||||
dateEnd: 2026-11-06
|
||||
---
|
||||
|
||||
Bachelor's thesis: "[Limitations of the Random Oracle Model](/blog/limitations-of-the-random-oracle-model/)" at the "Codes and Cryptography" research group.
|
||||
|
||||
Elective modules:
|
||||
- Einführung in Kryptographie (Introduction to Cryptography)
|
||||
- 3D Rendering
|
||||
- Algorithmische Geometrie (Algorithmic Geometry)
|
||||
- Gestaltung von Nutzungsschnittstellen (User Interface Design)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
institution: "Paderborn University"
|
||||
degree: "Master of Science"
|
||||
field: "Computer Science"
|
||||
dateStart: 2025-10-01
|
||||
dateEnd: "expected sep 2027"
|
||||
---
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
company: "Diebold Nixdorf"
|
||||
role: "Working Student - Infrastructure & Operations"
|
||||
dateStart: 2024-05-01
|
||||
dateEnd: 2025-04-30
|
||||
dateEnd: 2026-10-31
|
||||
---
|
||||
|
||||
At at Diebold Nixdorf, I am responsible for conducting "experiments" with new
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
---
|
||||
import { getCollection, render } from "astro:content";
|
||||
import PageLayout from "@/layouts/PageLayout.astro";
|
||||
import TopLayout from "@/layouts/TopLayout.astro";
|
||||
import BottomLayout from "@/layouts/BottomLayout.astro";
|
||||
import { QUALIFICATIONS } from "@/consts";
|
||||
|
||||
const workCollection = await getCollection("work");
|
||||
const educationCollection = await getCollection("education");
|
||||
|
||||
workCollection.sort(
|
||||
(a, b) =>
|
||||
new Date(b.data.dateStart).getTime() -
|
||||
new Date(a.data.dateStart).getTime(),
|
||||
);
|
||||
educationCollection.sort(
|
||||
(a, b) =>
|
||||
new Date(b.data.dateStart).getTime() -
|
||||
new Date(a.data.dateStart).getTime(),
|
||||
);
|
||||
|
||||
const work = await Promise.all(
|
||||
workCollection.map(async (item) => {
|
||||
const { Content } = await render(item);
|
||||
return { ...item, Content };
|
||||
}),
|
||||
);
|
||||
const education = await Promise.all(
|
||||
educationCollection.map(async (item) => {
|
||||
const { Content } = await render(item);
|
||||
return { ...item, Content };
|
||||
}),
|
||||
);
|
||||
|
||||
function formatShortDate(input: Date | string) {
|
||||
if (typeof input === "string") return input;
|
||||
|
||||
const month = input.toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
});
|
||||
|
||||
const year = new Date(input).getFullYear();
|
||||
return `${month} ${year}`;
|
||||
}
|
||||
---
|
||||
|
||||
<PageLayout
|
||||
title={QUALIFICATIONS.TITLE}
|
||||
description={QUALIFICATIONS.DESCRIPTION}
|
||||
>
|
||||
<!-- Work -->
|
||||
<TopLayout>
|
||||
<div class="animate page-heading font-departure text-2xl">Work</div>
|
||||
</TopLayout>
|
||||
<BottomLayout>
|
||||
<ul class="border-b border-black/10 dark:border-white/25">
|
||||
{
|
||||
work.map((entry) => (
|
||||
<li class="animate border-b border-black/10 dark:border-white/25 mt-4 py-8 first-of-type:mt-0 first-of-type:pt-0 last-of-type:border-none">
|
||||
<div class="font-departure text-sm uppercase mb-4">
|
||||
{formatShortDate(entry.data.dateStart)} -{" "}
|
||||
{formatShortDate(entry.data.dateEnd)}
|
||||
</div>
|
||||
<div class="font-departure text-black dark:text-white font-semibold">
|
||||
{entry.data.company}
|
||||
</div>
|
||||
<div class="font-departure text-sm font-semibold">
|
||||
{entry.data.role}
|
||||
</div>
|
||||
{entry.body && (
|
||||
<article class="prose dark:prose-invert mt-2 pb-8">
|
||||
<entry.Content />
|
||||
</article>
|
||||
)}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</BottomLayout>
|
||||
|
||||
<!-- Education -->
|
||||
<TopLayout>
|
||||
<div class="animate page-heading font-departure text-2xl">
|
||||
Education
|
||||
</div>
|
||||
</TopLayout>
|
||||
<BottomLayout>
|
||||
<ul>
|
||||
{
|
||||
education.map((entry) => (
|
||||
<li class="animate border-b border-black/10 dark:border-white/25 mt-4 py-8 first-of-type:mt-0 first-of-type:pt-0 last-of-type:border-none">
|
||||
<div class="font-departure text-sm uppercase mb-4">
|
||||
{formatShortDate(entry.data.dateStart)} -{" "}
|
||||
{formatShortDate(entry.data.dateEnd)}
|
||||
</div>
|
||||
<div class="font-departure text-black dark:text-white font-semibold">
|
||||
{entry.data.institution}
|
||||
</div>
|
||||
<div class="font-departure text-sm font-semibold">
|
||||
{entry.data.degree}
|
||||
{entry.data.field && ` - ${entry.data.field}`}
|
||||
</div>
|
||||
{(entry.data.finalGrade || entry.data.location) && (
|
||||
<div class="text-sm">
|
||||
{entry.data.finalGrade &&
|
||||
`Grade: ${
|
||||
entry.data.finalGrade +
|
||||
(entry.data.location ? ", " : "")
|
||||
}`}
|
||||
{entry.data.location}
|
||||
</div>
|
||||
)}
|
||||
{entry.body && (
|
||||
<article class="prose dark:prose-invert mt-2 pb-8">
|
||||
<entry.Content />
|
||||
</article>
|
||||
)}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</BottomLayout>
|
||||
</PageLayout>
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
---
|
||||
import { getCollection, render } from "astro:content";
|
||||
import PageLayout from "@/layouts/PageLayout.astro";
|
||||
import TopLayout from "@/layouts/TopLayout.astro";
|
||||
import BottomLayout from "@/layouts/BottomLayout.astro";
|
||||
import { WORK } from "@/consts";
|
||||
|
||||
const collection = await getCollection("work");
|
||||
|
||||
collection.sort(
|
||||
(a, b) =>
|
||||
new Date(b.data.dateStart).getTime() -
|
||||
new Date(a.data.dateStart).getTime(),
|
||||
);
|
||||
|
||||
const work = await Promise.all(
|
||||
collection.map(async (item) => {
|
||||
const { Content } = await render(item);
|
||||
return { ...item, Content };
|
||||
}),
|
||||
);
|
||||
|
||||
function formatWorkDate(input: Date | string) {
|
||||
if (typeof input === "string") return input;
|
||||
|
||||
const month = input.toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
});
|
||||
|
||||
const year = new Date(input).getFullYear();
|
||||
return `${month} ${year}`;
|
||||
}
|
||||
---
|
||||
|
||||
<PageLayout title={WORK.TITLE} description={WORK.DESCRIPTION}>
|
||||
<TopLayout>
|
||||
<div class="animate page-heading">
|
||||
{WORK.TITLE}
|
||||
</div>
|
||||
</TopLayout>
|
||||
<BottomLayout>
|
||||
<ul>
|
||||
{
|
||||
work.map((entry) => (
|
||||
<li class="animate border-b border-black/10 dark:border-white/25 mt-4 py-8 first-of-type:mt-0 first-of-type:pt-0 last-of-type:border-none">
|
||||
<div class="font-departure text-sm uppercase mb-4">
|
||||
{formatWorkDate(entry.data.dateStart)} -{" "}
|
||||
{formatWorkDate(entry.data.dateEnd)}
|
||||
</div>
|
||||
<div class="font-departure text-black dark:text-white font-semibold">
|
||||
{entry.data.company}
|
||||
</div>
|
||||
<div class="font-departure text-sm font-semibold">
|
||||
{entry.data.role}
|
||||
</div>
|
||||
<article class="prose dark:prose-invert">
|
||||
<entry.Content />
|
||||
</article>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</BottomLayout>
|
||||
</PageLayout>
|
||||
Loading…
Reference in New Issue