Compare commits
No commits in common. "c7e3b2c2d6f15129c6e197bf02fc2b95849a08b9" and "a839560bff09fe73c746a96f802f588b39f1a3e9" have entirely different histories.
c7e3b2c2d6
...
a839560bff
12 changed files with 127 additions and 231 deletions
|
|
@ -23,7 +23,6 @@
|
||||||
"@astrojs/sitemap": "^3.2.1",
|
"@astrojs/sitemap": "^3.2.1",
|
||||||
"@astrojs/tailwind": "^5.1.3",
|
"@astrojs/tailwind": "^5.1.3",
|
||||||
"@cloudflare/workers-types": "^4.20241230.0",
|
"@cloudflare/workers-types": "^4.20241230.0",
|
||||||
"@fontsource/fira-sans": "^5.1.1",
|
|
||||||
"@fontsource/ubuntu": "^5.1.0",
|
"@fontsource/ubuntu": "^5.1.0",
|
||||||
"@iconify-json/mdi": "^1.2.1",
|
"@iconify-json/mdi": "^1.2.1",
|
||||||
"@iconify-json/simple-icons": "^1.2.14",
|
"@iconify-json/simple-icons": "^1.2.14",
|
||||||
|
|
|
||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
|
@ -29,9 +29,6 @@ importers:
|
||||||
'@cloudflare/workers-types':
|
'@cloudflare/workers-types':
|
||||||
specifier: ^4.20241230.0
|
specifier: ^4.20241230.0
|
||||||
version: 4.20241230.0
|
version: 4.20241230.0
|
||||||
'@fontsource/fira-sans':
|
|
||||||
specifier: ^5.1.1
|
|
||||||
version: 5.1.1
|
|
||||||
'@fontsource/ubuntu':
|
'@fontsource/ubuntu':
|
||||||
specifier: ^5.1.0
|
specifier: ^5.1.0
|
||||||
version: 5.1.0
|
version: 5.1.0
|
||||||
|
|
@ -964,9 +961,6 @@ packages:
|
||||||
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
'@fontsource/fira-sans@5.1.1':
|
|
||||||
resolution: {integrity: sha512-LdbPwcMEADFjbcMx5sdPcyLi0NnEzP34YO+4d2eOeIKjCu1SyJiG/bBz5K07qm4pyhh2cQveifhFrG7gQDG9wQ==}
|
|
||||||
|
|
||||||
'@fontsource/ubuntu@5.1.0':
|
'@fontsource/ubuntu@5.1.0':
|
||||||
resolution: {integrity: sha512-0XG/HrFsfP1q3phf4QN8IO7tetd0zOZKHZSHcTnBuVoQedoo1wS/hXxY2FMZuqoG+mVfrXh+Q614MDVmQPJq2w==}
|
resolution: {integrity: sha512-0XG/HrFsfP1q3phf4QN8IO7tetd0zOZKHZSHcTnBuVoQedoo1wS/hXxY2FMZuqoG+mVfrXh+Q614MDVmQPJq2w==}
|
||||||
|
|
||||||
|
|
@ -4163,8 +4157,6 @@ snapshots:
|
||||||
|
|
||||||
'@fastify/busboy@2.1.1': {}
|
'@fastify/busboy@2.1.1': {}
|
||||||
|
|
||||||
'@fontsource/fira-sans@5.1.1': {}
|
|
||||||
|
|
||||||
'@fontsource/ubuntu@5.1.0': {}
|
'@fontsource/ubuntu@5.1.0': {}
|
||||||
|
|
||||||
'@iconify-json/mdi@1.2.1':
|
'@iconify-json/mdi@1.2.1':
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
import "../styles/global.css";
|
import "../styles/global.css";
|
||||||
import ubuntuRegularWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-400-normal.woff2?url";
|
import ubuntuRegularWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-400-normal.woff2?url";
|
||||||
import ubuntuBoldWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-700-normal.woff2?url";
|
import ubuntuBoldWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-700-normal.woff2?url";
|
||||||
import "@fontsource/fira-sans";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
||||||
15
src/components/Header.astro
Normal file
15
src/components/Header.astro
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
import HeaderLink from "./HeaderLink.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<header class="mb-8 w-full lg:w-[768px] max-w-[calc(100%-2em)] lg:mx-auto">
|
||||||
|
<nav>
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<HeaderLink href="/">Home</HeaderLink>
|
||||||
|
<HeaderLink href="/blog">Blog</HeaderLink>
|
||||||
|
<HeaderLink href="/projects">Projects</HeaderLink>
|
||||||
|
<HeaderLink href="/publications">Publications</HeaderLink>
|
||||||
|
<HeaderLink href="/contact">Contact</HeaderLink>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
---
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import HeaderLink from "./HeaderLink.astro";
|
|
||||||
---
|
|
||||||
|
|
||||||
<header
|
|
||||||
class="mb-8 w-full lg:w-[768px] max-w-[calc(100%-2em)] lg:mx-auto overflow-scroll hidden lg:block"
|
|
||||||
>
|
|
||||||
<nav>
|
|
||||||
<div class="flex gap-4">
|
|
||||||
<HeaderLink href="/">Home</HeaderLink>
|
|
||||||
<HeaderLink href="/blog">Blog</HeaderLink>
|
|
||||||
<HeaderLink href="/projects">Projects</HeaderLink>
|
|
||||||
<HeaderLink href="/publications">Publications</HeaderLink>
|
|
||||||
<HeaderLink href="/contact">Contact</HeaderLink>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<button id="nav-menu" class="lg:hidden relative w-[30px] h-[30px]">
|
|
||||||
<Icon
|
|
||||||
name="mdi:menu"
|
|
||||||
id="iconMenu"
|
|
||||||
class="absolute inset-0 transition-all duration-300 ease-in-out"
|
|
||||||
size={30}
|
|
||||||
/>
|
|
||||||
<Icon
|
|
||||||
name="mdi:close"
|
|
||||||
id="iconClose"
|
|
||||||
class="absolute inset-0 opacity-0 rotate-90 transition-all duration-300 ease-in-out"
|
|
||||||
size={30}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<header
|
|
||||||
id="drawer"
|
|
||||||
class="fixed z-50 top-14 right-0 h-full bg-neutral-50 shadow dark:bg-gray-700 p-6 rounded w-54 transform translate-x-full transition-transform duration-300 ease-in-out"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
<HeaderLink href="/">Home</HeaderLink>
|
|
||||||
<HeaderLink href="/blog">Blog</HeaderLink>
|
|
||||||
<HeaderLink href="/projects">Projects</HeaderLink>
|
|
||||||
<HeaderLink href="/publications">Publications</HeaderLink>
|
|
||||||
<HeaderLink href="/contact">Contact</HeaderLink>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const menu = document.getElementById("nav-menu");
|
|
||||||
const drawer = document.getElementById("drawer");
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
drawer.classList.toggle("translate-x-full");
|
|
||||||
document.body.classList.toggle("overflow-hidden");
|
|
||||||
if (iconMenu.classList.contains("opacity-0")) {
|
|
||||||
iconMenu.classList.remove("opacity-0", "rotate-90");
|
|
||||||
iconClose.classList.add("opacity-0", "rotate-90");
|
|
||||||
} else {
|
|
||||||
iconMenu.classList.add("opacity-0", "rotate-90");
|
|
||||||
iconClose.classList.remove("opacity-0", "rotate-90");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menu.addEventListener("click", () => {
|
|
||||||
toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
// click-away listener
|
|
||||||
document.addEventListener("click", (event) => {
|
|
||||||
console.log("click outside");
|
|
||||||
if (
|
|
||||||
!drawer.classList.contains("translate-x-full") &&
|
|
||||||
!drawer.contains(event.target) &&
|
|
||||||
!menu.contains(event.target)
|
|
||||||
) {
|
|
||||||
console.log(
|
|
||||||
!drawer.classList.contains("translate-x-full"),
|
|
||||||
!drawer.contains(event.target),
|
|
||||||
!menu.contains(event.target),
|
|
||||||
);
|
|
||||||
toggle();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
@ -108,7 +108,7 @@ const { cv } = Astro.props;
|
||||||
</span>
|
</span>
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
<div class="p-4 sm:p-6 pt-6 space-y-6">
|
<div class="p-6 pt-6 space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h4 class="text-xl font-bold mb-2 text-gray-800 dark:text-gray-200">
|
<h4 class="text-xl font-bold mb-2 text-gray-800 dark:text-gray-200">
|
||||||
1. Verify SHA256 Hash
|
1. Verify SHA256 Hash
|
||||||
|
|
@ -136,12 +136,9 @@ const { cv } = Astro.props;
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Import the key into your keyring with<br />
|
Import the key into your keyring with
|
||||||
<code
|
<pre
|
||||||
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-sm font-mono sm:ml-6 mb-2 break-all"
|
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-sm font-mono sm:ml-6 mb-2">gpg --import ~/Downloads/pub.key</pre>
|
||||||
>gpg --import ~/Downloads/pub.key</code
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
Download the above PGP signature by clicking <button
|
Download the above PGP signature by clicking <button
|
||||||
|
|
@ -150,22 +147,16 @@ const { cv } = Astro.props;
|
||||||
>here
|
>here
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>Run the following command:</li>
|
||||||
Run the following command:<br />
|
|
||||||
<code
|
|
||||||
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-sm font-mono sm:ml-6"
|
|
||||||
>gpg --verify signature.asc cv.pdf</code
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
<pre
|
||||||
|
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-sm font-mono sm:ml-6">gpg --verify signature.asc cv.pdf</pre>
|
||||||
<p class="text-gray-600 dark:text-gray-400 mt-2">
|
<p class="text-gray-600 dark:text-gray-400 mt-2">
|
||||||
If the verification is successful, GPG will indicate so.<br />
|
If the verification is successful, GPG will indicate so.
|
||||||
<code
|
<pre
|
||||||
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-xs font-mono mt-2 break-all"
|
class="bg-gray-100 dark:bg-gray-800 p-3 rounded text-xs font-mono mt-2">gpg: Good signature from "Alexander Daichendt <alexander@daichendt.one>" [ultimate]</pre>
|
||||||
>gpg: Good signature from "Alexander Daichendt
|
|
||||||
<alexander@daichendt.one>" [ultimate]</code
|
|
||||||
>
|
|
||||||
</p>
|
</p>
|
||||||
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,7 @@ Pretty cool gimmick! This effectively binds the CV document to my personal websi
|
||||||
|
|
||||||
On this astro page, I have a route `/admin` which allows me to create a new verification id. This endpoint is secured with Cloudflare access.
|
On this astro page, I have a route `/admin` which allows me to create a new verification id. This endpoint is secured with Cloudflare access.
|
||||||
|
|
||||||
<div style={{
|
<div align="center" style={{ width: '500px', margin: '0 auto' }}>
|
||||||
maxWidth: '500px',
|
|
||||||
width: '100%',
|
|
||||||
margin: '0 auto',
|
|
||||||
textAlign: 'center'
|
|
||||||
}}>
|
|
||||||

|

|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -105,12 +100,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
Finally, I enter the generated sha256 hash and the PGP signature into the second page of the create verification workflow.
|
Finally, I enter the generated sha256 hash and the PGP signature into the second page of the create verification workflow.
|
||||||
|
|
||||||
<div style={{
|
<div align="center" style={{ width: '500px', margin: '0 auto' }}>
|
||||||
maxWidth: '500px',
|
|
||||||
width: '100%',
|
|
||||||
margin: '0 auto',
|
|
||||||
textAlign: 'center'
|
|
||||||
}}>
|
|
||||||

|

|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import BaseHead from "../components/BaseHead.astro";
|
import BaseHead from "../components/BaseHead.astro";
|
||||||
import NavMenu from "../components/NavMenu.astro";
|
import Header from "../components/Header.astro";
|
||||||
import Footer from "../components/Footer.astro";
|
import Footer from "../components/Footer.astro";
|
||||||
import { SITE_TITLE, SITE_DESCRIPTION } from "../consts";
|
import { SITE_TITLE, SITE_DESCRIPTION } from "../consts";
|
||||||
import DarkModeToggle from "../components/DarkModeToggle.astro";
|
import DarkModeToggle from "../components/DarkModeToggle.astro";
|
||||||
|
|
@ -34,17 +34,16 @@ const { title = SITE_TITLE, description = SITE_DESCRIPTION } = Astro.props;
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-white dark:bg-gray-900 text-black dark:text-white">
|
<body class="bg-white dark:bg-gray-900 text-black dark:text-white">
|
||||||
<!-- Mobile layout -->
|
<!-- Mobile layout -->
|
||||||
<div class="lg:hidden flex flex-col min-h-screen p-2 sm:p-4">
|
<div class="lg:hidden flex flex-col min-h-screen p-4">
|
||||||
<div class="flex justify-between items-center mb-4">
|
<div class="flex justify-between items-center mb-4">
|
||||||
<h2 class="font-bold text-lg mb-0">
|
<h2 class="font-bold text-lg">
|
||||||
<a href="/">{SITE_TITLE}</a>
|
<a href="/">{SITE_TITLE}</a>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<DarkModeToggle />
|
<DarkModeToggle />
|
||||||
<NavMenu />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Header />
|
||||||
|
|
||||||
<main class="flex-grow">
|
<main class="flex-grow">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
|
|
@ -61,7 +60,7 @@ const { title = SITE_TITLE, description = SITE_DESCRIPTION } = Astro.props;
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<NavMenu />
|
<Header />
|
||||||
<main class="w-full lg:w-[768px] max-w-[calc(100%-2em)] mx-auto p-2">
|
<main class="w-full lg:w-[768px] max-w-[calc(100%-2em)] mx-auto p-2">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ const posts = (await getCollection("blog")).sort(
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<h1 class="mb-16">Blog</h1>
|
|
||||||
<section class="max-w-4xl mx-auto">
|
<section class="max-w-4xl mx-auto">
|
||||||
<ul class="">
|
<ul class="">
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +18,9 @@ const posts = (await getCollection("blog")).sort(
|
||||||
href={`/blog/${post.id}`}
|
href={`/blog/${post.id}`}
|
||||||
class="grid grid-cols-[2fr,1fr] gap-4 items-center"
|
class="grid grid-cols-[2fr,1fr] gap-4 items-center"
|
||||||
>
|
>
|
||||||
<h6 class="text-lg font-medium mb-0">{post.data.title}</h6>
|
<h6 class="text-lg font-medium">
|
||||||
|
{post.data.title}
|
||||||
|
</h6>
|
||||||
<span class="date text-right text-gray-600 text-sm">
|
<span class="date text-right text-gray-600 text-sm">
|
||||||
<FormattedDate date={post.data.pubDate} />
|
<FormattedDate date={post.data.pubDate} />
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import { Icon } from "astro-icon/components";
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Contact">
|
<BaseLayout title="Contact">
|
||||||
<h1 class="mb-16">Contact</h1>
|
|
||||||
|
|
||||||
<ul class="space-y-2">
|
<ul class="space-y-2">
|
||||||
<li class="flex items-center space-x-3">
|
<li class="flex items-center space-x-3">
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,6 @@ const getCardStyle = (company?: string) => {
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="Projects">
|
<BaseLayout title="Projects">
|
||||||
<h1 class="mb-16">Projects</h1>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here are some of the projects I have worked on in the past. They are sorted
|
Here are some of the projects I have worked on in the past. They are sorted
|
||||||
by my personal rating of relevancy. Projects done for a company are marked
|
by my personal rating of relevancy. Projects done for a company are marked
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,12 @@
|
||||||
@layer base {
|
@layer base {
|
||||||
h1 {
|
h1 {
|
||||||
@apply text-h1-mobile md:text-h1;
|
@apply text-h1-mobile md:text-h1;
|
||||||
font-family: "Fira Sans", sans-serif;
|
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
@apply text-h2-mobile md:text-h2;
|
@apply text-h2-mobile md:text-h2;
|
||||||
font-family: "Fira Sans", sans-serif;
|
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
@apply text-h3-mobile md:text-h3;
|
@apply text-h3-mobile md:text-h3;
|
||||||
font-family: "Fira Sans", sans-serif;
|
|
||||||
}
|
}
|
||||||
h4 {
|
h4 {
|
||||||
@apply text-h4-mobile md:text-h4;
|
@apply text-h4-mobile md:text-h4;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue