added viewing all availabilities in events view
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import AssignmentTable from "@/components/Event/AssignmentTable";
|
||||
import AssignmentGrid from "@/components/Event/AssignmentTable";
|
||||
import Event from "@/components/Event/Event";
|
||||
import Loading from "@/components/Loading";
|
||||
import { apiCall } from "@/lib";
|
||||
@@ -37,7 +37,7 @@ export default function MyEvents() {
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
{events.items.map((e) => (
|
||||
<Event key={e.eventID} event={e}>
|
||||
<AssignmentTable
|
||||
<AssignmentGrid
|
||||
className="mt-auto"
|
||||
tasks={e.tasks}
|
||||
highlightUser={user?.userName}
|
||||
|
||||
@@ -137,7 +137,7 @@ export default function Availabilities() {
|
||||
{(availability) => (
|
||||
<TableRow key={availability.availabilityName}>
|
||||
<TableCell>
|
||||
<AvailabilityChip availability={availability} />
|
||||
<AvailabilityChip>{availability}</AvailabilityChip>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Checkbox isSelected={availability.enabled} />
|
||||
@@ -199,7 +199,7 @@ export default function Availabilities() {
|
||||
{!!deleteAvailability ? (
|
||||
<>
|
||||
The availability{" "}
|
||||
<AvailabilityChip availability={deleteAvailability} /> will be
|
||||
<AvailabilityChip>{deleteAvailability}</AvailabilityChip>
|
||||
deleted.
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function EditAvailability(props: {
|
||||
<>
|
||||
Edit Availability{" "}
|
||||
{!!props.value ? (
|
||||
<AvailabilityChip availability={props.value} className="ms-4" />
|
||||
<AvailabilityChip className="ms-4">{props.value}</AvailabilityChip>
|
||||
) : null}
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -129,9 +129,9 @@ export default function VolunteerSelector({
|
||||
}}
|
||||
title={
|
||||
(
|
||||
<AvailabilityChip
|
||||
availability={getAvailabilityById(parseInt(availabilityId))}
|
||||
/>
|
||||
<AvailabilityChip>
|
||||
{getAvailabilityById(parseInt(availabilityId))}
|
||||
</AvailabilityChip>
|
||||
) as ReactElement & string
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,24 +1,50 @@
|
||||
"use client";
|
||||
import AddEvent from "@/components/Event/AddEvent";
|
||||
import AssignmentTable from "@/components/Event/AssignmentTable";
|
||||
import AssigmentTable from "@/components/Event/AssignmentTable";
|
||||
import Event from "@/components/Event/Event";
|
||||
import { apiCall, getUserTasks } from "@/lib";
|
||||
import zustand, { EventDataWithAvailability } from "@/Zustand";
|
||||
import { Add } from "@carbon/icons-react";
|
||||
import { Button, Tab, Tabs } from "@heroui/react";
|
||||
import { apiCall, getAvailabilities, getUserTasks } from "@/lib";
|
||||
import zustand, { EventDataWithAvailabilityAvailabilities } from "@/Zustand";
|
||||
import { Add, Filter } from "@carbon/icons-react";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Tab,
|
||||
Tabs,
|
||||
} from "@heroui/react";
|
||||
import { useAsyncList } from "@react-stately/data";
|
||||
import { useState } from "react";
|
||||
import AvailabilitySelector from "@/components/Event/AvailabilitySelector";
|
||||
import AvailabilityTable from "@/components/Event/AvailabilityTable";
|
||||
|
||||
const filterValues: { text: string; value: string }[] = [
|
||||
{
|
||||
text: "Description",
|
||||
value: "description",
|
||||
},
|
||||
{
|
||||
text: "Availabilities",
|
||||
value: "availabilities",
|
||||
},
|
||||
{
|
||||
text: "Tasks",
|
||||
value: "tasks",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Events() {
|
||||
const [showAddItemDialogue, setShowAddItemDialogue] = useState(false);
|
||||
const [filter, setFilter] = useState<string | number>("");
|
||||
const [filter, setFilter] = useState<string | number>("all");
|
||||
const [contentFilter, setContentFilter] = useState(["description", "tasks"]);
|
||||
|
||||
const user = zustand((state) => state.user);
|
||||
|
||||
const events = useAsyncList({
|
||||
async load() {
|
||||
const result = await apiCall<EventDataWithAvailability[]>(
|
||||
const result = await apiCall<EventDataWithAvailabilityAvailabilities[]>(
|
||||
"GET",
|
||||
"events/user/assignmentAvailability",
|
||||
);
|
||||
@@ -45,7 +71,15 @@ export default function Events() {
|
||||
},
|
||||
});
|
||||
|
||||
function showEvent(event: EventDataWithAvailability): boolean {
|
||||
const availabilites = useAsyncList({
|
||||
async load() {
|
||||
return {
|
||||
items: await getAvailabilities(),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function showEvent(event: EventDataWithAvailabilityAvailabilities): boolean {
|
||||
switch (filter) {
|
||||
case "assigned":
|
||||
return event.tasks.some((t) => {
|
||||
@@ -60,7 +94,9 @@ export default function Events() {
|
||||
}
|
||||
}
|
||||
|
||||
function showAvailabilitySelector(event: EventDataWithAvailability): boolean {
|
||||
function showAvailabilitySelector(
|
||||
event: EventDataWithAvailabilityAvailabilities,
|
||||
): boolean {
|
||||
return event.tasks.some((t) => userTasks.items.includes(t.taskID));
|
||||
}
|
||||
|
||||
@@ -68,30 +104,68 @@ export default function Events() {
|
||||
<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="relative flex w-full">
|
||||
<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="absolute right-0">
|
||||
<Popover placement="bottom-end">
|
||||
<PopoverTrigger>
|
||||
<Button isIconOnly>
|
||||
<Filter className="cursor-pointer" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<CheckboxGroup
|
||||
value={contentFilter}
|
||||
onValueChange={setContentFilter}
|
||||
>
|
||||
{filterValues.map((f) => (
|
||||
<Checkbox key={f.value} value={f.value}>
|
||||
{f.text}
|
||||
</Checkbox>
|
||||
))}
|
||||
</CheckboxGroup>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto flex flex-wrap gap-4">
|
||||
{events.items.filter(showEvent).map((e) => (
|
||||
<Event key={e.eventID} event={e}>
|
||||
<AssignmentTable
|
||||
highlightUser={user?.userName}
|
||||
tasks={e.tasks}
|
||||
className="mt-auto"
|
||||
/>
|
||||
{showAvailabilitySelector(e) ? (
|
||||
<AvailabilitySelector event={e} startSelection={e.availability} />
|
||||
) : undefined}
|
||||
</Event>
|
||||
))}
|
||||
{availabilites.items.length > 0
|
||||
? events.items.filter(showEvent).map((e) => (
|
||||
<Event
|
||||
key={e.eventID}
|
||||
event={e}
|
||||
hideDescription={!contentFilter.includes("description")}
|
||||
>
|
||||
<div className="mt-auto flex flex-col gap-4">
|
||||
{contentFilter.includes("availabilities") ? (
|
||||
<AvailabilityTable availabilities={e.availabilities} />
|
||||
) : null}
|
||||
{contentFilter.includes("tasks") ? (
|
||||
<AssigmentTable
|
||||
highlightUser={user?.userName}
|
||||
tasks={e.tasks}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
{showAvailabilitySelector(e) ? (
|
||||
<AvailabilitySelector
|
||||
event={e}
|
||||
startSelection={e.availability}
|
||||
/>
|
||||
) : undefined}
|
||||
</Event>
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
|
||||
{user?.admin ? (
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
12
client/src/app/icon.svg
Executable file
12
client/src/app/icon.svg
Executable file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="32px" height="32px" viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;}
|
||||
</style>
|
||||
<title>calendar</title>
|
||||
<path d="M26,4h-4V2h-2v2h-8V2h-2v2H6C4.9,4,4,4.9,4,6v20c0,1.1,0.9,2,2,2h20c1.1,0,2-0.9,2-2V6C28,4.9,27.1,4,26,4z M26,26H6V12h20
|
||||
V26z M26,10H6V6h4v2h2V6h8v2h2V6h4V10z"/>
|
||||
<rect id="_Transparent_Rectangle_" class="st0" width="32" height="32"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 693 B |
Reference in New Issue
Block a user