made styling the cards stat tiles
This commit is contained in:
parent
d1ef7f4838
commit
f8c3658243
1
.env
Normal file
1
.env
Normal file
@ -0,0 +1 @@
|
||||
VITE_GOOGLE_MAPS_API_KEY=AIzaSyDMWCLgNVsigqHdgwgdV0yurVhy6n5dnb0
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,5 +24,4 @@ dist-ssr
|
||||
*.sw?
|
||||
|
||||
# vite-plugin-pwa dev output
|
||||
dev-dist
|
||||
.env
|
||||
dev-dist
|
||||
@ -203,7 +203,7 @@ export function DailyLogCard({ row, onPunchOut, isDetailView = false }: { row: R
|
||||
)}
|
||||
|
||||
{isPunchedIn && onPunchOut && (
|
||||
<div style={{ padding: '16px 6px 0px 6px' }}>
|
||||
<div>
|
||||
<Button
|
||||
variant="danger"
|
||||
full
|
||||
|
||||
@ -60,11 +60,9 @@ export function OrderCard({ row, fields, isDetailView = false }: { row: Record<s
|
||||
|
||||
const productsSection = gridVal.length > 0 ? (
|
||||
<div style={{
|
||||
marginTop: '16px',
|
||||
backgroundColor: 'var(--tiles-card-bg)',
|
||||
border: '1px solid #e2e8f0',
|
||||
borderRadius: '16px',
|
||||
padding: '16px'
|
||||
marginTop: '16px',
|
||||
marginLeft: '-12px',
|
||||
marginRight: '-12px'
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '16px' }}>
|
||||
<div style={{ backgroundColor: '#e6f9ed', padding: '6px', borderRadius: '50%' }}>
|
||||
|
||||
@ -109,7 +109,10 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.z-card-footer:not(:last-child) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.z-card-footer-item {
|
||||
|
||||
@ -154,18 +154,18 @@ export function DailyLogDetail({ instanceId, onBack }: DailyLogDetailProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-nowrap items-center gap-3 w-full lg:w-auto overflow-x-auto pb-2 min-w-0">
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-3 text-center min-w-[100px] flex-1">
|
||||
<div className="text-[10px] font-bold text-primary uppercase tracking-wider mb-0.5">PROD. CALLS</div>
|
||||
<div className="text-[20px] font-extrabold text-primary">{prodCalls}</div>
|
||||
<div className="grid grid-cols-3 gap-2 w-full lg:w-auto">
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-2 text-center flex flex-col justify-center">
|
||||
<div className="text-[9px] font-bold text-primary uppercase tracking-wider mb-0.5 whitespace-nowrap overflow-hidden text-ellipsis">PROD. CALLS</div>
|
||||
<div className="text-[18px] font-extrabold text-primary leading-none mt-0.5">{prodCalls}</div>
|
||||
</div>
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-3 text-center min-w-[100px] flex-1">
|
||||
<div className="text-[10px] font-bold text-primary uppercase tracking-wider mb-0.5">NON PROD.</div>
|
||||
<div className="text-[20px] font-extrabold text-primary">{nonProdCalls}</div>
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-2 text-center flex flex-col justify-center">
|
||||
<div className="text-[9px] font-bold text-primary uppercase tracking-wider mb-0.5 whitespace-nowrap overflow-hidden text-ellipsis">NON PROD.</div>
|
||||
<div className="text-[18px] font-extrabold text-primary leading-none mt-0.5">{nonProdCalls}</div>
|
||||
</div>
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-3 text-center min-w-[110px] flex-1">
|
||||
<div className="text-[10px] font-bold text-primary uppercase tracking-wider mb-0.5">TOTAL CALLS</div>
|
||||
<div className="text-sm font-bold text-primary mt-1 whitespace-nowrap overflow-hidden text-ellipsis">
|
||||
<div className="bg-primary-light-bg border border-primary-light-border rounded-2xl p-2 text-center flex flex-col justify-center">
|
||||
<div className="text-[9px] font-bold text-primary uppercase tracking-wider mb-0.5 whitespace-nowrap overflow-hidden text-ellipsis">TOTAL CALLS</div>
|
||||
<div className="text-[18px] font-extrabold text-primary leading-none mt-0.5">
|
||||
{Number(prodCalls) + Number(nonProdCalls)}
|
||||
</div>
|
||||
</div>
|
||||
@ -173,8 +173,8 @@ export function DailyLogDetail({ instanceId, onBack }: DailyLogDetailProps) {
|
||||
</div>
|
||||
|
||||
<div className="border-t border-slate-100 pt-4">
|
||||
<div className="flex items-center gap-8 overflow-x-auto pb-2">
|
||||
<div className="flex items-center gap-3 min-w-max">
|
||||
<div className="flex flex-col gap-4 pb-2">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-emerald-50 text-emerald-600 flex items-center justify-center text-xs shrink-0">
|
||||
<Clock size={16} />
|
||||
</div>
|
||||
@ -187,7 +187,7 @@ export function DailyLogDetail({ instanceId, onBack }: DailyLogDetailProps) {
|
||||
</div>
|
||||
|
||||
{checkOutTime && (
|
||||
<div className="flex items-center gap-3 min-w-max">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-blue-50 text-blue-600 flex items-center justify-center text-xs shrink-0">
|
||||
<Clock size={16} />
|
||||
</div>
|
||||
|
||||
@ -47,7 +47,7 @@ export function AnalyticsChart({ data }: AnalyticsChartProps) {
|
||||
|
||||
return (
|
||||
<Card key={chart.chart_uid || idx} title={title} className="shadow-sm">
|
||||
<div className="h-[320px] w-full mt-4">
|
||||
<div className="h-[320px] w-full mt-4 [&_.recharts-wrapper]:!outline-none [&_.recharts-surface]:!outline-none [&_*]:!outline-none">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={formattedRows} margin={{ top: 25, right: 10, left: -20, bottom: 0 }}>
|
||||
<defs>
|
||||
@ -81,6 +81,7 @@ export function AnalyticsChart({ data }: AnalyticsChartProps) {
|
||||
fill={`url(#colorGradient-${idx})`}
|
||||
radius={[8, 8, 0, 0]}
|
||||
maxBarSize={40}
|
||||
activeBar={{ stroke: '#cbd5e1', strokeWidth: 1, fill: `url(#colorGradient-${idx})` }}
|
||||
>
|
||||
<LabelList dataKey="value" position="top" fill="#475569" fontSize={12} fontWeight="bold" />
|
||||
</Bar>
|
||||
|
||||
@ -39,7 +39,6 @@ export function Select({
|
||||
}: SelectProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
@ -56,39 +55,7 @@ export function Select({
|
||||
o.label.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
|
||||
const updatePosition = useCallback(() => {
|
||||
if (containerRef.current) {
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const dropdownHeight = 260; // Max height approximation
|
||||
const spaceBelow = window.innerHeight - rect.bottom;
|
||||
const openUpwards = spaceBelow < dropdownHeight && rect.top > dropdownHeight;
|
||||
|
||||
setDropdownStyle({
|
||||
position: 'fixed',
|
||||
left: `${rect.left}px`,
|
||||
minWidth: `${rect.width}px`,
|
||||
width: 'max-content',
|
||||
maxWidth: 'min(92vw, 450px)',
|
||||
zIndex: 999999,
|
||||
...(openUpwards
|
||||
? { bottom: `${window.innerHeight - rect.top + 4}px` }
|
||||
: { top: `${rect.bottom + 4}px` }),
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
updatePosition();
|
||||
const handleScrollOrResize = () => updatePosition();
|
||||
window.addEventListener('resize', handleScrollOrResize);
|
||||
window.addEventListener('scroll', handleScrollOrResize, true);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleScrollOrResize);
|
||||
window.removeEventListener('scroll', handleScrollOrResize, true);
|
||||
};
|
||||
}
|
||||
}, [isOpen, updatePosition]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: MouseEvent) => {
|
||||
@ -117,7 +84,7 @@ export function Select({
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className={cn('flex flex-col gap-1.5 font-sans relative w-full', className)}>
|
||||
<div ref={containerRef} className={cn('flex flex-col gap-1.5 font-sans relative w-full', isOpen ? 'z-50' : 'z-10', className)}>
|
||||
{label && (
|
||||
<label className="text-sm font-semibold text-slate-700">
|
||||
{label}
|
||||
@ -148,12 +115,11 @@ export function Select({
|
||||
<ChevronDown size={15} className={cn("transition-transform duration-150 text-faint shrink-0 ml-1", isOpen && "rotate-180")} />
|
||||
</div>
|
||||
|
||||
{/* Portaled Dropdown Menu Overlay (bypasses parent overflow:hidden clipping) */}
|
||||
{isOpen && !disabled && createPortal(
|
||||
{/* Dropdown Menu Overlay */}
|
||||
{isOpen && !disabled && (
|
||||
<div
|
||||
ref={dropdownRef}
|
||||
style={dropdownStyle}
|
||||
className="bg-card border border-border-default rounded-md shadow-2xl overflow-hidden flex flex-col max-h-64 animate-in fade-in-50 duration-100"
|
||||
className="absolute left-0 top-[calc(100%+4px)] w-full bg-card border border-border-default rounded-md shadow-2xl overflow-hidden flex flex-col max-h-64 animate-in fade-in-50 duration-100 z-50"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{searchable && (
|
||||
@ -178,7 +144,7 @@ export function Select({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="overflow-y-auto flex-1 py-1">
|
||||
<div className="overflow-y-auto overflow-x-auto flex-1 py-1">
|
||||
{filteredOptions.length > 0 ? (
|
||||
filteredOptions.map((opt) => {
|
||||
const isSelected = opt.value === currentValue;
|
||||
@ -187,11 +153,11 @@ export function Select({
|
||||
key={opt.value}
|
||||
onClick={() => handleSelect(opt.value)}
|
||||
className={cn(
|
||||
"px-3 py-2 text-sm flex items-center justify-between cursor-pointer transition-colors",
|
||||
"px-3 py-2 text-sm flex items-center justify-between cursor-pointer transition-colors w-max min-w-full",
|
||||
isSelected ? "bg-navy-50/20 text-navy-700 font-semibold" : "hover:bg-black/5 text-foreground"
|
||||
)}
|
||||
>
|
||||
<span className="whitespace-normal break-words leading-tight flex-1">{opt.label}</span>
|
||||
<span className="whitespace-nowrap leading-tight flex-1 pr-4">{opt.label}</span>
|
||||
{isSelected && <Check size={14} className="text-navy-600 shrink-0 ml-2" />}
|
||||
</div>
|
||||
);
|
||||
@ -202,8 +168,7 @@ export function Select({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Hidden Native Select for Required/Form Validation */}
|
||||
@ -262,9 +227,8 @@ export function MultiSelect({
|
||||
}: MultiSelectProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});
|
||||
const [draftValues, setDraftValues] = useState<string[]>(value ?? []);
|
||||
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -288,39 +252,7 @@ export function MultiSelect({
|
||||
o.label.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
|
||||
const updatePosition = useCallback(() => {
|
||||
if (containerRef.current) {
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const dropdownHeight = 320;
|
||||
const spaceBelow = window.innerHeight - rect.bottom;
|
||||
const openUpwards = spaceBelow < dropdownHeight && rect.top > dropdownHeight;
|
||||
|
||||
setDropdownStyle({
|
||||
position: 'fixed',
|
||||
left: `${rect.left}px`,
|
||||
minWidth: `${rect.width}px`,
|
||||
width: 'max-content',
|
||||
maxWidth: 'min(92vw, 450px)',
|
||||
zIndex: 999999,
|
||||
...(openUpwards
|
||||
? { bottom: `${window.innerHeight - rect.top + 4}px` }
|
||||
: { top: `${rect.bottom + 4}px` }),
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
updatePosition();
|
||||
const handleScrollOrResize = () => updatePosition();
|
||||
window.addEventListener('resize', handleScrollOrResize);
|
||||
window.addEventListener('scroll', handleScrollOrResize, true);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleScrollOrResize);
|
||||
window.removeEventListener('scroll', handleScrollOrResize, true);
|
||||
};
|
||||
}
|
||||
}, [isOpen, updatePosition]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: MouseEvent) => {
|
||||
@ -363,7 +295,7 @@ export function MultiSelect({
|
||||
: `${selectedLabels.length} selected`;
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className={cn('flex flex-col gap-1.5 font-sans relative w-full', className)}>
|
||||
<div ref={containerRef} className={cn('flex flex-col gap-1.5 font-sans relative w-full', isOpen ? 'z-50' : 'z-10', className)}>
|
||||
{label && (
|
||||
<label className="text-xs font-bold text-slate-700">
|
||||
{label}
|
||||
@ -386,12 +318,11 @@ export function MultiSelect({
|
||||
<ChevronDown size={15} className={cn("transition-transform duration-150 text-faint shrink-0 ml-1", isOpen && "rotate-180")} />
|
||||
</div>
|
||||
|
||||
{/* Portaled Dropdown Menu Overlay */}
|
||||
{isOpen && !disabled && createPortal(
|
||||
{/* Dropdown Menu Overlay */}
|
||||
{isOpen && !disabled && (
|
||||
<div
|
||||
ref={dropdownRef}
|
||||
style={dropdownStyle}
|
||||
className="bg-card border border-border-default rounded-md shadow-2xl overflow-hidden flex flex-col max-h-72 animate-in fade-in-50 duration-100 z-[999999]"
|
||||
className="absolute left-0 top-[calc(100%+4px)] w-full bg-card border border-border-default rounded-md shadow-2xl overflow-hidden flex flex-col max-h-72 animate-in fade-in-50 duration-100 z-50"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{searchable && (
|
||||
@ -416,7 +347,7 @@ export function MultiSelect({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="overflow-y-auto flex-1 py-1 min-h-[100px]">
|
||||
<div className="overflow-y-auto overflow-x-auto flex-1 py-1 min-h-[100px]">
|
||||
{filteredOptions.length > 0 ? (
|
||||
filteredOptions.map((opt) => {
|
||||
const isSelected = draftValues.includes(opt.value);
|
||||
@ -425,7 +356,7 @@ export function MultiSelect({
|
||||
key={opt.value}
|
||||
onClick={() => toggleOption(opt.value)}
|
||||
className={cn(
|
||||
"px-3 py-2 text-xs flex items-center gap-2.5 cursor-pointer transition-colors select-none",
|
||||
"px-3 py-2 text-xs flex items-center gap-2.5 cursor-pointer transition-colors select-none w-max min-w-full",
|
||||
isSelected ? "bg-navy-50/40 text-navy-900 font-semibold" : "hover:bg-black/5 text-strong"
|
||||
)}
|
||||
>
|
||||
@ -433,9 +364,9 @@ export function MultiSelect({
|
||||
type="checkbox"
|
||||
checked={isSelected}
|
||||
onChange={() => {}}
|
||||
className="rounded border-slate-300 text-navy-600 focus:ring-navy-500 pointer-events-none h-3.5 w-3.5"
|
||||
className="shrink-0 rounded border-slate-300 text-navy-600 focus:ring-navy-500 pointer-events-none h-3.5 w-3.5"
|
||||
/>
|
||||
<span className="whitespace-normal break-words leading-tight flex-1">{opt.label}</span>
|
||||
<span className="whitespace-nowrap leading-tight flex-1 pr-4">{opt.label}</span>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
@ -464,8 +395,7 @@ export function MultiSelect({
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(hint || error) && (
|
||||
|
||||
@ -31,7 +31,7 @@ export function StatsTile({ tile, idx = 0 }: StatsTileProps) {
|
||||
return (
|
||||
<div className={`z-stats-tile z-stats-tile--${colorTheme}`}>
|
||||
<div className="z-stats-icon-wrapper">
|
||||
<Icon size={26} className="z-stats-icon" strokeWidth={2.5} />
|
||||
<Icon size={22} className="z-stats-icon" strokeWidth={2.5} />
|
||||
</div>
|
||||
<div className="z-stats-content">
|
||||
<span className="z-stats-label">{displayLabel}</span>
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Base Tile */
|
||||
@ -25,7 +24,7 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
padding: 12px 16px;
|
||||
background-color: #FFFBF4;
|
||||
border-radius: var(--z-border-radius-lg, 12px);
|
||||
box-shadow: var(--block-shadow);
|
||||
@ -43,13 +42,13 @@
|
||||
}
|
||||
|
||||
.z-stats-icon-wrapper {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 14px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@ -88,7 +87,7 @@
|
||||
}
|
||||
|
||||
.z-stats-label {
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
/* subtle gray */
|
||||
@ -98,7 +97,7 @@
|
||||
}
|
||||
|
||||
.z-stats-value {
|
||||
font-size: 32px;
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
line-height: 1.1;
|
||||
color: var(--primary-color);
|
||||
|
||||
@ -187,7 +187,7 @@ export function RecordView({
|
||||
}, [activeFilters]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-5 w-full max-w-full overflow-x-hidden">
|
||||
<div className="flex flex-col gap-4 w-full max-w-full overflow-x-hidden">
|
||||
{!hideTiles && <StatsTiles tiles={tileValues} />}
|
||||
|
||||
{!hideChart && <AnalyticsChart data={chartData} />}
|
||||
|
||||
@ -76,11 +76,11 @@ export function AnalyticsPage() {
|
||||
// Decide chart type based on key
|
||||
if (chart.key === 'status_overview') {
|
||||
return (
|
||||
<div key={chart.chart_uid} className="bg-white rounded-2xl shadow-[0_2px_12px_-4px_rgba(0,0,0,0.08)] border border-slate-100 p-5 flex flex-col gap-4">
|
||||
<div key={chart.chart_uid} className="bg-[#FFFBF4] rounded-2xl shadow-[0_2px_12px_-4px_rgba(0,0,0,0.08)] border border-slate-200 p-5 flex flex-col gap-4">
|
||||
<div>
|
||||
<h2 className="text-[15px] font-bold text-slate-800 tracking-tight">{title}</h2>
|
||||
</div>
|
||||
<div className="h-64 w-full">
|
||||
<div className="h-64 w-full [&_.recharts-wrapper]:!outline-none [&_.recharts-surface]:!outline-none [&_*]:!outline-none">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie
|
||||
@ -108,11 +108,11 @@ export function AnalyticsPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={chart.chart_uid} className="bg-white rounded-2xl shadow-[0_2px_12px_-4px_rgba(0,0,0,0.08)] border border-slate-100 p-5 flex flex-col gap-4">
|
||||
<div key={chart.chart_uid} className="bg-[#FFFBF4] rounded-2xl shadow-[0_2px_12px_-4px_rgba(0,0,0,0.08)] border border-slate-200 p-5 flex flex-col gap-4">
|
||||
<div>
|
||||
<h2 className="text-[15px] font-bold text-slate-800 tracking-tight">{title}</h2>
|
||||
</div>
|
||||
<div className="h-64 w-full">
|
||||
<div className="h-64 w-full [&_.recharts-wrapper]:!outline-none [&_.recharts-surface]:!outline-none [&_*]:!outline-none">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={data} margin={{ top: 10, right: 10, left: -20, bottom: 0 }}>
|
||||
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f1f5f9" />
|
||||
@ -122,7 +122,13 @@ export function AnalyticsPage() {
|
||||
cursor={{ fill: '#f8fafc' }}
|
||||
contentStyle={{ borderRadius: '8px', border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
|
||||
/>
|
||||
<Bar dataKey="value" fill={COLORS[index % COLORS.length]} radius={[4, 4, 0, 0]} barSize={40} />
|
||||
<Bar
|
||||
dataKey="value"
|
||||
fill={COLORS[index % COLORS.length]}
|
||||
radius={[4, 4, 0, 0]}
|
||||
barSize={40}
|
||||
activeBar={{ stroke: '#cbd5e1', strokeWidth: 1, fill: COLORS[index % COLORS.length] }}
|
||||
/>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user