91 lines
3.8 KiB
Vue
91 lines
3.8 KiB
Vue
|
<script setup lang="ts">
|
||
|
import { onMounted, watch, ref } from 'vue';
|
||
|
import fm from 'front-matter';
|
||
|
|
||
|
import PostCard from '~/components/PostCard.vue';
|
||
|
import * as pages from '~/utils/page_updater/update_pagelist';
|
||
|
import type { PageInfo, PageInfoMetdata } from '~/utils/page_updater/pages';
|
||
|
import type { ParsedContent } from '@nuxt/content';
|
||
|
|
||
|
// Automatically maintained is a blog_list.json in assets/meta. This file contains a list of all blog posts and their metadata.
|
||
|
// This file is generated by a script in the utils/pageupdater folder.
|
||
|
const article_list: pages.PageList = await import('~/assets/meta/blog_list.json') as pages.PageList;
|
||
|
|
||
|
let route = useRoute()
|
||
|
console.log(route)
|
||
|
|
||
|
const loading: Ref<boolean> = ref(false)
|
||
|
|
||
|
const listCategoryKeys: Ref<string[]> = ref([])
|
||
|
|
||
|
const tagList: Ref<string[]> = ref([])
|
||
|
const tagFilter: Ref<string[]> = ref([])
|
||
|
tagFilter.value = []
|
||
|
|
||
|
function resetReadingPosition() {
|
||
|
window.scrollTo(0, 0)
|
||
|
}
|
||
|
|
||
|
onMounted(() => {
|
||
|
// Extract the tags from each post in each category
|
||
|
var tags: string[] = []
|
||
|
for (const category in article_list.categories) {
|
||
|
console.log("Category: " + category)
|
||
|
for (const post of article_list.categories[category].posts) {
|
||
|
if (post.metadata.tags) {
|
||
|
for (const tag of post.metadata.tags) {
|
||
|
if (!tags.includes(tag)) {
|
||
|
console.log("Adding tag: " + tag)
|
||
|
tags.push(tag)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
tagList.value = tags
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<div class="relative z-50 flex w-full justify-center text-white">
|
||
|
<!-- Metadata -->
|
||
|
<MetaSet title="Articles" description="Ramblings." background="https://avatars.githubusercontent.com/u/94077364?v=4"
|
||
|
tags="blog, personal, author" />
|
||
|
|
||
|
<!-- Main Content -->
|
||
|
<div class="mt-8 flex-col text-center">
|
||
|
<Transition name="list">
|
||
|
<div>
|
||
|
<!-- Article List -->
|
||
|
<h1>Articles</h1>
|
||
|
<div class="flex justify-center">
|
||
|
|
||
|
<div class="flex flex-wrap justify-center m-5 max-w-96">
|
||
|
<div v-for="tag in tagList" :key="tag" class="m-1">
|
||
|
<button
|
||
|
@click="tagFilter.includes(tag) ? tagFilter.splice(tagFilter.indexOf(tag), 1) : tagFilter.push(tag)"
|
||
|
class="text-xs bg-black border-purple-400 border text-white p-1 rounded-md"
|
||
|
:class="tagFilter.includes(tag) ? 'border-2 border-white bg-slate-700' : 'border-2 bg-black text-white'">{{
|
||
|
tag }}</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div v-for="categoryKey in Object.keys(article_list.categories)" :key="categoryKey">
|
||
|
<div class="lg:w-[48rem] md:w-max flex flex-col bg-secondary bg-opacity-50 rounded-md shadow-md shadow-secondary p-2 m-2">
|
||
|
<h2>{{ categoryKey }}</h2>
|
||
|
<div
|
||
|
v-for="post in tagFilter.length == 0 ? article_list.categories[categoryKey].posts : article_list.categories[categoryKey].posts.filter((post) => post.metadata.tags ? post.metadata.tags.some((tag) => tagFilter.includes(tag)) : true)">
|
||
|
<PostCard class="lg:w-[48rem]" :url="post.url" :key="post.id" :tagFilter="tagFilter" />
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</Transition>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<style scoped>
|
||
|
</style>
|