import { Avatar, Box, Card, CardContent, CardHeader, Typography, } from "@mui/material"; import React, { useEffect, useRef, useState } from "react"; import { stringAvatar } from "../utils/eventUtils"; import { ErrorEventChip } from "./ErrorEventChip"; import { DisplayedIcons, EventChipProps, getBestColor, getCardStyle, getEventDuration, getEventTimes, getOwnerAttendee, getTitleStyle, IconDisplayConfig, useCompactMode, } from "./EventChipUtils"; import { SimpleEventChip } from "./SimpleEventChip"; const PRIVATE_CLASSIFICATIONS = ["PRIVATE", "CONFIDENTIAL"]; export const EVENT_DURATION = { SHORT: 15, MEDIUM: 30, LONG: 60, } as const; export function EventChip({ arg, calendars, tempcalendars, errorHandler, }: EventChipProps) { const cardRef = useRef(null); const showCompact = useCompactMode(cardRef); const event = arg.event; const props = event._def.extendedProps; const { calId, temp, attendee: attendees = [], class: classification, } = props; try { // Calendar validation const calendarsSource = temp ? tempcalendars : calendars; const calendar = calendarsSource[calId]; if (!calendar) return null; // Event properties const isPrivate = PRIVATE_CLASSIFICATIONS.includes(classification); const ownerEmails = new Set( calendar.ownerEmails?.map((e) => e.toLowerCase()) ); const delegated = calendar.delegated; // Determine owner attendee const ownerAttendee = getOwnerAttendee(attendees, ownerEmails); // Handle non-owner attendee case if (attendees.length && !delegated && !ownerAttendee) { return ; } // Color and contrast logic const bestColor = getBestColor( (calendar.color as { light: string; dark: string }) ?? { light: "#fff", dark: "#000", } ); // Icon display configuration const IconDisplayed: IconDisplayConfig = { declined: ownerAttendee?.partstat === "DECLINED", tentative: ownerAttendee?.partstat === "TENTATIVE", needAction: ownerAttendee?.partstat === "NEEDS-ACTION", private: isPrivate, }; // View and time calculations const isMonthView = arg.view.type === "dayGridMonth"; const timeZone = arg.view.calendar?.getOption("timeZone") || "UTC"; const { startTime, endTime } = getEventTimes(event, timeZone); const eventLength = getEventDuration(event); const isMoreThan15 = eventLength > EVENT_DURATION.SHORT; const isMoreThan30 = eventLength > EVENT_DURATION.MEDIUM; const isMoreThan60 = eventLength > EVENT_DURATION.LONG; // Style calculation const titleStyle = getTitleStyle( bestColor, ownerAttendee?.partstat, calendar ); const cardStyle = getCardStyle( bestColor, eventLength, ownerAttendee?.partstat, calendar ); // Organizer avatar const OrganizerAvatar = event._def.extendedProps.organizer ? stringAvatar( event._def.extendedProps.organizer?.cn ?? event._def.extendedProps.organizer?.cal_address ) : { style: {}, children: null }; return ( {event.title} ) : ( {(!isMoreThan30 || isMonthView) && !event._def.extendedProps.allday && ( {startTime} )} {DisplayedIcons(IconDisplayed)} {event.title} ) } subheader={ isMoreThan30 && !isMonthView && !event._def.extendedProps.allday && ( {startTime} {!showCompact && ` - ${endTime}`} ) } /> {isMoreThan60 && !showCompact && !isMonthView && !event._def.extendedProps.allday && ( {event._def.extendedProps.location && ( {event._def.extendedProps.location} )} {event._def.extendedProps.description && ( {event._def.extendedProps.description} )} )} {(isMoreThan60 || eventLength === 60) && !isMonthView && !event._def.extendedProps.allday && event._def.extendedProps.organizer && !showCompact && (window as any).displayOrgAvatar && ( )} ); } catch (e) { return ( ); } }