Set up & retrieve HBForm to Admin
This commit is contained in:
@@ -24,6 +24,7 @@ import UsersManagement from "./pages/UsersManagement";
|
|||||||
import ResetPasswordPage from "./pages/ResetPasswordPage";
|
import ResetPasswordPage from "./pages/ResetPasswordPage";
|
||||||
import ForgotPasswordPage from "./pages/ForgotPasswordPage";
|
import ForgotPasswordPage from "./pages/ForgotPasswordPage";
|
||||||
import RestrictedLayout from "./layouts/restricted";
|
import RestrictedLayout from "./layouts/restricted";
|
||||||
|
import Ranking from "./pages/Ranking";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
@@ -89,6 +90,10 @@ function App() {
|
|||||||
<Route element={<CreateEventsPage />} path="createEvent" />
|
<Route element={<CreateEventsPage />} path="createEvent" />
|
||||||
<Route element={<EditEventsPage />} path="editEvent/:id" />
|
<Route element={<EditEventsPage />} path="editEvent/:id" />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
<Route path="ranking">
|
||||||
|
<Route index element={<Ranking />} />
|
||||||
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|||||||
@@ -63,9 +63,8 @@ export default function AdministratorNavigationPanel() {
|
|||||||
return (
|
return (
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<div
|
<div
|
||||||
className={`fixed transition-all ${
|
className={`fixed transition-all ${isScrolled ? "top-2" : "top-10"
|
||||||
isScrolled ? "top-2" : "top-10"
|
} left-2`}
|
||||||
} left-2`}
|
|
||||||
>
|
>
|
||||||
<div className="bg-white rounded-full z-40">
|
<div className="bg-white rounded-full z-40">
|
||||||
<Button
|
<Button
|
||||||
@@ -86,20 +85,17 @@ export default function AdministratorNavigationPanel() {
|
|||||||
|
|
||||||
{/* Panel */}
|
{/* Panel */}
|
||||||
<div
|
<div
|
||||||
className={`h-full transition-all z-50 ${
|
className={`h-full transition-all z-50 ${panelVisible
|
||||||
panelVisible
|
? "scale-100 opacity-100 w-[300px] px-2"
|
||||||
? "scale-100 opacity-100 w-[300px] px-2"
|
: "w-0 scale-[98%] opacity-0 px-0"
|
||||||
: "w-0 scale-[98%] opacity-0 px-0"
|
}`}
|
||||||
}`}
|
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
className={`fixed h-full transition-all z-50 ${
|
className={`fixed h-full transition-all z-50 ${isScrolled ? "pb-2 -mt-8" : "pb-10"
|
||||||
isScrolled ? "pb-2 -mt-8" : "pb-10"
|
} ${panelVisible
|
||||||
} ${
|
|
||||||
panelVisible
|
|
||||||
? "scale-100 opacity-100 w-[300px] p-2"
|
? "scale-100 opacity-100 w-[300px] p-2"
|
||||||
: "w-0 scale-[98%] opacity-0 p-0"
|
: "w-0 scale-[98%] opacity-0 p-0"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Card className="h-full w-full">
|
<Card className="h-full w-full">
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
@@ -167,7 +163,7 @@ export default function AdministratorNavigationPanel() {
|
|||||||
<AdministratorNavigationPanelNavigationButton
|
<AdministratorNavigationPanelNavigationButton
|
||||||
text="Ranking"
|
text="Ranking"
|
||||||
icon={<ChartBarIcon />}
|
icon={<ChartBarIcon />}
|
||||||
onClickRef="#"
|
onClickRef="ranking"
|
||||||
/>
|
/>
|
||||||
<AdministratorNavigationPanelNavigationButton
|
<AdministratorNavigationPanelNavigationButton
|
||||||
text="Vouchers"
|
text="Vouchers"
|
||||||
|
|||||||
120
client/src/pages/Ranking.tsx
Normal file
120
client/src/pages/Ranking.tsx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import config from '../config';
|
||||||
|
import instance from '../security/http';
|
||||||
|
import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, SortDescriptor, Button } from '@nextui-org/react';
|
||||||
|
import { EmailIcon, TrashDeleteIcon } from '../icons';
|
||||||
|
|
||||||
|
interface FormData {
|
||||||
|
id: number;
|
||||||
|
electricalBill: number;
|
||||||
|
waterBill: number;
|
||||||
|
totalBill: number;
|
||||||
|
noOfDependents: number;
|
||||||
|
avgBill: number;
|
||||||
|
ebPicture: string;
|
||||||
|
wbPicture: string;
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Ranking() {
|
||||||
|
const [formData, setFormData] = useState<FormData[]>([]);
|
||||||
|
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
|
||||||
|
column: 'avgBill',
|
||||||
|
direction: 'ascending',
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const getFormData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await instance.get(`${config.serverAddress}/hbcform`);
|
||||||
|
const processedData = response.data.map((data: FormData) => ({
|
||||||
|
...data,
|
||||||
|
electricalBill: Number(data.electricalBill),
|
||||||
|
waterBill: Number(data.waterBill),
|
||||||
|
totalBill: Number(data.totalBill),
|
||||||
|
avgBill: Number(data.avgBill),
|
||||||
|
}));
|
||||||
|
setFormData(processedData);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to fetch form data");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getFormData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const sortFormData = (list: FormData[], descriptor: SortDescriptor) => {
|
||||||
|
const { column, direction } = descriptor;
|
||||||
|
|
||||||
|
if (column === 'avgBill') {
|
||||||
|
return [...list].sort((a, b) =>
|
||||||
|
direction === 'ascending' ? a.avgBill - b.avgBill : b.avgBill - a.avgBill
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list; // No sorting if the column is not 'avgBill'
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSort = () => {
|
||||||
|
const { direction } = sortDescriptor;
|
||||||
|
const newDirection = direction === 'ascending' ? 'descending' : 'ascending';
|
||||||
|
|
||||||
|
setSortDescriptor({ column: 'avgBill', direction: newDirection });
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderSortIndicator = () => {
|
||||||
|
if (sortDescriptor.column === 'avgBill') {
|
||||||
|
return sortDescriptor.direction === 'ascending' ? <span>↑</span> : <span>↓</span>;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const sortedFormData = sortFormData(formData, sortDescriptor);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="flex flex-col items-center justify-center py-5">
|
||||||
|
<p className="text-2xl font-bold">Form Data</p>
|
||||||
|
<div className="gap-8 p-8">
|
||||||
|
<Table aria-label="Form Data Table">
|
||||||
|
<TableHeader>
|
||||||
|
<TableColumn onClick={handleSort}>
|
||||||
|
Average Bill {renderSortIndicator()}
|
||||||
|
</TableColumn>
|
||||||
|
<TableColumn>Form ID</TableColumn>
|
||||||
|
<TableColumn>User ID</TableColumn>
|
||||||
|
<TableColumn>Electrical Bill</TableColumn>
|
||||||
|
<TableColumn>Water Bill</TableColumn>
|
||||||
|
<TableColumn>Total Bill</TableColumn>
|
||||||
|
<TableColumn>Number of Dependents</TableColumn>
|
||||||
|
<TableColumn>Electrical Bill Picture</TableColumn>
|
||||||
|
<TableColumn>Water Bill Picture</TableColumn>
|
||||||
|
<TableColumn>Actions</TableColumn>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{sortedFormData.map((data) => (
|
||||||
|
<TableRow key={data.id}>
|
||||||
|
<TableCell>${data.avgBill.toFixed(2)}</TableCell>
|
||||||
|
<TableCell>{data.id}</TableCell>
|
||||||
|
<TableCell>{data.userId}</TableCell>
|
||||||
|
<TableCell>${data.electricalBill.toFixed(2)}</TableCell>
|
||||||
|
<TableCell>${data.waterBill.toFixed(2)}</TableCell>
|
||||||
|
<TableCell>${data.totalBill.toFixed(2)}</TableCell>
|
||||||
|
<TableCell>{data.noOfDependents}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{data.ebPicture && <img src={`${config.serverAddress}/hbcform/ebPicture/${data.id}`} alt="Electrical Bill" className="w-full" />}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{data.wbPicture && <img src={`${config.serverAddress}/hbcform/wbPicture/${data.id}`} alt="Water Bill" className="w-full" />}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="flex flex-row">
|
||||||
|
<Button isIconOnly variant="light"><EmailIcon /></Button>
|
||||||
|
<Button isIconOnly variant="light"><TrashDeleteIcon /></Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user