413 lines
14 KiB
TypeScript
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>
|
|
);
|
|
}
|