mirror of
https://github.com/anotherhadi/blog.git
synced 2026-05-20 05:32:32 +02:00
@@ -0,0 +1,178 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import NoteNavSidebar from "../../components/NoteNavSidebar.svelte";
|
||||
import { getCategory } from "../../utils/notes";
|
||||
import { List } from "@lucide/astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const notes = await getCollection("notes");
|
||||
|
||||
const folderCategories = [
|
||||
...new Set(
|
||||
notes.filter((n) => n.id.includes("/")).map((n) => getCategory(n)),
|
||||
),
|
||||
];
|
||||
|
||||
return folderCategories.map((category) => {
|
||||
const allNotes = notes.sort((a, b) =>
|
||||
a.data.title.localeCompare(b.data.title),
|
||||
);
|
||||
const categories = [...new Set(notes.map(getCategory))].sort();
|
||||
return {
|
||||
params: { category },
|
||||
props: {
|
||||
category,
|
||||
categoryNotes: notes
|
||||
.filter((n) => getCategory(n) === category)
|
||||
.sort((a, b) => a.data.title.localeCompare(b.data.title)),
|
||||
allNotes,
|
||||
categories,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { category, categoryNotes, allNotes, categories } = Astro.props;
|
||||
|
||||
if (!categoryNotes) {
|
||||
return new Response(null, { status: 404, statusText: "Not found" });
|
||||
}
|
||||
---
|
||||
|
||||
<style>
|
||||
.drawer.lg\:drawer-open > .drawer-side {
|
||||
top: 3rem;
|
||||
height: calc(100vh - 3rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
<Layout
|
||||
title={`${category} - Security Notes`}
|
||||
description={`Notes on ${category}.`}
|
||||
>
|
||||
<main class="max-w-screen-2xl mx-auto">
|
||||
<div class="drawer lg:drawer-open min-h-[calc(100vh-3rem)]">
|
||||
<input id="nav-drawer" type="checkbox" class="drawer-toggle" />
|
||||
|
||||
<div class="drawer-content flex flex-col min-w-0">
|
||||
<main class="flex-1 px-4 sm:px-6 lg:px-10 py-6 lg:py-10 min-w-0">
|
||||
<div class="max-w-3xl mx-auto lg:mx-0">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<div
|
||||
class="breadcrumbs text-xs font-mono text-base-content/35 p-0"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/notes" class="hover:text-base-content/70"
|
||||
>notes</a>
|
||||
</li>
|
||||
<li class="text-base-content/60">{category}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<label
|
||||
for="nav-drawer"
|
||||
class="btn btn-ghost btn-xs lg:hidden font-mono text-base-content/40 hover:text-base-content/70 border border-base-300/50"
|
||||
>
|
||||
<List size={11} />
|
||||
nav
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-10">
|
||||
<div class="flex items-baseline gap-3 mb-1">
|
||||
<h1 class="text-4xl sm:text-5xl font-bold">
|
||||
<span class="text-primary/40 font-mono mr-1">/</span>{
|
||||
category
|
||||
}
|
||||
</h1>
|
||||
</div>
|
||||
<p class="font-mono text-xs text-base-content/25 ml-8">
|
||||
{categoryNotes.length} note{
|
||||
categoryNotes.length !== 1 ? "s" : ""
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-base-300/40 mb-1"></div>
|
||||
<ul class="divide-y divide-base-300/20">
|
||||
{
|
||||
categoryNotes.map((note) => (
|
||||
<li>
|
||||
<a
|
||||
href={`/notes/${note.id}`}
|
||||
class="group flex items-center gap-4 py-3 hover:bg-base-200/30 px-2 -mx-2 transition-colors"
|
||||
>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex flex-col mb-0.5">
|
||||
<span class="font-semibold text-sm group-hover:text-primary transition-colors">
|
||||
{note.data.title}
|
||||
</span>
|
||||
{note.data.description && (
|
||||
<span class="text-xs text-base-content/35 truncate">
|
||||
{note.data.description}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{note.data.tags.length > 0 && (
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
{note.data.tags.map((tag) => (
|
||||
<span class="badge badge-ghost badge-xs font-mono text-base-content/30">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="text-base-content/20 group-hover:text-primary/50 shrink-0 transition-colors"
|
||||
>
|
||||
<path d="m9 18 6-6-6-6" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div
|
||||
class="border-t border-base-300/30 mt-12 pt-6 flex items-center justify-between font-mono text-[10px] text-base-content/25"
|
||||
>
|
||||
<a
|
||||
href="/notes"
|
||||
class="hover:text-base-content/50 transition-colors"
|
||||
>
|
||||
← all notes
|
||||
</a>
|
||||
<a href="/" class="hover:text-base-content/50 transition-colors">
|
||||
~/hadi
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div class="drawer-side z-50">
|
||||
<label
|
||||
for="nav-drawer"
|
||||
aria-label="close sidebar"
|
||||
class="drawer-overlay"></label>
|
||||
<NoteNavSidebar
|
||||
client:load
|
||||
notes={allNotes}
|
||||
currentCategory={category}
|
||||
categories={categories}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
Reference in New Issue
Block a user