Initial commit
This commit is contained in:
commit
92e96b9107
85 changed files with 24969 additions and 0 deletions
108
app/pages/index.vue
Normal file
108
app/pages/index.vue
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
Ghost Guild Knowledge Commons
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400 mb-8">
|
||||
Collaborative knowledge base for the Baby Ghosts community
|
||||
</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">📚 Browse Articles</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Explore our growing collection of guides and resources
|
||||
</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">👥 Community</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Connect with other Baby Ghosts members
|
||||
</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.slug"
|
||||
class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow"
|
||||
>
|
||||
<NuxtLink
|
||||
:to="`/articles/${article.slug}`"
|
||||
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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue