MyFavStuff3/src/pages/admin/edit.astro

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>