Skip to content

Commit ec94c11

Browse files
authored
Refactor getClassNames function and cleanup code
1 parent 6bea3f9 commit ec94c11

1 file changed

Lines changed: 109 additions & 115 deletions

File tree

src/components/LBDashboard/LBDashboard.jsx

Lines changed: 109 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState, useEffect, useMemo } from 'react';
22
import PropTypes from 'prop-types';
33
import { useSelector } from 'react-redux';
44
import moment from 'moment';
5+
56
import {
67
Container,
78
Button,
@@ -65,8 +66,8 @@ const propertiesData = [
6566
{ property: 'Room 5', value: 3.0 },
6667
];
6768

68-
// const getClassNames = (baseClass, darkClass, darkMode) =>
69-
// `${baseClass} ${darkMode ? darkClass : ''}`;
69+
const getClassNames = (baseClass, darkClass, darkMode) =>
70+
`${baseClass} ${darkMode ? darkClass : ''}`;
7071

7172
function GraphCard({ title, metricLabel, darkMode }) {
7273
return (
@@ -156,12 +157,6 @@ CategoryControls.propTypes = {
156157
onToggleDD: PropTypes.func.isRequired,
157158
};
158159

159-
// Helper function to get class names
160-
const getClassNames = (baseClass, darkClass, darkMode) =>
161-
`${baseClass} ${darkMode ? darkClass : ''}`;
162-
163-
// Extracted header component
164-
165160
const DashboardHeader = ({ darkMode, onBack }) => (
166161
<header className={styles.dashboardHeader}>
167162
<h1 className={getClassNames(styles.title, styles.darkText, darkMode)}>
@@ -276,36 +271,37 @@ export function LBDashboard() {
276271
const [selectedMetricKey, setSelectedMetricKey] = useState(DEFAULTS.DEMAND);
277272
const [openDD, setOpenDD] = useState({ DEMAND: false, REVENUE: false, VACANCY: false });
278273
const darkMode = useSelector(state => state.theme.darkMode);
279-
// --- Villages backend data ---
280-
const [villagesRaw, setVillagesRaw] = useState([]);
281-
const [loadingVillages, setLoadingVillages] = useState(false);
282-
const [villagesError, setVillagesError] = useState(null);
283-
284-
useEffect(() => {
285-
let mounted = true;
286-
287-
(async () => {
288-
try {
289-
setLoadingVillages(true);
290-
setVillagesError(null);
291-
292-
const res = await httpService.get(`${ApiEndpoint}/villages`);
293-
if (!mounted) return;
294-
295-
setVillagesRaw(Array.isArray(res?.data) ? res.data : []);
296-
} catch (e) {
297-
if (!mounted) return;
298-
setVillagesError('Failed to load villages');
299-
setVillagesRaw([]);
300-
} finally {
301-
if (mounted) setLoadingVillages(false);
302-
}
303-
})();
304274

305-
return () => {
306-
mounted = false;
307-
};
308-
}, []);
275+
// --- Villages backend data ---
276+
const [villagesRaw, setVillagesRaw] = useState([]);
277+
const [loadingVillages, setLoadingVillages] = useState(false);
278+
const [villagesError, setVillagesError] = useState(null);
279+
280+
useEffect(() => {
281+
let mounted = true;
282+
283+
(async () => {
284+
try {
285+
setLoadingVillages(true);
286+
setVillagesError(null);
287+
288+
const res = await httpService.get(`${ApiEndpoint}/villages`);
289+
if (!mounted) return;
290+
291+
setVillagesRaw(Array.isArray(res?.data) ? res.data : []);
292+
} catch (e) {
293+
if (!mounted) return;
294+
setVillagesError('Failed to load villages');
295+
setVillagesRaw([]);
296+
} finally {
297+
if (mounted) setLoadingVillages(false);
298+
}
299+
})();
300+
301+
return () => {
302+
mounted = false;
303+
};
304+
}, []);
309305

310306
const dateRange = [
311307
moment()
@@ -318,70 +314,70 @@ useEffect(() => {
318314
const all = Object.values(METRIC_OPTIONS).flat();
319315
return (all.find(o => o.key === selectedMetricKey) || {}).label || '';
320316
};
321-
// Decide which numeric value to calculate for the bar chart
322-
const effectiveMetric = useMemo(() => {
323-
switch (selectedMetricKey) {
324-
case 'avgBid':
325-
case 'finalPrice':
326-
return 'avgCurrentBid';
327-
case 'pageVisits':
328-
case 'numBids':
329-
case 'avgRating':
330-
case 'occupancyRate':
331-
case 'avgStay':
332-
return 'totalCurrentBid';
333-
default:
334-
return 'totalCurrentBid';
335-
}
336-
}, [selectedMetricKey]);
337-
338-
const valueFormatter = useMemo(() => {
339-
if (selectedMetricKey === 'avgRating') return v => Number(v).toFixed(2);
340-
if (selectedMetricKey === 'occupancyRate') return v => `${v}%`;
341-
if (selectedMetricKey === 'avgStay') return v => `${v} days`;
342-
if (selectedMetricKey === 'avgBid' || selectedMetricKey === 'finalPrice') {
343-
return v => `₹${Number(v).toLocaleString()}`;
344-
}
345-
return v => Number(v);
346-
}, [selectedMetricKey]);
347-
348-
// Derive villagesData from backend
349-
const villagesData = useMemo(() => {
350-
if (!villagesRaw.length) return [];
351-
352-
return villagesRaw
353-
.map(v => {
354-
const props = Array.isArray(v.properties) ? v.properties : [];
355-
const bids = props.map(p => Number(p?.currentBid || 0));
356-
const sum = bids.reduce((a, b) => a + b, 0);
357-
const avg = bids.length ? sum / bids.length : 0;
358-
359-
const value = effectiveMetric === 'avgCurrentBid' ? avg : sum;
360-
361-
return {
362-
village: v.name || v.regionId || 'Unknown',
363-
value,
364-
};
365-
})
366-
.sort((a, b) => b.value - a.value)
367-
.slice(0, 20);
368-
}, [villagesRaw, effectiveMetric]);
369-
370-
const stripVillageWord = s => {
371-
const str = String(s || '');
372-
const suffix = ' village';
373-
return str.toLowerCase().endsWith(suffix) ? str.slice(0, str.length - suffix.length) : str;
374-
};
375317

376-
const villagesDataClean = useMemo(
377-
() =>
378-
villagesData.map(d => ({
379-
...d,
380-
village: stripVillageWord(d.village),
381-
})),
382-
[villagesData],
383-
);
318+
// Decide which numeric value to calculate for the bar chart
319+
const effectiveMetric = useMemo(() => {
320+
switch (selectedMetricKey) {
321+
case 'avgBid':
322+
case 'finalPrice':
323+
return 'avgCurrentBid';
324+
case 'pageVisits':
325+
case 'numBids':
326+
case 'avgRating':
327+
case 'occupancyRate':
328+
case 'avgStay':
329+
return 'totalCurrentBid';
330+
default:
331+
return 'totalCurrentBid';
332+
}
333+
}, [selectedMetricKey]);
334+
335+
const valueFormatter = useMemo(() => {
336+
if (selectedMetricKey === 'avgRating') return v => Number(v).toFixed(2);
337+
if (selectedMetricKey === 'occupancyRate') return v => `${v}%`;
338+
if (selectedMetricKey === 'avgStay') return v => `${v} days`;
339+
if (selectedMetricKey === 'avgBid' || selectedMetricKey === 'finalPrice') {
340+
return v => `₹${Number(v).toLocaleString()}`;
341+
}
342+
return v => Number(v);
343+
}, [selectedMetricKey]);
344+
345+
// Derive villagesData from backend
346+
const villagesData = useMemo(() => {
347+
if (!villagesRaw.length) return [];
348+
349+
return villagesRaw
350+
.map(v => {
351+
const props = Array.isArray(v.properties) ? v.properties : [];
352+
const bids = props.map(p => Number(p?.currentBid || 0));
353+
const sum = bids.reduce((a, b) => a + b, 0);
354+
const avg = bids.length ? sum / bids.length : 0;
355+
356+
const value = effectiveMetric === 'avgCurrentBid' ? avg : sum;
357+
358+
return {
359+
village: v.name || v.regionId || 'Unknown',
360+
value,
361+
};
362+
})
363+
.sort((a, b) => b.value - a.value)
364+
.slice(0, 20);
365+
}, [villagesRaw, effectiveMetric]);
366+
367+
const stripVillageWord = s => {
368+
const str = String(s || '');
369+
const suffix = ' village';
370+
return str.toLowerCase().endsWith(suffix) ? str.slice(0, str.length - suffix.length) : str;
371+
};
384372

373+
const villagesDataClean = useMemo(
374+
() =>
375+
villagesData.map(d => ({
376+
...d,
377+
village: stripVillageWord(d.village),
378+
})),
379+
[villagesData],
380+
);
385381

386382
const handleCategoryClick = category => {
387383
setActiveCategory(category);
@@ -418,19 +414,18 @@ const villagesDataClean = useMemo(
418414
/>
419415

420416
<AnalysisSection title="By Village" darkMode={darkMode}>
421-
<div className={styles.chartRow}>
422-
<div className={styles.chartCol}>
423-
417+
<Row xs="1" md="3" className="g-3">
418+
<Col>
424419
<DemandOverTime
425420
compareType="villages"
426421
metric={mappedMetric}
427422
chartLabel="Comparing Demand of Villages across Months"
428423
darkMode={darkMode}
429424
dateRange={dateRange}
430425
/>
431-
</div>
426+
</Col>
432427

433-
<div className={styles.chartCol}>
428+
<Col>
434429
{loadingVillages && (
435430
<div className={getClassNames('', styles.darkText, darkMode)}>Loading villages…</div>
436431
)}
@@ -462,27 +457,27 @@ const villagesDataClean = useMemo(
462457
]}
463458
/>
464459
)}
465-
</div>
460+
</Col>
466461

467-
<div className={styles.chartCol}>
462+
<Col>
468463
<GraphCard title="Comparing Villages" metricLabel={metricLabel} darkMode={darkMode} />
469-
</div>
470-
</div>
464+
</Col>
465+
</Row>
471466
</AnalysisSection>
472467

473468
<AnalysisSection title="By Property" darkMode={darkMode}>
474-
<div className={styles.chartRow}>
475-
<div className={styles.chartCol}>
469+
<Row xs="1" md="2" className="g-3">
470+
<Col>
476471
<DemandOverTime
477472
compareType="properties"
478473
metric={mappedMetric}
479474
chartLabel="Comparing Demand of Properties across Time"
480475
darkMode={darkMode}
481476
dateRange={dateRange}
482477
/>
483-
</div>
478+
</Col>
484479

485-
<div className={styles.chartCol}>
480+
<Col>
486481
<CompareBarGraph
487482
title="Comparing Ratings of Properties"
488483
orientation="vertical"
@@ -505,9 +500,8 @@ const villagesDataClean = useMemo(
505500
{ label: 'Properties', value: 'ALL' },
506501
]}
507502
/>
508-
</div>
509-
</div>
510-
503+
</Col>
504+
</Row>
511505
</AnalysisSection>
512506

513507
<AnalysisSection title="Insights from Reviews" darkMode={darkMode}>

0 commit comments

Comments
 (0)