-
-
setDateRange(r => ({ ...r, to: e.target.value }))}
- className={styles.input}
- />
+
+
+ {/* Project Filter */}
+
+
+
+
+
+ {/* Date Filter */}
+
+
+ {/* Top N */}
+
+
+ e.target.select()}
+ onChange={e => {
+ const val = e.target.value;
+ if (val === '') {
+ setTopN('');
+ return;
+ }
+ const num = Number(val);
+ if (!Number.isNaN(num)) {
+ setTopN(num);
+ }
+ }}
+ onBlur={() => {
+ setTopN(prev => {
+ const n = Number(prev);
+ if (Number.isNaN(n)) return 8;
+ return Math.max(1, Math.min(8, n));
+ });
+ }}
+ className={`${styles.dateInput}`}
+ />
+
-
-
-
e.target.select()}
- onChange={e => {
- const val = e.target.value;
-
- // Allow empty input while typing
- if (val === '') {
- setTopN('');
- return;
- }
-
- const num = Number(val);
- if (!Number.isNaN(num)) {
- setTopN(num);
- }
- }}
- onBlur={() => {
- // Clamp value only when leaving the field
- setTopN(prev => {
- const n = Number(prev);
- if (Number.isNaN(n)) return 1;
- return Math.max(1, Math.min(20, n));
- });
- }}
- className={styles.input}
- />
+ {/* Action Buttons */}
+
+
+
-
-
-
-
-
-
-
- {/* Chart */}
-
- {chartData.length === 0 ? (
-
No data for the selected filters.
- ) : (
-
+ {/* Chart */}
+
+
-
+
} />
-
+
`${fmtPct(v)}%`}
- style={{ fill: darkMode ? '#e2e8f0' : '#374151' }}
+ formatter={v => `${v}%`}
+ style={{ fill: darkMode ? '#ffffff' : '#374151' }}
/>
- )}
+
);
diff --git a/src/components/MostWastedMaterials/MostWastedMaterials.module.css b/src/components/MostWastedMaterials/MostWastedMaterials.module.css
index 35fcc71cc5..23a9f8636e 100644
--- a/src/components/MostWastedMaterials/MostWastedMaterials.module.css
+++ b/src/components/MostWastedMaterials/MostWastedMaterials.module.css
@@ -1,249 +1,170 @@
-/* MostWastedMaterials.module.css */
-
-/* Light mode (default) */
-.container {
+.mostWastedMaterialsContainer {
+ padding: 20px;
+ font-family: Arial, sans-serif;
width: 100%;
- max-width: 1200px;
- margin: 0 auto;
- padding: 24px;
- background-color: #f9fafb;
- min-height: 100vh;
- transition: background-color 0.3s ease, color 0.3s ease;
-}
-
-.darkMode {
- background-color: #1a202c !important;
- color: #e2e8f0 !important;
+ background-color: #fff;
+ box-sizing: border-box;
+ padding-bottom: 80px;
+ height: 100vh;
}
-.header {
- text-align: center;
- margin-bottom: 32px;
+.mostWastedMaterialsHeader {
+ margin-bottom: 24px;
}
-.title {
- font-size: 32px;
- font-weight: bold;
+.headerTitle {
+ font-size: 30px;
+ font-weight: 500;
color: #111827;
- margin: 0;
- transition: color 0.3s ease;
-}
-
-.darkMode .title {
- color: #e2e8f0;
-}
-
-.subtitle {
- color: #6b7280;
- margin-top: 8px;
- font-size: 14px;
- transition: color 0.3s ease;
-}
-
-.darkMode .subtitle {
- color: #a0aec0;
}
-.card {
+.mostWastedMaterialsCard {
background-color: #ffffff;
border-radius: 8px;
border: 1px solid #e5e7eb;
padding: 24px;
- margin-bottom: 24px;
+ margin-bottom: 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
- transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
-.darkMode .card {
- background-color: #2d3748;
- border-color: #4a5568;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+.mostWastedMaterialsFilter {
+ display: flex;
+ gap: 24px;
+ flex-wrap: wrap;
+ align-items: flex-end;
}
-.filterGrid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
- gap: 20px;
+.mostWastedMaterialsFilterItem {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ min-width: 200px;
}
.filterLabel {
- display: block;
+ font-weight: 500;
font-size: 14px;
- font-weight: 600;
color: #374151;
- margin-bottom: 8px;
- transition: color 0.3s ease;
-}
-
-.darkMode .filterLabel {
- color: #cbd5e0;
}
-.dropdownButton {
- width: 100%;
- padding: 8px 16px;
- text-align: left;
- background-color: #ffffff;
- border: 1px solid #d1d5db;
- border-radius: 6px;
- cursor: pointer;
- display: flex;
- justify-content: space-between;
- align-items: center;
- transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
-}
-
-.darkMode .dropdownButton {
- background-color: #4a5568;
- border-color: #718096;
- color: #e2e8f0;
-}
-
-.dropdownButton:hover {
- border-color: #9ca3af;
+.dateFilterGrid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 8px;
}
-.darkMode .dropdownButton:hover {
- border-color: #a0aec0;
- background-color: #4a5568;
+.dateLabel {
+ font-size: 12px;
+ color: #6b7280;
}
-.dropdownMenu {
- position: absolute;
- z-index: 10;
+.dateInput {
width: 100%;
- margin-top: 4px;
- background-color: #ffffff;
+ padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
- transition: background-color 0.3s ease, border-color 0.3s ease;
+ font-size: 14px;
}
-.darkMode .dropdownMenu {
- background-color: #4a5568;
- border-color: #718096;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
+.actionButtons {
+ display: flex;
+ gap: 12px;
+ margin-top: 16px;
+ flex-wrap: wrap;
}
-.dropdownItem {
- width: 100%;
+.actionButton {
padding: 8px 16px;
- text-align: left;
- background-color: transparent;
- border: none;
- cursor: pointer;
- color: #374151;
- transition: background-color 0.2s ease, color 0.3s ease;
-}
-
-.darkMode .dropdownItem {
- color: #e2e8f0;
-}
-
-.input {
- width: 100%;
- padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
- font-size: 14px;
background-color: #ffffff;
color: #374151;
- transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
+ font-size: 14px;
+ cursor: pointer;
+ transition: background-color 0.2s;
}
-.darkMode .input {
- background-color: #4a5568;
- border-color: #718096;
- color: #e2e8f0;
+.actionButton:hover {
+ background-color: #f3f4f6;
}
-.input:focus {
- outline: none;
- border-color: #3b82f6;
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
+.chartWrapper {
+ background-color: #ffffff;
+ border-radius: 8px;
+ border: 1px solid #e5e7eb;
+ margin-bottom: 100px;
+ padding: 14px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ height: 500px;
}
-.darkMode .input:focus {
- border-color: #63b3ed;
- box-shadow: 0 0 0 3px rgba(99, 179, 237, 0.2);
+.chartContainer {
+ width: 100%;
+ height: 100%;
}
-.actionButtons {
- margin-top: 16px;
- display: flex;
- gap: 12px;
- flex-wrap: wrap;
+.chartGrid {
+ stroke: #e5e7eb;
}
-.actionButton {
- padding: 8px 12px;
- border: 1px solid #d1d5db;
- border-radius: 6px;
- background-color: #fff;
- cursor: pointer;
- color: #374151;
- font-size: 14px;
- transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
+/* Dark Mode Styles */
+.darkMode .mostWastedMaterialsContainer {
+ background-color: #1b2a41;
}
-.darkMode .actionButton {
- background-color: #4a5568;
- border-color: #718096;
- color: #e2e8f0;
+.darkMode .headerTitle {
+ color: #f9fafb;
}
-.actionButton:hover {
- background-color: #f3f4f6;
+.darkMode .mostWastedMaterialsCard {
+ background-color: #1f2937;
+ border-color: #374151;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
-.darkMode .actionButton:hover {
- background-color: #5a6578;
+.darkMode .filterLabel {
+ color: #d1d5db;
}
-.chartContainer {
- width: 100%;
- height: 500px;
+.darkMode .dateLabel {
+ color: #9ca3af;
}
-.noData {
- height: 500px;
- display: grid;
- place-items: center;
- color: #6b7280;
- transition: color 0.3s ease;
+.darkMode .dateInput {
+ background-color: #374151;
+ border-color: #4b5563;
+ color: #f3f4f6;
+ color-scheme: dark;
}
-.darkMode .noData {
- color: #a0aec0;
+.darkMode .actionButton {
+ background-color: #374151;
+ border-color: #4b5563;
+ color: #f3f4f6;
}
-/* Chart specific styles */
-.darkMode .recharts-cartesian-grid-horizontal line,
-.darkMode .recharts-cartesian-grid-vertical line {
- stroke: #4a5568;
+.darkMode .actionButton:hover {
+ background-color: #4b5563;
}
-.darkMode .recharts-x-axis .recharts-cartesian-axis-tick-value,
-.darkMode .recharts-y-axis .recharts-cartesian-axis-tick-value {
- fill: #cbd5e0;
+.darkMode .chartWrapper {
+ background-color: #1f2937;
+ border-color: #374151;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
-.darkMode .recharts-x-axis .recharts-cartesian-axis-line,
-.darkMode .recharts-y-axis .recharts-cartesian-axis-line {
- stroke: #718096;
+.darkMode .chartGrid {
+ stroke: #374151;
}
-.darkMode .recharts-tooltip-wrapper {
- background-color: #2d3748 !important;
- border-color: #4a5568 !important;
+.darkMode :global(.recharts-bar-rectangle) {
+ fill: #3b82f6;
}
-.darkMode .recharts-tooltip-item {
- color: #e2e8f0 !important;
+.darkMode :global(.recharts-bar-rectangle:hover) {
+ fill: #93c5fd !important;
}
-.darkMode .recharts-default-tooltip {
- background-color: #2d3748 !important;
- border: 1px solid #4a5568 !important;
-}
\ No newline at end of file
+.darkMode :global(.recharts-label-list) text {
+ fill: #ffffff;
+}
diff --git a/src/components/MostWastedMaterials/Tooltip.jsx b/src/components/MostWastedMaterials/Tooltip.jsx
new file mode 100644
index 0000000000..5d72b45eef
--- /dev/null
+++ b/src/components/MostWastedMaterials/Tooltip.jsx
@@ -0,0 +1,17 @@
+// Custom Tooltip Component
+import styles from './Tooltip.module.css';
+import { useSelector } from 'react-redux';
+export default function CustomTooltip({ active, payload, label }) {
+ const darkMode = useSelector(state => state.theme.darkMode);
+ if (active && payload && payload.length) {
+ return (
+
+
+
{label}
+
Waste: {payload[0].value}%
+
+
+ );
+ }
+ return null;
+}
diff --git a/src/components/MostWastedMaterials/Tooltip.module.css b/src/components/MostWastedMaterials/Tooltip.module.css
new file mode 100644
index 0000000000..0457af183f
--- /dev/null
+++ b/src/components/MostWastedMaterials/Tooltip.module.css
@@ -0,0 +1,35 @@
+.tooltipWrapper {
+ background-color: #ffffff;
+ border: 1px solid #e5e7eb;
+ border-radius: 8px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ padding: 12px;
+}
+
+.tooltipLabel {
+ font-weight: 500;
+ margin: 0 0 4px 0;
+}
+
+.tooltipLabel.labelBlue {
+ color: #3b82f6 !important;
+}
+
+.darkMode .tooltipLabel.labelBlue {
+ color: #60a5fa !important;
+}
+
+.tooltipValue {
+ font-size: 14px;
+ color: #6b7280;
+ margin: 0;
+}
+
+.darkMode .tooltipWrapper {
+ background-color: #1f2937; /* dark gray */
+ border: 1px solid #374151;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
+}
+.darkMode .tooltipValue {
+ color: #d1d5db;
+}
diff --git a/src/components/MostWastedMaterials/mockData.js b/src/components/MostWastedMaterials/mockData.js
new file mode 100644
index 0000000000..eebd56b9f5
--- /dev/null
+++ b/src/components/MostWastedMaterials/mockData.js
@@ -0,0 +1,41 @@
+// Mock data for demonstration
+export const mockProjects = [
+ { id: 'all', name: 'All Projects' },
+ { id: 'project-1', name: 'Construction Site A' },
+ { id: 'project-2', name: 'Office Building B' },
+ { id: 'project-3', name: 'Residential Complex C' },
+];
+
+export const mockData = {
+ all: [
+ { material: 'Concrete', wastePercentage: 15.8, date: '2024-01-15' },
+ { material: 'Steel Rebar', wastePercentage: 12.3, date: '2024-02-12' },
+ { material: 'Lumber', wastePercentage: 11.7, date: '2024-03-08' },
+ { material: 'Drywall', wastePercentage: 9.4, date: '2024-04-05' },
+ { material: 'Insulation', wastePercentage: 8.9, date: '2024-05-22' },
+ { material: 'Tiles', wastePercentage: 7.2, date: '2024-06-14' },
+ { material: 'Paint', wastePercentage: 6.8, date: '2024-07-09' },
+ { material: 'Electrical Wire', wastePercentage: 5.1, date: '2024-08-18' },
+ ],
+ 'project-1': [
+ { material: 'Concrete', wastePercentage: 18.2, date: '2024-02-10' },
+ { material: 'Steel Rebar', wastePercentage: 14.1, date: '2024-03-16' },
+ { material: 'Lumber', wastePercentage: 10.3, date: '2024-05-03' },
+ { material: 'Drywall', wastePercentage: 8.7, date: '2024-06-21' },
+ { material: 'Insulation', wastePercentage: 7.9, date: '2024-08-02' },
+ ],
+ 'project-2': [
+ { material: 'Drywall', wastePercentage: 13.5, date: '2024-01-28' },
+ { material: 'Steel Rebar', wastePercentage: 11.8, date: '2024-04-11' },
+ { material: 'Concrete', wastePercentage: 10.9, date: '2024-06-07' },
+ { material: 'Tiles', wastePercentage: 9.2, date: '2024-07-19' },
+ { material: 'Paint', wastePercentage: 8.4, date: '2024-09-04' },
+ ],
+ 'project-3': [
+ { material: 'Lumber', wastePercentage: 16.3, date: '2024-02-05' },
+ { material: 'Insulation', wastePercentage: 12.7, date: '2024-03-27' },
+ { material: 'Drywall', wastePercentage: 11.1, date: '2024-05-18' },
+ { material: 'Paint', wastePercentage: 9.8, date: '2024-07-01' },
+ { material: 'Tiles', wastePercentage: 6.5, date: '2024-08-23' },
+ ],
+};