mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 15:35:22 +02:00
feat: improve 'Group By' dropdown UI/UX in Grid tab (click-to-open and click-outside to close)
This commit is contained in:
+46
-23
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useMemo, useEffect } from 'react';
|
import React, { useState, useMemo, useEffect, useRef } from 'react';
|
||||||
import {
|
import {
|
||||||
LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer
|
LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer
|
||||||
} from 'recharts';
|
} from 'recharts';
|
||||||
@@ -233,6 +233,19 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData =
|
|||||||
const [visibleMetrics, setVisibleMetrics] = useState<('sellOut' | 'units')[]>(['sellOut', 'units']);
|
const [visibleMetrics, setVisibleMetrics] = useState<('sellOut' | 'units')[]>(['sellOut', 'units']);
|
||||||
const [showAdsMetrics, setShowAdsMetrics] = useState(true);
|
const [showAdsMetrics, setShowAdsMetrics] = useState(true);
|
||||||
const [showAttributedSales, setShowAttributedSales] = useState(false);
|
const [showAttributedSales, setShowAttributedSales] = useState(false);
|
||||||
|
const [showDimensionMenu, setShowDimensionMenu] = useState(false);
|
||||||
|
const dimensionRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// Close dimension menu on click outside
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (dimensionRef.current && !dimensionRef.current.contains(event.target as Node)) {
|
||||||
|
setShowDimensionMenu(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Calculate Ads Summary for the Grid
|
// Calculate Ads Summary for the Grid
|
||||||
const adsSummary = useMemo(() => {
|
const adsSummary = useMemo(() => {
|
||||||
@@ -682,31 +695,41 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData =
|
|||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-3 w-full lg:w-auto">
|
<div className="flex flex-wrap items-center gap-3 w-full lg:w-auto">
|
||||||
{/* Dimensions Selector */}
|
{/* Dimensions Selector */}
|
||||||
<div className="relative group z-30">
|
<div className="relative z-30" ref={dimensionRef}>
|
||||||
<button className="flex items-center gap-2 px-3 py-2 bg-slate-800 hover:bg-slate-700 border border-slate-700 rounded-lg text-sm font-medium transition-colors">
|
<button
|
||||||
|
onClick={() => setShowDimensionMenu(!showDimensionMenu)}
|
||||||
|
className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-all border shadow-sm ${showDimensionMenu ? 'bg-slate-700 text-white border-indigo-500/50 ring-1 ring-indigo-500/30' : 'bg-slate-800 text-slate-300 border-slate-700 hover:bg-slate-700'}`}
|
||||||
|
>
|
||||||
<span className="text-slate-300">Group By:</span>
|
<span className="text-slate-300">Group By:</span>
|
||||||
<span className="text-white font-bold">{effectiveDimensions.length} Columns</span>
|
<span className="text-white font-bold">{effectiveDimensions.length} Columns</span>
|
||||||
<svg className="w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
|
<svg className={`w-4 h-4 text-slate-400 transition-transform duration-200 ${showDimensionMenu ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
|
||||||
</button>
|
</button>
|
||||||
<div className="absolute top-full left-0 mt-2 w-48 bg-slate-900 border border-slate-700 rounded-xl shadow-xl p-2 hidden group-hover:block animate-fade-in">
|
{showDimensionMenu && (
|
||||||
{DIMENSION_OPTIONS.map(dim => (
|
<div className="absolute top-full left-0 mt-2 w-56 bg-slate-900 border border-slate-700 rounded-xl shadow-2xl p-2 animate-fade-in z-50">
|
||||||
<label key={dim.value} className="flex items-center gap-2 p-2 hover:bg-slate-800 rounded cursor-pointer">
|
<div className="px-2 py-1.5 mb-1 border-b border-slate-800">
|
||||||
<input
|
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">Select Columns</span>
|
||||||
type="checkbox"
|
</div>
|
||||||
checked={selectedDimensions.includes(dim.value)}
|
{DIMENSION_OPTIONS.map(dim => (
|
||||||
onChange={() => {
|
<label key={dim.value} className="flex items-center gap-3 p-2.5 hover:bg-white/[0.03] rounded-lg cursor-pointer group transition-colors">
|
||||||
if (selectedDimensions.includes(dim.value)) {
|
<input
|
||||||
setSelectedDimensions(selectedDimensions.filter(d => d !== dim.value));
|
type="checkbox"
|
||||||
} else {
|
checked={selectedDimensions.includes(dim.value)}
|
||||||
setSelectedDimensions([...selectedDimensions, dim.value]);
|
onChange={() => {
|
||||||
}
|
if (selectedDimensions.includes(dim.value)) {
|
||||||
}}
|
setSelectedDimensions(selectedDimensions.filter(d => d !== dim.value));
|
||||||
className="rounded border-slate-600 bg-slate-800 text-primary focus:ring-primary"
|
} else {
|
||||||
/>
|
setSelectedDimensions([...selectedDimensions, dim.value]);
|
||||||
<span className="text-sm text-slate-300">{dim.label}</span>
|
}
|
||||||
</label>
|
}}
|
||||||
))}
|
className="w-4 h-4 rounded border-slate-600 bg-slate-800 text-indigo-500 focus:ring-indigo-500/50 transition-all"
|
||||||
</div>
|
/>
|
||||||
|
<span className={`text-sm font-medium transition-colors ${selectedDimensions.includes(dim.value) ? 'text-white' : 'text-slate-400 group-hover:text-slate-300'}`}>
|
||||||
|
{dim.label}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Filter Builder Trigger */}
|
{/* Filter Builder Trigger */}
|
||||||
|
|||||||
Reference in New Issue
Block a user