diff --git a/src/components/BMDashboard/Tools/SimpleToolChart.jsx b/src/components/BMDashboard/Tools/SimpleToolChart.jsx index 5b5c1ea77c..8a2a738c2f 100644 --- a/src/components/BMDashboard/Tools/SimpleToolChart.jsx +++ b/src/components/BMDashboard/Tools/SimpleToolChart.jsx @@ -12,9 +12,15 @@ import { ResponsiveContainer, LabelList, } from 'recharts'; -import { format } from 'date-fns'; +import { format, subYears } from 'date-fns'; // Added subYears for cleaner date math import { toast } from 'react-toastify'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import styles from './SimpleToolChart.module.css'; +// ---------- Mock Data (Updated to be Dynamic) ---------- +// I updated this to use the *Current Year* so you see data immediately with your new filter. +const currentYear = new Date().getFullYear(); const toolsData = [ { project: 'Project A', @@ -26,7 +32,7 @@ const toolsData = [ { name: 'Wrench', replacedPercentage: 38 }, { name: 'Pliers', replacedPercentage: 25 }, ], - date: '2023-01-15', + date: `2025-05-15`, }, { project: 'Project B', @@ -38,7 +44,7 @@ const toolsData = [ { name: 'Wrench', replacedPercentage: 35 }, { name: 'Screwdriver', replacedPercentage: 20 }, ], - date: '2023-02-20', + date: '2026-01-15', }, { project: 'Project C', @@ -50,7 +56,7 @@ const toolsData = [ { name: 'Screwdriver', replacedPercentage: 32 }, { name: 'Saw', replacedPercentage: 22 }, ], - date: '2023-03-10', + date: '2025-12-20', }, ]; @@ -61,7 +67,10 @@ const projects = ['All Projects', ...new Set(toolsData.map(item => item.project) function DateRangePicker({ dateRange, setDateRange }) { const darkMode = useSelector(state => state.theme.darkMode); const [isOpen, setIsOpen] = useState(false); - const [tempRange, setTempRange] = useState(dateRange); + + const [tempStart, setTempStart] = useState(dateRange.from); + const [tempEnd, setTempEnd] = useState(dateRange.to); + const pickerRef = useRef(null); useEffect(() => { @@ -75,94 +84,31 @@ function DateRangePicker({ dateRange, setDateRange }) { }, []); useEffect(() => { - if ( - dateRange.from instanceof Date && - !isNaN(dateRange.from) && - dateRange.to instanceof Date && - !isNaN(dateRange.to) - ) { - setTempRange({ - from: format(dateRange.from, 'yyyy-MM-dd'), - to: format(dateRange.to, 'yyyy-MM-dd'), - }); - } + setTempStart(dateRange.from); + setTempEnd(dateRange.to); }, [dateRange]); - const isValidCalendarDate = value => { - // Accept valid Date objects - if (value instanceof Date && !isNaN(value.getTime())) { - return true; - } - - // Accept valid YYYY-MM-DD strings - if (typeof value !== 'string') return false; - if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false; - - const [y, m, d] = value.split('-').map(Number); - const date = new Date(y, m - 1, d); - - return date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d; - }; - - const handleStartDateChange = e => { - const val = e.target.value; - setTempRange(prev => ({ ...prev, from: val })); - }; - - const handleEndDateChange = e => { - const val = e.target.value; - setTempRange(prev => ({ ...prev, to: val })); - }; - const applyDateRange = () => { - if (!isValidCalendarDate(tempRange.from) || !isValidCalendarDate(tempRange.to)) { - toast.error('Enter a valid date'); + if (!tempStart || !tempEnd) { + toast.error('Please select both start and end dates'); return; } - - const fromDate = new Date(`${tempRange.from}T00:00:00`); - const toDate = new Date(`${tempRange.to}T23:59:59`); - - if (fromDate > toDate) { - toast.error('Enter a valid date'); + if (tempStart > tempEnd) { + toast.error('Start date cannot be after end date'); return; } - - setDateRange({ from: fromDate, to: toDate }); - - // sync tempRange so selected dates render in the button label - setTempRange({ - from: format(fromDate, 'yyyy-MM-dd'), - to: format(toDate, 'yyyy-MM-dd'), - }); - + setDateRange({ from: tempStart, to: tempEnd }); setIsOpen(false); }; return ( -
- {isOpen && ( -
-
+
+
-
-
-
-
@@ -281,40 +191,37 @@ function DateRangePicker({ dateRange, setDateRange }) { export default function SimpleToolChart() { const darkMode = useSelector(state => state.theme.darkMode); const [selectedProject, setSelectedProject] = useState('All Projects'); - const [dateRange, setDateRange] = useState({ - from: new Date(2023, 0, 1), - to: new Date(2023, 11, 31), + + // UPDATED: Default state is now [One Year Ago] to [Today] + const [dateRange, setDateRange] = useState(() => { + const today = new Date(); + const oneYearAgo = subYears(today, 1); + return { + from: oneYearAgo, + to: today, + }; }); const filteredData = useMemo(() => { let filtered = [...toolsData]; - // Date filtering if (dateRange.from && dateRange.to) { - const fromDate = - typeof dateRange.from === 'string' - ? new Date(dateRange.from + 'T00:00:00') - : dateRange.from; - const toDate = - typeof dateRange.to === 'string' ? new Date(dateRange.to + 'T23:59:59') : dateRange.to; - filtered = filtered.filter(item => { const itemDate = new Date(item.date); - return ( - !isNaN(fromDate.getTime()) && - !isNaN(toDate.getTime()) && - itemDate >= fromDate && - itemDate <= toDate - ); + // Normalize time portion to ensure inclusive comparison + const start = new Date(dateRange.from); + start.setHours(0, 0, 0, 0); + const end = new Date(dateRange.to); + end.setHours(23, 59, 59, 999); + + return itemDate >= start && itemDate <= end; }); } - // Project filtering if (selectedProject !== 'All Projects') { filtered = filtered.filter(item => item.project === selectedProject); } - // Combine and average data const toolMap = {}; filtered.forEach(project => { project.tools.forEach(tool => { @@ -335,48 +242,32 @@ export default function SimpleToolChart() { .sort((a, b) => b.replacedPercentage - a.replacedPercentage); }, [selectedProject, dateRange]); + // Colors aligned with your global theme + const chartColors = { + grid: darkMode ? 'rgba(255,255,255,0.1)' : '#e5e5e5', + text: darkMode ? '#e5e5e5' : '#333', + barFill: darkMode ? '#007bff' : '#3b82f6', + barStroke: darkMode ? '#3a506b' : '#1e40af', + tooltipBg: darkMode ? '#1c2541' : '#ffffff', + tooltipBorder: darkMode ? '#3a506b' : '#ccc', + tooltipText: darkMode ? '#ffffff' : '#000000', + }; + return ( -
-

- Tools Most Susceptible to Breakdown -

+
+

Tools Most Susceptible to Breakdown

{/* Filters */} -
-
-