Skip to content

Commit dfb6ba5

Browse files
Merge pull request #4845 from OneCommunityGlobal/Fixed_Page_Crash_in_LessonsLearntPage
Ramsundar - Resolved Page Crash for Bar Chart For Lessons Learned
2 parents a8454c8 + 4f176d4 commit dfb6ba5

1 file changed

Lines changed: 105 additions & 30 deletions

File tree

src/components/BMDashboard/LessonsLearnt/LessonsLearntChart.jsx

Lines changed: 105 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import axios from 'axios';
66
import Select from 'react-select';
77
import DatePicker from 'react-datepicker';
88

9+
import { ENDPOINTS } from '../../../utils/URL';
910
import styles from './LessonsLearntChart.module.css';
1011
import 'react-datepicker/dist/react-datepicker.css';
1112

@@ -15,29 +16,58 @@ const useLessonsData = (selectedProjects, startDate, endDate) => {
1516
const [allProjects, setAllProjects] = useState([]);
1617
const [lessonsData, setLessonsData] = useState([]);
1718
const [isLoading, setIsLoading] = useState(true);
19+
const [error, setError] = useState(null);
1820

1921
useEffect(() => {
2022
const fetchProjects = async () => {
2123
try {
22-
const response = await axios.get('/api/projects');
23-
setAllProjects(response.data);
24-
} catch (error) {}
24+
const response = await axios.get(ENDPOINTS.BM_PROJECTS);
25+
const projects = Array.isArray(response.data) ? response.data : [];
26+
setAllProjects(projects);
27+
} catch (err) {
28+
console.error('Error fetching projects:', err);
29+
setAllProjects([]);
30+
}
2531
};
2632
fetchProjects();
2733
}, []);
2834

2935
useEffect(() => {
3036
const fetchLessons = async () => {
3137
setIsLoading(true);
38+
setError(null);
3239
try {
33-
const params = {
34-
projects: selectedProjects.map(p => p.value).join(','),
35-
from: startDate?.toISOString(),
36-
to: endDate?.toISOString(),
37-
};
38-
const response = await axios.get('/api/lessons-learnt', { params });
39-
setLessonsData(response.data);
40-
} catch (error) {
40+
const params = {};
41+
42+
if (selectedProjects && selectedProjects.length > 0) {
43+
params.projectId = selectedProjects.length === 1 ? selectedProjects[0].value : 'ALL';
44+
}
45+
46+
if (startDate) {
47+
params.startDate = startDate.toISOString();
48+
}
49+
if (endDate) {
50+
params.endDate = endDate.toISOString();
51+
}
52+
53+
const response = await axios.get(`${ENDPOINTS.BM_LESSONS}-learnt`, { params });
54+
55+
const responseData = response.data?.data || response.data || [];
56+
const lessonsArray = Array.isArray(responseData) ? responseData : [];
57+
58+
const transformedData = lessonsArray.map(item => ({
59+
projectName: item.project || 'Unknown Project',
60+
projectId: item.projectId,
61+
lessonsCount: item.lessonsCount || 0,
62+
percentage:
63+
parseFloat((item.changePercentage || '0%').replace('%', '').replace('+', '')) || 0,
64+
changePercentage: item.changePercentage || '0%',
65+
}));
66+
67+
setLessonsData(transformedData);
68+
} catch (err) {
69+
console.error('Error fetching lessons learnt:', err);
70+
setError(err.message || 'Failed to fetch lessons data');
4171
setLessonsData([]);
4272
} finally {
4373
setIsLoading(false);
@@ -46,7 +76,7 @@ const useLessonsData = (selectedProjects, startDate, endDate) => {
4676
fetchLessons();
4777
}, [selectedProjects, startDate, endDate]);
4878

49-
return { allProjects, lessonsData, isLoading };
79+
return { allProjects, lessonsData, isLoading, error };
5080
};
5181

5282
function ChartTitle({ title }) {
@@ -58,7 +88,7 @@ const LessonsLearntChart = () => {
5888
const [startDate, setStartDate] = useState(null);
5989
const [endDate, setEndDate] = useState(null);
6090

61-
const { allProjects, lessonsData, isLoading } = useLessonsData(
91+
const { allProjects, lessonsData, isLoading, error } = useLessonsData(
6292
selectedProjects,
6393
startDate,
6494
endDate,
@@ -68,23 +98,58 @@ const LessonsLearntChart = () => {
6898
setSelectedProjects(selected || []);
6999
};
70100

101+
const projectOptions = Array.isArray(allProjects)
102+
? allProjects
103+
.filter(proj => proj && (proj._id || proj.id))
104+
.map(proj => ({
105+
value: proj._id || proj.id,
106+
label: proj.name || 'Unnamed Project',
107+
}))
108+
: [];
109+
110+
const safeLabels = Array.isArray(lessonsData)
111+
? lessonsData.map(d => d?.projectName || 'Unknown')
112+
: [];
113+
114+
const safeData = Array.isArray(lessonsData) ? lessonsData.map(d => d?.lessonsCount || 0) : [];
115+
71116
const chartData = {
72-
labels: lessonsData.map(d => d.projectName),
117+
labels: safeLabels,
73118
datasets: [
74119
{
75-
label: 'Lessons Learnt',
76-
data: lessonsData.map(d => d.percentage),
120+
label: 'Lessons Count',
121+
data: safeData,
77122
backgroundColor: '#10b981',
78123
},
79124
],
80125
};
81126

82127
const chartOptions = {
83128
responsive: true,
129+
maintainAspectRatio: false,
84130
plugins: {
85131
title: {
86132
display: false,
87133
},
134+
tooltip: {
135+
callbacks: {
136+
afterLabel: context => {
137+
const dataIndex = context.dataIndex;
138+
if (Array.isArray(lessonsData) && lessonsData[dataIndex]) {
139+
return `Change: ${lessonsData[dataIndex].changePercentage || '0%'}`;
140+
}
141+
return '';
142+
},
143+
},
144+
},
145+
},
146+
scales: {
147+
y: {
148+
beginAtZero: true,
149+
ticks: {
150+
stepSize: 1,
151+
},
152+
},
88153
},
89154
};
90155

@@ -97,45 +162,55 @@ const LessonsLearntChart = () => {
97162
<label>Select Projects</label>
98163
<Select
99164
isMulti
100-
options={allProjects.map(proj => ({
101-
value: proj.id,
102-
label: proj.name,
103-
}))}
165+
options={projectOptions}
104166
value={selectedProjects}
105167
onChange={handleProjectChange}
168+
placeholder="Select projects..."
169+
isClearable
106170
/>
107171
</div>
108172
<div className={styles.filter}>
109173
<label>From</label>
110-
<DatePicker selected={startDate} onChange={date => setStartDate(date)} />
174+
<DatePicker
175+
selected={startDate}
176+
onChange={date => setStartDate(date)}
177+
placeholderText="Start date"
178+
isClearable
179+
/>
111180
</div>
112181
<div className={styles.filter}>
113182
<label>To</label>
114-
<DatePicker selected={endDate} onChange={date => setEndDate(date)} />
183+
<DatePicker
184+
selected={endDate}
185+
onChange={date => setEndDate(date)}
186+
placeholderText="End date"
187+
isClearable
188+
/>
115189
</div>
116190
</div>
117191

118192
<div className={styles.chartWrapper}>
119193
{isLoading ? (
120194
<p>Loading...</p>
121-
) : lessonsData.length === 0 ? (
195+
) : error ? (
196+
<p>Error loading data: {error}</p>
197+
) : !Array.isArray(lessonsData) || lessonsData.length === 0 ? (
122198
<p>No lessons data available for the selected criteria</p>
123199
) : (
124200
<>
125-
<Bar data={chartData} options={chartOptions} />
201+
<div style={{ height: '400px', width: '100%' }}>
202+
<Bar data={chartData} options={chartOptions} />
203+
</div>
126204
<div className={styles.percentageLabels}>
127205
{lessonsData.map((d, idx) => (
128206
<span
129-
key={idx}
207+
key={d?.projectId || idx}
130208
className={styles.percentageLabel}
131209
style={{
132-
left:
133-
lessonsData.length > 0
134-
? `${(idx + 0.5) * (100 / lessonsData.length)}%`
135-
: '0%',
210+
left: `${(idx + 0.5) * (100 / lessonsData.length)}%`,
136211
}}
137212
>
138-
{d.percentage}%
213+
{d?.changePercentage || '0%'}
139214
</span>
140215
))}
141216
</div>

0 commit comments

Comments
 (0)