157 lines
6.0 KiB
Plaintext
157 lines
6.0 KiB
Plaintext
---
|
|
import "../styles/global.css";
|
|
import Sidebar from "../components/SidebarEdit.astro";
|
|
|
|
const supabaseUrl = import.meta.env.PUBLIC_SUPABASE_URL;
|
|
const supabaseKey = import.meta.env.PUBLIC_SUPABASE_ANON_KEY;
|
|
---
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<title>Prompt Catalog - Edit Prompt</title>
|
|
</head>
|
|
|
|
<body class="font-sans antialiased bg-gray-800 text-gray-100">
|
|
<div
|
|
id="supabase-env"
|
|
data-url={supabaseUrl}
|
|
data-key={supabaseKey}
|
|
hidden
|
|
></div>
|
|
|
|
<div class="border-b p-4">
|
|
<h1 class="text-2xl font-bold">Prompt Catalog - Add New Prompt</h1>
|
|
<p class="text-sm mt-1">Add a new AI prompt to the catalog</p>
|
|
</div>
|
|
|
|
<div class="flex h-screen">
|
|
<Sidebar />
|
|
|
|
<div class="flex-1 flex flex-col overflow-hidden">
|
|
<main class="flex-1 overflow-y-auto p-4">
|
|
<div id="edit-root">Loading...</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm';
|
|
|
|
const env = document.getElementById('supabase-env').dataset;
|
|
const supabase = createClient(env.url, env.key);
|
|
const slug = new URLSearchParams(window.location.search).get('slug');
|
|
|
|
const root = document.getElementById('edit-root');
|
|
|
|
if (!slug) {
|
|
root.innerHTML = `<p class="text-red-600 font-medium">❌ No slug provided.</p>`;
|
|
} else {
|
|
const { data, error } = await supabase
|
|
.from('prompts')
|
|
.select('*')
|
|
.eq('slug', slug)
|
|
.limit(1);
|
|
|
|
const prompt = data?.[0];
|
|
|
|
if (error || !prompt) {
|
|
root.innerHTML = `<p class="text-red-600 font-medium">❌ Prompt not found or error loading it.</p>`;
|
|
} else {
|
|
root.innerHTML = `
|
|
<form id="edit-form" class="space-y-4">
|
|
<input type="hidden" name="slug" value="${prompt.slug}" />
|
|
|
|
<div>
|
|
<label for="title" class="block text-md font-semibold mb-1">Title</label>
|
|
<input name="title" id="title" value="${prompt.title}" required class="border p-2 w-full rounded" />
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<div>
|
|
<label for="type" class="block text-md font-semibold mb-1">Type</label>
|
|
<select name="type" id="type" required class="border p-2 w-full rounded">
|
|
<option value="System" ${prompt.type === 'System' ? 'selected' : ''}>System</option>
|
|
<option value="Task" ${prompt.type === 'Task' ? 'selected' : ''}>Task</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="tags" class="block text-md font-semibold mb-1">Tags (comma-separated)</label>
|
|
<input name="tags" id="tags" value="${(prompt.tags ?? []).join(', ')}" class="border p-2 pt-1 w-full rounded" />
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="description" class="block text-md font-semibold mb-1">Prompt</label>
|
|
<textarea name="description" id="description" rows="6" required class="border p-2 w-full rounded">${prompt.description}</textarea>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="notes" class="block text-md font-semibold mb-1">Description</label>
|
|
<textarea name="notes" id="notes" rows="3" class="border p-2 w-full rounded">${prompt.notes ?? ''}</textarea>
|
|
</div>
|
|
|
|
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors duration-300 cursor-pointer">
|
|
Save Changes
|
|
</button>
|
|
|
|
<div class="flex justify-between items-center pt-4 border-t mt-6">
|
|
<span class="text-lg text-red-400 font-bold">Be careful! Deletion is permanent.</span>
|
|
<button
|
|
id="delete-btn"
|
|
type="button"
|
|
class="bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition-colors duration-300 cursor-pointer"
|
|
>
|
|
Delete Prompt
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div id="success" class="text-green-600 mt-4 hidden">Prompt Updated.</div>
|
|
<div id="error" class="text-red-600 mt-4 hidden"></div>
|
|
`;
|
|
|
|
document.getElementById('edit-form').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const formData = new FormData(e.target);
|
|
const payload = {
|
|
title: formData.get('title'),
|
|
type: formData.get('type'),
|
|
description: formData.get('description'),
|
|
tags: formData.get('tags')?.split(',').map(t => t.trim()).filter(Boolean),
|
|
notes: formData.get('notes')
|
|
};
|
|
|
|
const { error: updateError } = await supabase
|
|
.from('prompts')
|
|
.update(payload)
|
|
.eq('slug', slug);
|
|
|
|
document.getElementById('success').style.display = updateError ? 'none' : 'block';
|
|
document.getElementById('error').innerText = updateError?.message || '';
|
|
document.getElementById('error').style.display = updateError ? 'block' : 'none';
|
|
});
|
|
|
|
document.getElementById('delete-btn').addEventListener('click', async () => {
|
|
const confirmed = window.confirm("Are you sure you want to delete this prompt? This cannot be undone.");
|
|
|
|
if (!confirmed) return;
|
|
|
|
const { error: deleteError } = await supabase
|
|
.from('prompts')
|
|
.delete()
|
|
.eq('slug', slug);
|
|
|
|
if (deleteError) {
|
|
document.getElementById('error').innerText = deleteError.message;
|
|
document.getElementById('error').style.display = 'block';
|
|
} else {
|
|
window.location.href = '/';
|
|
}
|
|
});
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|