Add complete edit functionality for sermons with update API endpoint and enhanced Bible reference management

This commit is contained in:
2025-10-01 23:00:51 -04:00
parent 441a7af81b
commit 4b2ae9482b
3 changed files with 154 additions and 20 deletions

View File

@@ -20,13 +20,13 @@
<main class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<!-- Manage Existing Sermons Section -->
<div class="bg-white shadow-lg rounded-lg p-8 mb-8">
<h2 class="text-2xl font-bold text-gray-900 mb-6">Manage Existing Sermons</h2>
<h2 class="text-2xl font-bold text-gray-900 mb-6">Select Sermon to Manage</h2>
<div v-if="allSermons && allSermons.length > 0" class="space-y-4">
<div class="flex gap-4 items-end">
<div class="flex-1">
<label for="sermon-select" class="block text-sm font-medium text-gray-700 mb-2">
Select Sermon to Delete
Choose a Sermon
</label>
<select
id="sermon-select"
@@ -39,13 +39,21 @@
</option>
</select>
</div>
<button
type="button"
@click="handleEdit"
:disabled="!selectedSermonId"
class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
>
Edit
</button>
<button
type="button"
@click="handleDelete"
:disabled="!selectedSermonId || deleting"
class="px-6 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
>
{{ deleting ? 'Deleting...' : 'Delete Sermon' }}
{{ deleting ? 'Deleting...' : 'Delete' }}
</button>
</div>
@@ -62,9 +70,21 @@
</div>
</div>
<!-- Create New Sermon Form -->
<!-- Create/Edit Sermon Form -->
<form @submit.prevent="handleSubmit" class="bg-white shadow-lg rounded-lg p-8 space-y-8">
<h2 class="text-2xl font-bold text-gray-900">Create New Sermon</h2>
<div class="flex items-center justify-between">
<h2 class="text-2xl font-bold text-gray-900">
{{ editingSermonId ? 'Edit Sermon' : 'Create New Sermon' }}
</h2>
<button
v-if="editingSermonId"
type="button"
@click="cancelEdit"
class="text-sm text-gray-600 hover:text-gray-800"
>
Cancel Edit
</button>
</div>
<!-- Basic Info -->
<div class="space-y-6">
<div>
@@ -202,7 +222,7 @@
:disabled="loading"
class="flex-1 py-3 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50"
>
{{ loading ? 'Creating...' : 'Create Sermon' }}
{{ loading ? (editingSermonId ? 'Updating...' : 'Creating...') : (editingSermonId ? 'Update Sermon' : 'Create Sermon') }}
</button>
<NuxtLink
to="/"
@@ -231,6 +251,7 @@ const deleteSuccess = ref('')
const deleting = ref(false)
// Create sermon form state
const editingSermonId = ref<number | null>(null)
const bibleReferences = ref([{ version: 'ESV', reference: '', text: '' }])
const formData = ref({
date: '',
@@ -269,21 +290,33 @@ async function handleSubmit() {
)
const bible_references = JSON.stringify(validReferences)
await $fetch('/api/sermons', {
method: 'POST',
body: {
slug,
title: formData.value.title,
date: formData.value.date,
bible_references,
personal_appliance: formData.value.personal_appliance,
pastors_challenge: formData.value.pastors_challenge
}
})
const body = {
slug,
title: formData.value.title,
date: formData.value.date,
bible_references,
personal_appliance: formData.value.personal_appliance,
pastors_challenge: formData.value.pastors_challenge
}
success.value = 'Sermon created successfully!'
if (editingSermonId.value) {
// Update existing sermon
await $fetch(`/api/sermons/update/${editingSermonId.value}`, {
method: 'PUT',
body
})
success.value = 'Sermon updated successfully!'
} else {
// Create new sermon
await $fetch('/api/sermons', {
method: 'POST',
body
})
success.value = 'Sermon created successfully!'
}
// Reset form
editingSermonId.value = null
formData.value = {
date: '',
title: '',
@@ -292,17 +325,60 @@ async function handleSubmit() {
}
bibleReferences.value = [{ version: 'ESV', reference: '', text: '' }]
// Refresh sermon list
await refreshSermons()
// Redirect after 2 seconds
setTimeout(() => {
navigateTo('/')
}, 2000)
} catch (e: any) {
error.value = e.data?.message || 'Failed to create sermon'
error.value = e.data?.message || `Failed to ${editingSermonId.value ? 'update' : 'create'} sermon`
} finally {
loading.value = false
}
}
function cancelEdit() {
editingSermonId.value = null
formData.value = {
date: '',
title: '',
personal_appliance: '',
pastors_challenge: ''
}
bibleReferences.value = [{ version: 'ESV', reference: '', text: '' }]
}
function handleEdit() {
if (!selectedSermonId.value) return
const sermon = allSermons.value?.find((s: any) => s.id === parseInt(selectedSermonId.value))
if (!sermon) return
// Set editing mode
editingSermonId.value = sermon.id
// Load sermon data into form
formData.value = {
date: sermon.date,
title: sermon.title,
personal_appliance: sermon.personal_appliance,
pastors_challenge: sermon.pastors_challenge
}
// Parse and load Bible references
try {
bibleReferences.value = JSON.parse(sermon.bible_references)
} catch {
// Fallback for old format
bibleReferences.value = [{ version: 'ESV', reference: sermon.bible_references, text: '' }]
}
// Scroll to form
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' })
}
async function handleDelete() {
if (!selectedSermonId.value) return

View File

@@ -14,7 +14,7 @@
to="/admin"
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 font-medium text-sm"
>
Create New Sermon
Manage Sermons
</NuxtLink>
<button
@click="handleLogout"

View File

@@ -0,0 +1,58 @@
import { isAuthenticated } from '~/server/utils/auth'
import { getDatabase } from '~/server/utils/database'
export default defineEventHandler(async (event) => {
// Check authentication
if (!isAuthenticated(event)) {
throw createError({
statusCode: 401,
message: 'Unauthorized'
})
}
const id = getRouterParam(event, 'id')
if (!id) {
throw createError({
statusCode: 400,
message: 'Sermon ID is required'
})
}
const body = await readBody(event)
const { slug, title, date, bible_references, personal_appliance, pastors_challenge } = body
if (!slug || !title || !date || !bible_references || !personal_appliance || !pastors_challenge) {
throw createError({
statusCode: 400,
message: 'All fields are required'
})
}
try {
const db = getDatabase()
const result = db.prepare(`
UPDATE sermons
SET slug = ?, title = ?, date = ?, bible_references = ?,
personal_appliance = ?, pastors_challenge = ?
WHERE id = ?
`).run(slug, title, date, bible_references, personal_appliance, pastors_challenge, parseInt(id))
if (result.changes === 0) {
throw createError({
statusCode: 404,
message: 'Sermon not found'
})
}
return {
success: true,
message: 'Sermon updated successfully'
}
} catch (error: any) {
throw createError({
statusCode: 500,
message: error.message || 'Failed to update sermon'
})
}
})