1
1
// employee-dashboard.tsx
2
- "use client" ;
2
+ "use client" ;
3
3
import React , { useEffect , useState } from 'react' ;
4
- import { createClient } from '@/utils/supabase/client' ;
4
+ import { createClient } from '@/utils/supabase/client' ;
5
+ import {
6
+ BarChart ,
7
+ Bar ,
8
+ LineChart ,
9
+ Line ,
10
+ PieChart ,
11
+ Pie ,
12
+ Cell ,
13
+ XAxis ,
14
+ YAxis ,
15
+ CartesianGrid ,
16
+ Tooltip ,
17
+ ResponsiveContainer ,
18
+ } from 'recharts' ;
19
+ import { Card , CardHeader , CardContent } from '@/components/ui/card' ;
5
20
6
21
const EmployeeDashboard = ( ) => {
7
- const supabase = createClient ( ) ;
22
+ const [ supabase , setSupabase ] = useState < ReturnType < typeof createClient > | null > ( null ) ;
23
+
24
+ useEffect ( ( ) => {
25
+ const client = createClient ( ) ;
26
+ setSupabase ( client ) ;
27
+ } , [ ] ) ;
28
+
8
29
interface LoanApplication {
9
30
id : number ;
10
31
name : string ;
@@ -26,19 +47,23 @@ const EmployeeDashboard = () => {
26
47
yearly_turnover : number ;
27
48
is_eligible : boolean ;
28
49
interest_rate_range : string ;
29
- rejection_reason : string | null ;
50
+ rejection_reason : string | null ;
30
51
}
31
52
32
53
const [ loanApplications , setLoanApplications ] = useState < LoanApplication [ ] > ( [ ] ) ;
54
+ const [ selectedName , setSelectedName ] = useState < string | null > ( null ) ;
55
+ const [ selectedPhone , setSelectedPhone ] = useState < string | null > ( null ) ;
56
+ const [ selectedPAN , setSelectedPAN ] = useState < string | null > ( null ) ;
33
57
const [ loading , setLoading ] = useState ( true ) ;
34
58
35
59
useEffect ( ( ) => {
36
60
const fetchLoanApplications = async ( ) => {
37
61
try {
38
- const { data, error } = await supabase
39
- . from ( 'loan_applications' )
40
- . select ( '*' ) ;
41
-
62
+ if ( ! supabase ) {
63
+ console . error ( 'Supabase client is not initialized' ) ;
64
+ return ;
65
+ }
66
+ const { data, error } = await supabase . from ( 'loan_applications' ) . select ( '*' ) ;
42
67
if ( error ) {
43
68
console . error ( 'Error fetching loan applications:' , error ) ;
44
69
} else {
@@ -51,30 +76,64 @@ const EmployeeDashboard = () => {
51
76
}
52
77
} ;
53
78
54
- fetchLoanApplications ( ) ;
55
- } , [ ] ) ;
79
+ if ( supabase ) {
80
+ fetchLoanApplications ( ) ;
81
+ }
82
+ } , [ supabase ] ) ;
83
+
84
+ const handleNameChange = ( event : React . ChangeEvent < HTMLSelectElement > ) => {
85
+ setSelectedName ( event . target . value ) ;
86
+ setSelectedPhone ( null ) ;
87
+ setSelectedPAN ( null ) ;
88
+ } ;
89
+
90
+ const handlePhoneChange = ( event : React . ChangeEvent < HTMLSelectElement > ) => {
91
+ setSelectedPhone ( event . target . value ) ;
92
+ setSelectedName ( null ) ;
93
+ setSelectedPAN ( null ) ;
94
+ } ;
95
+
96
+ const handlePANChange = ( event : React . ChangeEvent < HTMLSelectElement > ) => {
97
+ setSelectedPAN ( event . target . value ) ;
98
+ setSelectedName ( null ) ;
99
+ setSelectedPhone ( null ) ;
100
+ } ;
101
+
102
+ const selectedUser = loanApplications . find (
103
+ ( app ) =>
104
+ app . name === selectedName ||
105
+ app . phone === selectedPhone ||
106
+ app . pan_number === selectedPAN
107
+ ) ;
108
+
109
+ const prepareChartData = ( field : keyof LoanApplication ) => {
110
+ return loanApplications . map ( ( app ) => ( {
111
+ name : app . name ,
112
+ value : app [ field ] ,
113
+ } ) ) ;
114
+ } ;
56
115
57
116
if ( loading ) {
58
117
return < div > Loading loan applications...</ div > ;
59
118
}
60
119
61
120
return (
62
- < div >
63
- < h1 > Loan Applications </ h1 >
64
- < table className = "table-auto w-full" >
121
+ < div className = "space-y-6 p-4" >
122
+
123
+ < table className = "table-auto w-full" >
65
124
< thead >
66
125
< tr >
67
126
< th className = "px-4 py-2" > ID</ th >
68
127
< th className = "px-4 py-2" > Name</ th >
69
- < th className = "px-4 py-2" > Email</ th >
70
- < th className = "px-4 py-2" > Phone</ th >
128
+ { /* <th className="px-4 py-2">Email</th> */ }
129
+ { /* <th className="px-4 py-2">Phone</th> */ }
71
130
< th className = "px-4 py-2" > Loan Type</ th >
72
131
< th className = "px-4 py-2" > Age</ th >
73
132
< th className = "px-4 py-2" > Loan Amount</ th >
74
133
< th className = "px-4 py-2" > Employment Status</ th >
75
134
< th className = "px-4 py-2" > Income</ th >
76
- < th className = "px-4 py-2" > Additional Notes</ th >
77
- < th className = "px-4 py-2" > PAN Number</ th >
135
+ { /* <th className="px-4 py-2">Additional Notes</th> */ }
136
+ { /* <th className="px-4 py-2">PAN Number</th> */ }
78
137
< th className = "px-4 py-2" > Months Employed</ th >
79
138
< th className = "px-4 py-2" > Preferred Tenure</ th >
80
139
< th className = "px-4 py-2" > Fixed Monthly Income</ th >
@@ -84,23 +143,23 @@ const EmployeeDashboard = () => {
84
143
< th className = "px-4 py-2" > Yearly Turnover</ th >
85
144
< th className = "px-4 py-2" > Is Eligible</ th >
86
145
< th className = "px-4 py-2" > Interest Rate Range</ th >
87
- < th className = "px-4 py-2" > Rejection Reason</ th >
146
+ { /* <th className="px-4 py-2">Rejection Reason</th> */ }
88
147
</ tr >
89
148
</ thead >
90
149
< tbody >
91
150
{ loanApplications . map ( ( application ) => (
92
151
< tr key = { application . id } >
93
152
< td className = "border px-4 py-2" > { application . id } </ td >
94
153
< td className = "border px-4 py-2" > { application . name } </ td >
95
- < td className = "border px-4 py-2" > { application . email } </ td >
96
- < td className = "border px-4 py-2" > { application . phone } </ td >
154
+ { /* <td className="border px-4 py-2">{application.email}</td> */ }
155
+ { /* <td className="border px-4 py-2">{application.phone}</td> */ }
97
156
< td className = "border px-4 py-2" > { application . loan_type } </ td >
98
157
< td className = "border px-4 py-2" > { application . age } </ td >
99
158
< td className = "border px-4 py-2" > { application . loan_amount } </ td >
100
159
< td className = "border px-4 py-2" > { application . employment_status } </ td >
101
160
< td className = "border px-4 py-2" > { application . income } </ td >
102
- < td className = "border px-4 py-2" > { application . additional_notes } </ td >
103
- < td className = "border px-4 py-2" > { application . pan_number } </ td >
161
+ { /* <td className="border px-4 py-2">{application.additional_notes}</td> */ }
162
+ { /* <td className="border px-4 py-2">{application.pan_number}</td> */ }
104
163
< td className = "border px-4 py-2" > { application . months_employed } </ td >
105
164
< td className = "border px-4 py-2" > { application . preferred_tenure } </ td >
106
165
< td className = "border px-4 py-2" > { application . fixed_monthly_income } </ td >
@@ -110,13 +169,185 @@ const EmployeeDashboard = () => {
110
169
< td className = "border px-4 py-2" > { application . yearly_turnover } </ td >
111
170
< td className = "border px-4 py-2" > { application . is_eligible ? 'Yes' : 'No' } </ td >
112
171
< td className = "border px-4 py-2" > { application . interest_rate_range } </ td >
113
- < td className = "border px-4 py-2" > { application . rejection_reason || '-' } </ td >
172
+ { /* <td className="border px-4 py-2">{application.rejection_reason || '-'}</td> */ }
114
173
</ tr >
115
174
) ) }
116
175
</ tbody >
117
176
</ table >
118
- </ div >
119
- ) ;
177
+
178
+
179
+
180
+ < h1 className = "text-2xl font-bold mb-4" > Loan Applications</ h1 >
181
+
182
+ < Card >
183
+ < CardHeader className = "flex justify-between items-center" >
184
+ < h2 className = "text-xl" > Filter Users</ h2 >
185
+ </ CardHeader >
186
+ < CardContent >
187
+ < div className = "flex space-x-4" >
188
+ < div className = "flex-1" >
189
+ < label className = "block mb-2" > Select by Name:</ label >
190
+ < select
191
+ className = "w-full p-2 border border-gray-300 rounded"
192
+ value = { selectedName || '' }
193
+ onChange = { handleNameChange }
194
+ >
195
+ < option value = "" > Select Name</ option >
196
+ { loanApplications . map ( ( app ) => (
197
+ < option key = { app . id } value = { app . name } >
198
+ { app . name }
199
+ </ option >
200
+ ) ) }
201
+ </ select >
202
+ </ div >
203
+ < div className = "flex-1" >
204
+ < label className = "block mb-2" > Select by Phone:</ label >
205
+ < select
206
+ className = "w-full p-2 border border-gray-300 rounded"
207
+ value = { selectedPhone || '' }
208
+ onChange = { handlePhoneChange }
209
+ >
210
+ < option value = "" > Select Phone</ option >
211
+ { loanApplications . map ( ( app ) => (
212
+ < option key = { app . id } value = { app . phone } >
213
+ { app . phone }
214
+ </ option >
215
+ ) ) }
216
+ </ select >
217
+ </ div >
218
+ < div className = "flex-1" >
219
+ < label className = "block mb-2" > Select by PAN:</ label >
220
+ < select
221
+ className = "w-full p-2 border border-gray-300 rounded"
222
+ value = { selectedPAN || '' }
223
+ onChange = { handlePANChange }
224
+ >
225
+ < option value = "" > Select PAN</ option >
226
+ { loanApplications . map ( ( app ) => (
227
+ < option key = { app . id } value = { app . pan_number } >
228
+ { app . pan_number }
229
+ </ option >
230
+ ) ) }
231
+ </ select >
232
+ </ div >
233
+ </ div >
234
+ </ CardContent >
235
+ </ Card >
236
+
237
+ < div className = "grid grid-cols-2 gap-6" >
238
+ < Card >
239
+ < CardHeader >
240
+ < h2 className = "text-lg" > Loan Amount Distribution</ h2 >
241
+ </ CardHeader >
242
+ < CardContent >
243
+ < ResponsiveContainer width = "100%" height = { 300 } >
244
+ < BarChart data = { prepareChartData ( 'loan_amount' ) } >
245
+ < XAxis dataKey = "name" />
246
+ < YAxis />
247
+ < Tooltip />
248
+ < CartesianGrid stroke = "#f5f5f5" />
249
+ < Bar dataKey = "value" fill = "#8884d8" />
250
+ </ BarChart >
251
+ </ ResponsiveContainer >
252
+ </ CardContent >
253
+ </ Card >
254
+
255
+ < Card >
256
+ < CardHeader >
257
+ < h2 className = "text-lg" > Income Distribution</ h2 >
258
+ </ CardHeader >
259
+ < CardContent >
260
+ < ResponsiveContainer width = "100%" height = { 300 } >
261
+ < BarChart data = { prepareChartData ( 'income' ) } >
262
+ < XAxis dataKey = "name" />
263
+ < YAxis />
264
+ < Tooltip />
265
+ < CartesianGrid stroke = "#f5f5f5" />
266
+ < Bar dataKey = "value" fill = "#82ca9d" />
267
+ </ BarChart >
268
+ </ ResponsiveContainer >
269
+ </ CardContent >
270
+ </ Card >
271
+
272
+ < Card >
273
+ < CardHeader >
274
+ < h2 className = "text-lg" > Credit Score Distribution</ h2 >
275
+ </ CardHeader >
276
+ < CardContent >
277
+ < ResponsiveContainer width = "100%" height = { 300 } >
278
+ < LineChart data = { prepareChartData ( 'credit_score' ) } >
279
+ < XAxis dataKey = "name" />
280
+ < YAxis />
281
+ < Tooltip />
282
+ < CartesianGrid stroke = "#f5f5f5" />
283
+ < Line type = "monotone" dataKey = "value" stroke = "#ff7300" />
284
+ </ LineChart >
285
+ </ ResponsiveContainer >
286
+ </ CardContent >
287
+ </ Card >
288
+
289
+ < Card >
290
+ < CardHeader >
291
+ < h2 className = "text-lg" > Monthly Expenditure Distribution</ h2 >
292
+ </ CardHeader >
293
+ < CardContent >
294
+ < ResponsiveContainer width = "100%" height = { 300 } >
295
+ < LineChart data = { prepareChartData ( 'expenditure' ) } >
296
+ < XAxis dataKey = "name" />
297
+ < YAxis />
298
+ < Tooltip />
299
+ < CartesianGrid stroke = "#f5f5f5" />
300
+ < Line type = "monotone" dataKey = "value" stroke = "#387908" />
301
+ </ LineChart >
302
+ </ ResponsiveContainer >
303
+ </ CardContent >
304
+ </ Card >
305
+
306
+ < Card >
307
+ < CardHeader >
308
+ < h2 className = "text-lg" > Preferred Loan Tenure</ h2 >
309
+ </ CardHeader >
310
+ < CardContent >
311
+ < ResponsiveContainer width = "100%" height = { 300 } >
312
+ < BarChart data = { prepareChartData ( 'preferred_tenure' ) } >
313
+ < XAxis dataKey = "name" />
314
+ < YAxis />
315
+ < Tooltip />
316
+ < CartesianGrid stroke = "#f5f5f5" />
317
+ < Bar dataKey = "value" fill = "#8884d8" />
318
+ </ BarChart >
319
+ </ ResponsiveContainer >
320
+ </ CardContent >
321
+ </ Card >
322
+
323
+ { /* <Card>
324
+ <CardHeader>
325
+ <h2 className="text-lg">Fixed Monthly Income</h2>
326
+ </CardHeader>
327
+ <CardBody>
328
+ <ResponsiveContainer width="100%" height={300}>
329
+ <PieChart>
330
+ <Pie
331
+ data={prepareChartData('fixed_monthly_income')}
332
+ dataKey="value"
333
+ nameKey="name"
334
+ outerRadius={100}
335
+ fill="#82ca9d"
336
+ >
337
+ {prepareChartData('fixed_monthly_income').map((entry, index) => (
338
+ <Cell
339
+ key={`cell-${index}`}
340
+ fill={index % 2 === 0 ? '#82ca9d' : '#8884d8'}
341
+ />
342
+ ))}
343
+ </Pie>
344
+ </PieChart>
345
+ </ResponsiveContainer>
346
+ </CardBody>
347
+ </Card> */ }
348
+ </ div >
349
+ </ div >
350
+ ) ;
120
351
} ;
121
352
122
353
export default EmployeeDashboard ;
0 commit comments