Skip to content

Commit

Permalink
[WEB-169] Check for clashes when a user goes to sign up to a role
Browse files Browse the repository at this point in the history
  • Loading branch information
archessmn committed Jul 22, 2024
1 parent 9a2c575 commit 26f2e75
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 19 deletions.
129 changes: 111 additions & 18 deletions app/(authenticated)/calendar/[eventID]/SignupSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
"use client";

import { isBefore, isSameDay } from "date-fns";
import { useMemo, useState, useTransition } from "react";
import { useEffect, useMemo, useState, useTransition } from "react";
import { getUserName } from "@/components/UserHelpers";
import type { UserType } from "@/lib/auth/server";
import invariant from "@/lib/invariant";
import { Alert, Button, Modal, Paper } from "@mantine/core";
import {
Alert,
Button,
Card,
Checkbox,
Group,
List,
Modal,
Paper,
Stack,
Text,
} from "@mantine/core";
import {
canManage,
canManageSignUpSheet,
} from "@/features/calendar/permissions";
import { DateTime } from "@/components/DateTimeHelpers";
import { AddEditSignUpSheetForm } from "@/app/(authenticated)/calendar/[eventID]/AddEditSignUpSheetForm";
import { CrewType, SignUpSheetType } from "@/features/calendar/signup_sheets";
import {
CrewType,
SignUpSheetType,
SignUpSheetWithEvent,
} from "@/features/calendar/signup_sheets";
import { EventObjectType } from "@/features/calendar/events";
import { ExposedUser } from "@/features/people";
import {
checkRoleClashes,
createSignUpSheet,
deleteSignUpSheet,
editSignUpSheet,
Expand Down Expand Up @@ -242,6 +258,28 @@ export function MyRoleSignUpModal({
me?: ExposedUser;
buttonless?: boolean;
}) {
const [clashes, setClashes] = useState<SignUpSheetWithEvent[] | undefined>(
undefined,
);

const [acceptClashes, setAcceptClashes] = useState<boolean>(false);

useEffect(() => {
async function updateClashes() {
const clashesResponse = await checkRoleClashes(crew.crew_id);

if (clashesResponse) {
setClashes(clashesResponse?.clashSheets);
}
}

updateClashes();

return () => {
setClashes(undefined);
};
}, [crew]);

const [isPending, startTransition] = useTransition();
const [error, setError] = useState<string | null>(null);
return (
Expand Down Expand Up @@ -273,22 +311,77 @@ export function MyRoleSignUpModal({
Drop Out
</Button>
) : (
<Button
size="large"
loading={isPending}
onClick={() => {
startTransition(async () => {
const res = await signUpToRole(sheet.signup_id, crew.crew_id);
if (!res.ok) {
setError(res.errors!.root as string);
return;
<Stack>
{clashes && clashes.length > 0 && (
<>
<Text fw={700}>
This role clashes with some of your other roles:
</Text>
<Stack>
{clashes.map((clash) => {
return (
<Card key={clash.signup_id}>
<Stack gap={"xs"}>
<Group>
<Stack gap={0}>
<Text fw={700}>{clash.events.name}</Text>
<Text size="xs">{clash.title}</Text>
</Stack>
<Text size="xs" ml={"auto"}>
{dayjs(clash.arrival_time).format(
"DD/MM HH:mm",
)}{" "}
- {dayjs(clash.end_time).format("DD/MM HH:mm")}
</Text>
</Group>
<Text size="sm" fw={600}>
Role{clash.crews.length > 1 && "s"}:
</Text>
<List size="sm">
{clash.crews.map((crew) => {
return (
<List.Item key={crew.crew_id}>
{crew.positions.name}
</List.Item>
);
})}
</List>
</Stack>
</Card>
);
})}
</Stack>
</>
)}
{clashes && clashes?.length !== 0 && (
<Checkbox
label={"Accept clashes"}
onChange={(event) =>
setAcceptClashes(event.currentTarget.checked)
}
onSuccess();
});
}}
>
Sign Up
</Button>
/>
)}
<Button
size="large"
loading={isPending || !clashes}
onClick={() => {
startTransition(async () => {
const res = await signUpToRole(
sheet.signup_id,
crew.crew_id,
);
if (!res.ok) {
setError(res.errors!.root as string);
return;
}
onSuccess();
});
}}
disabled={clashes?.length !== 0 && !acceptClashes}
>
Sign Up
</Button>
</Stack>
)}
</div>
)}
Expand Down
14 changes: 14 additions & 0 deletions app/(authenticated)/calendar/[eventID]/signUpSheetActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,17 @@ export async function removeSelfFromRole(sheetID: number, crewID: number) {
revalidatePath(`/calendar/${sheet.events.event_id}`);
return { ok: true };
}

export async function checkRoleClashes(
crewID: number,
): Promise<{ clashSheets: Calendar.SignUpSheetWithEvent[] } | undefined> {
const me = await getCurrentUser();
const crewRole = await Calendar.getCrewRole(crewID);

if (!crewRole) return undefined;
const sheet = crewRole.signup_sheets;

const clashes = await Calendar.getClashingSheets(me, sheet);

return { clashSheets: clashes };
}
78 changes: 77 additions & 1 deletion features/calendar/signup_sheets.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import SignupSheetUpdateInput = Prisma.SignupSheetUpdateInput;
import { prisma } from "@/lib/db";
import { Event, Prisma } from "@prisma/client";
import { Event, Prisma, SignupSheet } from "@prisma/client";
import { CrewPositionType } from "@/features/calendar/crew_positions";
import { omit } from "lodash";
import { ExposedUser } from "@/features/people";
import invariant from "@/lib/invariant";
import { UserType } from "@/lib/auth/server";

export interface CrewType {
crew_id: number;
Expand Down Expand Up @@ -279,3 +280,78 @@ export async function removeUserFromRole(
throw e;
}
}

export async function getCrewRole(crewID: number) {
return prisma.crew.findFirst({
where: {
crew_id: crewID,
},
include: {
signup_sheets: {
include: {
events: true,
},
},
},
});
}

export async function getClashingSheets(user: UserType, sheet: SignupSheet) {
const clashingSheets = await prisma.signupSheet.findMany({
where: {
AND: [
{
crews: {
some: {
user_id: user.user_id,
},
},
},
{
OR: [
{
arrival_time: {
gte: sheet.arrival_time,
lte: sheet.end_time,
},
},
{
end_time: {
gte: sheet.arrival_time,
lte: sheet.end_time,
},
},
{
AND: [
{
arrival_time: {
lte: sheet.arrival_time,
},
},
{
end_time: {
gte: sheet.end_time,
},
},
],
},
],
},
],
},
include: {
events: true,
crews: {
include: {
positions: true,
users: true,
},
where: {
user_id: user.user_id,
},
},
},
});

return clashingSheets;
}

0 comments on commit 26f2e75

Please sign in to comment.