added availability changing to events view

This commit is contained in:
z1glr
2025-01-24 12:35:05 +00:00
parent c1020d26b2
commit ea3e4573b3
10 changed files with 207 additions and 71 deletions

View File

@@ -1,5 +1,5 @@
import MyEvents from "./MyEvents";
import PengingEvents from "./PendingEvents";
import PendingEvents from "./PendingEvents";
export default function Overview() {
return (
@@ -12,7 +12,7 @@ export default function Overview() {
<h1 className="mb-4 mt-8 text-center text-4xl lg:mt-0">
Pending Events
</h1>
<PengingEvents />
<PendingEvents />
</div>
</div>
);

View File

@@ -1,17 +1,12 @@
"use client";
import AvailabilityChip from "@/components/AvailabilityChip";
import AvailabilitySelector from "@/components/Event/AvailabilitySelector";
import Event from "@/components/Event/Event";
import { apiCall, getAvailabilities } from "@/lib";
import { BaseEvent } from "@/Zustand";
import { Select, SelectItem } from "@heroui/react";
import { apiCall } from "@/lib";
import { EventAvailability } from "@/Zustand";
import { useAsyncList } from "@react-stately/data";
type EventAvailability = BaseEvent & {
availability: number;
};
export default function PengingEvents() {
export default function PendingEvents() {
// get the events the user hasn't yet inserted his availability for
const events = useAsyncList({
async load() {
@@ -32,56 +27,11 @@ export default function PengingEvents() {
},
});
// the individual, selectable availabilities
const availabilities = useAsyncList({
async load() {
return {
items: (await getAvailabilities()).filter((a) => a.enabled),
};
},
});
async function setAvailability(eventID: number, availabilityID: number) {
await apiCall(
"PUT",
"events/user/availability",
{ eventID },
availabilityID,
);
}
return (
<div className="flex justify-center gap-4">
{events.items.map((e) => (
<Event key={e.eventID} event={e}>
<Select
items={availabilities.items}
label="Availability"
variant="bordered"
className="mt-auto"
isMultiline
renderValue={(availability) => (
<div>
{availability.map((a) =>
!!a.data ? (
<AvailabilityChip key={a.key} availability={a.data} />
) : null,
)}
</div>
)}
onSelectionChange={(a) =>
setAvailability(e.eventID, parseInt(a.anchorKey ?? ""))
}
>
{(availability) => (
<SelectItem
key={availability.availabilityID}
textValue={availability.availabilityName}
>
<AvailabilityChip availability={availability} />
</SelectItem>
)}
</Select>
<AvailabilitySelector event={e} className="mt-auto" />
</Event>
))}
</div>

View File

@@ -3,23 +3,31 @@ import AddEvent from "@/components/Event/AddEvent";
import AssignmentTable from "@/components/Event/AssignmentTable";
import Event from "@/components/Event/Event";
import { apiCall } from "@/lib";
import zustand, { EventData } from "@/Zustand";
import zustand, { EventDataWithAvailability } from "@/Zustand";
import { Add } from "@carbon/icons-react";
import { Button } from "@heroui/react";
import { Button, Tab, Tabs } from "@heroui/react";
import { useAsyncList } from "@react-stately/data";
import { useState } from "react";
import AvailabilitySelector from "@/components/Event/AvailabilitySelector";
export default function Events() {
const [showAddItemDialogue, setShowAddItemDialogue] = useState(false);
const admin = zustand((state) => state.user?.admin);
const [filter, setFilter] = useState<string | number>("");
const events = useAsyncList<EventData>({
const user = zustand((state) => state.user);
const events = useAsyncList({
async load() {
const result = await apiCall<EventData[]>("GET", "events/assignments");
const result = await apiCall<EventDataWithAvailability[]>(
"GET",
"events/user/assignmentAvailability",
);
if (result.ok) {
const data = await result.json();
console.debug(data);
return {
items: data,
};
@@ -31,20 +39,52 @@ export default function Events() {
},
});
function showEvent(event: EventDataWithAvailability): boolean {
switch (filter) {
case "assigned":
return event.tasks.some((t) => {
return t.userName === user?.userName;
});
case "pending":
return event.availability === null;
default:
return true;
}
}
return (
<div className="relative flex-1">
<h2 className="mb-4 text-center text-4xl">Upcoming Events</h2>
<div className="relative flex flex-1 flex-col gap-4">
<h2 className="text-center text-4xl">Upcoming Events</h2>
<Tabs
selectedKey={filter}
onSelectionChange={setFilter}
color="primary"
className="mx-auto"
>
<Tab key="all" title="All" />
<Tab key="pending" title="Pending" />
<Tab key="assigned" title="Assigned" />
</Tabs>
<div className="flex flex-wrap justify-center gap-4">
{events.items.map((ee, ii) => (
<Event key={ii} event={ee}>
{events.items.filter(showEvent).map((e) => (
<Event key={e.eventID} event={e}>
<div className="mt-auto">
<AssignmentTable tasks={ee.tasks} />
<AvailabilitySelector
event={e}
className="mb-2"
startSelection={e.availability}
/>
<AssignmentTable tasks={e.tasks} />
</div>
</Event>
))}
</div>
{admin ? (
{user?.admin ? (
<>
<Button
color="primary"