+
Material Usage Dashboard
+
+ {/* Filters Section */}
+
+
+
+
Filters
+
Select options to filter the chart data
+
+ {/* Project Filter */}
+
+
+
+
- {/* Material Type Filter */}
-
-
-
-
+ {/* Material Type Filter */}
+
+
+
+
- {/* Increase Over Last Week Filter */}
-
-
- {/* Increase Counter */}
- {showIncreaseOnly && increasePercentage !== 0 && (
-
-
- Usage Trend
-
-
-
0
- ? `${styles.trendBadge} ${styles.trendBadgeIncrease}`
- : `${styles.trendBadge} ${styles.trendBadgeDecrease}`
- }
- >
- {increasePercentage > 0 ? '↑' : '↓'} {Math.abs(increasePercentage).toFixed(1)}%
-
-
- {increasePercentage > 0
- ? 'Increase in material usage'
- : 'Decrease in material usage'}{' '}
- compared to last week
-
+ {/* Increase Counter */}
+ {showIncreaseOnly && increasePercentage !== 0 && (
+
+
Usage Trend
+
+ 0
+ ? `${styles.trendBadge} ${styles.trendBadgeIncrease}`
+ : `${styles.trendBadge} ${styles.trendBadgeDecrease}`
+ }
+ >
+ {increasePercentage > 0 ? '↑' : '↓'} {Math.abs(increasePercentage).toFixed(1)}%
+
+
+ {increasePercentage > 0
+ ? 'Increase in material usage'
+ : 'Decrease in material usage'}{' '}
+ compared to last week
+
+
-
- )}
-
+ )}
+
- {/* Chart Section */}
-
-
-
-
- Material Usage Breakdown
- {selectedMaterial !== 'all' &&
- ` - ${selectedMaterial.charAt(0).toUpperCase() + selectedMaterial.slice(1)}`}
-
-
- {mockProjects.find(p => p.id === selectedProject)?.name}
-
-
-
- {loading && (
-
- )}
- {!loading && chartData && (
-
-
+
+
+
+ Material Usage Breakdown
+ {selectedMaterial !== 'all' &&
+ ` - ${selectedMaterial.charAt(0).toUpperCase() + selectedMaterial.slice(1)}`}
+
+
+ {mockProjects.find(p => p.id === selectedProject)?.name}
+
+
+
+ {loading && (
+
+ )}
+ {!loading && chartData && (
+
+
{
- const label = context.label || '';
- const value = context.raw || 0;
- return `${label} (${value} units)`;
+ tooltip: {
+ callbacks: {
+ label: context => {
+ const label = context.label || '';
+ const value = context.raw || 0;
+ return `${label} (${value} units)`;
+ },
},
},
},
- },
- }}
- plugins={plugins}
- />
-
- )}
- {!loading && !chartData &&
No data available
}
-
- {/* Material Breakdown List */}
- {chartData && !loading && (
-
-
Material Breakdown
-
- {chartData.datasets[0].data.map((value, index) => {
- const label = chartData.labels[index].split(':')[0];
- const color = chartData.datasets[0].backgroundColor[index];
- return (
-
+ }}
+ plugins={[
+ {
+ id: 'donutTitle',
+ afterDatasetsDraw(chart) {
+ const { width, height } = chart;
+ const ctx = chart.ctx;
+
+ ctx.save();
+
+ // Get the center point
+ const centerX = width / 2;
+ const centerY = height / 2;
+
+ // Set text properties
+ const fontSize = Math.floor(height / 12);
+ ctx.font = `bold ${fontSize}px 'Helvetica Neue', Helvetica, Arial, sans-serif`;
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ ctx.fillStyle = darkMode ? '#ffffff' : '#1a1a1a';
+
+ // Draw text
+ const text = 'Materials';
+ ctx.fillText(text, centerX, centerY);
+
+ ctx.restore();
+ },
+ },
+ ]}
+ />
+
+ )}
+ {!loading && !chartData &&
No data available
}
+
+ {/* Material Breakdown List */}
+ {chartData && !loading && (
+
+
Material Breakdown
+
+ {chartData.datasets[0].data.map((value, index) => {
+ const label = chartData.labels[index].split(':')[0];
+ const color = chartData.datasets[0].backgroundColor[index];
+ return (
-
-
- {label}
-
-
- {value}{' '}
-
- units
-
-
+ key={`${chartData.labels[index]}-${value}`}
+ className={styles.materialBreakdownItem}
+ >
+
+
+
{label}
+
+ {value} units
+
+
-
- );
- })}
+ );
+ })}
+
-
- )}
+ )}
+
-
+ >
);
}
diff --git a/src/components/MaterialSummary/MaterialSummary.module.css b/src/components/MaterialSummary/MaterialSummary.module.css
index 46e601a0e6..dfd79dd6c1 100644
--- a/src/components/MaterialSummary/MaterialSummary.module.css
+++ b/src/components/MaterialSummary/MaterialSummary.module.css
@@ -1,74 +1,75 @@
.dashboardWrapper {
- max-width: 1200px;
- margin: 0 auto;
- padding: 16px;
-}
-
-.dashboardTitle {
- font-size: 1.875rem;
- font-weight: bold;
- margin-bottom: 24px;
-}
-
-.gridContainer {
- display: grid;
- gap: 24px;
-}
-
-@media (min-width: 1024px) {
- .gridContainer {
- grid-template-columns: 1fr 3fr;
- }
-}
-
-.filterPanel {
- display: flex;
- flex-direction: column;
- gap: 24px;
-}
-
-.filterCard {
- background: white;
- border-radius: 8px;
- box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
- padding: 16px;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ background-color: var(--bg-color);
+ min-height: calc(100vh - 70px);
+ transition: background-color 0.3s ease, color 0.3s ease;
+ --bg-color: #f3f4f6;
+ --text-color: #000;
+ --card-bg: #ffffff;
+ --card-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
+ --secondary-text: #6b7280;
+ --border-color: #d1d5db;
+ --input-bg: #fff;
+ --input-text: #000;
+ --input-border: #d1d5db;
+ --accent-card: #f9fafb;
+ display: block;
+ visibility: visible;
}
-.filterCardTitle {
- font-size: 1.25rem;
- font-weight: 600;
- margin-bottom: 4px;
+.dashboardWrapper.darkMode {
+ --bg-color: #1B2A41;
+ --text-color: #f1f1f1;
+ --card-bg: #2a3f5f;
+ --card-shadow: 0 4px 6px -1px rgba(0,0,0,0.3);
+ --secondary-text: #b0b0b0;
+ --border-color: #4a5f7f;
+ --input-bg: #1f3a52;
+ --input-text: #f1f1f1;
+ --input-border: #4a5f7f;
+ --accent-card: #1f3a52;
}
-.filterCardDesc {
- color: #6b7280;
- font-size: 0.875rem;
+.dashboardTitle {
+ font-size: 2rem;
+ font-weight: 700;
+ margin: 0;
+ padding: 28px 40px 24px 40px;
+ color: var(--text-color);
+ text-align: center;
+ border-bottom: 1px solid var(--border-color);
}
.filterFields {
display: flex;
flex-direction: column;
- gap: 16px;
+ gap: 18px;
+ margin-top: 8px;
}
.fieldGroup {
display: flex;
flex-direction: column;
- gap: 8px;
+ gap: 6px;
}
.fieldLabel {
display: block;
font-size: 0.875rem;
font-weight: 500;
+ color: var(--text-color);
}
.selectInput {
width: 100%;
padding: 8px;
- border: 1px solid #d1d5db;
+ border: 1px solid var(--input-border);
border-radius: 6px;
outline: none;
+ background-color: var(--input-bg);
+ color: var(--input-text);
}
.checkboxGroup {
@@ -86,19 +87,22 @@
.checkboxLabel {
font-size: 0.875rem;
cursor: pointer;
+ color: var(--text-color);
}
.increaseCard {
- background: white;
+ background: var(--card-bg);
border-radius: 8px;
- box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
+ box-shadow: var(--card-shadow);
padding: 16px;
+ color: var(--text-color);
}
.increaseCardTitle {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
+ color: var(--text-color);
}
.increaseTrendRow {
@@ -127,22 +131,28 @@
.increaseText {
margin-left: 8px;
font-size: 0.875rem;
+ color: var(--text-color);
}
.chartPanel {
- background: white;
+ background: var(--card-bg);
border-radius: 8px;
- box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
- padding: 16px;
+ box-shadow: var(--card-shadow);
+ padding: 20px;
+ color: var(--text-color);
+ visibility: visible;
+ display: block;
+ width: 100%;
}
.chartPanelTitle {
font-size: 1.25rem;
font-weight: 600;
+ color: var(--text-color);
}
.chartPanelDesc {
- color: #6b7280;
+ color: var(--secondary-text);
font-size: 0.875rem;
}
@@ -150,7 +160,8 @@
display: flex;
justify-content: center;
align-items: center;
- min-height: 220px;
+ min-height: 280px;
+ margin: 24px 0;
}
.loadingArea {
@@ -176,7 +187,7 @@
.materialBreakdown {
margin-top: 24px;
- border-top: 1px solid #e5e7eb;
+ border-top: 1px solid var(--border-color);
padding-top: 16px;
}
@@ -184,40 +195,107 @@
font-size: 1.125rem;
font-weight: 500;
margin-bottom: 12px;
+ color: var(--text-color);
}
.materialBreakdownGrid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px,1fr));
- gap: 16px;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 20px;
+ margin-top: 16px;
}
.materialBreakdownItem {
display: flex;
+ flex-direction: column;
align-items: center;
+ justify-content: center;
gap: 12px;
- padding: 12px;
- border-radius: 6px;
- background: #f9fafb;
+ padding: 16px;
+ border-radius: 8px;
+ background: var(--accent-card);
+ color: var(--text-color);
+ text-align: center;
}
.materialBreakdownDot {
- width: 16px;
- height: 16px;
+ width: 14px;
+ height: 14px;
border-radius: 50%;
+ flex-shrink: 0;
}
.materialBreakdownName {
- font-weight: 500;
+ font-weight: 600;
+ color: var(--text-color);
+ font-size: 0.95rem;
}
.materialBreakdownValue {
- font-size: 1.5rem;
+ font-size: 1.75rem;
font-weight: bold;
+ color: var(--text-color);
+ margin-top: 4px;
}
.materialBreakdownUnit {
font-size: 0.875rem;
- color: #6b7280;
+ color: var(--secondary-text);
font-weight: normal;
}
+
+.gridContainer {
+ display: grid;
+ gap: 32px;
+ align-items: start;
+ grid-template-columns: 320px 1fr;
+ max-width: 100%;
+ margin: 0;
+ padding: 32px 40px;
+ visibility: visible;
+ width: 100%;
+}
+
+@media (max-width: 1024px) {
+ .gridContainer {
+ grid-template-columns: 1fr;
+ padding: 32px 24px;
+ }
+}
+
+.filterPanel {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.filterCard {
+ background: var(--card-bg);
+ border-radius: 8px;
+ box-shadow: var(--card-shadow);
+ padding: 20px;
+ color: var(--text-color);
+ height: fit-content;
+ visibility: visible;
+ display: block;
+}
+
+.filterCardTitle {
+ font-size: 1.25rem;
+ font-weight: 600;
+ margin-bottom: 4px;
+ color: var(--text-color);
+}
+
+.filterCardDesc {
+ color: var(--secondary-text);
+ font-size: 0.875rem;
+}
+
+.filterCardHeader {
+ margin-bottom: 16px;
+}
+
+.chartPanelHeader {
+ margin-bottom: 16px;
+}