feat: Update Event Preview Modal UI with custom MUI theme (#240)
- Add custom MUI theme - Update ResponsiveDialog with actionsBorderTop prop for modal footer border - Redesign EventDisplayPreview modal with improved typography and spacing - Replace ButtonGroup with individual RSVP buttons (Accept/Maybe/Decline) - Add pill-shaped buttons for RSVP actions - Ensure backward compatibility with existing modals
This commit is contained in:
@@ -66,17 +66,19 @@ export function TimezoneSelector({ value, onChange }: TimezoneSelectProps) {
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: { width: 280, maxHeight: 400, overflow: "auto", p: 1 },
|
||||
sx: { width: 280, maxHeight: 400, overflow: "hidden", p: 0 },
|
||||
},
|
||||
}}
|
||||
>
|
||||
<TimezoneAutocomplete
|
||||
size="medium"
|
||||
value={effectiveTimezone}
|
||||
onChange={onChange}
|
||||
zones={timezoneList.zones}
|
||||
getTimezoneOffset={getTimezoneOffset}
|
||||
autoFocus={true}
|
||||
inputFontSize="10px"
|
||||
showIcon={true}
|
||||
inputFontSize="14px"
|
||||
inputPadding="2px 4px"
|
||||
onClose={handleClose}
|
||||
disableClearable={true}
|
||||
|
||||
@@ -78,6 +78,14 @@ interface ResponsiveDialogProps
|
||||
dividers?: boolean;
|
||||
/** Whether to show header action icons (expand/close) in normal mode (default: true) */
|
||||
showHeaderActions?: boolean;
|
||||
/** Whether to add border-top to DialogActions */
|
||||
actionsBorderTop?: boolean;
|
||||
/** Justify content alignment for DialogActions */
|
||||
actionsJustifyContent?:
|
||||
| "flex-start"
|
||||
| "center"
|
||||
| "flex-end"
|
||||
| "space-between";
|
||||
}
|
||||
|
||||
function ResponsiveDialog({
|
||||
@@ -99,6 +107,8 @@ function ResponsiveDialog({
|
||||
dialogTitleProps,
|
||||
dividers = false,
|
||||
showHeaderActions = true,
|
||||
actionsBorderTop = false,
|
||||
actionsJustifyContent = "flex-end",
|
||||
sx,
|
||||
...otherDialogProps
|
||||
}: ResponsiveDialogProps) {
|
||||
@@ -199,7 +209,20 @@ function ResponsiveDialog({
|
||||
<Stack spacing={currentSpacing}>{children}</Stack>
|
||||
)}
|
||||
</DialogContent>
|
||||
{actions && <DialogActions>{actions}</DialogActions>}
|
||||
{actions && (
|
||||
<DialogActions
|
||||
sx={{
|
||||
borderTop: actionsBorderTop
|
||||
? (theme) => `1px solid ${theme.palette.divider}`
|
||||
: undefined,
|
||||
justifyContent: actionsJustifyContent,
|
||||
paddingTop: "18px",
|
||||
paddingBottom: "18px",
|
||||
}}
|
||||
>
|
||||
{actions}
|
||||
</DialogActions>
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,51 +1,22 @@
|
||||
import { IconButton, MenuItem } from "@mui/material";
|
||||
import { MenuItem } from "@mui/material";
|
||||
import { CalendarEvent } from "../../features/Events/EventsTypes";
|
||||
import AddToPhotosIcon from "@mui/icons-material/AddToPhotos";
|
||||
import { useRef, useState } from "react";
|
||||
import EventPopover from "../../features/Events/EventModal";
|
||||
import { CalendarApi, DateSelectArg } from "@fullcalendar/core";
|
||||
|
||||
export default function EventDuplication({
|
||||
onClose,
|
||||
event,
|
||||
onOpenDuplicate,
|
||||
}: {
|
||||
onClose: Function;
|
||||
event: CalendarEvent;
|
||||
onOpenDuplicate?: () => void;
|
||||
}) {
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
const [selectedRange, setSelectedRange] = useState<DateSelectArg | null>({
|
||||
start: new Date(event.start),
|
||||
startStr: event.start,
|
||||
end: new Date(event.end ?? ""),
|
||||
endStr: event.end ?? "",
|
||||
allDay: event.allday ?? false,
|
||||
} as DateSelectArg);
|
||||
const calendarRef = useRef<CalendarApi | null>(null);
|
||||
|
||||
const handleClosePopover = () => {
|
||||
calendarRef.current?.unselect();
|
||||
setSelectedRange(null);
|
||||
setOpenModal(!openModal);
|
||||
onClose({}, "backdropClick");
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setOpenModal(true);
|
||||
}}
|
||||
>
|
||||
Duplicate event
|
||||
</MenuItem>
|
||||
<EventPopover
|
||||
anchorEl={null}
|
||||
open={openModal}
|
||||
selectedRange={selectedRange}
|
||||
setSelectedRange={setSelectedRange}
|
||||
calendarRef={calendarRef}
|
||||
onClose={handleClosePopover}
|
||||
event={event}
|
||||
/>
|
||||
</>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onOpenDuplicate?.();
|
||||
}}
|
||||
>
|
||||
Duplicate event
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,12 +77,14 @@ export function InfoRow({
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={error ? "error" : "textPrimary"}
|
||||
style={{
|
||||
sx={{
|
||||
wordBreak: "break-word",
|
||||
whiteSpace: "pre-line",
|
||||
maxHeight: "33vh",
|
||||
overflowY: "auto",
|
||||
width: "100%",
|
||||
fontSize: "16px",
|
||||
fontFamily: "'Inter', sans-serif",
|
||||
}}
|
||||
>
|
||||
{data ? (
|
||||
|
||||
@@ -44,6 +44,7 @@ export function renderAttendeeBadge(
|
||||
>
|
||||
<Badge
|
||||
overlap="circular"
|
||||
sx={{ marginRight: 2 }}
|
||||
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
|
||||
badgeContent={
|
||||
classIcon && (
|
||||
@@ -65,7 +66,6 @@ export function renderAttendeeBadge(
|
||||
</Badge>
|
||||
<Box style={{ display: "flex", flexDirection: "column", minWidth: 0 }}>
|
||||
<Typography
|
||||
variant="body2"
|
||||
noWrap
|
||||
style={{
|
||||
maxWidth: "180px",
|
||||
@@ -76,11 +76,7 @@ export function renderAttendeeBadge(
|
||||
{a.cn || a.cal_address}
|
||||
</Typography>
|
||||
{isOrganizer && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
style={{ fontStyle: "italic" }}
|
||||
>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Organizer
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user