Implement DTOs, add managed state for schedule, export to txt

This commit is contained in:
2026-01-11 22:28:10 +02:00
parent 53f8695572
commit 92a9c6d704
11 changed files with 254 additions and 70 deletions

View File

@@ -1,6 +1,4 @@
<script lang="ts">
import type { CalendarDate } from "@internationalized/date";
import { trace } from "@tauri-apps/plugin-log";
import { Calendar, Popover } from "bits-ui";
import { Button } from "$lib/components/ui/button/index.js";
import { rota, steps } from "../../state.svelte.js";

View File

@@ -321,7 +321,7 @@
<div class="flex flex-col items-center space-y-2 px-4">
<p class="text-[10px] font-black tracking-widest text-zinc-500 uppercase">Shift Types</p>
<div class="flex gap-1">
{#each ["OpenAsFirst", "OpenAsSecond", "Closed"] as type}
{#each ["Closed", "OpenFirst", "OpenSecond"] as type}
{@const active = resident.allowedTypes.includes(type)}
<button
type="button"
@@ -348,14 +348,14 @@
Reduced Workload
</p>
<button
onclick={() => (resident.hasReducedLoad = !resident.hasReducedLoad)}
onclick={() => (resident.reducedLoad = !resident.reducedLoad)}
class="flex items-center gap-2 rounded-lg border px-3 py-1 transition-all hover:border-blue-200 hover:bg-white
{resident.hasReducedLoad
{resident.reducedLoad
? 'border-green-200 bg-green-50 text-green-700'
: 'border-zinc-200 bg-white text-zinc-500'}"
>
<div
class="size-2 rounded-full {resident.hasReducedLoad
class="size-2 rounded-full {resident.reducedLoad
? 'animate-pulse bg-green-500'
: 'bg-zinc-300'}"
></div>

View File

@@ -1,8 +1,14 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button/index.js";
import { rota, steps } from "../../state.svelte.js";
import { invoke } from "@tauri-apps/api/core";
import { type MonthlyScheduleDTO, rota, steps, type ShiftPosition } from "../../state.svelte.js";
function getResidentName(day: number, slot: number) {
function getResidentName(day: number, pos: ShiftPosition) {
const residentId = rota.solution[`${day}-${pos}`];
const r = rota.findResident(residentId);
if (r) return r.name;
// check for manual
const assignedResidents = rota.residents.filter((resident) =>
resident.manualShifts.some(
(shift) =>
@@ -12,6 +18,13 @@
)
);
let slot;
if (pos == "First") {
slot = 1;
} else {
slot = 2;
}
const resident = assignedResidents[slot - 1];
return resident ? resident.name : "-";
}
@@ -21,23 +34,31 @@
return day % 2 === 0 ? 1 : 2;
}
//TODO: invoke rust?
// const resident = {
// id: crypto.randomUUID(),
// name: "",
// negativeShifts: [] as CalendarDate[],
// manualShifts: [] as CalendarDate[]
// };
async function generate() {
let config = rota.toDTO();
console.log(config);
// try {
// let replyFrom = await invoke("add_resident", { resident });
// console.log("Result:", replyFrom);
// residents = [...residents, resident];
// } catch (error) {
// console.error("Error:", error);
// }
try {
let schedule = await invoke<MonthlyScheduleDTO>("generate", { config });
console.log("replyFromGenerate:", schedule);
rota.solution = schedule;
} catch (error) {
console.error("Error:", error);
}
}
async function export_file() {
let config = rota.toDTO();
let schedule = rota.solution;
try {
await invoke("export", { config, schedule });
} catch (error) {
console.error("Error:", error);
}
}
</script>
<div class="mb-6 flex items-center justify-between">
<h2 class="text-2xl font-bold text-zinc-800">{steps[rota.currentStep - 1].title}</h2>
<div class="justify-end">
@@ -78,15 +99,15 @@
onclick={() => "handleCellClick(day, 1)"}
class="w-full overflow-hidden rounded border border-pink-200 bg-pink-50 px-1.5 py-1 text-left text-[10px] font-bold text-pink-600 transition-colors hover:bg-pink-100"
>
{getResidentName(day, 1)}
{getResidentName(day, "First")}
</button>
{/if}
{#if slotCount == 2}
{#if slotCount > 1}
<button
onclick={() => "handleCellClick(day, 2)"}
class="w-full overflow-hidden rounded border border-emerald-200 bg-emerald-50 px-1.5 py-1 text-left text-[10px] font-bold text-emerald-600 transition-colors hover:bg-emerald-100"
>
{getResidentName(day, 2)}
{getResidentName(day, "Second")}
</button>
{/if}
</div>
@@ -99,13 +120,14 @@
<Button
variant="outline"
class="border-zinc-200 bg-white text-zinc-600 shadow-sm transition-all hover:bg-zinc-50 hover:text-zinc-900 active:scale-95"
onclick={() => generate()}
>
Ανακατανομή
</Button>
<Button
onclick={() => "export adasds"}
variant="outline"
class="border-zinc-200 bg-white text-zinc-600 shadow-sm transition-all hover:bg-zinc-50 hover:text-zinc-900 active:scale-95"
onclick={() => export_file()}
>
Εξαγωγή</Button
>

View File

@@ -21,7 +21,7 @@
return day % 2 === 0 ? 1 : 2;
}
</script>
<div class="mb-6 flex items-center justify-between">
<h2 class="text-2xl font-bold text-zinc-800">{steps[rota.currentStep - 1].title}</h2>
<div class="justify-end">