/**
* 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 */}
);
}