change work -> qualifications (add education)
This commit is contained in:
parent
dde76774ac
commit
2828d3d166
|
|
@ -32,7 +32,7 @@ const { Content, headings } = await render(entry);
|
||||||
|
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<Container size="md">
|
<Container size="md">
|
||||||
<article class="animate content">
|
<article class="animate content prose dark:prose-invert">
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ const subpath = pathname.match(/[^/]+/g);
|
||||||
|
|
||||||
<header id="header" class="fixed top-0 w-full h-16 z-50">
|
<header id="header" class="fixed top-0 w-full h-16 z-50">
|
||||||
<Container size="md">
|
<Container size="md">
|
||||||
<div class="relative h-full w-full">
|
<div
|
||||||
<div
|
class="relative h-full w-full flex flex-row justify-between items-center"
|
||||||
class="absolute left-0 top-1/2 -translate-y-1/2 flex gap-1 font-semibold"
|
>
|
||||||
>
|
<div class="flex gap-1 font-semibold">
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
class="flex gap-1 text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out"
|
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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div>
|
||||||
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
|
|
||||||
>
|
|
||||||
<nav
|
<nav
|
||||||
class="hidden md:flex items-center justify-center text-sm gap-1"
|
class="hidden md:flex items-center justify-center text-sm gap-1"
|
||||||
>
|
>
|
||||||
|
|
@ -61,9 +59,7 @@ const subpath = pathname.match(/[^/]+/g);
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="buttons flex gap-1">
|
||||||
class="buttons absolute right-0 top-1/2 -translate-y-1/2 flex gap-1"
|
|
||||||
>
|
|
||||||
<a
|
<a
|
||||||
href="/search/"
|
href="/search/"
|
||||||
aria-label="Search blog posts and projects"
|
aria-label="Search blog posts and projects"
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ export const SITE: Site = {
|
||||||
AUTHOR: "Moritz Hölting",
|
AUTHOR: "Moritz Hölting",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Work Page
|
// Qualifications Page
|
||||||
export const WORK: Page = {
|
export const QUALIFICATIONS: Page = {
|
||||||
TITLE: "Work",
|
TITLE: "Work & Education",
|
||||||
DESCRIPTION: "Places I have worked.",
|
DESCRIPTION: "My work and education history.",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Blog Page
|
// Blog Page
|
||||||
|
|
@ -38,8 +38,8 @@ export const LINKS: Links = [
|
||||||
HREF: "/",
|
HREF: "/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
TEXT: "Work",
|
TEXT: "Qualifications",
|
||||||
HREF: "/work/",
|
HREF: "/qualifications/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
TEXT: "Blog",
|
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({
|
const blog = defineCollection({
|
||||||
loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
|
loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
|
||||||
schema: z.object({
|
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"
|
company: "Diebold Nixdorf"
|
||||||
role: "Working Student - Infrastructure & Operations"
|
role: "Working Student - Infrastructure & Operations"
|
||||||
dateStart: 2024-05-01
|
dateStart: 2024-05-01
|
||||||
dateEnd: 2025-04-30
|
dateEnd: 2026-10-31
|
||||||
---
|
---
|
||||||
|
|
||||||
At at Diebold Nixdorf, I am responsible for conducting "experiments" with new
|
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