add project page
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<template v-if="project">
|
||||
<NuxtLink class="project-card" :to="project?.path">
|
||||
<img :src="project?.logo" :alt="project?.title + '’s cover image'"/>
|
||||
<div class="project-card-content">
|
||||
<h3 :title="project?.title">{{ project?.title }}</h3>
|
||||
<p style="margin-block: 0.25em" :title="project?.description">{{ project?.description }}</p>
|
||||
<p class="post-more-info" :title="useFormatDate(project?.dateUpdated)">📅 {{ useRelativeDate(project?.dateUpdated) }}</p>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const config = useRuntimeConfig();
|
||||
const baseUrl = config.public.baseUrl
|
||||
import { useFormatDate } from '~/composables/formatDate';
|
||||
import { useRelativeDate } from '~/composables/relativeDate';
|
||||
import type { ProjectsCollectionItem } from '@nuxt/content'
|
||||
|
||||
|
||||
|
||||
defineProps<{
|
||||
project: ProjectsCollectionItem
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<section class="post-card-container">
|
||||
<template v-for="project in projects" :key="project.id">
|
||||
<ProjectCard :project="project" />
|
||||
</template>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const route = useRoute();
|
||||
const currentRoute = route.path
|
||||
const props = defineProps<{
|
||||
limit?: number | null
|
||||
}>()
|
||||
const fetchLimit = props.limit ?? undefined
|
||||
const { data: projects } = await useAsyncData(
|
||||
`${currentRoute}-blog`,
|
||||
async () => {
|
||||
let query = queryCollection('projects').order('dateUpdated', 'DESC')
|
||||
if (fetchLimit) {
|
||||
query = query.limit(fetchLimit)
|
||||
}
|
||||
return query.all()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<main>
|
||||
<article v-if="project" class="article">
|
||||
<section class="web-section" aria-labelledby="hero" aria-describedby="hero-desc">
|
||||
<section class="max-w-6xl mx-auto z-[1]">
|
||||
<small class="prose-blog-pretext" aria-hidden="true">You are viewing project:</small>
|
||||
<h1 id="hero" class="font-hero">{{ project?.title }}</h1>
|
||||
<div class="post-cover">
|
||||
<section class="w-full">
|
||||
<p id="hero-desc" class="font-hero-desc">{{ project?.description }}</p>
|
||||
</section>
|
||||
<img :width="512" class="img-cover" :src="project?.logo" />
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="web-section web-section" aria-labelledby="project-content" aria-describedby="project-content-desc">
|
||||
<div class="prose">
|
||||
<ContentRenderer v-if="project" :value="project"/>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article v-else class="article">
|
||||
<section class="web-section" aria-labelledby="hero" aria-describedby="hero-desc">
|
||||
<section class="max-w-6xl mx-auto z-[1]">
|
||||
<small class="prose-blog-pretext" aria-hidden="true">An error occurred:</small>
|
||||
<h1 id="hero" class="font-hero">Project not found!</h1>
|
||||
<div class="post-cover">
|
||||
<section class="w-full">
|
||||
<p id="hero-desc" class="font-hero-desc">Check the URL; there might be a misspelling, or the project may not actually exist.</p>
|
||||
<NuxtLink class="btn" to="/posts">All posts</NuxtLink>
|
||||
</section>
|
||||
<img :width="512" class="img-cover" src="https://files.thawia.ng/files/assets/zUJfK8p1i.webp" />
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="web-section web-section" aria-labelledby="post-content" aria-describedby="post-content-desc">
|
||||
<div class="prose">
|
||||
<ContentRenderer v-if="post" :value="post"/>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const config = useRuntimeConfig();
|
||||
const baseUrl = config.public.baseUrl
|
||||
const route = useRoute()
|
||||
|
||||
// const { data: post } = await useAsyncData(route.path, () => {
|
||||
// return queryCollection('posts').path(route.path).first()
|
||||
// })
|
||||
|
||||
const { data: project } = await useAsyncData(() => queryCollection('projects').path(route.path).first())
|
||||
|
||||
const ogUrl = config.public.baseUrl + route.path
|
||||
useSeoMeta({
|
||||
title: project.value?.title,
|
||||
description: project.value?.description || 'A project without description',
|
||||
keywords: project.value?.tags?.join(', ') || 'project',
|
||||
ogTitle: project.value?.title + ' / ' + config.public.siteName,
|
||||
ogDescription: project.value?.description,
|
||||
ogType: 'article',
|
||||
ogUrl: ogUrl,
|
||||
ogImage: project.value?.logo || undefined,
|
||||
ogSiteName: config.public.siteName,
|
||||
twitterCard: 'summary_large_image',
|
||||
twitterTitle: project.value?.title + ' / ' + config.public.siteName,
|
||||
twitterDescription: project.value?.description,
|
||||
twitterImage: project.value?.logo || undefined,
|
||||
twitterSite: '@' + config.public.twitterUsername
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.katex-html {
|
||||
display: none;
|
||||
}
|
||||
.katex-mathml {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<main>
|
||||
<article class="article">
|
||||
<section class="web-section" aria-labelledby="hero" aria-describedby="hero-desc">
|
||||
<h1 id="hero" class="font-hero">{{ TITLE }}</h1>
|
||||
<p id="hero-desc" class="font-hero-desc">{{ DESC }}</p>
|
||||
</section>
|
||||
<section class="web-section" aria-labelledby="latest-projects">
|
||||
<h2 class="web-title" id="latest-posts">All Projects</h2>
|
||||
<ProjectsArticleList/>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const config = useRuntimeConfig();
|
||||
const TITLE = "Projects"
|
||||
const DESC = "My projects I spent my time on instead of playing games, this includes non-programming stuff too."
|
||||
|
||||
useSeoMeta({
|
||||
title: TITLE,
|
||||
description: DESC,
|
||||
ogTitle: TITLE + ' / ' + config.public.siteName,
|
||||
ogDescription: DESC,
|
||||
ogSiteName: config.public.siteName,
|
||||
twitterCard: 'summary_large_image',
|
||||
twitterTitle: TITLE + ' / ' + config.public.siteName,
|
||||
twitterDescription: DESC,
|
||||
twitterSite: config.public.twitterUsername
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user