516 lines
26 KiB
TypeScript
516 lines
26 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
import { Button, Input, Group, Stack, Text, Title, Box, Select, Paper, Switch } from '@mantine/core';
|
|
import { IconBuildingBank, IconEye, IconLink } from '@tabler/icons-react';
|
|
import { useRouter } from "next/navigation";
|
|
import { Providers } from "../../providers";
|
|
import { notifications } from '@mantine/notifications';
|
|
import dayjs from 'dayjs';
|
|
import { useMediaQuery } from '@mantine/hooks';
|
|
|
|
interface accountData {
|
|
stAccountNo: string;
|
|
stAccountType: string;
|
|
stAvailableBalance: string;
|
|
custname: string;
|
|
activeAccounts: string;
|
|
}
|
|
|
|
export default function Home() {
|
|
const [authorized, SetAuthorized] = useState<boolean | null>(null);
|
|
const router = useRouter();
|
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
const [userName, setUserName] = useState<string>("");
|
|
const [accountData, SetAccountData] = useState<accountData[]>([]);
|
|
const depositAccounts = accountData.filter(acc => acc.stAccountType !== "LN");
|
|
const [selectedDA, setSelectedDA] = useState(depositAccounts[0]?.stAccountNo || "");
|
|
const selectedDAData = depositAccounts.find(acc => acc.stAccountNo === selectedDA);
|
|
const loanAccounts = accountData.filter(acc => acc.stAccountType === "LN");
|
|
const [selectedLN, setSelectedLN] = useState(loanAccounts[0]?.stAccountNo || "");
|
|
const selectedLNData = loanAccounts.find(acc => acc.stAccountNo === selectedLN);
|
|
const [showBalance, setShowBalance] = useState(false);
|
|
const PassExpiryRemains = (dayjs(localStorage.getItem("pswExpiryDate"))).diff(dayjs(), "day")
|
|
const [loadingAccountNo, setLoadingAccountNo] = useState<string | null>(null);
|
|
|
|
// If back and forward button is clicked
|
|
useEffect(() => {
|
|
window.history.pushState(null, "", window.location.href);
|
|
const handlePopState = () => {
|
|
localStorage.removeItem("access_token");
|
|
sessionStorage.removeItem("access_token");
|
|
localStorage.removeItem("remitter_name");
|
|
localStorage.removeItem("pswExpiryDate");
|
|
localStorage.clear();
|
|
sessionStorage.clear();
|
|
router.push("/login");
|
|
};
|
|
const handleBeforeUnload = () => {
|
|
// logout on tab close / refresh
|
|
localStorage.removeItem("access_token");
|
|
sessionStorage.removeItem("access_token");
|
|
localStorage.clear();
|
|
sessionStorage.clear();
|
|
};
|
|
window.addEventListener("popstate", handlePopState);
|
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
return () => {
|
|
window.removeEventListener("popstate", handlePopState);
|
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
};
|
|
}, []);
|
|
|
|
async function handleFetchUserDetails() {
|
|
try {
|
|
const token = localStorage.getItem("access_token");
|
|
const response = await fetch('api/customer', {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
"X-Login-Type": "IB",
|
|
'Authorization': `Bearer ${token}`
|
|
},
|
|
});
|
|
const data = await response.json();
|
|
if (response.ok && Array.isArray(data)) {
|
|
SetAccountData(data);
|
|
sessionStorage.setItem("accountData", JSON.stringify(data));
|
|
if (data.length > 0) {
|
|
const firstDeposit = data.find(acc => acc.stAccountType !== "LN");
|
|
const firstLoan = data.find(acc => acc.stAccountType === "LN");
|
|
if (firstDeposit) setSelectedDA(firstDeposit.stAccountNo);
|
|
if (firstLoan) setSelectedLN(firstLoan.stAccountNo);
|
|
}
|
|
} else {
|
|
throw new Error();
|
|
}
|
|
} catch {
|
|
notifications.show({
|
|
withBorder: true,
|
|
color: "red",
|
|
title: "Please try again later",
|
|
message: "Unable to Fetch, Please try again later",
|
|
autoClose: 5000,
|
|
});
|
|
}
|
|
}
|
|
|
|
async function handleGetAccountStatement(accountNo: string) {
|
|
if (loadingAccountNo) return;
|
|
setLoadingAccountNo(accountNo);
|
|
// simulate loading delay
|
|
setTimeout(() => {
|
|
router.push(`/accounts/account_statement?accNo=${accountNo}`);
|
|
setLoadingAccountNo(null);
|
|
}, 6000);
|
|
}
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem("access_token");
|
|
if (!token) {
|
|
SetAuthorized(false);
|
|
router.push("/login");
|
|
} else {
|
|
SetAuthorized(true);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (authorized) {
|
|
handleFetchUserDetails();
|
|
const fullName = localStorage.getItem("remitter_name") || "User";
|
|
// const first = fullName.split(" ")[0];
|
|
setUserName(fullName);
|
|
}
|
|
}, [authorized]);
|
|
|
|
if (authorized) {
|
|
return (
|
|
<Providers>
|
|
<Box p={isMobile ? "8px" : "10px"}>
|
|
|
|
{/* ---------------------- WELCOME CARD ---------------------- */}
|
|
<Title
|
|
order={2}
|
|
style={{
|
|
marginTop: "4px",
|
|
fontSize: isMobile ? "20px" : "28px",
|
|
fontWeight: 800,
|
|
background: "linear-gradient(56deg, rgba(16,114,152,1) 0%, rgba(62,230,132,1) 86%)",
|
|
WebkitBackgroundClip: "text",
|
|
WebkitTextFillColor: "transparent",
|
|
}}
|
|
>
|
|
Welcome, {userName}
|
|
</Title>
|
|
|
|
{/* -------------------- ACCOUNT OVERVIEW HEADER -------------------- */}
|
|
<Title
|
|
order={4}
|
|
style={{
|
|
fontSize: isMobile ? "18px" : "22px",
|
|
marginTop: isMobile ? "6px" : "10px", // ⭐ ADD THIS GAP
|
|
}}
|
|
>
|
|
Accounts Overview
|
|
</Title>
|
|
|
|
|
|
<Text size="sm" c="dimmed" mb={isMobile ? 10 : 14}>
|
|
Your accounts at a glance
|
|
</Text>
|
|
|
|
{/* --------------------- SHOW BALANCE TOGGLE ---------------------- */}
|
|
<Group
|
|
style={{
|
|
marginBottom: isMobile ? "10px" : "14px",
|
|
alignItems: "center",
|
|
justifyContent: "flex-start",
|
|
gap: 10,
|
|
}}
|
|
>
|
|
<IconEye size={isMobile ? 16 : 20} />
|
|
<Text fw={700} style={{ fontSize: isMobile ? "14px" : "18px" }}>
|
|
Show Balance
|
|
</Text>
|
|
|
|
<Switch
|
|
size={isMobile ? "sm" : "md"}
|
|
checked={showBalance}
|
|
onChange={(event) => setShowBalance(event.currentTarget.checked)}
|
|
/>
|
|
</Group>
|
|
|
|
{/* ----------------------- DESKTOP VIEW ------------------------ */}
|
|
{!isMobile && (
|
|
<Group align="flex-start" grow gap="md">
|
|
|
|
{/* ----------------------- DEPOSIT CARD ----------------------- */}
|
|
<Paper p="md" radius="md"
|
|
style={{
|
|
background: "linear-gradient(56deg,rgba(179,214,227,1) 0%, rgba(142,230,179,1) 86%)",
|
|
height: 195,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between"
|
|
}}
|
|
>
|
|
<Group gap="xs">
|
|
<IconBuildingBank size={25} />
|
|
<Text fw={700}>Deposit Account</Text>
|
|
|
|
<Select
|
|
data={depositAccounts.map((acc) => ({
|
|
value: acc.stAccountNo,
|
|
label: `${acc.stAccountType}- ${acc.stAccountNo}`,
|
|
}))}
|
|
value={selectedDA}
|
|
// @ts-ignore
|
|
onChange={setSelectedDA}
|
|
size="xs"
|
|
styles={{
|
|
input: { backgroundColor: "white", color: "black", marginLeft: 5, width: 140 }
|
|
}}
|
|
/>
|
|
</Group>
|
|
|
|
<Text c="dimmed">{selectedDAData?.stAccountNo}</Text>
|
|
|
|
<Title order={2}>
|
|
{showBalance
|
|
? `₹${Number(selectedDAData?.stAvailableBalance || 0).toLocaleString("en-IN")}`
|
|
: "****"}
|
|
</Title>
|
|
|
|
<Button
|
|
fullWidth
|
|
disabled={loadingAccountNo === selectedDA}
|
|
onClick={() => handleGetAccountStatement(selectedDA)}
|
|
>
|
|
{loadingAccountNo === selectedDA ? "Loading...Please Wait" : "Get Statement"}
|
|
</Button>
|
|
</Paper>
|
|
|
|
{/* ----------------------- LOAN CARD ----------------------- */}
|
|
<Paper p="md" radius="md"
|
|
style={{
|
|
background: "linear-gradient(56deg,rgba(179,214,227,1) 0%, rgba(142,230,179,1) 86%)",
|
|
height: 195,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between"
|
|
}}
|
|
>
|
|
<Group gap="xs">
|
|
<IconBuildingBank size={25} />
|
|
<Text fw={700}>Loan Account</Text>
|
|
|
|
<Select
|
|
data={loanAccounts.map((acc) => ({
|
|
value: acc.stAccountNo,
|
|
label: `${acc.stAccountType}- ${acc.stAccountNo}`,
|
|
}))}
|
|
value={selectedLN}
|
|
// @ts-ignore
|
|
onChange={setSelectedLN}
|
|
size="xs"
|
|
styles={{
|
|
input: { backgroundColor: "white", color: "black", marginLeft: 30, width: 140 }
|
|
}}
|
|
/>
|
|
</Group>
|
|
|
|
<Text c="dimmed">{selectedLNData?.stAccountNo}</Text>
|
|
|
|
<Title order={2}>
|
|
{showBalance
|
|
? `₹${Number(selectedLNData?.stAvailableBalance || 0).toLocaleString("en-IN")}`
|
|
: "****"}
|
|
</Title>
|
|
|
|
<Button
|
|
fullWidth
|
|
disabled={loadingAccountNo === selectedLN}
|
|
onClick={() => handleGetAccountStatement(selectedLN)}
|
|
>
|
|
{loadingAccountNo === selectedLN ? "Loading...Please Wait" : "Get Statement"}
|
|
</Button>
|
|
</Paper>
|
|
|
|
{/* ----------------------- QUICK LINKS ----------------------- */}
|
|
<Paper p="md" radius="md" style={{ width: 300, backgroundColor: "#FFFFFF", border: "1px solid grey" }}>
|
|
<Title order={5} mb="sm">Quick Links</Title>
|
|
|
|
<Stack gap="xs">
|
|
<Button
|
|
variant="light"
|
|
color="green"
|
|
fullWidth
|
|
onClick={() => window.open("https://kccbhp.bank.in/about-us/history-of-kccb/", "_blank")}
|
|
>
|
|
About Us
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/BranchLocator" target="_blank">
|
|
Branch Locator
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/ATMLocator" target="_blank">
|
|
ATM Locator
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/CustomerCare" target="_blank">
|
|
Customer Care
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/FAQs" target="_blank">
|
|
FAQs
|
|
</Button>
|
|
</Stack>
|
|
</Paper>
|
|
|
|
</Group>
|
|
)}
|
|
|
|
{/* ----------------------- MOBILE VERSION STAYS SAME ----------------------- */}
|
|
{isMobile && (
|
|
<Stack gap="md" style={{ width: "100%", marginTop: "10px" }}>
|
|
{/* Deposit Account Card */}
|
|
<Paper
|
|
p="md"
|
|
radius="md"
|
|
style={{
|
|
backgroundColor: "#c1e0f0",
|
|
width: "100%",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between",
|
|
}}
|
|
>
|
|
<Group gap="xs">
|
|
<IconBuildingBank size={20} />
|
|
<Text fw={700} style={{ fontSize: "14px" }}>
|
|
Deposit Account
|
|
</Text>
|
|
{depositAccounts.length > 0 ? (
|
|
<Select
|
|
data={depositAccounts.map((acc) => ({
|
|
value: acc.stAccountNo,
|
|
label: `${acc.stAccountType}- ${acc.stAccountNo}`,
|
|
}))}
|
|
value={selectedDA}
|
|
// @ts-ignore
|
|
onChange={setSelectedDA}
|
|
size="xs"
|
|
styles={{
|
|
input: {
|
|
backgroundColor: "white",
|
|
color: "black",
|
|
marginLeft: 5,
|
|
width: "150px",
|
|
},
|
|
}}
|
|
/>
|
|
) : (
|
|
<Text c="dimmed" size="sm" ml="sm">
|
|
No deposit account available
|
|
</Text>
|
|
)}
|
|
</Group>
|
|
|
|
{depositAccounts.length > 0 ? (
|
|
<>
|
|
<Text c="dimmed" style={{ fontSize: "12px" }}>
|
|
{Number(selectedDAData?.stAccountNo || 0)}
|
|
</Text>
|
|
<Title order={4} mt="md">
|
|
{showBalance
|
|
? `₹${Number(selectedDAData?.stAvailableBalance || 0).toLocaleString("en-IN")}`
|
|
: "****"}
|
|
</Title>
|
|
<Button fullWidth mt="xs"
|
|
// loading={loadingAccountNo === selectedDA}
|
|
disabled={loadingAccountNo === selectedDA}
|
|
onClick={() => handleGetAccountStatement(selectedDA)}
|
|
>
|
|
{loadingAccountNo === selectedDA ? "Loading...Please Wait" : "Get Statement"}
|
|
</Button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Text c="dimmed" mt="md">
|
|
Apply for a deposit account to get started
|
|
</Text>
|
|
<Button fullWidth mt="xs">
|
|
Apply Now
|
|
</Button>
|
|
</>
|
|
)}
|
|
</Paper>
|
|
|
|
{/* Loan Account Card */}
|
|
<Paper
|
|
p="md"
|
|
radius="md"
|
|
style={{
|
|
backgroundColor: "#c1e0f0",
|
|
width: "100%",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between",
|
|
}}
|
|
>
|
|
<Group gap="xs">
|
|
<IconBuildingBank size={20} />
|
|
<Text fw={700} style={{ fontSize: "14px" }}>
|
|
Loan Account
|
|
</Text>
|
|
{loanAccounts.length > 0 ? (
|
|
<Select
|
|
data={loanAccounts.map((acc) => ({
|
|
value: acc.stAccountNo,
|
|
label: `${acc.stAccountType}- ${acc.stAccountNo}`,
|
|
}))}
|
|
value={selectedLN}
|
|
// @ts-ignore
|
|
onChange={setSelectedLN}
|
|
size="xs"
|
|
styles={{
|
|
input: {
|
|
backgroundColor: "white",
|
|
color: "black",
|
|
marginLeft: 5,
|
|
width: "150px",
|
|
},
|
|
}}
|
|
/>
|
|
) : (
|
|
<Text c="dimmed" size="sm" ml="sm">
|
|
No loan account available
|
|
</Text>
|
|
)}
|
|
</Group>
|
|
|
|
{loanAccounts.length > 0 ? (
|
|
<>
|
|
<Text c="dimmed" style={{ fontSize: "12px" }}>
|
|
{Number(selectedLNData?.stAccountNo || 0)}
|
|
</Text>
|
|
<Title order={4} mt="md">
|
|
{showBalance
|
|
? `₹${Number(selectedLNData?.stAvailableBalance || 0).toLocaleString("en-IN")}`
|
|
: "****"}
|
|
</Title>
|
|
<Button fullWidth mt="xs"
|
|
// loading={loadingAccountNo === selectedLN}
|
|
disabled={loadingAccountNo === selectedLN}
|
|
onClick={() => handleGetAccountStatement(selectedLN)}
|
|
>
|
|
{/* Get Statement */}
|
|
{loadingAccountNo === selectedLN ? "Loading...Please Wait" : "Get Statement"}
|
|
</Button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Text c="dimmed" mt="md">
|
|
Apply for a loan account to get started
|
|
</Text>
|
|
<Button fullWidth mt="xs">
|
|
Apply Now
|
|
</Button>
|
|
</>
|
|
)}
|
|
</Paper>
|
|
|
|
{/* Important Links Card */}
|
|
<Paper
|
|
p="md"
|
|
radius="md"
|
|
style={{
|
|
width: "100%",
|
|
backgroundColor: "#FFFFFF",
|
|
border: "1px solid grey",
|
|
}}
|
|
>
|
|
<Title order={5} mb="sm">
|
|
Quick Links
|
|
</Title>
|
|
<Stack gap="xs">
|
|
<Button
|
|
variant="light"
|
|
color="green"
|
|
fullWidth
|
|
onClick={() => window.open("https://kccbhp.bank.in/about-us/history-of-kccb/", "_blank")}
|
|
>
|
|
About Us
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/BranchLocator" target="_blank">
|
|
Branch Locator
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/ATMLocator" target="_blank">
|
|
ATM Locator
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/CustomerCare" target="_blank">
|
|
Customer Care
|
|
</Button>
|
|
<Button variant="light" color="green" fullWidth component="a" href="/FAQs" target="_blank">
|
|
FAQs
|
|
</Button>
|
|
</Stack>
|
|
</Paper>
|
|
</Stack>
|
|
)}
|
|
|
|
{/* -------------------- NOTES SECTION (BOTTOM) --------------------- */}
|
|
<Box mt="md">
|
|
<Stack>
|
|
<Text fw={700}> ** Book Balance includes uncleared effect.</Text>
|
|
<Text fw={700}> ** Click "Show Balance" to display account balances.</Text>
|
|
<Text fw={400} c="red">
|
|
** Your Password will expire in {PassExpiryRemains} days.
|
|
</Text>
|
|
</Stack>
|
|
</Box>
|
|
|
|
</Box>
|
|
</Providers>
|
|
);
|
|
}
|
|
return null;
|
|
} |