import { timeFormatter, timeRangeFormatter, TXCalendarEvent } from "@core/app/theme/scheduleView"; import { useEffect, useState, useRef } from "react"; import { DaySchedule } from "react-schedule-view"; import style from "../../theme/scheduleView.module.css"; import Avatar from "@components/Avatar/Avatar"; export interface CalendarRowViewProps { daySchedules: DaySchedule[]; handleEventClick: (event: TXCalendarEvent) => void; onEventLongPress?: (event: TXCalendarEvent) => void; } type CalendarRowViewData = { name: string; events: TXCalendarEvent[]; }; // Custom component to manage long press state per item function EventItem({ item, onClick, onLongPress, }: { item: TXCalendarEvent; onClick: () => void; onLongPress?: () => void; }) { const timerRef = useRef(null); const isLongPress = useRef(false); const isScrolling = useRef(false); const startPos = useRef({ x: 0, y: 0 }); const [pressed, setPressed] = useState(false); const getAvatar = (data: string | undefined) => { let imageAvatar = ""; if (data) { imageAvatar = data; } return imageAvatar; }; const startPress = (e: React.TouchEvent | React.MouseEvent) => { isLongPress.current = false; isScrolling.current = false; if ('touches' in e) { startPos.current = { x: e.touches[0].clientX, y: e.touches[0].clientY }; } setPressed(true); timerRef.current = setTimeout(() => { isLongPress.current = true; setPressed(false); if (window.navigator && window.navigator.vibrate) { window.navigator.vibrate(50); // Haptic feedback } if (onLongPress) { onLongPress(); } }, 500); }; const handleTouchMove = (e: React.TouchEvent) => { if (!isScrolling.current) { const moveX = e.touches[0].clientX; const moveY = e.touches[0].clientY; if ( Math.abs(moveX - startPos.current.x) > 10 || Math.abs(moveY - startPos.current.y) > 10 ) { isScrolling.current = true; cancelPress(); } } }; const cancelPress = () => { setPressed(false); if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } }; const handleClick = () => { cancelPress(); if (!isLongPress.current) { onClick(); } }; return (
e.preventDefault()} // Prevent context menu on long press >

{item.title}

{timeRangeFormatter(item.startTime, item.endTime)} {item.payment && ( 💰 )}
); } export default function CalendarRowView(props: CalendarRowViewProps) { const { daySchedules = [ { name: "", events: [], }, ], handleEventClick = () => {}, onEventLongPress, } = props; const [data, setData] = useState([]); const getTimeHeader = (event: TXCalendarEvent): string => { return timeFormatter(event.startTime); }; useEffect(() => { const auxData: CalendarRowViewData[] = []; for (const item of daySchedules[0].events) { const time = getTimeHeader(item); const check = auxData.find((x) => x.name === time); if (check) { check.events.push(item); } else { auxData.push({ name: time, events: [item], }); } } setData(auxData.sort((a, b) => a.name.localeCompare(b.name))); }, [daySchedules]); return ( <> {data.map((event: CalendarRowViewData) => { return (
{event.name}
{event.events.map((item: TXCalendarEvent) => ( handleEventClick(item)} onLongPress={() => { if (onEventLongPress && item.appointmentId) { onEventLongPress(item); } }} /> ))}
); })} ); }