diff --git a/src/components/MaterialSummary/MaterialSummary.jsx b/src/components/MaterialSummary/MaterialSummary.jsx index ede2267635..31b56278e6 100644 --- a/src/components/MaterialSummary/MaterialSummary.jsx +++ b/src/components/MaterialSummary/MaterialSummary.jsx @@ -108,7 +108,7 @@ export default function MaterialUsageDashboard() { return ( <>
-
+

Material Usage Dashboard

{/* Filters Section */} @@ -238,6 +238,7 @@ export default function MaterialUsageDashboard() { padding: 10, font: { size: 12 }, boxWidth: 12, + color: darkMode ? '#f1f5f9' : '#1f2937', }, }, tooltip: { @@ -249,6 +250,13 @@ export default function MaterialUsageDashboard() { }, }, }, + datalabels: { + color: '#000', + font: { + size: 14, + weight: 'bold', + }, + }, }, }} plugins={[ @@ -316,7 +324,7 @@ export default function MaterialUsageDashboard() {
- + ); } diff --git a/src/components/MaterialSummary/MaterialSummary.module.css b/src/components/MaterialSummary/MaterialSummary.module.css index 7abd763302..1b65415888 100644 --- a/src/components/MaterialSummary/MaterialSummary.module.css +++ b/src/components/MaterialSummary/MaterialSummary.module.css @@ -1,92 +1,89 @@ -/* stylelint-disable */ +/* stylelint-disable no-descending-specificity */ .dashboardWrapper { - max-width: 1200px; - margin: 0 auto; - padding: 16px; - background-color: var(--bg-color, #fff); - color: var(--text-color, #000); - min-height: 100vh; + --bg-color: #f3f4f6; + --text-color: #1f2937; + --title-color: #1f2937; + --text-secondary: #6b7280; + --card-bg: #fff; + --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 10%); + --border-color: #d1d5db; + --input-bg: #fff; + --input-text: #1f2937; + --input-border: #d1d5db; + --focus-border-color: #3b82f6; + --accent-card: #f9fafb; + + width: 100%; + min-height: calc(100vh - 70px); + margin: 0; + padding: 28px 40px 40px; + background-color: var(--bg-color); + color: var(--text-color); + font-family: inherit; + transition: background-color 0.3s ease, color 0.3s ease; } .dashboardTitle { - font-size: 1.875rem; - font-weight: bold; - margin-bottom: 24px; - color: var(--title-color, #000); + margin: 0 0 24px; + color: var(--title-color); + font-size: 2rem; + font-weight: 700; + text-align: center; } .gridContainer { display: grid; - gap: 24px; -} - -@media (width >= 1024px) { - .gridContainer { - grid-template-columns: 1fr 3fr; - } + grid-template-columns: 320px minmax(0, 1fr); + gap: 32px; + align-items: start; + width: 100%; + max-width: 1280px; + margin: 0 auto; } .filterPanel { display: flex; flex-direction: column; gap: 24px; + min-width: 0; } -.filterCard { - background: var(--card-bg, white); +.filterCard, +.increaseCard, +.chartPanel { + background: var(--card-bg); + border: 1px solid var(--border-color); border-radius: 8px; - box-shadow: var(--shadow, 0 4px 6px -1px rgb(0 0 0 / 10%)); - padding: 16px; + box-shadow: var(--card-shadow); + color: var(--text-color); } -.filterCardTitle { +.filterCard { + height: fit-content; + padding: 20px; +} + +.filterCardHeader, +.chartPanelHeader { + margin-bottom: 16px; +} + +.filterCardTitle, +.chartPanelTitle, +.increaseCardTitle { + color: var(--title-color); font-size: 1.25rem; font-weight: 600; +} + +.filterCardTitle { margin-bottom: 4px; - color: var(--title-color, #000); } .filterCardDesc { - color: var(--text-secondary, #6b7280); - font-size: 0.875rem; - width: 100%; - padding: 0; margin: 0; - background-color: var(--bg-color, #f3f4f6); - min-height: calc(100vh - 70px); - transition: background-color 0.3s ease, color 0.3s ease; - - --bg-color: #f3f4f6; - --text-color: #000; - --card-bg: #fff; - --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 10%); - --secondary-text: #6b7280; - --border-color: #d1d5db; - --input-bg: #fff; - --input-text: #000; - --input-border: #d1d5db; - --accent-card: #f9fafb; - - display: block; - visibility: visible; -.dashboardWrapper.darkMode { - --bg-color: #1b2a41; - --text-color: #f1f1f1; - --card-bg: #2a3f5f; - --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 30%); - --secondary-text: #b0b0b0; - --border-color: #4a5f7f; - --input-bg: #1f3a52; - --input-text: #f1f1f1; - --input-border: #4a5f7f; - --accent-card: #1f3a52; - font-size: 2rem; - font-weight: 700; - margin: 0; - padding: 28px 40px 24px; - color: var(--text-color); - text-align: center; - border-bottom: 1px solid var(--border-color); + color: var(--text-secondary); + font-size: 0.875rem; } .filterFields { @@ -104,10 +101,9 @@ .fieldLabel { display: block; + color: var(--text-color); font-size: 0.875rem; font-weight: 500; - color: var(--label-color, #000); - color: var(--text-color); } .selectInput { @@ -116,14 +112,17 @@ border: 1px solid var(--input-border); border-radius: 6px; outline: none; - background-color: var(--input-bg, #fff); - color: var(--text-color, #000); background-color: var(--input-bg); color: var(--input-text); } .selectInput:focus { - border-color: var(--focus-border-color, #3b82f6); + border-color: var(--focus-border-color); +} + +.selectInput option { + background-color: var(--input-bg); + color: var(--input-text); } .checkboxGroup { @@ -134,46 +133,40 @@ } .checkboxInput { - height: 16px; width: 16px; + height: 16px; } .checkboxLabel { + margin: 0; + color: var(--text-color); font-size: 0.875rem; cursor: pointer; - color: var(--text-color, #000); - color: var(--text-color); } .increaseCard { - background: var(--card-bg); - border-radius: 8px; - box-shadow: var(--shadow, 0 4px 6px -1px rgb(0 0 0 / 10%)); - box-shadow: var(--card-shadow); padding: 16px; - color: var(--text-color); } .increaseCardTitle { - font-size: 1.25rem; - font-weight: 600; margin-bottom: 8px; - color: var(--title-color, #000); - color: var(--text-color); } .increaseTrendRow { display: flex; align-items: center; + gap: 8px; } .trendBadge { display: inline-flex; align-items: center; + justify-content: center; padding: 2px 10px; border-radius: 9999px; font-size: 0.75rem; font-weight: 500; + white-space: nowrap; } .trendBadgeIncrease { @@ -187,41 +180,30 @@ } .increaseText { - margin-left: 8px; - font-size: 0.875rem; - color: var(--text-color, #000); color: var(--text-color); + font-size: 0.875rem; } .chartPanel { - background: var(--card-bg); - border-radius: 8px; - box-shadow: var(--shadow, 0 4px 6px -1px rgb(0 0 0 / 10%)); - padding: 16px; - box-shadow: var(--card-shadow); - padding: 20px; - color: var(--text-color); - visibility: visible; - display: block; width: 100%; + min-width: 0; + padding: 20px; } .chartPanelTitle { - font-size: 1.25rem; - font-weight: 600; - color: var(--title-color, #000); - color: var(--text-color); + margin: 0; } .chartPanelDesc { - color: var(--secondary-text); + margin: 4px 0 0; + color: var(--text-secondary); font-size: 0.875rem; } .chartArea { display: flex; - justify-content: center; align-items: center; + justify-content: center; min-height: 280px; margin: 24px 0; } @@ -234,23 +216,25 @@ } .loadingSpinner { - animation: spin 1s linear infinite; - border-radius: 50%; - height: 48px; width: 48px; - border-bottom: 2px solid #3b82f6; + height: 48px; margin-bottom: 8px; + border-bottom: 2px solid #3b82f6; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +.loadingText, +.noDataText { + margin: 0; } .loadingText { - color: var(--text-color, #000); color: var(--text-color); - margin: 0; } .noDataText { - color: var(--secondary-text); - margin: 0; + color: var(--text-secondary); } @keyframes spin { @@ -265,21 +249,20 @@ .materialBreakdown { margin-top: 24px; - border-top: 1px solid var(--border-color); padding-top: 16px; + border-top: 1px solid var(--border-color); } .materialBreakdownTitle { + margin-bottom: 12px; + color: var(--title-color); font-size: 1.125rem; font-weight: 500; - margin-bottom: 12px; - color: var(--title-color, #000); - color: var(--text-color); } .materialBreakdownGrid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 16px; } @@ -290,6 +273,7 @@ align-items: center; justify-content: center; gap: 12px; + min-width: 0; padding: 16px; border-radius: 8px; background: var(--accent-card); @@ -298,100 +282,77 @@ } .materialBreakdownDot { + flex-shrink: 0; width: 14px; height: 14px; border-radius: 50%; - flex-shrink: 0; } .materialBreakdownName { - font-weight: 500; - color: var(--text-color, #000); - font-weight: 600; + margin: 0; color: var(--text-color); font-size: 0.95rem; + font-weight: 600; } .materialBreakdownValue { - font-size: 1.75rem; - font-weight: bold; - color: var(--text-color, #000); + margin: 4px 0 0; color: var(--text-color); - margin-top: 4px; + font-size: 1.75rem; + font-weight: 700; } .materialBreakdownUnit { + color: var(--text-secondary); font-size: 0.875rem; - color: var(--secondary-text); - font-weight: normal; + font-weight: 400; } -/* ============ DARK MODE ============ */ .dashboardWrapper.darkMode { --bg-color: #1b2a41; - --text-color: #fff; + --text-color: #f1f5f9; --title-color: #fff; - --text-secondary: #e0e0e0; + --text-secondary: #cbd5e1; --card-bg: #2b3e59; - --input-bg: #3a506b; + --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 30%); --border-color: #4a5a77; + --input-bg: #3a506b; + --input-text: #fff; + --input-border: #60789b; --focus-border-color: #e8a71c; - --label-color: #e0e0e0; - --shadow: 0 4px 6px -1px rgb(255 255 255 / 10%); - --breakdown-item-bg: #3a506b; -.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%; + --accent-card: #3a506b; +} + +/* dark mode , usage trend contrast */ +.dashboardWrapper.darkMode .trendBadgeIncrease { + background: #052d46; } @media (width <= 1024px) { + .dashboardWrapper { + padding: 28px 24px 36px; + } + .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); -} +@media (width <= 640px) { + .dashboardWrapper { + padding: 20px 16px 32px; + } -.filterCardDesc { - color: var(--secondary-text); - font-size: 0.875rem; -} + .dashboardTitle { + font-size: 1.5rem; + } -.filterCardHeader { - margin-bottom: 16px; -} + .materialBreakdownGrid { + grid-template-columns: 1fr; + } -.chartPanelHeader { - margin-bottom: 16px; + .increaseTrendRow { + align-items: flex-start; + flex-direction: column; + } } -}} \ No newline at end of file diff --git a/src/components/ProjectStatus/ProjectStatus.jsx b/src/components/ProjectStatus/ProjectStatus.jsx index 8b7d529062..518208fe07 100644 --- a/src/components/ProjectStatus/ProjectStatus.jsx +++ b/src/components/ProjectStatus/ProjectStatus.jsx @@ -14,6 +14,9 @@ ChartJS.register(ArcElement, Tooltip, Legend); const centerTextPlugin = { id: 'centerText', afterDraw(chart) { + const centerTextOptions = chart.options.plugins.centerText; + if (!centerTextOptions?.display) return; + const { ctx } = chart; const { width, height } = chart; const isDarkMode = chart.options.plugins.centerText?.darkMode || false; @@ -177,6 +180,7 @@ export default function ProjectStatus() { }, title: { display: false }, centerText: { + display: true, total: data?.totalProjects ?? 0, darkMode, },