From f2459918169e613f4c3a4b278cf205cb11982cad Mon Sep 17 00:00:00 2001 From: lenhanphung Date: Fri, 3 Oct 2025 14:50:37 +0700 Subject: [PATCH] feat: improve video conference UI in EventModal - Replace 'Meeting link generated' text with 'Join Visio conference' button - Button opens video conference link in new tab when clicked - Use contained variant styling to match Save button appearance - Maintain copy and delete functionality for meeting links --- src/components/Attendees/AttendeeSearch.tsx | 1 - src/components/Attendees/PeopleSearch.tsx | 10 ---------- src/components/Calendar/Calendar.tsx | 13 +------------ src/components/Calendar/CalendarLayout.tsx | 2 -- src/components/Calendar/CalendarModal.tsx | 14 -------------- src/components/Calendar/CalendarSearch.tsx | 7 ------- src/components/Calendar/CalendarSelection.tsx | 1 - src/components/Calendar/TempCalendarsInput.tsx | 2 +- .../Calendar/hooks/useCalendarEventHandlers.ts | 1 - .../Calendar/hooks/useCalendarViewHandlers.ts | 1 - src/components/Menubar/Menubar.tsx | 4 ---- src/features/Calendars/CalendarSlice.ts | 17 +++++++---------- src/features/Events/EventDisplay.tsx | 5 +---- src/features/Events/EventDisplayPreview.tsx | 9 +-------- src/features/Events/EventModal.tsx | 15 ++++++++++++--- src/features/User/LoginCallback.tsx | 2 +- src/setupTests.ts | 3 +-- 17 files changed, 25 insertions(+), 82 deletions(-) diff --git a/src/components/Attendees/AttendeeSearch.tsx b/src/components/Attendees/AttendeeSearch.tsx index db6c9f2..2616053 100644 --- a/src/components/Attendees/AttendeeSearch.tsx +++ b/src/components/Attendees/AttendeeSearch.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "react"; -import { searchUsers } from "../../features/User/userAPI"; import { userAttendee } from "../../features/User/userDataTypes"; import { PeopleSearch, User } from "./PeopleSearch"; diff --git a/src/components/Attendees/PeopleSearch.tsx b/src/components/Attendees/PeopleSearch.tsx index 3939630..1a08a1b 100644 --- a/src/components/Attendees/PeopleSearch.tsx +++ b/src/components/Attendees/PeopleSearch.tsx @@ -1,20 +1,10 @@ -import CloseIcon from "@mui/icons-material/Close"; import Autocomplete from "@mui/material/Autocomplete"; import Avatar from "@mui/material/Avatar"; -import Box from "@mui/material/Box"; -import Button from "@mui/material/Button"; -import Card from "@mui/material/Card"; -import CardActions from "@mui/material/CardActions"; -import CardContent from "@mui/material/CardContent"; -import CardHeader from "@mui/material/CardHeader"; import CircularProgress from "@mui/material/CircularProgress"; -import IconButton from "@mui/material/IconButton"; import ListItem from "@mui/material/ListItem"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import ListItemText from "@mui/material/ListItemText"; -import Modal from "@mui/material/Modal"; import TextField from "@mui/material/TextField"; -import Typography from "@mui/material/Typography"; import { useState, useEffect } from "react"; import { searchUsers } from "../../features/User/userAPI"; import PeopleOutlineOutlinedIcon from "@mui/icons-material/PeopleOutlineOutlined"; diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 754ff56..efeb23a 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -11,29 +11,18 @@ import { useAppDispatch, useAppSelector } from "../../app/hooks"; import EventPopover from "../../features/Events/EventModal"; import { CalendarEvent } from "../../features/Events/EventsTypes"; import CalendarSelection from "./CalendarSelection"; -import { - getCalendarDetailAsync, - getEventAsync, - putEventAsync, - updateEventLocal, -} from "../../features/Calendars/CalendarSlice"; +import { getCalendarDetailAsync } from "../../features/Calendars/CalendarSlice"; import ImportAlert from "../../features/Events/ImportAlert"; import { computeStartOfTheWeek, formatDateToYYYYMMDDTHHMMSS, getCalendarRange, - getDeltaInMilliseconds, } from "../../utils/dateUtils"; import { Calendars } from "../../features/Calendars/CalendarTypes"; import { push } from "redux-first-history"; import EventPreviewModal from "../../features/Events/EventDisplayPreview"; import { createSelector } from "@reduxjs/toolkit"; -import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; -import ClearIcon from "@mui/icons-material/Clear"; import AddIcon from "@mui/icons-material/Add"; -import AccessTimeIcon from "@mui/icons-material/AccessTime"; -import LockIcon from "@mui/icons-material/Lock"; -import { userAttendee } from "../../features/User/userDataTypes"; import { TempCalendarsInput } from "./TempCalendarsInput"; import Button from "@mui/material/Button"; import { diff --git a/src/components/Calendar/CalendarLayout.tsx b/src/components/Calendar/CalendarLayout.tsx index c9b8bc1..4d44d42 100644 --- a/src/components/Calendar/CalendarLayout.tsx +++ b/src/components/Calendar/CalendarLayout.tsx @@ -16,8 +16,6 @@ export default function CalendarLayout() { const calendarRef = useRef(null); const dispatch = useAppDispatch(); const selectedCalendars = useAppSelector((state) => state.calendars.list); - const userId = - useAppSelector((state) => state.user.userData?.openpaasId) ?? ""; const [currentDate, setCurrentDate] = useState(new Date()); const [currentView, setCurrentView] = useState("timeGridWeek"); diff --git a/src/components/Calendar/CalendarModal.tsx b/src/components/Calendar/CalendarModal.tsx index 6dd4fbb..5d2c5c8 100644 --- a/src/components/Calendar/CalendarModal.tsx +++ b/src/components/Calendar/CalendarModal.tsx @@ -79,20 +79,6 @@ function CalendarPopover({ } }; - const palette = [ - "#D50000", - "#E67C73", - "#F4511E", - "#F6BF26", - "#33B679", - "#0B8043", - "#039BE5", - "#3F51B5", - "#7986CB", - "#8E24AA", - "#616161", - ]; - return ( onClose(e, reason)}> diff --git a/src/components/Calendar/CalendarSearch.tsx b/src/components/Calendar/CalendarSearch.tsx index b2d9e49..b1d4d1e 100644 --- a/src/components/Calendar/CalendarSearch.tsx +++ b/src/components/Calendar/CalendarSearch.tsx @@ -1,5 +1,4 @@ import CloseIcon from "@mui/icons-material/Close"; -import Autocomplete from "@mui/material/Autocomplete"; import Avatar from "@mui/material/Avatar"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; @@ -7,17 +6,11 @@ import Card from "@mui/material/Card"; import CardActions from "@mui/material/CardActions"; import CardContent from "@mui/material/CardContent"; import CardHeader from "@mui/material/CardHeader"; -import CircularProgress from "@mui/material/CircularProgress"; import IconButton from "@mui/material/IconButton"; -import ListItem from "@mui/material/ListItem"; -import ListItemAvatar from "@mui/material/ListItemAvatar"; -import ListItemText from "@mui/material/ListItemText"; import Modal from "@mui/material/Modal"; -import TextField from "@mui/material/TextField"; import Typography from "@mui/material/Typography"; import { useState } from "react"; import { useAppDispatch, useAppSelector } from "../../app/hooks"; -import { searchUsers } from "../../features/User/userAPI"; import { getCalendars } from "../../features/Calendars/CalendarApi"; import { addSharedCalendarAsync } from "../../features/Calendars/CalendarSlice"; import { ColorPicker } from "./CalendarColorPicker"; diff --git a/src/components/Calendar/CalendarSelection.tsx b/src/components/Calendar/CalendarSelection.tsx index 59d02c8..7a43327 100644 --- a/src/components/Calendar/CalendarSelection.tsx +++ b/src/components/Calendar/CalendarSelection.tsx @@ -8,7 +8,6 @@ import { useState } from "react"; import CalendarPopover from "./CalendarModal"; import { Calendars } from "../../features/Calendars/CalendarTypes"; import MoreVertIcon from "@mui/icons-material/MoreVert"; -import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import IconButton from "@mui/material/IconButton"; import Checkbox from "@mui/material/Checkbox"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; diff --git a/src/components/Calendar/TempCalendarsInput.tsx b/src/components/Calendar/TempCalendarsInput.tsx index 4f481f2..3a38092 100644 --- a/src/components/Calendar/TempCalendarsInput.tsx +++ b/src/components/Calendar/TempCalendarsInput.tsx @@ -1,4 +1,4 @@ -import { useState, useRef, useMemo } from "react"; +import { useState, useRef } from "react"; import { useAppDispatch, useAppSelector } from "../../app/hooks"; import { getTempCalendarsListAsync, diff --git a/src/components/Calendar/hooks/useCalendarEventHandlers.ts b/src/components/Calendar/hooks/useCalendarEventHandlers.ts index f44cf38..ca1a948 100644 --- a/src/components/Calendar/hooks/useCalendarEventHandlers.ts +++ b/src/components/Calendar/hooks/useCalendarEventHandlers.ts @@ -1,5 +1,4 @@ import { useCallback } from "react"; -import { CalendarApi } from "@fullcalendar/core"; import { createEventHandlers, EventHandlersProps, diff --git a/src/components/Calendar/hooks/useCalendarViewHandlers.ts b/src/components/Calendar/hooks/useCalendarViewHandlers.ts index cb00b62..77df655 100644 --- a/src/components/Calendar/hooks/useCalendarViewHandlers.ts +++ b/src/components/Calendar/hooks/useCalendarViewHandlers.ts @@ -1,5 +1,4 @@ import { useCallback } from "react"; -import { CalendarApi } from "@fullcalendar/core"; import { createViewHandlers, ViewHandlersProps, diff --git a/src/components/Menubar/Menubar.tsx b/src/components/Menubar/Menubar.tsx index bbcb17f..87a9377 100644 --- a/src/components/Menubar/Menubar.tsx +++ b/src/components/Menubar/Menubar.tsx @@ -98,10 +98,6 @@ export function Menubar({ } }; - const handleRefresh = () => { - onRefresh(); - }; - const open = Boolean(anchorEl); return ( <> diff --git a/src/features/Calendars/CalendarSlice.ts b/src/features/Calendars/CalendarSlice.ts index 0f10074..3db77ed 100644 --- a/src/features/Calendars/CalendarSlice.ts +++ b/src/features/Calendars/CalendarSlice.ts @@ -121,10 +121,7 @@ export const putEventAsync = createAsyncThunk< { calId: string; events: CalendarEvent[]; calType?: "temp" }, // Return type { cal: Calendars; newEvent: CalendarEvent; calType?: "temp" } // Arg type >("calendars/putEvent", async ({ cal, newEvent, calType }) => { - const response = await putEvent( - newEvent, - cal.ownerEmails ? cal.ownerEmails[0] : undefined - ); + await putEvent(newEvent, cal.ownerEmails ? cal.ownerEmails[0] : undefined); const eventDate = new Date(newEvent.start); const weekStart = new Date(eventDate); @@ -184,7 +181,7 @@ export const patchCalendarAsync = createAsyncThunk< patch: { name: string; desc: string; color: string }; } // Arg type >("calendars/patchCalendar", async ({ calId, calLink, patch }) => { - const response = await proppatchCalendar(calLink, patch); + await proppatchCalendar(calLink, patch); return { calId, calLink, @@ -201,7 +198,7 @@ export const removeCalendarAsync = createAsyncThunk< calLink: string; } >("calendars/removeCalendar", async ({ calId, calLink }) => { - const response = await removeCalendar(calLink); + await removeCalendar(calLink); return { calId, calLink, @@ -212,7 +209,7 @@ export const moveEventAsync = createAsyncThunk< { calId: string; events: CalendarEvent[] }, // Return type { cal: Calendars; newEvent: CalendarEvent; newURL: string } // Arg type >("calendars/moveEvent", async ({ cal, newEvent, newURL }) => { - const response = await moveEvent(newEvent, newURL); + await moveEvent(newEvent, newURL); const calEvents = (await getCalendar(cal.id, { start: formatDateToYYYYMMDDTHHMMSS(new Date(newEvent.start)), end: formatDateToYYYYMMDDTHHMMSS( @@ -239,7 +236,7 @@ export const deleteEventAsync = createAsyncThunk< { calId: string; eventId: string }, // Return type { calId: string; eventId: string; eventURL: string } // Arg type >("calendars/delEvent", async ({ calId, eventId, eventURL }) => { - const response = await deleteEvent(eventURL); + await deleteEvent(eventURL); return { calId, eventId }; }); @@ -255,7 +252,7 @@ export const createCalendarAsync = createAsyncThunk< }, // Return type { userId: string; calId: string; color: string; name: string; desc: string } // Arg type >("calendars/createCalendar", async ({ userId, calId, color, name, desc }) => { - const response = await postCalendar(userId, calId, color, name, desc); + await postCalendar(userId, calId, color, name, desc); const ownerData: any = await getUserDetails(userId.split("/")[0]); return { @@ -283,7 +280,7 @@ export const addSharedCalendarAsync = createAsyncThunk< }, // Return type { userId: string; calId: string; cal: Record } // Arg type >("calendars/addSharedCalendar", async ({ userId, calId, cal }) => { - const response = await addSharedCalendar(userId, calId, cal); + await addSharedCalendar(userId, calId, cal); const ownerData: any = await getUserDetails( cal.cal._links.self.href .replace("/calendars/", "") diff --git a/src/features/Events/EventDisplay.tsx b/src/features/Events/EventDisplay.tsx index ce20d37..e8b3974 100644 --- a/src/features/Events/EventDisplay.tsx +++ b/src/features/Events/EventDisplay.tsx @@ -1,7 +1,6 @@ import { useEffect, useState } from "react"; import { deleteEventAsync, - getEventAsync, moveEventAsync, putEventAsync, removeEvent, @@ -9,7 +8,6 @@ import { import { useAppDispatch, useAppSelector } from "../../app/hooks"; import AttendeeSelector from "../../components/Attendees/AttendeeSearch"; import { - Popover, Button, Box, Typography, @@ -41,7 +39,6 @@ import CircleIcon from "@mui/icons-material/Circle"; import CancelIcon from "@mui/icons-material/Cancel"; import CheckCircleIcon from "@mui/icons-material/CheckCircle"; import { userAttendee } from "../User/userDataTypes"; -import { TIMEZONES } from "../../utils/timezone-data"; import { Calendars } from "../Calendars/CalendarTypes"; import { CalendarEvent, RepetitionObject } from "./EventsTypes"; import { isValidUrl } from "../../utils/apiUtils"; @@ -94,7 +91,7 @@ export default function EventDisplayModal({ const [alarm, setAlarm] = useState(event?.alarm?.trigger ?? ""); const [busy, setBusy] = useState(event?.transp ?? "OPAQUE"); const [eventClass, setEventClass] = useState(event?.class ?? "PUBLIC"); - const [timezone, setTimezone] = useState(event?.timezone ?? "UTC"); + const [timezone] = useState(event?.timezone ?? "UTC"); const [newCalId, setNewCalId] = useState(event?.calId); const [calendarid, setCalendarid] = useState( calId.split("/")[0] === user.userData?.openpaasId diff --git a/src/features/Events/EventDisplayPreview.tsx b/src/features/Events/EventDisplayPreview.tsx index f70c989..7b4b52c 100644 --- a/src/features/Events/EventDisplayPreview.tsx +++ b/src/features/Events/EventDisplayPreview.tsx @@ -15,8 +15,6 @@ import { CardContent, Divider, IconButton, - Avatar, - Badge, PopoverPosition, } from "@mui/material"; import EditIcon from "@mui/icons-material/Edit"; @@ -29,18 +27,13 @@ import LocationOnIcon from "@mui/icons-material/LocationOn"; import VideocamIcon from "@mui/icons-material/Videocam"; import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; import CircleIcon from "@mui/icons-material/Circle"; -import CancelIcon from "@mui/icons-material/Cancel"; import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined"; -import { userAttendee } from "../User/userDataTypes"; import EventDisplayModal, { InfoRow, renderAttendeeBadge, - stringAvatar, } from "./EventDisplay"; -import { dlEvent, getEvent } from "./EventApi"; -import { CalendarEvent } from "./EventsTypes"; +import { dlEvent } from "./EventApi"; import EventDuplication from "../../components/Event/EventDuplicate"; -import { getCalendar } from "../Calendars/CalendarApi"; export default function EventPreviewModal({ eventId, diff --git a/src/features/Events/EventModal.tsx b/src/features/Events/EventModal.tsx index a4674ee..cc27a23 100644 --- a/src/features/Events/EventModal.tsx +++ b/src/features/Events/EventModal.tsx @@ -610,9 +610,18 @@ function EventPopover({ {hasVideoConference && meetingLink && ( <> - - Meeting link generated - +