'use client'; import * as React from 'react'; import { cn } from '@/lib/utils/cn'; import type { Marker } from '@/types/marker'; import { Flag, Edit2, Trash2 } from 'lucide-react'; import { Button } from '@/components/ui/Button'; export interface MarkerTimelineProps { markers: Marker[]; duration: number; currentTime: number; onMarkerClick?: (marker: Marker) => void; onMarkerEdit?: (marker: Marker) => void; onMarkerDelete?: (markerId: string) => void; onSeek?: (time: number) => void; className?: string; } export function MarkerTimeline({ markers, duration, currentTime, onMarkerClick, onMarkerEdit, onMarkerDelete, onSeek, className, }: MarkerTimelineProps) { const containerRef = React.useRef(null); const [hoveredMarkerId, setHoveredMarkerId] = React.useState(null); const timeToX = React.useCallback( (time: number): number => { if (!containerRef.current) return 0; const width = containerRef.current.clientWidth; return (time / duration) * width; }, [duration] ); return (
{/* Markers */} {markers.map((marker) => { const x = timeToX(marker.time); const isHovered = hoveredMarkerId === marker.id; if (marker.type === 'point') { return (
setHoveredMarkerId(marker.id)} onMouseLeave={() => setHoveredMarkerId(null)} onClick={() => { onMarkerClick?.(marker); onSeek?.(marker.time); }} > {/* Marker line */}
{/* Marker flag */} {/* Hover tooltip with actions */} {isHovered && (
{marker.name}
{marker.description && (
{marker.description}
)}
{onMarkerEdit && ( )} {onMarkerDelete && ( )}
)}
); } else { // Region marker const endX = timeToX(marker.endTime || marker.time); const width = endX - x; return (
setHoveredMarkerId(marker.id)} onMouseLeave={() => setHoveredMarkerId(null)} onClick={() => { onMarkerClick?.(marker); onSeek?.(marker.time); }} > {/* Region background */}
{/* Region borders */}
{/* Region label */}
{marker.name}
{/* Hover tooltip with actions */} {isHovered && (
{marker.name}
{marker.description && (
{marker.description}
)}
{onMarkerEdit && ( )} {onMarkerDelete && ( )}
)}
); } })}
); }