mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 20:59:05 +00:00
calendar refresh quick action icon
This commit is contained in:
@@ -201,20 +201,32 @@ export default function ICSSettings({
|
||||
bg="gray.100"
|
||||
_hover={{ bg: "gray.200" }}
|
||||
_focus={{ bg: "gray.200" }}
|
||||
pr="48px"
|
||||
pr="90px"
|
||||
width="100%"
|
||||
/>
|
||||
<IconButton
|
||||
aria-label="Copy room URL"
|
||||
onClick={handleCopyRoomUrl}
|
||||
variant="ghost"
|
||||
position="absolute"
|
||||
right="4px"
|
||||
size="sm"
|
||||
zIndex={1}
|
||||
>
|
||||
{justCopied ? <LuCheck /> : <LuCopy />}
|
||||
</IconButton>
|
||||
<HStack position="absolute" right="4px" gap={1} zIndex={1}>
|
||||
<IconButton
|
||||
aria-label="Force sync calendar"
|
||||
onClick={handleForceSync}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
disabled={syncStatus === "syncing" || !icsUrl || !isEditing}
|
||||
>
|
||||
{syncStatus === "syncing" ? (
|
||||
<Spinner size="sm" />
|
||||
) : (
|
||||
<LuRefreshCw />
|
||||
)}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Copy room URL"
|
||||
onClick={handleCopyRoomUrl}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
>
|
||||
{justCopied ? <LuCheck /> : <LuCopy />}
|
||||
</IconButton>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Field.Root>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Table,
|
||||
@@ -9,12 +9,15 @@ import {
|
||||
Spinner,
|
||||
Badge,
|
||||
VStack,
|
||||
Icon,
|
||||
} from "@chakra-ui/react";
|
||||
import { LuLink } from "react-icons/lu";
|
||||
import { LuLink, LuRefreshCw } from "react-icons/lu";
|
||||
import { FaCalendarAlt } from "react-icons/fa";
|
||||
import type { components } from "../../../reflector-api";
|
||||
import {
|
||||
useRoomActiveMeetings,
|
||||
useRoomUpcomingMeetings,
|
||||
useRoomIcsSync,
|
||||
} from "../../../lib/apiHooks";
|
||||
|
||||
type Room = components["schemas"]["Room"];
|
||||
@@ -23,6 +26,34 @@ type CalendarEventResponse = components["schemas"]["CalendarEventResponse"];
|
||||
import { RoomActionsMenu } from "./RoomActionsMenu";
|
||||
import { MEETING_DEFAULT_TIME_MINUTES } from "../../../[roomName]/[meetingId]/constants";
|
||||
|
||||
// Custom icon component that combines calendar and refresh icons
|
||||
const CalendarSyncIcon = () => (
|
||||
<Box position="relative" display="inline-block" w="20px" h="20px">
|
||||
<Icon
|
||||
as={FaCalendarAlt}
|
||||
position="absolute"
|
||||
top={0}
|
||||
left={0}
|
||||
boxSize="20px"
|
||||
/>
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="-2px"
|
||||
right="-2px"
|
||||
bg="white"
|
||||
borderRadius="full"
|
||||
p="1px"
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
w="12px"
|
||||
h="12px"
|
||||
>
|
||||
<Icon as={LuRefreshCw} boxSize="10px" color="gray.700" />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
interface RoomTableProps {
|
||||
rooms: Room[];
|
||||
linkCopied: string;
|
||||
@@ -148,6 +179,28 @@ export function RoomTable({
|
||||
onDelete,
|
||||
loading,
|
||||
}: RoomTableProps) {
|
||||
const [syncingRooms, setSyncingRooms] = useState<Set<string>>(new Set());
|
||||
const syncMutation = useRoomIcsSync();
|
||||
|
||||
const handleForceSync = async (roomName: string) => {
|
||||
setSyncingRooms((prev) => new Set(prev).add(roomName));
|
||||
try {
|
||||
await syncMutation.mutateAsync({
|
||||
params: {
|
||||
path: { room_name: roomName },
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to sync calendar:", err);
|
||||
} finally {
|
||||
setSyncingRooms((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.delete(roomName);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box display={{ base: "none", lg: "block" }} position="relative">
|
||||
{loading && (
|
||||
@@ -217,6 +270,21 @@ export function RoomTable({
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Flex alignItems="center" gap={2}>
|
||||
{room.ics_enabled && (
|
||||
<IconButton
|
||||
aria-label="Force sync calendar"
|
||||
onClick={() => handleForceSync(room.name)}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
disabled={syncingRooms.has(room.name)}
|
||||
>
|
||||
{syncingRooms.has(room.name) ? (
|
||||
<Spinner size="sm" />
|
||||
) : (
|
||||
<CalendarSyncIcon />
|
||||
)}
|
||||
</IconButton>
|
||||
)}
|
||||
{linkCopied === room.name ? (
|
||||
<Text color="green.500" fontSize="sm">
|
||||
Copied!
|
||||
|
||||
Reference in New Issue
Block a user