Add images; update urls
This commit is contained in:
parent
ef432e3f74
commit
fe3d170dbe
37 changed files with 488 additions and 109 deletions
|
|
@ -1,49 +1,8 @@
|
|||
@import url("https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400;1,600&display=swap");
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer components {
|
||||
/* Custom prose styles */
|
||||
.prose {
|
||||
@apply max-w-none;
|
||||
}
|
||||
|
||||
/* Article content styles */
|
||||
.article-content {
|
||||
@apply max-w-none leading-relaxed;
|
||||
}
|
||||
|
||||
.article-content h1 {
|
||||
@apply text-3xl font-bold mb-4 mt-6;
|
||||
}
|
||||
|
||||
.article-content h2 {
|
||||
@apply text-2xl font-semibold mb-3 mt-8;
|
||||
}
|
||||
|
||||
.article-content h3 {
|
||||
@apply text-xl font-semibold mb-2 mt-6;
|
||||
}
|
||||
|
||||
.article-content p {
|
||||
@apply mb-4;
|
||||
}
|
||||
|
||||
.article-content ul,
|
||||
.article-content ol {
|
||||
@apply mb-4 ml-6;
|
||||
}
|
||||
|
||||
.article-content li {
|
||||
@apply mb-2;
|
||||
}
|
||||
|
||||
.article-content code {
|
||||
@apply bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded text-sm font-mono;
|
||||
}
|
||||
|
||||
.article-content pre {
|
||||
@apply bg-gray-100 dark:bg-gray-800 p-4 rounded-lg overflow-x-auto mb-4;
|
||||
}
|
||||
|
||||
/* Editor styles */
|
||||
.editor-container {
|
||||
@apply min-h-[500px] border rounded-lg;
|
||||
|
|
|
|||
54
app/components/mdc/Alert.vue
Normal file
54
app/components/mdc/Alert.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<UAlert
|
||||
:color="color"
|
||||
:variant="variant"
|
||||
:icon="icon"
|
||||
:title="title"
|
||||
:description="description"
|
||||
class="my-4 font-serif"
|
||||
>
|
||||
<template v-if="$slots.default" #description>
|
||||
<div class="prose prose-sm dark:prose-invert max-w-none font-serif">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
</UAlert>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
type AlertColor =
|
||||
| "error"
|
||||
| "info"
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "neutral";
|
||||
|
||||
interface Props {
|
||||
type?: "info" | "warning" | "error" | "success" | "primary";
|
||||
title?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
variant?: "solid" | "outline" | "soft" | "subtle";
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
type: "primary",
|
||||
variant: "soft",
|
||||
});
|
||||
|
||||
// Map type to Nuxt UI 3 color
|
||||
const color = computed<AlertColor>(() => {
|
||||
const colorMap: Record<string, AlertColor> = {
|
||||
info: "info",
|
||||
warning: "warning",
|
||||
error: "error",
|
||||
success: "success",
|
||||
primary: "primary",
|
||||
};
|
||||
return colorMap[props.type || "primary"] || "primary";
|
||||
});
|
||||
</script>
|
||||
20
app/components/mdc/List.vue
Normal file
20
app/components/mdc/List.vue
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<div class="my-4">
|
||||
<ul v-if="!ordered" class="list-disc list-inside space-y-2 prose prose-lg dark:prose-invert">
|
||||
<slot />
|
||||
</ul>
|
||||
<ol v-else class="list-decimal list-inside space-y-2 prose prose-lg dark:prose-invert">
|
||||
<slot />
|
||||
</ol>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
ordered?: boolean
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
ordered: false
|
||||
})
|
||||
</script>
|
||||
|
|
@ -5,14 +5,24 @@
|
|||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex items-center">
|
||||
<NuxtLink to="/" class="text-xl font-bold text-gray-900 dark:text-white">
|
||||
Wiki.GhostGuild
|
||||
<NuxtLink
|
||||
to="/"
|
||||
class="text-xl font-bold text-gray-900 dark:text-white"
|
||||
>
|
||||
Ghost Guild Wiki
|
||||
</NuxtLink>
|
||||
<div class="ml-10 flex space-x-4">
|
||||
<NuxtLink to="/articles" class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white px-3 py-2 rounded-md">
|
||||
<NuxtLink
|
||||
to="/articles"
|
||||
class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white px-3 py-2 rounded-md"
|
||||
>
|
||||
Articles
|
||||
</NuxtLink>
|
||||
<NuxtLink v-if="isAuthenticated" to="/articles/new" class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white px-3 py-2 rounded-md">
|
||||
<NuxtLink
|
||||
v-if="isAuthenticated"
|
||||
to="/articles/new"
|
||||
class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white px-3 py-2 rounded-md"
|
||||
>
|
||||
New Article
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
|
@ -20,12 +30,21 @@
|
|||
|
||||
<div class="flex items-center space-x-4">
|
||||
<div v-if="isAuthenticated" class="flex items-center space-x-4">
|
||||
<span class="text-gray-700 dark:text-gray-300">{{ user?.displayName }}</span>
|
||||
<button @click="logout" class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white">
|
||||
<span class="text-gray-700 dark:text-gray-300">{{
|
||||
user?.displayName
|
||||
}}</span>
|
||||
<button
|
||||
@click="logout"
|
||||
class="text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
<button v-else @click="login" class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700">
|
||||
<button
|
||||
v-else
|
||||
@click="login"
|
||||
class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -41,5 +60,5 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
const { user, isAuthenticated, login, logout } = useAuth()
|
||||
</script>
|
||||
const { user, isAuthenticated, login, logout } = useAuth();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -83,9 +83,10 @@
|
|||
</div>
|
||||
|
||||
<!-- Article Body -->
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<ContentRenderer :value="article" />
|
||||
</div>
|
||||
<ContentRenderer
|
||||
:value="article"
|
||||
class="prose prose-lg prose-gray dark:prose-invert max-w-none"
|
||||
/>
|
||||
|
||||
<!-- Tags -->
|
||||
<div
|
||||
|
|
@ -122,25 +123,13 @@
|
|||
const route = useRoute();
|
||||
const slug = route.params.slug;
|
||||
|
||||
const getArticleSlug = (article) => {
|
||||
if (!article) return "";
|
||||
const candidate =
|
||||
article.slug ||
|
||||
article.stem ||
|
||||
article._path ||
|
||||
article._id ||
|
||||
article.id ||
|
||||
"";
|
||||
const segments = candidate.split("/").filter(Boolean);
|
||||
return segments[segments.length - 1] || "";
|
||||
};
|
||||
|
||||
// Fetch article from Nuxt Content
|
||||
const { data: article, pending } = await useAsyncData(
|
||||
`article-${slug}`,
|
||||
async () => {
|
||||
// Query for the specific article by stem (filename without extension)
|
||||
const articles = await queryCollection("articles").all();
|
||||
return articles.find((a) => getArticleSlug(a) === slug);
|
||||
return articles.find((a) => a.stem === slug);
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@
|
|||
{{ article.title }}
|
||||
</NuxtLink>
|
||||
|
||||
<p class="text-gray-600 dark:text-gray-400 mt-2">
|
||||
<p
|
||||
class="text-gray-600 dark:text-gray-400 mt-2 font-serif text-lg leading-relaxed"
|
||||
>
|
||||
{{ article.description }}
|
||||
</p>
|
||||
|
||||
|
|
@ -117,20 +119,14 @@ const getArticleTitle = (article) => {
|
|||
// Resolve the correct Nuxt route for an article entry
|
||||
const getArticleSlug = (article) => {
|
||||
if (!article) return "";
|
||||
const candidate =
|
||||
article.slug ||
|
||||
article.stem ||
|
||||
article._path ||
|
||||
article._id ||
|
||||
article.id ||
|
||||
"";
|
||||
const segments = candidate.split("/").filter(Boolean);
|
||||
return segments[segments.length - 1] || "";
|
||||
// stem is the filename without extension
|
||||
return article.stem || "";
|
||||
};
|
||||
|
||||
const getArticlePath = (article) => {
|
||||
if (!article) return "/articles";
|
||||
const slug = getArticleSlug(article);
|
||||
return slug ? `/articles/${slug}` : "/articles";
|
||||
return `/articles/${slug}`;
|
||||
};
|
||||
|
||||
// Filter and search articles
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
<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
|
||||
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">📚 Browse Articles</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Explore our growing collection of guides and resources
|
||||
</p>
|
||||
<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>
|
||||
|
|
@ -32,10 +27,8 @@
|
|||
</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>
|
||||
<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"
|
||||
|
|
@ -56,11 +49,11 @@
|
|||
<div v-else-if="articles?.length" class="space-y-4">
|
||||
<article
|
||||
v-for="article in articles"
|
||||
:key="article.slug"
|
||||
:key="article.stem"
|
||||
class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow"
|
||||
>
|
||||
<NuxtLink
|
||||
:to="`/articles/${article.slug}`"
|
||||
:to="`/articles/${article.stem}`"
|
||||
class="text-xl font-semibold text-blue-600 hover:text-blue-800"
|
||||
>
|
||||
{{ article.title }}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue