Skip to content

Commit

Permalink
Merge pull request #100 from ystv/event-empty-state-1
Browse files Browse the repository at this point in the history
I've made a mess
  • Loading branch information
markspolakovs authored Feb 27, 2024
2 parents 1e69298 + 97f7082 commit d68178d
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 0 deletions.
121 changes: 121 additions & 0 deletions app/(authenticated)/calendar/[eventID]/CheckWithTech.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"use client";

import { Alert, Button, ButtonGroup, Modal, Textarea } from "@mantine/core";
import { useState, useTransition } from "react";
import { TbBrandSlack, TbTool } from "react-icons/tb";
import { doCheckWithTech } from "./actions";
import { notifications } from "@mantine/notifications";

function PostMessage(props: {
eventID: number;
isConfident: boolean;
done: () => void;
}) {
const [isPending, startTransition] = useTransition();
const [memo, setMemo] = useState("");
return (
<>
<Textarea
label="Notes"
value={memo}
onChange={(e) => setMemo(e.target.value)}
rows={5}
/>
<p>
These notes will be posted in a public Slack channel.{" "}
{props.isConfident ? (
<p>
Please include a list of what equipment you&apos;ll need (cameras,
audio, lighting etc.)
</p>
) : (
<p>
Please describe your production, especially any unusual technical
aspects.
</p>
)}
</p>
<Button
loading={isPending}
onClick={() =>
startTransition(async () => {
await doCheckWithTech(props.eventID, memo, props.isConfident);
notifications.show({
title: "Sent!",
message:
"Keep an eye out on Slack in case the tech team need any further details.",
});
props.done();
})
}
leftSection={<TbBrandSlack size={14} />}
>
Send
</Button>
</>
);
}

export function CheckWithTechPromptContents(props: { eventID: number }) {
const [isPostOpen, setPostOpen] = useState(false);
const [confident, setConfident] = useState<boolean | null>(null);
return (
<>
<Alert
variant="light"
color="blue"
title="#CheckWithTech"
icon={<TbTool />}
>
<strong>Don&apos;t forget to #CheckWithTech!</strong>
<p>
Make sure the tech team knows about your plans, so they can have the
equipment you need ready for you. Do this by posting in the
#check-with-tech channel on Slack. The Calendar can also do this for
you if you like!
</p>
<Button onClick={() => setPostOpen(true)}>Check With Tech</Button>
</Alert>
<Modal opened={isPostOpen} onClose={() => setPostOpen(false)}>
<h1 className="mt-0">Check With Tech</h1>
{confident === null ? (
<>
<p>
<strong>
Do you already know what equipment you&apos;ll need for your
production?
</strong>
</p>
<p>Don&apos;t worry if you don&apos;t - we&apos;ll help you out.</p>
<ButtonGroup>
<Button
onClick={() => {
setConfident(true);
}}
>
Yes, I know what I need
</Button>
<Button
variant="default"
onClick={() => {
setConfident(false);
}}
>
No, I&apos;m not sure
</Button>
</ButtonGroup>
</>
) : (
<PostMessage
eventID={props.eventID}
isConfident={confident}
done={() => {
setPostOpen(false);
setConfident(null);
}}
/>
)}
</Modal>
</>
);
}
27 changes: 27 additions & 0 deletions app/(authenticated)/calendar/[eventID]/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,30 @@ export async function deleteEvent(eventID: number) {
revalidatePath("/calendar");
return { ok: true };
}

export async function doCheckWithTech(
eventID: number,
memo: string,
isConfident: boolean,
) {
const me = await mustGetCurrentUser();
const event = await Calendar.getEvent(eventID);
invariant(event, "Event does not exist");

if (!canManage(event, me)) {
return {
ok: false,
errors: {
root: "You do not have permission to do this.",
},
};
}

if (isConfident) {
await Calendar.postCheckWithTech(eventID, memo);
} else {
await Calendar.postTechHelpRequest(eventID, memo);
}

return { ok: true };
}
28 changes: 28 additions & 0 deletions app/(authenticated)/calendar/[eventID]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { ConversationsInfoResponse } from "@slack/web-api/dist/response";
import { Suspense } from "react";
import SlackChannelName from "@/components/slack/SlackChannelName";
import SlackLoginButton from "@/components/slack/SlackLoginButton";
import { CheckWithTechPromptContents } from "./CheckWithTech";
import { C } from "@fullcalendar/core/internal-common";

async function AttendeesView({
event,
Expand Down Expand Up @@ -86,6 +88,31 @@ async function AttendeesView({
);
}

async function CheckWithTechPrompt({
event,
me,
}: {
event: EventObjectType;
me: UserType;
}) {
if (me.user_id !== event.host) {
return null;
}
if (event.adam_rms_project_id) {
// assume already checked
return null;
}
if (event.signup_sheets.length === 0) {
// signup sheets take priority
return null;
}
const slack = await slackApiConnection();
if (!slack) {
return null;
}
return <CheckWithTechPromptContents eventID={event.event_id} />;
}

async function ShowView({
event,
me,
Expand All @@ -103,6 +130,7 @@ async function ShowView({
return (
<CrewPositionsProvider positions={positions}>
<MembersProvider members={members}>
<CheckWithTechPrompt event={event} me={me} />
<SignupSheetsView event={event} me={me} />
</MembersProvider>
</CrewPositionsProvider>
Expand Down
72 changes: 72 additions & 0 deletions features/calendar/check_with_tech.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { getCurrentUser } from "@/lib/auth/server";
import slackApiConnection from "@/lib/slack/slackApiConnection";
import { getEvent } from "./events";
import dayjs from "dayjs";

export async function postCheckWithTech(eventID: number, memo: string) {
const slack = await slackApiConnection();
if (!slack) {
throw new Error("No Slack app");
}
const event = await getEvent(eventID);
if (!event) {
throw new Error("Event not found");
}
const me = await getCurrentUser();
const user = me.slack_user_id
? `<@${me.slack_user_id}>`
: `${me.first_name} ${me.last_name}`;

const lines = [
`*#check-with-tech request from ${user}*`,
event.name,
dayjs(event.start_date).format("dddd, MMMM D, YYYY") +
" - " +
(dayjs(event.end_date).isSame(event.start_date, "day")
? dayjs(event.end_date).format("h:mma")
: dayjs(event.end_date).format("dddd, MMMM D, YYYY h:mma")),
`${process.env.PUBLIC_URL}/calendar/${eventID}`,
event.location,
memo,
];

await slack.client.chat.postMessage({
channel: process.env.SLACK_CHECK_WITH_TECH_CHANNEL ?? "#check-with-tech",
text: lines.join("\n"),
mrkdwn: true,
});
}

export async function postTechHelpRequest(eventID: number, memo: string) {
const slack = await slackApiConnection();
if (!slack) {
throw new Error("No Slack app");
}
const event = await getEvent(eventID);
if (!event) {
throw new Error("Event not found");
}
const me = await getCurrentUser();
const user = me.slack_user_id
? `<@${me.slack_user_id}>`
: `${me.first_name} ${me.last_name}`;

const lines = [
`*${user} needs help with their production*`,
event.name,
dayjs(event.start_date).format("dddd, MMMM D, YYYY") +
" - " +
(dayjs(event.end_date).isSame(event.start_date, "day")
? dayjs(event.end_date).format("h:mma")
: dayjs(event.end_date).format("dddd, MMMM D, YYYY h:mma")),
`${process.env.PUBLIC_URL}/calendar/${eventID}`,
event.location,
memo,
];

await slack.client.chat.postMessage({
channel: process.env.SLACK_TECH_HELP_CHANNEL ?? "#tech",
text: lines.join("\n"),
mrkdwn: true,
});
}
1 change: 1 addition & 0 deletions features/calendar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from "./permissions";
export * from "./crew_positions";
export * from "./ical";
export * from "./adamRMS";
export * from "./check_with_tech";

0 comments on commit d68178d

Please sign in to comment.