diff options
| author | Furkan Sahin <furkan-dev@proton.me> | 2022-07-23 23:38:33 -0500 |
|---|---|---|
| committer | Furkan Sahin <furkan-dev@proton.me> | 2022-07-23 23:38:33 -0500 |
| commit | e4915154c6bb71b3d0fb8da6e971783156548b8e (patch) | |
| tree | 0894a1c35280389e2c7d1067cfcb734712d93c17 /src/components/AssignLabs.svelte | |
| parent | 31530fcb5b881d3ac83f202f0b2c913aba935b8b (diff) | |
Restructure file organization
Diffstat (limited to 'src/components/AssignLabs.svelte')
| -rw-r--r-- | src/components/AssignLabs.svelte | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/components/AssignLabs.svelte b/src/components/AssignLabs.svelte new file mode 100644 index 0000000..6ff006f --- /dev/null +++ b/src/components/AssignLabs.svelte @@ -0,0 +1,151 @@ +<script lang="ts"> + import type PeerTeacher from "../models/PeerTeacher"; + import type Lab from "../models/Lab"; + import { labStore, ptStore } from "../stores"; + import LabBox from "./helpers/LabBox.svelte"; + import PT from "./helpers/PTBox.svelte"; + + let selectedPeerTeacher: PeerTeacher | undefined; + let selectedLab: Lab | undefined; + + $: peerTeachers = [...$ptStore.values()].sort((a, b) => + a.lastname.toUpperCase() === b.lastname.toUpperCase() + ? a.firstname.toUpperCase().localeCompare(b.firstname.toUpperCase()) + : a.lastname.toUpperCase().localeCompare(b.lastname.toUpperCase()) + ); + + $: labs = [...$labStore.values()].sort((a, b) => a.id - b.id); + + $: selectedPtAssignedLabs = [...(selectedPeerTeacher?.labs.values() ?? [])] + .flatMap((labId) => { + const lab = $labStore.get(labId); + return lab === undefined ? [] : [lab]; + }) + .sort((a, b) => a.id - b.id); + + $: unassignedLabs = labs.filter((lab) => !lab.assigned); + + $: compatibleLabs = labs.filter((lab) => + isPTandLabCompatible(lab, selectedPeerTeacher) + ); + + $: compatiblePTs = peerTeachers.filter((pt) => + isPTandLabCompatible(selectedLab, pt) + ); + + function isPTandLabCompatible( + lab: Lab | undefined, + pt: PeerTeacher | undefined + ): boolean { + return ( + pt != undefined && + lab != undefined && + !lab?.assigned && + !pt?.conflictsWith(lab.event) + ); + } + + function updateReactiveDeclarations() { + selectedPeerTeacher = selectedPeerTeacher; + selectedLab = selectedLab; + peerTeachers = peerTeachers; + labs = labs; + } + + function assignLab(id: number) { + const lab = $labStore.get(id); + if (lab === undefined) return; + lab.assigned = true; + selectedPeerTeacher?.labs.add(id); + updateReactiveDeclarations(); + } + + function unassignLab(id: number) { + const lab = $labStore.get(id); + if (lab === undefined) return; + lab.assigned = false; + selectedPeerTeacher?.labs.delete(id); + updateReactiveDeclarations(); + } +</script> + +<div + class="flex-none overflow-hidden flex-col h-[100vh] w-[80vw] px-[2vw] pt-[1vh]" +> + <!-- Top half: 3 Columns --> + <div class="flex flex-row h-[80vh]"> + <!-- PT Box --> + <div class="assign-box rounded-l-xl"> + <!-- PT Header --> + <div class="assign-box-header">Peer Teacher</div> + <!-- PT Body --> + <div class="assign-box-body"> + {#each peerTeachers as pt} + <div + class={compatiblePTs.includes(pt) //selectedPeerTeacher == pt + ? "bg-info text-info-content" // "border-l-8 border-blue-500" + : "bg-base-100 text-base-100-content"} + on:click={() => { + selectedPeerTeacher = pt; + }} + > + <svelte:component this={PT} {pt} /> + </div> + {/each} + </div> + </div> + + <!-- Available Labs --> + <div class="assign-box"> + <div class="assign-box-header">Labs: {labs.length}</div> + <div class="assign-box-body"> + {#each compatibleLabs as lab} + <svelte:component + this={LabBox} + {lab} + iconName="plus-circle" + iconClick={() => { + assignLab(lab.id); + }} + /> + {/each} + </div> + </div> + + <!-- Selected PT's Labs --> + <div class="assign-box rounded-r-xl"> + <div class="assign-box-header"> + {selectedPeerTeacher?.name ?? "PT's Labs"} + </div> + <div class="assign-box-body"> + {#each selectedPtAssignedLabs as lab} + <svelte:component + this={LabBox} + {lab} + iconName="minus-circle" + iconClick={() => { + unassignLab(lab.id); + }} + /> + {/each} + </div> + </div> + </div> + + <!-- Bottom half: Universal unassigned labs --> + <div class="flex flex-col mt-2 text-center"> + <h1>Unassigned Labs: {unassignedLabs.length}</h1> + <ul class="menu menu-horizontal bg-base-100 rounded-box overflow-auto"> + {#each unassignedLabs as lab} + <li + on:click={() => { + selectedLab = lab; + }} + class={selectedLab == lab ? "bg-info text-info-content" : ""} + > + <span>{lab.course} {lab.section}</span> + </li> + {/each} + </ul> + </div> +</div> |
