Add frontend

This commit is contained in:
Sami Abuzakuk
2025-10-11 00:09:31 +02:00
parent aa67ffa704
commit ed33bee7ce
25 changed files with 5061 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
<script lang="ts">
import { updateScript, deleteScript, addLog, deleteLog } from '$lib/api';
import type { Script, Log } from '$lib/api';
import CodeMirror from 'svelte-codemirror-editor';
import { python } from '@codemirror/lang-python';
export let data: { script: Script; logs: Log[] };
let script: Script = data.script;
let logs: Log[] = data.logs;
let updatedTitle: string = script.name || '';
let updatedContent: string = script.script_content || '';
let isEditMode: boolean = false;
let newLogMessage: string = '';
// Notifications are now handled globally via the layout
async function handleUpdateScript() {
if (script) {
try {
const updatedScript = await updateScript(script.id, {
name: updatedTitle,
script_content: updatedContent
});
script = updatedScript;
window.showNotification('success', 'Script updated successfully!');
isEditMode = false;
} catch (err) {
window.showNotification('error', 'Failed to update script. ' + err);
}
}
}
async function handleAddLog() {
if (newLogMessage.trim()) {
try {
const newLog = await addLog(script.id, newLogMessage);
logs = [newLog, ...logs];
newLogMessage = '';
window.showNotification('success', 'Log added successfully!');
} catch (err) {
window.showNotification('error', 'Failed to add log. ' + err);
}
}
}
async function handleDeleteLog(logId: number) {
try {
await deleteLog(script.id, logId);
logs = logs.filter((log) => log.id !== logId);
window.showNotification('success', 'Log deleted successfully!');
} catch (err) {
window.showNotification('error', 'Failed to delete log. ' + err);
}
}
// Delete the script
async function handleDeleteScript() {
if (script) {
try {
await deleteScript(script.id);
window.location.href = '/scripts'; // Redirect to scripts list after deletion
} catch (err) {
window.showNotification('error', 'Failed to delete script. ' + err);
}
}
}
</script>
<main class="p-4">
<!-- Removed local notification container as notifications are now global -->
{#if script}
{#if isEditMode}
<input
type="text"
bind:value={updatedTitle}
required
class="text-2xl font-bold mb-4 w-full p-2 border rounded"
/>
<CodeMirror bind:value={updatedContent} lang={python()} />
<button
class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
on:click={handleUpdateScript}
aria-label="Update the script title and content"
>
Update Script
</button>
<button
class="mt-4 px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"
on:click={() => (isEditMode = false)}
>
Cancel
</button>
{:else}
<a href="/scripts" class="text-blue-500 hover:underline mb-4 inline-block"
>← Return to Scripts</a
>
<h1 class="text-2xl font-bold mb-4">{script.name}</h1>
<pre
class="w-full p-2 border rounded font-mono text-sm bg-gray-100">{script.script_content}</pre>
<button
class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
on:click={() => (isEditMode = true)}
>
Edit Script
</button>
<button
class="mt-4 px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
on:click={handleDeleteScript}
>
Delete Script
</button>
{/if}
{/if}
<section class="mt-8">
<h2 class="text-xl font-bold mb-4">Logs</h2>
<form on:submit|preventDefault={handleAddLog} class="mb-4">
<input
type="text"
bind:value={newLogMessage}
placeholder="Enter new log message"
class="w-full p-2 border rounded mb-2"
required
/>
<button type="submit" class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">
Add Log
</button>
</form>
<ul class="space-y-4">
{#each logs as log (log.id)}
<li class="p-4 border rounded bg-gray-50 flex justify-between items-center">
<div>
<p class="text-sm text-gray-700">{log.message}</p>
<p class="text-xs text-gray-500">{log.created_at}</p>
</div>
<button
class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600"
on:click={() => handleDeleteLog(log.id)}
>
Delete
</button>
</li>
{/each}
</ul>
</section>
</main>
<style>
main {
max-width: 800px;
margin: 0 auto;
}
</style>