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
+30 -15
View File
@@ -109,22 +109,35 @@ describe("EventPopover", () => {
it("renders correctly with inputs and calendar options", () => {
renderPopover();
// Check dialog title
expect(screen.getByText("Create Event")).toBeInTheDocument();
expect(screen.getByLabelText("Calendar")).toBeInTheDocument();
expect(screen.getByLabelText("Title")).toBeInTheDocument();
expect(screen.getByLabelText("Start")).toBeInTheDocument();
expect(screen.getByLabelText("End")).toBeInTheDocument();
expect(screen.getByLabelText("Description")).toBeInTheDocument();
expect(screen.getByLabelText("Location")).toBeInTheDocument();
// Check inputs exist by their roles
const titleInput = screen.getByRole("textbox", { name: /title/i });
expect(titleInput).toBeInTheDocument();
const descriptionInput = screen.getByRole("textbox", {
name: /description/i,
});
expect(descriptionInput).toBeInTheDocument();
const calendarSelect = screen.getByRole("combobox", { name: /calendar/i });
expect(calendarSelect).toBeInTheDocument();
// Check button
expect(screen.getByText("Show More")).toBeInTheDocument();
// Extended mode
fireEvent.click(screen.getByText("Show More"));
expect(screen.getByLabelText("Repetition")).toBeInTheDocument();
expect(screen.getByLabelText("Alarm")).toBeInTheDocument();
expect(screen.getByLabelText("Visibility")).toBeInTheDocument();
// Calendar options
const select = screen.getByLabelText("Calendar");
fireEvent.mouseDown(select);
expect(screen.getAllByRole("option")).toHaveLength(2);
// Back button appears
expect(screen.getByLabelText("show less")).toBeInTheDocument();
// Extended labels appear
expect(screen.getAllByText("Repeat")).toHaveLength(1);
expect(screen.getAllByText("Alarm")).toHaveLength(1);
expect(screen.getAllByText("Visibility")).toHaveLength(1);
expect(screen.getAllByText("Show as")).toHaveLength(1);
});
it("fills start from selectedRange", () => {
@@ -289,11 +302,13 @@ describe("EventPopover", () => {
expect(receivedPayload.newEvent.title).toBe(newEvent.title);
expect(receivedPayload.newEvent.description).toBe(newEvent.description);
expect(
formatDateToYYYYMMDDTHHMMSS(receivedPayload.newEvent.start).split("T")[0]
formatDateToYYYYMMDDTHHMMSS(
new Date(receivedPayload.newEvent.start)
).split("T")[0]
).toBe(formatDateToYYYYMMDDTHHMMSS(new Date(newEvent.start)).split("T")[0]);
expect(
formatDateToYYYYMMDDTHHMMSS(
receivedPayload.newEvent.end || new Date()
new Date(receivedPayload.newEvent.end || new Date())
).split("T")[0]
).toBe(formatDateToYYYYMMDDTHHMMSS(new Date(newEvent.end)).split("T")[0]);
expect(receivedPayload.newEvent.location).toBe(newEvent.location);