Skip to content

Commit e6e7a2c

Browse files
committed
data viz 1 😊
1 parent 452e7b4 commit e6e7a2c

File tree

5 files changed

+403
-33
lines changed

5 files changed

+403
-33
lines changed

‎app/employee/page.tsx

+256-25
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
11
// employee-dashboard.tsx
2-
"use client";
2+
"use client";
33
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';
520

621
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+
829
interface LoanApplication {
930
id: number;
1031
name: string;
@@ -26,19 +47,23 @@ const EmployeeDashboard = () => {
2647
yearly_turnover: number;
2748
is_eligible: boolean;
2849
interest_rate_range: string;
29-
rejection_reason: string | null;
50+
rejection_reason: string | null;
3051
}
3152

3253
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);
3357
const [loading, setLoading] = useState(true);
3458

3559
useEffect(() => {
3660
const fetchLoanApplications = async () => {
3761
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('*');
4267
if (error) {
4368
console.error('Error fetching loan applications:', error);
4469
} else {
@@ -51,30 +76,64 @@ const EmployeeDashboard = () => {
5176
}
5277
};
5378

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+
};
56115

57116
if (loading) {
58117
return <div>Loading loan applications...</div>;
59118
}
60119

61120
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">
65124
<thead>
66125
<tr>
67126
<th className="px-4 py-2">ID</th>
68127
<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> */}
71130
<th className="px-4 py-2">Loan Type</th>
72131
<th className="px-4 py-2">Age</th>
73132
<th className="px-4 py-2">Loan Amount</th>
74133
<th className="px-4 py-2">Employment Status</th>
75134
<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> */}
78137
<th className="px-4 py-2">Months Employed</th>
79138
<th className="px-4 py-2">Preferred Tenure</th>
80139
<th className="px-4 py-2">Fixed Monthly Income</th>
@@ -84,23 +143,23 @@ const EmployeeDashboard = () => {
84143
<th className="px-4 py-2">Yearly Turnover</th>
85144
<th className="px-4 py-2">Is Eligible</th>
86145
<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> */}
88147
</tr>
89148
</thead>
90149
<tbody>
91150
{loanApplications.map((application) => (
92151
<tr key={application.id}>
93152
<td className="border px-4 py-2">{application.id}</td>
94153
<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> */}
97156
<td className="border px-4 py-2">{application.loan_type}</td>
98157
<td className="border px-4 py-2">{application.age}</td>
99158
<td className="border px-4 py-2">{application.loan_amount}</td>
100159
<td className="border px-4 py-2">{application.employment_status}</td>
101160
<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> */}
104163
<td className="border px-4 py-2">{application.months_employed}</td>
105164
<td className="border px-4 py-2">{application.preferred_tenure}</td>
106165
<td className="border px-4 py-2">{application.fixed_monthly_income}</td>
@@ -110,13 +169,185 @@ const EmployeeDashboard = () => {
110169
<td className="border px-4 py-2">{application.yearly_turnover}</td>
111170
<td className="border px-4 py-2">{application.is_eligible ? 'Yes' : 'No'}</td>
112171
<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> */}
114173
</tr>
115174
))}
116175
</tbody>
117176
</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+
);
120351
};
121352

122353
export default EmployeeDashboard;

0 commit comments

Comments
 (0)