|
1 | | -/* eslint-disable */ |
2 | | -/* prettier-ignore */ |
3 | | - |
| 1 | +/* eslint-disable */ /* prettier-ignore */ |
4 | 2 | import { useState, useEffect } from 'react'; |
5 | 3 | import { Bar } from 'react-chartjs-2'; |
6 | 4 | import { Chart as ChartJS, BarElement, CategoryScale, LinearScale, Tooltip, Title } from 'chart.js'; |
7 | 5 | import axios from 'axios'; |
8 | 6 | import Select from 'react-select'; |
9 | 7 | import DatePicker from 'react-datepicker'; |
10 | 8 |
|
| 9 | +import styles from './LessonsLearntChart.module.css'; |
11 | 10 | import 'react-datepicker/dist/react-datepicker.css'; |
12 | | -import './LessonsLearntChart.css'; |
13 | 11 |
|
14 | 12 | ChartJS.register(BarElement, CategoryScale, LinearScale, Tooltip, Title); |
15 | 13 |
|
@@ -45,146 +43,92 @@ const useLessonsData = (selectedProjects, startDate, endDate) => { |
45 | 43 | setIsLoading(false); |
46 | 44 | } |
47 | 45 | }; |
48 | | - |
49 | 46 | fetchLessons(); |
50 | 47 | }, [selectedProjects, startDate, endDate]); |
51 | 48 |
|
52 | 49 | return { allProjects, lessonsData, isLoading }; |
53 | 50 | }; |
54 | 51 |
|
55 | 52 | function ChartTitle({ title }) { |
56 | | - return <h2 style={{ fontSize: '1.5rem', marginBottom: '1rem' }}>{title}</h2>; |
| 53 | + return <h2 className={styles.chartTitle}>{title}</h2>; |
57 | 54 | } |
58 | 55 |
|
59 | | -function Filters({ |
60 | | - allProjects, |
61 | | - selectedProjects, |
62 | | - setSelectedProjects, |
63 | | - startDate, |
64 | | - setStartDate, |
65 | | - endDate, |
66 | | - setEndDate, |
67 | | -}) { |
68 | | - return ( |
69 | | - <div className="filter-row"> |
70 | | - <div className="filter"> |
71 | | - <label>Project:</label> |
72 | | - <Select |
73 | | - options={allProjects?.map(p => ({ label: p.name, value: p.id })) || []} |
74 | | - isMulti |
75 | | - placeholder="All" |
76 | | - onChange={setSelectedProjects} |
77 | | - /> |
78 | | - </div> |
79 | | - <div className="filter"> |
80 | | - <label>From:</label> |
81 | | - <DatePicker |
82 | | - selected={startDate} |
83 | | - onChange={setStartDate} |
84 | | - selectsStart |
85 | | - startDate={startDate} |
86 | | - endDate={endDate} |
87 | | - placeholderText="Start Date" |
88 | | - /> |
89 | | - </div> |
90 | | - <div className="filter"> |
91 | | - <label>To:</label> |
92 | | - <DatePicker |
93 | | - selected={endDate} |
94 | | - onChange={setEndDate} |
95 | | - selectsEnd |
96 | | - startDate={startDate} |
97 | | - endDate={endDate} |
98 | | - placeholderText="End Date" |
99 | | - /> |
100 | | - </div> |
101 | | - </div> |
102 | | - ); |
103 | | -} |
| 56 | +export default function LessonsLearntChart() { |
| 57 | + const [selectedProjects, setSelectedProjects] = useState([]); |
| 58 | + const [startDate, setStartDate] = useState(null); |
| 59 | + const [endDate, setEndDate] = useState(null); |
104 | 60 |
|
105 | | -const PercentageLabels = ({ data }) => { |
106 | | - return ( |
107 | | - <div className="percentage-labels"> |
108 | | - {data?.map(item => ( |
109 | | - <div |
110 | | - key={item.id || item.name} // use a stable, unique identifier |
111 | | - className="percentage-label" |
112 | | - style={{ left: `${(data.indexOf(item) + 0.5) * (100 / data.length)}%` }} |
113 | | - > |
114 | | - {item.trend > 0 ? `+${item.trend}%` : `${item.trend}%`} |
115 | | - </div> |
116 | | - ))} |
117 | | - </div> |
| 61 | + const { allProjects, lessonsData, isLoading } = useLessonsData( |
| 62 | + selectedProjects, |
| 63 | + startDate, |
| 64 | + endDate, |
118 | 65 | ); |
119 | | -}; |
120 | 66 |
|
121 | | -const LessonsBarChart = ({ data, isLoading }) => { |
| 67 | + const handleProjectChange = selected => { |
| 68 | + setSelectedProjects(selected || []); |
| 69 | + }; |
| 70 | + |
122 | 71 | const chartData = { |
123 | | - labels: data?.map(item => item.project) || [], |
| 72 | + labels: lessonsData.map(d => d.projectName), |
124 | 73 | datasets: [ |
125 | 74 | { |
126 | | - label: 'No. of Lessons Learnt', |
127 | | - data: data?.map(item => item.count) || [], |
128 | | - backgroundColor: '#4F46E5', |
129 | | - borderRadius: 4, |
| 75 | + label: 'Lessons Learnt', |
| 76 | + data: lessonsData.map(d => d.percentage), |
| 77 | + backgroundColor: '#10b981', |
130 | 78 | }, |
131 | 79 | ], |
132 | 80 | }; |
133 | 81 |
|
134 | 82 | const chartOptions = { |
135 | 83 | responsive: true, |
136 | 84 | plugins: { |
137 | | - tooltip: { |
138 | | - callbacks: { |
139 | | - label: () => 'Click to view the Tags', |
140 | | - }, |
| 85 | + title: { |
| 86 | + display: false, |
141 | 87 | }, |
142 | 88 | }, |
143 | | - onClick: (_, elements) => { |
144 | | - if (elements.length > 0) { |
145 | | - const index = elements[0].index; |
146 | | - const project = chartData.labels[index]; |
147 | | - window.location.href = `/project-issues/${project}`; |
148 | | - } |
149 | | - }, |
150 | 89 | }; |
151 | 90 |
|
152 | | - if (isLoading) return <div className="loading">Loading...</div>; |
153 | | - |
154 | 91 | return ( |
155 | | - <div className="chart-wrapper"> |
156 | | - <Bar data={chartData} options={chartOptions} /> |
157 | | - <PercentageLabels data={data} /> |
158 | | - </div> |
159 | | - ); |
160 | | -}; |
161 | | - |
162 | | -const LessonsLearntChart = () => { |
163 | | - const [selectedProjects, setSelectedProjects] = useState([]); |
164 | | - const [startDate, setStartDate] = useState(null); |
165 | | - const [endDate, setEndDate] = useState(null); |
| 92 | + <div className={styles.chartContainer}> |
| 93 | + <ChartTitle title="Lessons Learnt" /> |
166 | 94 |
|
167 | | - const { allProjects, lessonsData, isLoading } = useLessonsData( |
168 | | - selectedProjects, |
169 | | - startDate, |
170 | | - endDate, |
171 | | - ); |
| 95 | + <div className={styles.filterRow}> |
| 96 | + <div className={styles.filter}> |
| 97 | + <label>Select Projects</label> |
| 98 | + <Select |
| 99 | + isMulti |
| 100 | + options={allProjects.map(proj => ({ |
| 101 | + value: proj.id, |
| 102 | + label: proj.name, |
| 103 | + }))} |
| 104 | + value={selectedProjects} |
| 105 | + onChange={handleProjectChange} |
| 106 | + /> |
| 107 | + </div> |
| 108 | + <div className={styles.filter}> |
| 109 | + <label>From</label> |
| 110 | + <DatePicker selected={startDate} onChange={date => setStartDate(date)} /> |
| 111 | + </div> |
| 112 | + <div className={styles.filter}> |
| 113 | + <label>To</label> |
| 114 | + <DatePicker selected={endDate} onChange={date => setEndDate(date)} /> |
| 115 | + </div> |
| 116 | + </div> |
172 | 117 |
|
173 | | - return ( |
174 | | - <div className="chart-container"> |
175 | | - <ChartTitle title="Lessons Learnt" /> |
176 | | - <Filters |
177 | | - allProjects={allProjects} |
178 | | - selectedProjects={selectedProjects} |
179 | | - setSelectedProjects={setSelectedProjects} |
180 | | - startDate={startDate} |
181 | | - setStartDate={setStartDate} |
182 | | - endDate={endDate} |
183 | | - setEndDate={setEndDate} |
184 | | - /> |
185 | | - <LessonsBarChart data={lessonsData} isLoading={isLoading} /> |
| 118 | + <div className={styles.chartWrapper}> |
| 119 | + {isLoading ? <p>Loading...</p> : <Bar data={chartData} options={chartOptions} />} |
| 120 | + <div className={styles.percentageLabels}> |
| 121 | + {lessonsData.map((d, idx) => ( |
| 122 | + <span |
| 123 | + key={idx} |
| 124 | + className={styles.percentageLabel} |
| 125 | + style={{ left: `${(idx + 0.5) * (100 / lessonsData.length)}%` }} |
| 126 | + > |
| 127 | + {d.percentage}% |
| 128 | + </span> |
| 129 | + ))} |
| 130 | + </div> |
| 131 | + </div> |
186 | 132 | </div> |
187 | 133 | ); |
188 | | -}; |
189 | | - |
190 | | -export default LessonsLearntChart; |
| 134 | +} |
0 commit comments