Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions app/web/features/communities/events/CancelEventDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,20 @@ export default function CancelEventDialog({
</DialogContent>
<DialogActions>
<Button
onClick={handleCancelEvent}
loading={cancelEventMutation.isPending}
>
{t("global:yes")}
</Button>
<Button
variant="outlined"
onClick={() =>
props.onClose ? props.onClose({}, "escapeKeyDown") : null
}
loading={cancelEventMutation.isPending}
>
{t("global:no")}
</Button>
<Button
onClick={handleCancelEvent}
loading={cancelEventMutation.isPending}
>
{t("global:yes")}
</Button>
</DialogActions>
</Dialog>
);
Expand Down
32 changes: 31 additions & 1 deletion app/web/features/communities/events/EditEventPage.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,50 @@
import { styled } from "@mui/material";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import Alert from "components/Alert";
import Button from "components/Button";
import CenteredSpinner from "components/CenteredSpinner/CenteredSpinner";
import HeaderButton from "components/HeaderButton";
import HtmlMeta from "components/HtmlMeta";
import { BackIcon } from "components/Icons";
import NotFoundPage from "features/NotFoundPage";
import { RpcError } from "grpc-web";
import { useTranslation } from "i18n";
import { COMMUNITIES, GLOBAL, PROFILE } from "i18n/namespaces";
import { useRouter } from "next/router";
import { service } from "service";
import type { UpdateEventInput } from "service/events";
import { theme } from "theme";
import dayjs from "utils/dayjs";
import { sendNativeBack, useIsNativeEmbed } from "utils/nativeLink";

import { Event } from "../../../proto/events_pb";
import { routeToEvent } from "../../../routes";
import { eventsRoute, routeToEvent } from "../../../routes";
import { communityEventsBaseKey, eventKey } from "../../queryKeys";
import EventForm, { CreateEventVariables } from "./EventForm";
import { useEvent } from "./hooks";

const StyledBackButton = styled(HeaderButton)(() => ({
width: "2.5rem",
height: "2.5rem",
marginTop: theme.spacing(2),
}));

export default function EditEventPage({ eventId }: { eventId: number }) {
const { t } = useTranslation([GLOBAL, COMMUNITIES, PROFILE]);
const router = useRouter();
const isNativeEmbed = useIsNativeEmbed();

const handleBackClick = () => {
if (isNativeEmbed) {
sendNativeBack();
return;
}
if (window.history.length > 1) {
router.back();
} else {
router.push(eventsRoute);
}
};

const {
data: event,
Expand Down Expand Up @@ -117,6 +141,12 @@ export default function EditEventPage({ eventId }: { eventId: number }) {
) : (
<>
<HtmlMeta title={t("communities:edit_event")} />
<StyledBackButton
onClick={handleBackClick}
aria-label={t("communities:previous_page")}
>
<BackIcon />
</StyledBackButton>
<EventForm
error={error}
event={event}
Expand Down
73 changes: 46 additions & 27 deletions app/web/features/communities/events/EventPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,24 @@ describe("Event page", () => {
getEventMock.mockResolvedValue({ ...firstEvent, canEdit: true });
renderEventPage();

const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
await screen.findByRole("button", { name: t("communities:edit_event") }),
await screen.findByRole("menuitem", {
name: t("communities:edit_event"),
}),
).toBeVisible();
});

it("does not show the 'edit event' button if the user does not have edit permission", async () => {
renderEventPage();

const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
await screen.queryByRole("button", { name: t("communities:edit_event") }),
screen.queryByRole("menuitem", { name: t("communities:edit_event") }),
).not.toBeInTheDocument();
});

Expand All @@ -227,8 +235,11 @@ describe("Event page", () => {
getEventMock.mockResolvedValue({ ...firstEvent, creatorUserId: 1 });
renderEventPage();

const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
await screen.findByRole("button", {
await screen.findByRole("menuitem", {
name: t("communities:duplicate_event"),
}),
).toBeVisible();
Expand All @@ -239,28 +250,32 @@ describe("Event page", () => {
getEventMock.mockResolvedValue({ ...firstEvent, creatorUserId: 2 });
renderEventPage();

await screen.findByRole("heading", { name: firstEvent.title });
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
screen.queryByRole("button", {
screen.queryByRole("menuitem", {
name: t("communities:duplicate_event"),
}),
).not.toBeInTheDocument();
});

it("disables the 'duplicate event' button for cancelled events", async () => {
it("hides the 'duplicate event' item for cancelled events", async () => {
getEventMock.mockResolvedValue({
...firstEvent,
creatorUserId: 1,
isCancelled: true,
});
renderEventPage();

const duplicateButton = await screen.findByRole("button", {
name: t("communities:duplicate_event"),
});
expect(duplicateButton).toBeDisabled();
expect(duplicateButton).toHaveAttribute("tabIndex", "-1");
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
screen.queryByRole("menuitem", {
name: t("communities:duplicate_event"),
}),
).not.toBeInTheDocument();
});

it("allows duplicating past events", async () => {
Expand All @@ -272,11 +287,14 @@ describe("Event page", () => {
getEventMock.mockResolvedValue(pastEvent);
renderEventPage();

const duplicateButton = await screen.findByRole("button", {
name: t("communities:duplicate_event"),
});
expect(duplicateButton).toBeEnabled();
expect(duplicateButton).not.toHaveAttribute("tabIndex", "-1");
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

expect(
await screen.findByRole("menuitem", {
name: t("communities:duplicate_event"),
}),
).toBeVisible();
});

it("navigates to create event page with duplicate query param when clicked", async () => {
Expand All @@ -285,11 +303,13 @@ describe("Event page", () => {
renderEventPage();

const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

const duplicateButton = await screen.findByRole("button", {
name: t("communities:duplicate_event"),
});
await user.click(duplicateButton);
await user.click(
await screen.findByRole("menuitem", {
name: t("communities:duplicate_event"),
}),
);

await waitFor(() =>
expect(mockRouter.push).toHaveBeenCalledWith(
Expand All @@ -302,15 +322,14 @@ describe("Event page", () => {
getEventMock.mockResolvedValue({ ...firstEvent, creatorUserId: 1 });
renderEventPage();

const duplicateButton = await screen.findByRole("button", {
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
await user.click(await screen.findByTestId("event-page-more-options"));

const duplicateItem = await screen.findByRole("menuitem", {
name: t("communities:duplicate_event"),
});
expect(duplicateButton).toHaveAttribute(
"aria-label",
t("communities:duplicate_event"),
);
expect(duplicateButton).toHaveAttribute("tabIndex", "0");
expect(duplicateButton).not.toBeDisabled();
expect(duplicateItem).toBeVisible();
expect(duplicateItem).not.toHaveAttribute("aria-disabled", "true");
});

it("shows the not found page if the user tries to find an event with an invalid ID in the URL", async () => {
Expand Down
Loading
Loading