Files
yphsalumni.org/app/pages/events/[slug].vue
xiaomai dbd1abdc1c feat(content): add draft support for content collections
This commit introduces a draft system for the 'events' and 'news' collections. A `draft` boolean field has been added to the content schema, and frontend queries are now updated to only fetch and
display content where `draft` is `false`. This allows content to be created and saved without being publicly visible, improving the publishing workflow.
2025-11-15 17:58:00 +08:00

57 lines
2.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="min-h-screen">
<section class="relative py-16 px-4 sm:px-6 lg:px-8">
<div class="container mx-auto max-w-4xl">
<!-- 内容卡片 -->
<div class="relative">
<!-- 卡片装饰边框浅色渐变 -->
<!-- <div class="absolute inset-0 bg-linear-to-r from-blue-100 to-purple-100 rounded-2xl blur-sm"></div> -->
<div class="relative rounded-xl border border-gray-200 shadow-xl overflow-hidden">
<!-- 顶部装饰条明亮渐变 -->
<div class="h-1 bg-linear-to-r from-blue-400 via-purple-400 to-cyan-400"></div>
<div class="p-8 sm:p-10 lg:p-12">
<!-- 内容渲染器 -->
<div class="prose prose-lg max-w-none text-gray-800">
<ContentRenderer :value="event ?? {}">
<template #empty>
<div class="text-center py-16">
<div class="inline-flex items-center justify-center w-16 h-16 bg-blue-100 rounded-full mb-4">
<svg class="w-8 h-8 text-blue-500 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4">
</circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
</div>
<p class="text-gray-700 text-lg font-medium">内容加载中...</p>
<p class="text-gray-400 text-sm mt-2">请稍等片刻</p>
</div>
</template>
</ContentRenderer>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script lang="ts" setup>
const route = useRoute()
const { data: event } = await useAsyncData('event-detail', () =>
queryCollection('events')
.path(`/events/${route.params.slug}`)
.first()
)
useHead({
title: event.value?.title
})
</script>
<style scoped></style>