redesign: finish blog & projects

This commit is contained in:
Moritz Hölting 2026-03-18 12:50:34 +01:00
parent e09e36ccb7
commit 4080f8b3b3
18 changed files with 373 additions and 151 deletions

View File

@ -19,6 +19,7 @@
"@astrojs/rss": "^4.0.17",
"@astrojs/sitemap": "^3.6.0",
"@astrojs/solid-js": "^6.0.0",
"@iconify-icon/solid": "^3.0.3",
"@iconify-json/devicon": "^1.2.61",
"@iconify-json/material-icon-theme": "^1.2.56",
"@iconify-json/pixel": "^1.2.1",
@ -31,6 +32,7 @@
"canvaskit-wasm": "^0.40.0",
"clsx": "^2.1.1",
"fuse.js": "^7.1.0",
"iconify-icon": "^3.0.2",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"sharp": "^0.34.5",

View File

@ -23,6 +23,9 @@ importers:
'@astrojs/solid-js':
specifier: ^6.0.0
version: 6.0.0(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(solid-js@1.9.11)(yaml@2.8.2)
'@iconify-icon/solid':
specifier: ^3.0.3
version: 3.0.3(solid-js@1.9.11)
'@iconify-json/devicon':
specifier: ^1.2.61
version: 1.2.61
@ -59,6 +62,9 @@ importers:
fuse.js:
specifier: ^7.1.0
version: 7.1.0
iconify-icon:
specifier: ^3.0.2
version: 3.0.2
rehype-katex:
specifier: ^7.0.1
version: 7.0.1
@ -426,6 +432,11 @@ packages:
cpu: [x64]
os: [win32]
'@iconify-icon/solid@3.0.3':
resolution: {integrity: sha512-VUM8/gscfrU0e6dUWjitdsJrNzYoY1bGTp1+gfZIAbvo+tIGcP9bD3WAvFb6pHaCYL/5X6erZUUn8pL0c0xX9Q==}
peerDependencies:
solid-js: '>=1.0.0'
'@iconify-json/devicon@1.2.61':
resolution: {integrity: sha512-GvJZrzyWbChwki9yscm8WaCfIHqFVi4hQbjNxoDS0JLsuAk4uyGOnmlHCJFN+SzAZ9FMU2RtmkdJGjYuw4G96w==}
@ -1501,6 +1512,9 @@ packages:
http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
iconify-icon@3.0.2:
resolution: {integrity: sha512-DYPAumiUeUeT/GHT8x2wrAVKn1FqZJqFH0Y5pBefapWRreV1BBvqBVMb0020YQ2njmbR59r/IathL2d2OrDrxA==}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@ -3021,6 +3035,11 @@ snapshots:
'@esbuild/win32-x64@0.27.4':
optional: true
'@iconify-icon/solid@3.0.3(solid-js@1.9.11)':
dependencies:
iconify-icon: 3.0.2
solid-js: 1.9.11
'@iconify-json/devicon@1.2.61':
dependencies:
'@iconify/types': 2.0.0
@ -4237,6 +4256,10 @@ snapshots:
http-cache-semantics@4.2.0: {}
iconify-icon@3.0.2:
dependencies:
'@iconify/types': 2.0.0
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2

View File

@ -1,29 +0,0 @@
---
import { Icon } from "astro-icon/components";
import ArrowCardInner from "./ArrowCardInner";
import type { CollectionEntry } from "astro:content";
export interface Props {
entry: CollectionEntry<"blog"> | CollectionEntry<"projects">;
pill?: string;
}
const { entry, pill } = Astro.props;
---
<ArrowCardInner {entry} {pill}>
<div class="relative overflow-hidden w-4 h-4">
<Icon
name="pixelarticons:arrow-right"
class:list="absolute right-0 inset-y-0 text-lg origin-left
scale-x-0 group-hover:scale-x-100
transition-all duration-300 ease-in-out"
/>
<Icon
name="pixelarticons:chevron-right"
class:list="absolute right-0 inset-y-0 text-lg
group-hover:translate-x-4
transition-all duration-300 ease-in-out"
/>
</div>
</ArrowCardInner>

View File

@ -1,16 +1,14 @@
import type { CollectionEntry } from "astro:content";
import { formatDate } from "@/lib/utils";
import { children } from "solid-js";
import { Icon } from '@iconify-icon/solid';
type Props = {
entry: CollectionEntry<"blog"> | CollectionEntry<"projects">;
pill?: string;
children: any;
};
export default function ArrowCard({ entry, pill, children: c }: Props) {
const arrow = children(() => c).toArray();
export default function ArrowCard({ entry, pill }: Props) {
return (
<a
href={`/${entry.collection}/${entry.id}/`}
@ -42,7 +40,20 @@ export default function ArrowCard({ entry, pill, children: c }: Props) {
)}
</ul>
</div>
{arrow}
<div class="relative overflow-hidden w-4 h-4">
<Icon
icon="pixelarticons:arrow-right"
class="absolute right-0 inset-y-0 text-lg origin-left
scale-x-0 group-hover:scale-x-100
transition-all duration-300 ease-in-out"
/>
<Icon
icon="pixelarticons:chevron-right"
class="absolute right-0 inset-y-0 text-lg
group-hover:translate-x-4
transition-all duration-300 ease-in-out"
/>
</div>
</a>
);
}

View File

@ -0,0 +1,33 @@
---
import { render, type CollectionEntry } from "astro:content";
import Container from "./Container.astro";
type Props = {
entry: CollectionEntry<"projects"> | CollectionEntry<"blog">;
};
const { entry } = Astro.props;
const { Content } = await render(entry);
---
<Container size="md">
<article class="animate content">
<Content />
</article>
</Container>
<style is:global>
article.content :is(h1, h2, h3, h4, h5, h6) {
font-family: "DepartureMono", monospace;
}
article.content a {
font-family: "DepartureMono", monospace;
text-decoration: none;
}
article.content a:hover {
text-decoration: underline;
}
</style>

View File

@ -97,6 +97,10 @@ const { title, description, image = "/open-graph.jpg" } = Astro.props;
);
</script>
<script>
import "iconify-icon";
</script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.27/dist/katex.css"

108
src/components/Blog.tsx Normal file
View File

@ -0,0 +1,108 @@
import type { CollectionEntry } from "astro:content";
import { createEffect, createSignal, For, Show } from "solid-js";
import ArrowCard from "@/components/ArrowCard";
import { cn } from "@/lib/utils";
import { Icon } from "@iconify-icon/solid";
type Props = {
tags: string[];
data: CollectionEntry<"blog">[];
};
export default function Blog({ data, tags }: Props) {
const [filter, setFilter] = createSignal(new Set<string>());
const [posts, setPosts] = createSignal<CollectionEntry<"blog">[]>([]);
createEffect(() => {
setPosts(
data.filter((entry) =>
Array.from(filter()).every((value) =>
entry.data.tags.some(
(tag: string) =>
tag.toLowerCase() === String(value).toLowerCase()
)
)
)
);
});
function toggleTag(tag: string) {
setFilter(
(prev) =>
new Set(
prev.has(tag)
? [...prev].filter((t) => t !== tag)
: [...prev, tag]
)
);
}
return (
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6">
<div class="col-span-3 sm:col-span-1">
<div class="sticky top-24">
<div class="text-sm font-semibold font-departure uppercase mb-2 text-black dark:text-white">
Filter
</div>
<ul class="flex flex-wrap sm:flex-col gap-1.5">
<For each={tags}>
{(tag) => (
<li>
<button
onClick={() => toggleTag(tag)}
class={cn(
"w-full px-2 py-1 rounded font-departure",
"whitespace-nowrap overflow-hidden overflow-ellipsis",
"flex gap-2 items-center",
"bg-black/5 dark:bg-white/10",
"hover:bg-black/10 hover:dark:bg-white/15",
"transition-colors duration-300 ease-in-out",
filter().has(tag) &&
"text-black dark:text-white"
)}
>
<div class={cn(
"relative size-5 fill-black/50 dark:fill-white/50",
"transition-colors duration-300 ease-in-out",
filter().has(tag) &&
"fill-black dark:fill-white"
)}>
<Icon icon="pixelarticons:square" />
<Icon icon="pixel:check" class={cn("absolute top-0 right-0",
filter().has(tag)
? "block"
: "hidden"
)} />
</div>
{tag}
</button>
</li>
)}
</For>
</ul>
</div>
</div>
<div class="col-span-3 sm:col-span-2">
<div class="flex flex-col">
<div class="text-sm font-departure uppercase mb-2">
SHOWING {posts().length} OF {data.length} POSTS
</div>
<ul class="flex flex-col gap-3">
{posts().map((post) => (
<li>
<ArrowCard entry={post} />
</li>
))}
<Show when={posts().length == 0}>
<h3 class="mt-5 text-2xl font-departure">
There seem to be no blogs matching the filters
yet...
</h3>
</Show>
</ul>
</div>
</div>
</div>
);
}

View File

@ -25,7 +25,7 @@ const subpath = pathname.match(/[^/]+/g);
src={pictureOfMe}
loading="eager"
alt="Me"
class="size-6 fill-current rounded-lg"
class="size-6 fill-current rounded-lg mr-2"
quality="low"
/>
<div class="font-departure font-bold">
@ -49,7 +49,7 @@ const subpath = pathname.match(/[^/]+/g);
"flex items-center justify-center",
"transition-colors duration-300 ease-in-out",
pathname === LINK.HREF ||
"/" + subpath?.[0] === LINK.HREF
"/" + subpath?.[0] + "/" === LINK.HREF
? "bg-black dark:bg-white text-white dark:text-black"
: "hover:bg-black/5 dark:hover:bg-white/20 hover:text-black dark:hover:text-white",
)}

109
src/components/Projects.tsx Normal file
View File

@ -0,0 +1,109 @@
import type { CollectionEntry } from "astro:content";
import { createEffect, createSignal, For, Show } from "solid-js";
import ArrowCard from "@/components/ArrowCard";
import { cn } from "@/lib/utils";
import { Icon } from "@iconify-icon/solid";
type Props = {
tags: string[];
data: CollectionEntry<"projects">[];
};
export default function Projects({ data, tags }: Props) {
const [filter, setFilter] = createSignal(new Set<string>());
const [projects, setProjects] = createSignal<CollectionEntry<"projects">[]>(
[]
);
createEffect(() => {
setProjects(
data.filter((entry) =>
Array.from(filter()).every((value) =>
entry.data.tags.some(
(tag: string) =>
tag.toLowerCase() === String(value).toLowerCase()
)
)
)
);
});
function toggleTag(tag: string) {
setFilter(
(prev) =>
new Set(
prev.has(tag)
? [...prev].filter((t) => t !== tag)
: [...prev, tag]
)
);
}
return (
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6">
<div class="col-span-3 sm:col-span-1">
<div class="sticky top-24">
<div class="text-sm font-semibold font-departure uppercase mb-2 text-black dark:text-white">
Filter
</div>
<ul class="flex flex-wrap sm:flex-col gap-1.5">
<For each={tags}>
{(tag) => (
<li>
<button
onClick={() => toggleTag(tag)}
class={cn(
"w-full px-2 py-1 rounded font-departure",
"whitespace-nowrap overflow-hidden overflow-ellipsis",
"flex gap-2 items-center",
"bg-black/5 dark:bg-white/10",
"hover:bg-black/10 hover:dark:bg-white/15",
"transition-colors duration-300 ease-in-out",
filter().has(tag) &&
"text-black dark:text-white"
)}
>
<div class={cn(
"relative size-5 fill-black/50 dark:fill-white/50",
"transition-colors duration-300 ease-in-out",
filter().has(tag) &&
"fill-black dark:fill-white"
)}>
<Icon icon="pixelarticons:square" />
<Icon icon="pixel:check" class={cn("absolute top-0 right-0",
filter().has(tag)
? "block"
: "hidden"
)} />
</div>
{tag}
</button>
</li>
)}
</For>
</ul>
</div>
</div>
<div class="col-span-3 sm:col-span-2">
<div class="flex flex-col">
<div class="text-sm font-departure uppercase mb-2">
SHOWING {projects().length} OF {data.length} PROJECTS
</div>
<ul class="flex flex-col gap-3">
{projects().map((project) => (
<li>
<ArrowCard entry={project} />
</li>
))}
<Show when={projects().length == 0}>
<h3 class="mt-5 text-2xl font-departure">
There seem to be no projects matching the
filters yet...
</h3>
</Show>
</ul>
</div>
</div>
</div>
);
}

View File

@ -1,13 +1,13 @@
import type { CollectionEntry } from "astro:content"
import { createEffect, createSignal } from "solid-js"
import Fuse from "fuse.js"
// import ArrowCard from "@components/ArrowCard"
import ArrowCard from "@/components/ArrowCard"
type Props = {
data: CollectionEntry<"blog">[]
}
export default function Search({data}: Props) {
export default function Search({ data }: Props) {
const [query, setQuery] = createSignal("")
const [results, setResults] = createSignal<CollectionEntry<"blog">[]>([])
@ -34,21 +34,20 @@ export default function Search({data}: Props) {
return (
<div class="flex flex-col">
<div class="relative">
<input name="search" type="text" value={query()} onInput={onInput} autocomplete="off" spellcheck={false} placeholder="What are you looking for?" class="w-full px-2.5 py-1.5 pl-10 rounded outline-none text-black dark:text-white bg-black/5 dark:bg-white/15 border border-black/10 dark:border-white/20 focus:border-black focus:dark:border-white"/>
<input name="search" type="text" value={query()} onInput={onInput} autocomplete="off" spellcheck={false} placeholder="What are you looking for?" class="w-full px-2.5 py-1.5 pl-10 rounded outline-none text-black dark:text-white bg-black/5 dark:bg-white/15 border border-black/10 dark:border-white/20 focus:border-black focus:dark:border-white" />
<svg class="absolute size-6 left-1.5 top-1/2 -translate-y-1/2 stroke-current">
<use href={`/ui.svg#search`}/>
<use href={`/ui.svg#search`} />
</svg>
</div>
{(query().length >= 2 && results().length >= 1) && (
<div class="mt-12">
<div class="text-sm uppercase mb-2">
<div class="text-sm uppercase mb-2 font-departure">
Found {results().length} results for {`'${query()}'`}
</div>
<ul class="flex flex-col gap-3">
{results().map(result => (
<li>
{/* <ArrowCard entry={result} pill={true} /> */}
<div>{JSON.stringify(result, undefined, 2)}</div>
<ArrowCard entry={result} pill={result.collection} />
</li>
))}
</ul>

View File

@ -1,5 +1,6 @@
---
import { type CollectionEntry, getCollection, render } from "astro:content";
import { type CollectionEntry, getCollection } from "astro:content";
import { Icon } from "astro-icon/components";
type Props = {
entry: CollectionEntry<"blog"> | CollectionEntry<"projects">;
@ -8,7 +9,6 @@ type Props = {
// Get the requested entry
const { entry } = Astro.props;
const { collection } = entry;
const { Content } = await render(entry);
// Get the next and prev entries (modulo to wrap index)
const items = (await getCollection(collection))
@ -20,9 +20,6 @@ const next = items[(index - 1 + items.length) % items.length];
---
<div>
<article>
<Content />
</article>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<a
href={`/${prev.collection}/${prev.id}/`}
@ -32,35 +29,26 @@ const next = items[(index - 1 + items.length) % items.length];
class="order-2 w-full h-full group-hover:text-black group-hover:dark:text-white blend"
>
<div class="flex flex-wrap gap-2">
<div class="text-sm uppercase">Prev</div>
<div class="text-sm font-departure uppercase">Prev</div>
</div>
<div class="font-semibold mt-3 text-black dark:text-white">
{prev.data.title}
</div>
</div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
class="order-1 stroke-current group-hover:stroke-black group-hover:dark:stroke-white rotate-180"
>
<line
x1="5"
y1="12"
x2="19"
y2="12"
class="scale-x-0 group-hover:scale-x-100 translate-x-4 group-hover:translate-x-1 transition-all duration-300 ease-in-out"
></line>
<polyline
points="12 5 19 12 12 19"
class="translate-x-0 group-hover:translate-x-1 transition-all duration-300 ease-in-out"
></polyline>
</svg>
<div class="relative overflow-hidden w-4 h-4">
<Icon
name="pixelarticons:arrow-left"
class:list="absolute left-0 inset-y-0 text-lg origin-right
scale-x-0 group-hover:scale-x-100
transition-all duration-300 ease-in-out"
/>
<Icon
name="pixelarticons:chevron-left"
class:list="absolute left-0 inset-y-0 text-lg
group-hover:-translate-x-4
transition-all duration-300 ease-in-out"
/>
</div>
</a>
<a
href={`/${next.collection}/${next.id}/`}
@ -69,34 +57,25 @@ const next = items[(index - 1 + items.length) % items.length];
<div
class="w-full h-full text-right group-hover:text-black group-hover:dark:text-white blend"
>
<div class="text-sm uppercase">Next</div>
<div class="text-sm font-departure uppercase">Next</div>
<div class="font-semibold mt-3 text-black dark:text-white">
{next.data.title}
</div>
</div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
class="stroke-current group-hover:stroke-black group-hover:dark:stroke-white"
>
<line
x1="5"
y1="12"
x2="19"
y2="12"
class="scale-x-0 group-hover:scale-x-100 translate-x-4 group-hover:translate-x-1 transition-all duration-300 ease-in-out"
></line>
<polyline
points="12 5 19 12 12 19"
class="translate-x-0 group-hover:translate-x-1 transition-all duration-300 ease-in-out"
></polyline>
</svg>
<div class="relative overflow-hidden w-4 h-4">
<Icon
name="pixelarticons:arrow-right"
class:list="absolute right-0 inset-y-0 text-lg origin-left
scale-x-0 group-hover:scale-x-100
transition-all duration-300 ease-in-out"
/>
<Icon
name="pixelarticons:chevron-right"
class:list="absolute right-0 inset-y-0 text-lg
group-hover:translate-x-4
transition-all duration-300 ease-in-out"
/>
</div>
</a>
</div>
</div>

View File

@ -1,5 +1,6 @@
---
import type { CollectionEntry } from "astro:content";
import { Icon } from "astro-icon/components";
import { formatDate, readingTime } from "@/lib/utils";
type Props = {
@ -19,50 +20,41 @@ const repoUrl = collection === "projects" ? data.repoUrl : null;
href={`/${collection}/`}
class="group w-fit p-1.5 gap-1.5 text-sm flex items-center border rounded hover:bg-black/5 hover:dark:bg-white/10 border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
class="stroke-current group-hover:stroke-black group-hover:dark:stroke-white"
>
<line
x1="19"
y1="12"
x2="5"
y2="12"
class="scale-x-0 group-hover:scale-x-100 translate-x-3 group-hover:translate-x-0 transition-all duration-300 ease-in-out"
></line>
<polyline
points="12 19 5 12 12 5"
class="translate-x-1 group-hover:translate-x-0 transition-all duration-300 ease-in-out"
></polyline>
</svg>
<div class="relative overflow-hidden w-4 h-4">
<Icon
name="pixelarticons:arrow-left"
class:list="absolute left-0 inset-y-0 text-lg origin-right
scale-x-0 group-hover:scale-x-100
transition-all duration-300 ease-in-out"
/>
<Icon
name="pixelarticons:chevron-left"
class:list="absolute left-0 inset-y-0 text-lg
group-hover:-translate-x-4
transition-all duration-300 ease-in-out"
/>
</div>
<div
class="w-full group-hover:text-black group-hover:dark:text-white transition-colors duration-300 ease-in-out"
class="w-full font-departure group-hover:text-black group-hover:dark:text-white transition-colors duration-300 ease-in-out"
>
Back to {collection}
</div>
</a>
<div class="flex flex-wrap text-sm uppercase mt-12 gap-3 opacity-75">
<div
class="flex flex-wrap text-sm font-departure uppercase mt-12 gap-3 opacity-75"
>
<div class="flex items-center gap-2">
<svg class="size-5 stroke-current">
<use href="/ui.svg#calendar"></use>
</svg>
<Icon name="pixelarticons:calendar-2" class:list="size-5" />
{formatDate(date)}
</div>
<div class="flex items-center gap-2">
<svg class="size-5 stroke-current">
<use href="/ui.svg#book-open"></use>
</svg>
<Icon name="pixelarticons:book-open" class:list="size-5" />
{readingTime(body ?? "")}
</div>
</div>
<h1 class="text-3xl font-semibold text-black dark:text-white mt-2">
<h1
class="text-3xl font-semibold font-departure text-black dark:text-white mt-2"
>
{title}
</h1>
<div class="mt-1">
@ -77,13 +69,8 @@ const repoUrl = collection === "projects" ? data.repoUrl : null;
target="_blank"
class="group flex gap-2 items-center px-3 py-1.5 truncate rounded text-xs md:text-sm lg:text-base border border-black/25 dark:border-white/25 hover:bg-black/5 hover:dark:bg-white/15 blend"
>
<svg class="size-4">
<use
href="/ui.svg#globe"
class="fill-current group-hover:fill-black group-hover:dark:fill-white blend"
/>
</svg>
<span class="text-current group-hover:text-black group-hover:dark:text-white blend">
<Icon name="pixelarticons:globe" class:list="size-4" />
<span class="text-current font-departure group-hover:text-black group-hover:dark:text-white blend">
See Demo
</span>
</a>
@ -94,13 +81,8 @@ const repoUrl = collection === "projects" ? data.repoUrl : null;
target="_blank"
class="group flex gap-2 items-center px-3 py-1.5 truncate rounded text-xs md:text-sm lg:text-base border border-black/25 dark:border-white/25 hover:bg-black/5 hover:dark:bg-white/15 blend"
>
<svg class="size-4">
<use
href="/ui.svg#link"
class="fill-current group-hover:fill-black group-hover:dark:fill-white blend"
/>
</svg>
<span class="text-current group-hover:text-black group-hover:dark:text-white blend">
<Icon name="pixelarticons:link" class:list="size-4" />
<span class="text-current font-departure group-hover:text-black group-hover:dark:text-white blend">
See Repository
</span>
</a>

View File

@ -5,6 +5,7 @@ import TopLayout from "@/layouts/TopLayout.astro";
import BottomLayout from "@/layouts/BottomLayout.astro";
import ArticleTopLayout from "@/layouts/ArticleTopLayout.astro";
import ArticleBottomLayout from "@/layouts/ArticleBottomLayout.astro";
import ArticleContent from "@/components/ArticleContent.astro";
// Create the static blog pages
export async function getStaticPaths() {
@ -33,6 +34,7 @@ const { title, summary } = post.data;
<ArticleTopLayout entry={post} />
</div>
</TopLayout>
<ArticleContent entry={post} />
<BottomLayout>
<div class="animate">
<ArticleBottomLayout entry={post} />

View File

@ -4,6 +4,7 @@ import PageLayout from "@/layouts/PageLayout.astro";
import TopLayout from "@/layouts/TopLayout.astro";
import BottomLayout from "@/layouts/BottomLayout.astro";
import { BLOG } from "@/consts";
import Blog from "@/components/Blog";
const posts = (await getCollection("blog"))
.filter((post) => !post.data.draft)
@ -22,9 +23,7 @@ const tags = [...new Set(posts.flatMap((post) => post.data.tags))].sort(
</TopLayout>
<BottomLayout>
<div class="animate">
<!-- <Blog client:load tags={tags} data={posts} /> -->
<div>{JSON.stringify(posts)}</div>
<div>{JSON.stringify(tags)}</div>
<Blog client:load tags={tags} data={posts} />
</div>
</BottomLayout>
</PageLayout>

View File

@ -1,7 +1,7 @@
---
import { getCollection } from "astro:content";
import PageLayout from "@/layouts/PageLayout.astro";
import ArrowCard from "@/components/ArrowCard.astro";
import ArrowCard from "@/components/ArrowCard";
import StackCard from "@/components/StackCard.astro";
import { SITE, SOCIALS } from "@/consts";

View File

@ -5,6 +5,7 @@ import TopLayout from "@/layouts/TopLayout.astro";
import BottomLayout from "@/layouts/BottomLayout.astro";
import ArticleTopLayout from "@/layouts/ArticleTopLayout.astro";
import ArticleBottomLayout from "@/layouts/ArticleBottomLayout.astro";
import ArticleContent from "@/components/ArticleContent.astro";
// Create the static projects pages
export async function getStaticPaths() {
@ -33,6 +34,7 @@ const { title, summary } = project.data;
<ArticleTopLayout entry={project} />
</div>
</TopLayout>
<ArticleContent entry={project} />
<BottomLayout>
<div class="animate">
<ArticleBottomLayout entry={project} />

View File

@ -3,7 +3,7 @@ import { getCollection } from "astro:content";
import PageLayout from "@/layouts/PageLayout.astro";
import TopLayout from "@/layouts/TopLayout.astro";
import BottomLayout from "@/layouts/BottomLayout.astro";
// import Projects from "@components/Projects";
import Projects from "@/components/Projects";
import { PROJECTS } from "@/consts";
const projects = (await getCollection("projects"))
@ -23,9 +23,7 @@ const tags = [
</TopLayout>
<BottomLayout>
<div class="animate">
<!-- <Projects client:load tags={tags} data={projects} /> -->
<div>{JSON.stringify(projects)}</div>
<div>{JSON.stringify(tags)}</div>
<Projects client:load tags={tags} data={projects} />
</div>
</BottomLayout>
</PageLayout>

View File

@ -17,7 +17,7 @@ const data = [...posts, ...projects] as CollectionEntry<"blog">[];
<PageLayout title={SEARCH.TITLE} description={SEARCH.DESCRIPTION}>
<TopLayout>
<div class="animate page-heading">
<div class="animate page-heading font-departure">
{SEARCH.TITLE}
</div>
</TopLayout>