mirror of
https://github.com/liyunze-coding/coworking-website.git
synced 2026-11-06 13:13:34 +00:00
189 lines
4.7 KiB
Text
189 lines
4.7 KiB
Text
---
|
|
import SearchModal from "../ui/SearchModal.astro";
|
|
|
|
type Navigation = Record<
|
|
string,
|
|
{ title: string; url: string; order: number }[]
|
|
>;
|
|
|
|
const currentUrl = Astro.url.pathname;
|
|
|
|
const isCurrentUrl = (url: string) => currentUrl === url;
|
|
|
|
export function formatTitle(title: string): string {
|
|
return title
|
|
.split("-")
|
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
.join(" ");
|
|
}
|
|
|
|
export async function setup() {
|
|
// setup navigation
|
|
|
|
// Define the order of categories
|
|
let categoryOrder = ["Get Started", "Guide", "Tutorials"];
|
|
|
|
const getStartedFiles = await Astro.glob("../../pages/get-started/*");
|
|
const guideFiles = await Astro.glob("../../pages/guide/*");
|
|
const tutorialFiles = await Astro.glob("../../pages/tutorials/*");
|
|
|
|
let markdownFiles = [...getStartedFiles, ...guideFiles, ...tutorialFiles];
|
|
let navigation: Navigation = {};
|
|
|
|
for (const file of markdownFiles) {
|
|
let filePath = file.url;
|
|
let [_, category] = filePath!.split("/");
|
|
let formattedCategory = formatTitle(category).toLowerCase();
|
|
let formattedTitle = file.frontmatter.title;
|
|
let order = file.frontmatter.order ?? 0;
|
|
|
|
if (!navigation[formattedCategory]) {
|
|
navigation[formattedCategory] = [];
|
|
}
|
|
|
|
navigation[formattedCategory].push({
|
|
title: formattedTitle,
|
|
url: filePath || "",
|
|
order,
|
|
});
|
|
}
|
|
|
|
// Create a new navigation object with the desired order
|
|
let orderedNavigation: Navigation = {};
|
|
for (let category of categoryOrder) {
|
|
if (navigation[category.toLowerCase()]) {
|
|
orderedNavigation[category] = navigation[
|
|
category.toLowerCase()
|
|
].sort((a, b) => a.order - b.order);
|
|
}
|
|
}
|
|
|
|
return {
|
|
navigation: orderedNavigation,
|
|
};
|
|
}
|
|
|
|
interface Props {
|
|
showHome?: boolean | null;
|
|
}
|
|
|
|
// setup navigation
|
|
const { navigation } = await setup();
|
|
|
|
// show Home link in vertical navbar only on mobile
|
|
const { showHome } = Astro.props;
|
|
---
|
|
|
|
<div class="relative">
|
|
<nav id="vertical-nav-component" class="flex flex-col" data-pagefind-ignore>
|
|
{
|
|
showHome && (
|
|
<div class="mb-5">
|
|
<SearchModal id="vertical" open="Open modal" />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
{
|
|
showHome && (
|
|
<div class="mb-2">
|
|
<a
|
|
href="/"
|
|
class={`no-target-blank px-2 rounded-md w-full hover:no-underline hover:text-white text-lg mt-0
|
|
${isCurrentUrl("/") ? "text-white" : "text-gray-400"}`}
|
|
>
|
|
Home
|
|
</a>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
{
|
|
Object.entries(navigation).map(([category, links]) => (
|
|
<div class="mb-2">
|
|
<div class="category no-target-blank rounded-md text-lg font-bold mb-1 mt-0 text-white">
|
|
{category}
|
|
</div>
|
|
<ul class="list-disc list-outside font-normal">
|
|
{links.map((link) => (
|
|
<li class="mb-1 pl-0">
|
|
<a
|
|
href={link.url}
|
|
class={`no-target-blank px-2 rounded-md w-full transition-colors duration-150 hover:no-underline hover:text-white ${isCurrentUrl(link.url) ? "text-black bg-primary-green" : "text-gray-400 bg-none"}`}
|
|
>
|
|
{link.title}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))
|
|
}
|
|
<div class="mb-2">
|
|
<a
|
|
href="/groups"
|
|
class={`no-target-blank px-2 rounded-md w-full transition-colors duration-150 hover:no-underline hover:text-white text-lg mt-0
|
|
${isCurrentUrl("/groups") ? "text-black bg-primary-green" : "text-gray-400"}`}
|
|
>
|
|
Groups
|
|
</a>
|
|
</div>
|
|
<div class="mb-2">
|
|
<a
|
|
href="/credits"
|
|
class={`no-target-blank px-2 rounded-md w-full transition-colors duration-150 hover:no-underline hover:text-white text-lg mt-0
|
|
${isCurrentUrl("/credits") ? "text-black bg-primary-green" : "text-gray-400"}`}
|
|
>
|
|
Credits
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener("astro:page-load", () => {
|
|
const currentUrl = window.location.pathname;
|
|
|
|
const isCurrentUrl = (url: string) => currentUrl === url;
|
|
|
|
const links = document.querySelectorAll(
|
|
"#vertical-nav-component a:not(.category), #vertical-nav-component a > a:not(.category)"
|
|
);
|
|
|
|
// add active class to current url
|
|
links.forEach((link) => {
|
|
if (isCurrentUrl(link.getAttribute("href")!)) {
|
|
link.classList.add("text-black", "bg-primary-green");
|
|
link.classList.remove(
|
|
"text-gray-400",
|
|
"bg-none",
|
|
"hover:text-white"
|
|
);
|
|
} else {
|
|
link.classList.remove("text-black", "bg-primary-green");
|
|
link.classList.add(
|
|
"text-gray-400",
|
|
"bg-none",
|
|
"hover:text-white"
|
|
);
|
|
}
|
|
});
|
|
|
|
// close dialog
|
|
const dialog = document.querySelector("dialog");
|
|
|
|
if (dialog) {
|
|
dialog.close();
|
|
}
|
|
});
|
|
|
|
// @ts-ignore
|
|
new PagefindUI({
|
|
element: "#vertical-search",
|
|
showSubResults: false,
|
|
showEmptyFilters: false,
|
|
debounceTimeoutMs: 0,
|
|
showImages: false,
|
|
autofocus: false,
|
|
});
|
|
</script>
|