137 lines
4.6 KiB
Plaintext
137 lines
4.6 KiB
Plaintext
---
|
|
import SiteLayout from '../../components/SiteLayout.astro';
|
|
|
|
// In a real app, you'd check authentication here
|
|
---
|
|
|
|
<SiteLayout title="Edit Content">
|
|
<div class="container mx-auto px-4 py-8">
|
|
<div class="mb-6 flex justify-between items-center">
|
|
<h1 class="text-3xl font-bold">Edit Book</h1>
|
|
<a href="/admin" class="text-blue-500 hover:underline">Back to Dashboard</a>
|
|
</div>
|
|
|
|
<div class="bg-white shadow rounded-lg p-6">
|
|
<form id="edit-form" class="space-y-6">
|
|
<div>
|
|
<label for="filename" class="block text-sm font-medium text-gray-700">Filename</label>
|
|
<input type="text" id="filename" name="filename" required
|
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
|
|
<p class="text-xs text-gray-500 mt-1">Include .md extension (e.g., my-book.md)</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="content" class="block text-sm font-medium text-gray-700">Content</label>
|
|
<textarea id="content" name="content" rows="15" required
|
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"></textarea>
|
|
</div>
|
|
|
|
<div>
|
|
<button type="submit"
|
|
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
|
Save
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="mt-8">
|
|
<h2 class="text-xl font-semibold mb-4">Preview</h2>
|
|
<div id="preview" class="bg-white shadow rounded-lg p-6 prose max-w-none">
|
|
<p>Type in the editor to see a preview...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Get query params
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const fileParam = urlParams.get('file');
|
|
|
|
const filenameInput = document.getElementById('filename');
|
|
const contentTextarea = document.getElementById('content');
|
|
const previewDiv = document.getElementById('preview');
|
|
const editForm = document.getElementById('edit-form');
|
|
|
|
// Base API URL - adapt for production vs. development
|
|
const getApiUrl = (path) => {
|
|
return window.location.hostname === 'localhost'
|
|
? `http://localhost:3000/api/${path}`
|
|
: `/api/${path}`;
|
|
};
|
|
|
|
// Load existing content if editing
|
|
async function loadContent() {
|
|
if (!fileParam) return;
|
|
|
|
try {
|
|
filenameInput.value = fileParam;
|
|
filenameInput.readOnly = true; // Don't allow changing filename if editing
|
|
|
|
const response = await fetch(getApiUrl(`content/${fileParam}`), {
|
|
headers: {
|
|
'Authorization': 'Basic ' + btoa('admin:password') // In production, use proper auth
|
|
}
|
|
});
|
|
|
|
if (!response.ok) throw new Error('Failed to load content');
|
|
|
|
const data = await response.json();
|
|
contentTextarea.value = data.content;
|
|
updatePreview();
|
|
} catch (error) {
|
|
alert('Error loading content: ' + error.message);
|
|
}
|
|
}
|
|
|
|
// Update preview when content changes
|
|
function updatePreview() {
|
|
// This is a simple preview. For proper Markdown, use a library like marked
|
|
previewDiv.innerHTML = `<pre>${contentTextarea.value}</pre>`;
|
|
}
|
|
|
|
// Save content
|
|
async function saveContent(e) {
|
|
e.preventDefault();
|
|
|
|
const filename = filenameInput.value;
|
|
const content = contentTextarea.value;
|
|
|
|
if (!filename || !content) {
|
|
alert('Filename and content are required');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const isNewFile = !fileParam;
|
|
const url = isNewFile
|
|
? getApiUrl('content')
|
|
: getApiUrl(`content/${filename}`);
|
|
|
|
const response = await fetch(url, {
|
|
method: isNewFile ? 'POST' : 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Basic ' + btoa('admin:password') // In production, use proper auth
|
|
},
|
|
body: JSON.stringify({ filename, content })
|
|
});
|
|
|
|
if (!response.ok) throw new Error('Failed to save content');
|
|
|
|
alert('Content saved successfully!');
|
|
window.location.href = '/admin';
|
|
} catch (error) {
|
|
alert('Error saving content: ' + error.message);
|
|
}
|
|
}
|
|
|
|
// Event listeners
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
loadContent();
|
|
contentTextarea.addEventListener('input', updatePreview);
|
|
editForm.addEventListener('submit', saveContent);
|
|
});
|
|
</script>
|
|
</SiteLayout>
|