wiki_ghostguild/app/pages/index.vue

101 lines
3.1 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<p class="text-xl text-gray-600 dark:text-gray-400 mb-8">
A wiki for ghosts! 👻
</p>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-2">View all articles</h2>
<p class="text-gray-600 dark:text-gray-400 mb-4"></p>
<NuxtLink to="/articles" class="text-blue-600 hover:text-blue-800">
View All Articles
</NuxtLink>
</div>
<div
v-if="isAuthenticated"
class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow"
>
<h2 class="text-xl font-semibold mb-2"> Contribute</h2>
<p class="text-gray-600 dark:text-gray-400 mb-4">
Share your knowledge with the community
</p>
<NuxtLink to="/articles/new" class="text-blue-600 hover:text-blue-800">
Create Article
</NuxtLink>
</div>
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-2">Ghost Guild</h2>
<p class="text-gray-600 dark:text-gray-400 mb-4"></p>
<a
href="https://ghostguild.org"
class="text-blue-600 hover:text-blue-800"
>
Visit Ghost Guild
</a>
</div>
</div>
<!-- Recent Articles -->
<div class="mt-12">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">
Recent Articles
</h2>
<div v-if="pending" class="text-gray-600 dark:text-gray-400">
Loading...
</div>
<div v-else-if="articles?.length" class="space-y-4">
<article
v-for="article in articles"
:key="article.stem"
class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow"
>
<NuxtLink
:to="`/articles/${article.stem}`"
class="text-xl font-semibold text-blue-600 hover:text-blue-800"
>
{{ article.title }}
</NuxtLink>
<p class="text-gray-600 dark:text-gray-400 mt-2">
{{ article.description }}
</p>
<div class="mt-2 text-sm text-gray-500">
<span>{{ article.category }}</span>
<span>{{
new Date(article.publishedAt).toLocaleDateString()
}}</span>
</div>
</article>
</div>
</div>
</div>
</template>
<script setup>
const { isAuthenticated } = useAuth();
// Fetch recent articles from Nuxt Content to keep generate static-friendly
const { data: recentArticles, pending } = await useAsyncData(
"recent-articles",
async () => {
const entries = await queryCollection("articles").all();
const getTimestamp = (value) => {
if (!value) {
return 0;
}
const date = new Date(value);
return Number.isNaN(date.getTime()) ? 0 : date.getTime();
};
return entries
.filter((article) => article.published !== false)
.sort((a, b) => getTimestamp(b.publishedAt) - getTimestamp(a.publishedAt))
.slice(0, 5);
},
);
const articles = computed(() => recentArticles.value || []);
</script>