Starting over
This commit is contained in:
154
pages/[slug].vue
154
pages/[slug].vue
@@ -1,154 +0,0 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-50">
|
||||
<!-- Header -->
|
||||
<header class="bg-white shadow-sm border-b">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center py-4">
|
||||
<div class="flex items-center">
|
||||
<img src="/logos/logo.png" alt="New Life Christian Church" class="logo-image" />
|
||||
<UButton
|
||||
@click="navigateTo('/')"
|
||||
variant="ghost"
|
||||
color="gray"
|
||||
icon="i-heroicons-arrow-left"
|
||||
>
|
||||
Back to Sermons
|
||||
</UButton>
|
||||
</div>
|
||||
<div>
|
||||
<QRCodeButton :url="currentUrl" :title="sermon?.title" @click="showQRModal = $event" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="flex justify-center py-12">
|
||||
<UIcon name="i-heroicons-arrow-path" class="animate-spin h-8 w-8 text-primary" />
|
||||
</div>
|
||||
|
||||
<!-- Sermon Content -->
|
||||
<div v-else-if="sermon">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="text-center">
|
||||
<h1 class="text-3xl font-bold text-gray-900">{{ sermon.title }}</h1>
|
||||
<p class="text-lg text-gray-600 mt-2">
|
||||
{{ formatDate(sermon.date) }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="space-y-8">
|
||||
<!-- Bible References -->
|
||||
<div v-if="sermon.bibleReferences && sermon.bibleReferences.length > 0">
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-4">Bible References</h2>
|
||||
<div class="grid gap-3 md:grid-cols-2">
|
||||
<div
|
||||
v-for="reference in sermon.bibleReferences"
|
||||
:key="reference"
|
||||
class="bg-red-50 border border-red-200 rounded-lg p-4"
|
||||
>
|
||||
<p class="text-red-800 font-medium">{{ reference }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Personal Application -->
|
||||
<div v-if="sermon.personalApplication">
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-4">Personal Application</h2>
|
||||
<UCard class="bg-blue-50 border-blue-200">
|
||||
<p class="text-blue-900 whitespace-pre-wrap">{{ sermon.personalApplication }}</p>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<!-- Pastor's Challenge -->
|
||||
<div v-if="sermon.pastorChallenge">
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-4">Pastor's Challenge</h2>
|
||||
<UCard class="bg-green-50 border-green-200">
|
||||
<p class="text-green-900 whitespace-pre-wrap">{{ sermon.pastorChallenge }}</p>
|
||||
</UCard>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<!-- Not Found -->
|
||||
<div v-else class="text-center py-12">
|
||||
<UIcon name="i-heroicons-exclamation-triangle" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-medium text-gray-900">Sermon not found</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
The sermon you're looking for doesn't exist.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<UButton @click="navigateTo('/')">
|
||||
Back to Sermons
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- QR Code Modal -->
|
||||
<QRCodeModal
|
||||
v-model="showQRModal"
|
||||
:url="currentUrl"
|
||||
:title="sermon?.title"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { format, parseISO } from 'date-fns'
|
||||
|
||||
interface Sermon {
|
||||
id: number
|
||||
title: string
|
||||
date: string
|
||||
slug: string
|
||||
bibleReferences?: string[]
|
||||
personalApplication?: string
|
||||
pastorChallenge?: string
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
const slug = route.params.slug as string
|
||||
|
||||
const sermon = ref<Sermon | null>(null)
|
||||
const loading = ref(true)
|
||||
const showQRModal = ref(false)
|
||||
|
||||
const currentUrl = computed(() => {
|
||||
if (process.client) {
|
||||
return window.location.pathname
|
||||
}
|
||||
return `/${slug}`
|
||||
})
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
try {
|
||||
return format(parseISO(dateString), 'MMMM d, yyyy')
|
||||
} catch {
|
||||
return dateString
|
||||
}
|
||||
}
|
||||
|
||||
const loadSermon = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await $fetch(`/api/sermons/${slug}`)
|
||||
sermon.value = data
|
||||
} catch (error) {
|
||||
console.error('Failed to load sermon:', error)
|
||||
sermon.value = null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (slug) {
|
||||
loadSermon()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user