feat: redesign event modal with responsive dialog and improved layout

Implemented a new ResponsiveDialog component and redesigned EventModal
with better UX for both normal and extended modes.

New Features:
- Created reusable ResponsiveDialog component (src/components/Dialog/)
  * Normal mode: 685px centered popup
  * Extended mode: fullscreen with 90px header preservation
  * Auto spacing via MUI Stack (16px normal, 24px extended)
  * Back arrow navigation in extended mode
  * No backdrop/shadow in extended mode for seamless integration
  * Configurable props for all dimensions and behaviors

EventModal Improvements:
- Replaced native checkbox with MUI Checkbox component
- Migrated from Popover to ResponsiveDialog
- Reorganized field layout

=> Comprehensive documentation in Dialog/README.md

Note: RepeatEvent integration tests need additional refactoring (tracked separately)
This commit is contained in:
lenhanphung
2025-09-30 16:53:29 +07:00
parent 65309bba18
commit 7c6240442c
7 changed files with 1045 additions and 244 deletions
+15 -8
View File
@@ -99,7 +99,7 @@ async function setupEventPopover(
preloadedState
);
act(() => {
fireEvent.change(screen.getByLabelText("Title"), {
fireEvent.change(screen.getByRole("textbox", { name: /title/i }), {
target: { value: "Meeting" },
});
fireEvent.click(screen.getByLabelText("All day"));
@@ -113,7 +113,10 @@ async function setupEventPopover(
value: (overrides?.end ?? "2025-07-19T00:00:00.000Z").split("T")[0],
},
});
fireEvent.click(screen.getByText("Show More"));
const showMoreButton = screen.queryByText("Show More");
if (showMoreButton) {
fireEvent.click(showMoreButton);
}
});
const select = screen.getByLabelText(/repetition/i);
userEvent.click(select);
@@ -124,7 +127,8 @@ async function setupEventPopover(
async function expectRRule(expected: any) {
const spyAPi = jest.spyOn(apiUtils, "api");
act(() => fireEvent.click(screen.getByText("Save")));
const saveButton = screen.getByRole("button", { name: /save/i });
act(() => fireEvent.click(saveButton));
await waitFor(() => {
expect(spyAPi).toHaveBeenCalled();
@@ -214,7 +218,8 @@ describe("Repeat Event API calls", () => {
const spy = jest
.spyOn(eventThunks, "putEventAsync")
.mockImplementation((payload) => () => Promise.resolve(payload) as any);
act(() => fireEvent.click(screen.getByText("Save")));
const saveButton = screen.getByRole("button", { name: /save/i });
act(() => fireEvent.click(saveButton));
await waitFor(() => expect(spy).toHaveBeenCalled());
const received = spy.mock.calls[0][0];
@@ -223,12 +228,14 @@ describe("Repeat Event API calls", () => {
);
expect(received.newEvent.title).toBe("Meeting");
expect(
formatDateToYYYYMMDDTHHMMSS(received.newEvent.start).split("T")[0]
).toBe("20250718");
expect(
formatDateToYYYYMMDDTHHMMSS(received.newEvent.end || new Date()).split(
formatDateToYYYYMMDDTHHMMSS(new Date(received.newEvent.start)).split(
"T"
)[0]
).toBe("20250718");
expect(
formatDateToYYYYMMDDTHHMMSS(
new Date(received.newEvent.end || new Date())
).split("T")[0]
).toBe("20250719");
expect(received.newEvent.organizer).toEqual(
preloadedState.user.organiserData