/** * Settings Sidebar Component * * Collapsible sidebar for chart configuration with drag-and-drop Y-axis fields. */ import React, { useState } from "react"; import { ChevronLeft, ChevronRight, GripVertical } from "lucide-react"; type ChartType = "bar" | "line"; interface SettingsSidebarProps { isOpen: boolean; onToggle: () => void; chartType: ChartType; onChartTypeChange: (type: ChartType) => void; xAxis: string; onXAxisChange: (field: string) => void; leftYAxes: string[]; rightYAxes: string[]; availableFields: string[]; allFields: string[]; numericFields: string[]; onFieldMove: (field: string, target: "left" | "right" | "available") => void; } interface DraggableFieldProps { field: string; onDragStart: (e: React.DragEvent, field: string) => void; } function DraggableField({ field, onDragStart }: DraggableFieldProps) { return (
onDragStart(e, field)} > {field}
); } interface DropZoneProps { title: string; fields: string[]; targetId: "left" | "right" | "available"; onDrop: (field: string, target: "left" | "right" | "available") => void; onDragStart: (e: React.DragEvent, field: string) => void; } function DropZone({ title, fields, targetId, onDrop, onDragStart }: DropZoneProps) { const [isDragOver, setIsDragOver] = useState(false); const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setIsDragOver(true); }; const handleDragLeave = () => { setIsDragOver(false); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setIsDragOver(false); const field = e.dataTransfer.getData("text/plain"); if (field) { onDrop(field, targetId); } }; return (
{fields.length === 0 ? ( Drop fields here ) : ( fields.map((field) => ( )) )}
); } export function SettingsSidebar({ isOpen, onToggle, chartType, onChartTypeChange, xAxis, onXAxisChange, leftYAxes, rightYAxes, availableFields, allFields, numericFields, onFieldMove, }: SettingsSidebarProps) { const handleDragStart = (e: React.DragEvent, field: string) => { e.dataTransfer.setData("text/plain", field); e.dataTransfer.effectAllowed = "move"; }; const handleFieldDrop = (field: string, target: "left" | "right" | "available") => { // Only allow numeric fields in Y-axis zones if ((target === "left" || target === "right") && !numericFields.includes(field)) { return; } onFieldMove(field, target); }; if (!isOpen) { return (
); } return (
Settings
{/* Chart Type */}
{(["bar", "line"] as const).map((type) => ( ))}
{/* X-Axis */}
{/* Left Y-Axis Drop Zone */} {/* Right Y-Axis Drop Zone */} {/* Available Fields */}
); }