144 lines
4.1 KiB
Svelte
144 lines
4.1 KiB
Svelte
<script>
|
|
import { onMount } from "svelte";
|
|
import { getAllSubstitutions, createSubstitution } from "../../lib/api";
|
|
import { addToast, loading } from "../../lib/stores";
|
|
|
|
let substitutions = [];
|
|
let newSub = { date: "", startTime: "", endTime: "", title: "", notes: "" };
|
|
|
|
onMount(loadData);
|
|
|
|
async function loadData() {
|
|
try {
|
|
substitutions = await getAllSubstitutions();
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function handleCreate() {
|
|
if (!newSub.date || !newSub.startTime || !newSub.title) {
|
|
addToast("Bitte Pflichtfelder ausfüllen", "warning");
|
|
return;
|
|
}
|
|
try {
|
|
await createSubstitution(newSub);
|
|
addToast("Vertretung ausgeschrieben", "success");
|
|
newSub = { date: "", startTime: "", endTime: "", title: "", notes: "" };
|
|
await loadData();
|
|
} catch (e) {
|
|
addToast(e.message, "error");
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
<div class="card bg-base-100 shadow-xl border border-base-200 h-fit">
|
|
<div class="card-body">
|
|
<h3 class="card-title text-lg mb-4">Neue Vertretung ausschreiben</h3>
|
|
|
|
<div class="space-y-4">
|
|
<div class="form-control">
|
|
<label class="label">Titel / Klasse</label>
|
|
<input
|
|
type="text"
|
|
class="input input-bordered"
|
|
placeholder="z.B. Mathe 4a"
|
|
bind:value={newSub.title}
|
|
/>
|
|
</div>
|
|
|
|
<div class="form-control">
|
|
<label class="label">Datum</label>
|
|
<input
|
|
type="date"
|
|
class="input input-bordered"
|
|
bind:value={newSub.date}
|
|
/>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-2">
|
|
<div class="form-control">
|
|
<label class="label">Von</label>
|
|
<input
|
|
type="time"
|
|
class="input input-bordered"
|
|
bind:value={newSub.startTime}
|
|
/>
|
|
</div>
|
|
<div class="form-control">
|
|
<label class="label">Bis</label>
|
|
<input
|
|
type="time"
|
|
class="input input-bordered"
|
|
bind:value={newSub.endTime}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-control">
|
|
<label class="label">Notizen (Optional)</label>
|
|
<textarea
|
|
class="textarea textarea-bordered"
|
|
placeholder="z.B. Arbeitsblätter im Fach..."
|
|
bind:value={newSub.notes}
|
|
></textarea>
|
|
</div>
|
|
|
|
<button
|
|
class="btn btn-primary w-full mt-4"
|
|
on:click={handleCreate}
|
|
disabled={$loading}
|
|
>
|
|
Veröffentlichen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="lg:col-span-2">
|
|
<h3 class="font-bold text-xl mb-4">Übersicht</h3>
|
|
<div
|
|
class="overflow-x-auto bg-base-100 rounded-lg shadow border border-base-200"
|
|
>
|
|
<table class="table w-full">
|
|
<thead>
|
|
<tr>
|
|
<th>Datum</th>
|
|
<th>Zeit</th>
|
|
<th>Titel</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each substitutions as s}
|
|
<tr class="hover">
|
|
<td class="whitespace-nowrap font-mono text-sm">{s.date}</td>
|
|
<td>{s.start_time} - {s.end_time}</td>
|
|
<td>
|
|
<div class="font-bold">{s.title}</div>
|
|
{#if s.notes}<div class="text-xs opacity-60 truncate max-w-xs">
|
|
{s.notes}
|
|
</div>{/if}
|
|
</td>
|
|
<td>
|
|
{#if s.taken_by_user_id}
|
|
<span class="badge badge-success gap-2"> Übernommen </span>
|
|
<div class="text-xs mt-1 opacity-70">
|
|
von {s.taken_by_username}
|
|
</div>
|
|
{:else}
|
|
<span class="badge badge-warning badge-outline">Offen</span>
|
|
{/if}
|
|
</td>
|
|
</tr>
|
|
{:else}
|
|
<tr
|
|
><td colspan="4" class="text-center opacity-50 py-8"
|
|
>Keine Einträge</td
|
|
></tr
|
|
>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|