'use client'; import { useCallback, useRef, useState } from 'react'; import { cn } from '@/lib/utils'; import { Section, SECTION_COLORS } from '@/types/audio'; interface SectionBlockProps { section: Section; pixelsPerBar: number; durationBars: number; onResize: (id: string, startBar: number, endBar: number) => void; onMove: (id: string, startBar: number) => void; onSelect: (id: string) => void; onDelete: (id: string) => void; selected?: boolean; } export function SectionBlock({ section, pixelsPerBar, durationBars, onResize, onMove, onSelect, onDelete, selected = false, }: SectionBlockProps) { const [dragging, setDragging] = useState<'move' | 'start' | 'end' | null>(null); const dragStart = useRef({ x: 0, startBar: 0, endBar: 0 }); const left = section.startBar * pixelsPerBar; const width = (section.endBar - section.startBar) * pixelsPerBar; const color = SECTION_COLORS[section.type]; const handleMouseDown = useCallback( (type: 'move' | 'start' | 'end', e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); setDragging(type); dragStart.current = { x: e.clientX, startBar: section.startBar, endBar: section.endBar, }; onSelect(section.id); const handleMouseMove = (e: MouseEvent) => { const deltaX = e.clientX - dragStart.current.x; const deltaBars = Math.round(deltaX / pixelsPerBar); const { startBar, endBar } = dragStart.current; if (type === 'start') { const newStart = Math.max(0, Math.min(endBar - 1, startBar + deltaBars)); onResize(section.id, newStart, endBar); } else if (type === 'end') { const newEnd = Math.max(startBar + 1, Math.min(durationBars, endBar + deltaBars)); onResize(section.id, startBar, newEnd); } else { const duration = endBar - startBar; const newStart = Math.max( 0, Math.min(durationBars - duration, startBar + deltaBars) ); onMove(section.id, newStart); } }; const handleMouseUp = () => { setDragging(null); document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); }, [section, pixelsPerBar, durationBars, onResize, onMove, onSelect] ); const handleContextMenu = useCallback( (e: React.MouseEvent) => { e.preventDefault(); onDelete(section.id); }, [section.id, onDelete] ); return (
handleMouseDown('start', e)} />
handleMouseDown('move', e)} > {section.name || section.type}
handleMouseDown('end', e)} />
); }