Files
IB/src/app/administrator/home/page.tsx
tomosa.sarkar 6258080848 fix: Change bank name
fix: otp filled null after complete the process
2025-11-18 16:13:23 +05:30

413 lines
14 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import {
Text,
Box,
Image,
Stack,
Divider,
Title,
Collapse,
Group,
UnstyledButton,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { Providers } from "@/app/providers";
import { useRouter } from "next/navigation";
import NextImage from "next/image";
import logo from "@/app/image/logo1.jpg";
import {
IconLogout,
IconPhoneFilled,
IconUsers,
IconChevronDown,
IconChevronUp,
IconReportSearch,
IconSettings,
} from "@tabler/icons-react";
import UserConfiguration from "./UserConfiguration";
import ViewUserConfiguration from "./ViewUserConfiguration";
import UnlockedUsers from "./UnlockedUsers";
export default function Login() {
const router = useRouter();
const [authorized, SetAuthorized] = useState<boolean | null>(null);
const [view, setView] = useState<string | null>(null);
const [name, setName] = useState<string | null>(null);
const [lastLoginDetails, setLastLoginDetails] = useState<string | null>(null);
const [userMenuOpen, setUserMenuOpen] = useState(true);
const [configMenuOpen, setConfigMenuOpen] = useState(false);
const [reportOpen, setReportMenuOpen] = useState(false);
async function handleLogout(e: React.FormEvent) {
e.preventDefault();
localStorage.clear();
sessionStorage.clear();
router.push("/administrator/login");
}
async function handleFetchUserDetails(e: React.FormEvent) {
e.preventDefault();
const token = localStorage.getItem("admin_access_token");
const response = await fetch("/api/auth/admin/admin_details", {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-Login-Type": "Admin",
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
if (response.ok) {
return data;
} else if (response.status === 401 || data.message === "invalid or expired token") {
localStorage.removeItem("admin_access_token");
router.push("/administrator/login");
} else {
notifications.show({
withBorder: true,
color: "red",
title: "Please try again later",
message: "Unable to fetch timestamp, please try again later",
autoClose: 5000,
});
}
}
useEffect(() => {
const token = localStorage.getItem("admin_access_token");
if (!token) {
SetAuthorized(false);
router.push("/administrator/login/");
} else {
SetAuthorized(true);
const fetchLoginTime = async () => {
const result = await handleFetchUserDetails({
preventDefault: () => { },
} as React.FormEvent);
if (result) {
setLastLoginDetails(result.last_login);
setName(result.name);
}
};
fetchLoginTime();
}
}, []);
if (!authorized) return null;
return (
<Providers>
<div style={{ backgroundColor: "#f8f9fa", width: "100%", height: "100%" }}>
{/* Header */}
<Box
style={{
height: "60px",
position: "relative",
width: "100%",
display: "flex",
justifyContent: "flex-start",
background:
"linear-gradient(15deg,rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
}}
>
<Image
fit="cover"
src={logo}
component={NextImage}
alt="ebanking"
style={{ width: "100%", height: "100%" }}
/>
<Title
order={2}
style={{
fontFamily: "Roboto",
position: "absolute",
top: "30%",
left: "6%",
color: "White",
}}
>
THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
</Title>
<Text
style={{
position: "absolute",
top: "50%",
left: "80%",
color: "white",
textShadow: "1px 1px 2px black",
}}
>
<IconPhoneFilled size={18} /> Toll Free No : 1800-180-8008
</Text>
</Box>
{/* Layout */}
<Box style={{ display: "flex", height: "90vh" }}>
{/* Sidebar */}
<Box
style={{
width: 240,
background: "#02a355",
padding: "0.75rem",
borderRight: "1px solid #ccc",
color: "white",
fontSize: "13px",
}}
>
<Title order={4} c="white" style={{ textAlign: "center", marginBottom: "6px" }}>
Admin Portal
</Title>
<Divider my="xs" color="rgba(255,255,255,0.3)" />
{/* User Maintenance */}
<UnstyledButton
onClick={() => setUserMenuOpen(!userMenuOpen)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
padding: "5px 6px",
borderRadius: "4px",
backgroundColor: "rgba(255,255,255,0.1)",
color: "white",
fontSize: "13px",
}}
>
<Group gap="xs">
<IconUsers size={15} />
<Text fw={600} size="sm">
User Maintenance
</Text>
</Group>
{userMenuOpen ? <IconChevronUp size={15} /> : <IconChevronDown size={15} />}
</UnstyledButton>
<Collapse in={userMenuOpen}>
<Stack gap={2} pl="md" mt={4}>
<Box
onClick={() => setView("userConf")}
style={{
cursor: "pointer",
color: view === "userConf" ? "#02a355" : "white",
backgroundColor: view === "userConf" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
User Create / Update
</Box>
<Box
onClick={() => setView("viewUser")}
style={{
cursor: "pointer",
color: view === "viewUser" ? "#02a355" : "white",
backgroundColor: view === "viewUser" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
Users Status
</Box>
<Box
onClick={() => setView("unlockUser")}
style={{
cursor: "pointer",
color: view === "unlockUser" ? "#02a355" : "white",
backgroundColor: view === "unlockUser" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
User Unlock
</Box>
</Stack>
</Collapse>
{/* Reports */}
<UnstyledButton
onClick={() => setReportMenuOpen(!reportOpen)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
padding: "5px 6px",
borderRadius: "4px",
marginTop: "8px",
backgroundColor: "rgba(255,255,255,0.1)",
color: "white",
fontSize: "13px",
}}
>
<Group gap="xs">
<IconReportSearch size={15} />
<Text fw={600} size="sm">
Reports
</Text>
</Group>
{reportOpen ? <IconChevronUp size={15} /> : <IconChevronDown size={15} />}
</UnstyledButton>
<Collapse in={reportOpen}>
<Stack gap={2} pl="md" mt={4}>
<Box
onClick={() => setView("activeUsersReport")}
style={{
cursor: "pointer",
color: view === "activeUsersReport" ? "#02a355" : "white",
backgroundColor: view === "activeUsersReport" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
Active Users Report
</Box>
<Box
onClick={() => setView("noOfTrans")}
style={{
cursor: "pointer",
color: view === "noOfTrans" ? "#02a355" : "white",
backgroundColor: view === "noOfTrans" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
Transactions Report
</Box>
{/* <Box
onClick={() => setView("unlockUser")}
style={{
cursor: "pointer",
color: view === "unlockUser" ? "#02a355" : "white",
backgroundColor: view === "unlockUser" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
• User Unlock
</Box> */}
</Stack>
</Collapse>
{/* Configuration */}
<UnstyledButton
onClick={() => setConfigMenuOpen(!configMenuOpen)}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
padding: "5px 6px",
marginTop: "8px",
borderRadius: "4px",
backgroundColor: "rgba(255,255,255,0.1)",
color: "white",
fontSize: "13px",
}}
>
<Group gap="xs">
<IconSettings size={15} />
<Text fw={600} size="sm">
Configuration
</Text>
</Group>
{configMenuOpen ? <IconChevronUp size={15} /> : <IconChevronDown size={15} />}
</UnstyledButton>
<Collapse in={configMenuOpen}>
<Stack gap={2} pl="md" mt={4}>
<Box
onClick={() => setView("ifscConfig")}
style={{
cursor: "pointer",
color: view === "ifscConfig" ? "#02a355" : "white",
backgroundColor: view === "ifscConfig" ? "white" : "transparent",
borderRadius: "3px",
padding: "3px 6px",
transition: "0.2s",
}}
>
IFSC Configuration
</Box>
</Stack>
</Collapse>
<Divider my="xs" color="rgba(255,255,255,0.3)" />
<Text
onClick={handleLogout}
style={{
cursor: "pointer",
display: "flex",
alignItems: "center",
gap: "4px",
color: "white",
marginTop: "8px",
fontSize: "13px",
}}
>
<IconLogout size={14} /> Logout
</Text>
</Box>
{/* Main Content */}
<Stack style={{ flex: 1, padding: "1rem" }}>
<Box>
<Text c="Blue" size="sm" fs="italic">
Welcome, {name}
</Text>
<Text size="xs" c="gray" style={{ fontFamily: "inter" }}>
Last logged in at{" "}
{lastLoginDetails
? new Date(lastLoginDetails).toLocaleString()
: "N/A"}
</Text>
</Box>
<Box>
{view === "userConf" && <UserConfiguration />}
{view === "viewUser" && <ViewUserConfiguration />}
{view === "unlockUser" && <UnlockedUsers />}
{view === "noOfTrans" && (
<Text size="sm" c="gray">
Reports will be Coming Soon
</Text>
)}
{view === "activeUsersReport" && (
<Text size="sm" c="gray">
Active users Reports will be Coming Soon
</Text>
)}
{view === "ifscConfig" && (
<Text size="sm" c="gray">
IFSC Configuration Page Coming Soon
</Text>
)}
{!view && (
<>
<Text size="xl" c="gray">
Welcome To The Internet Banking Admin Portal
</Text>
<Text size="sm" c="black">
Choose the service from the menu.
</Text>
</>
)}
</Box>
</Stack>
</Box>
<Divider size="xs" color="#99c2ff" />
<Text size="xs" style={{ textAlign: "center" }}>
© 2025 The Kangra Central Co-Operative Bank Ltd.
</Text>
</div>
</Providers>
);
}