459 lines
21 KiB
TypeScript
459 lines
21 KiB
TypeScript
"use client";
|
||
|
||
import React, { useState, useEffect, Suspense } from "react";
|
||
import { Text, Button, TextInput, PasswordInput, Title, Card, Group, Box, Image } 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 frontPage from '@/app/image/EMandate.jpg';
|
||
import { generateCaptcha } from '@/app/captcha';
|
||
import styles from './Login.module.css';
|
||
import { useSearchParams } from "next/navigation";
|
||
|
||
function LoginEmandate() {
|
||
const router = useRouter();
|
||
const [CIF, SetCIF] = useState("");
|
||
const [psw, SetPsw] = useState("");
|
||
const [captcha, setCaptcha] = useState("");
|
||
const [inputCaptcha, setInputCaptcha] = useState("");
|
||
const [isLogging, setIsLogging] = useState(false);
|
||
const searchParams = useSearchParams();
|
||
const data = searchParams.get("data");
|
||
const mandateReqDoc = searchParams.get("mandateReqDoc");
|
||
const mndtType = searchParams.get("mndtType");
|
||
|
||
// useEffect(() => {
|
||
// if (data) {
|
||
// console.log("URL parameter 'data':", data);
|
||
// localStorage.setItem("Emendate_data", data);
|
||
// localStorage.setItem("Emendate_req_doc", mandateReqDoc || "");
|
||
// localStorage.setItem("Emendate_type", mndtType || "");
|
||
// }
|
||
// }, [data]);
|
||
useEffect(() => {
|
||
if (data && mandateReqDoc && mndtType) {
|
||
console.log("eMandate parameters found");
|
||
localStorage.setItem("Emendate_data", data);
|
||
localStorage.setItem("Emendate_req_doc", mandateReqDoc);
|
||
localStorage.setItem("Emendate_type", mndtType);
|
||
} else {
|
||
console.log("eMandate parameters missing — clearing localStorage");
|
||
localStorage.removeItem("Emendate_data");
|
||
localStorage.removeItem("Emendate_req_doc");
|
||
localStorage.removeItem("Emendate_type");
|
||
}
|
||
}, [data, mandateReqDoc, mndtType]);
|
||
|
||
useEffect(() => {
|
||
const loadCaptcha = async () => {
|
||
const newCaptcha = await generateCaptcha();
|
||
setCaptcha(newCaptcha);
|
||
};
|
||
loadCaptcha();
|
||
}, []);
|
||
|
||
const regenerateCaptcha = () => {
|
||
// setCaptcha(generateCaptcha());
|
||
const loadCaptcha = async () => {
|
||
const newCaptcha = await generateCaptcha();
|
||
setCaptcha(newCaptcha);
|
||
};
|
||
loadCaptcha();
|
||
setInputCaptcha("");
|
||
};
|
||
|
||
async function handleMandateLogin(e: React.FormEvent) {
|
||
e.preventDefault();
|
||
const onlyDigit = /^\d{11}$/;
|
||
if (!onlyDigit.test(CIF)) {
|
||
// setError('Input value must be 11 digit');
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Invalid UserId",
|
||
message: "UserID must be 11 digit",
|
||
autoClose: 5000,
|
||
});
|
||
return;
|
||
}
|
||
if (!inputCaptcha) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Invalid Captcha",
|
||
message: "Please fill the Captcha filed",
|
||
autoClose: 5000,
|
||
});
|
||
return;
|
||
}
|
||
if (inputCaptcha !== captcha) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Captcha Error",
|
||
message: "Please enter the correct captcha",
|
||
autoClose: 5000,
|
||
});
|
||
regenerateCaptcha();
|
||
return;
|
||
}
|
||
if (!CIF || !psw) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Invalid Input",
|
||
message: "Please fill UserId and Password",
|
||
autoClose: 5000,
|
||
});
|
||
return;
|
||
}
|
||
try {
|
||
setIsLogging(true);
|
||
const response = await fetch('/api/auth/login', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-Login-Type': 'eMandate',
|
||
},
|
||
body: JSON.stringify({
|
||
customerNo: CIF,
|
||
password: psw,
|
||
}),
|
||
});
|
||
const data = await response.json();
|
||
if (!response.ok) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Error",
|
||
message: data?.error || "Internal Server Error",
|
||
autoClose: 5000,
|
||
});
|
||
regenerateCaptcha()
|
||
localStorage.removeItem("mandate_token");
|
||
localStorage.clear();
|
||
sessionStorage.clear();
|
||
setIsLogging(false);
|
||
return;
|
||
}
|
||
if (response.ok) {
|
||
// console.log(data);
|
||
const token = data.token;
|
||
localStorage.setItem("mandate_token", token);
|
||
// localStorage.setItem("pswExpiryDate", data.loginPswExpiry);
|
||
if (data.FirstTimeLogin === true) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Error",
|
||
message: "Please go to Internet Banking, set your credentials, and then try logging in here again.",
|
||
autoClose: 5000,
|
||
});
|
||
setIsLogging(false);
|
||
}
|
||
else {
|
||
console.log("Start to validate soft tech data");
|
||
const response = await fetch('/api/e-mandate/validation', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-Login-Type': 'eMandate',
|
||
'Authorization': `Bearer ${localStorage.getItem("mandate_token")}`
|
||
},
|
||
body: JSON.stringify({
|
||
data: localStorage.getItem("Emendate_data"),
|
||
mandateRequest: localStorage.getItem("Emendate_req_doc"),
|
||
mandateType: localStorage.getItem("Emendate_type"),
|
||
// customer_no:CIF
|
||
}),
|
||
});
|
||
const result = await response.json();
|
||
localStorage.setItem("Validate_data", result.data);
|
||
console.log("Validate Result : ", result);
|
||
if (response.ok) {
|
||
router.push("/eMandate/otp_page");
|
||
}
|
||
else {
|
||
console.log("validation failed: response",result);
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Validation failed",
|
||
message: "Failed to validate.Please try again later.",
|
||
autoClose: 5000,
|
||
});
|
||
setIsLogging(false);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
regenerateCaptcha();
|
||
setIsLogging(false);
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Wrong User Id or Password",
|
||
message: "Wrong User Id or Password",
|
||
autoClose: 5000,
|
||
});
|
||
}
|
||
}
|
||
catch (error: any) {
|
||
notifications.show({
|
||
withBorder: true,
|
||
color: "red",
|
||
title: "Error",
|
||
message: "Internal Server Error,Please try again Later",
|
||
autoClose: 5000,
|
||
});
|
||
setIsLogging(false);
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (data && mandateReqDoc && mndtType) {
|
||
return (
|
||
<Providers>
|
||
{/* Main Screen */}
|
||
<div style={{ backgroundColor: "#f8f9fa", width: "100%", height: "auto", paddingTop: "5%" }}>
|
||
{/* Header */}
|
||
|
||
<Box className={styles.header}>
|
||
<Image src={logo} component={NextImage} fit="contain" alt="ebanking" style={{ width: "60px", height: "auto" }} />
|
||
<Box className={styles['header-text']}>
|
||
<Title className={styles['desktop-text']} order={4}>THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.</Title>
|
||
<Text className={styles['desktop-text']} size="xs">Head Office: Dharmshala, District Kangra (H.P), Pin: 176215</Text>
|
||
<Title className={styles['mobile-text']} order={5}>THE KANGRA CENTRAL</Title>
|
||
<Title className={styles['mobile-text']} order={5}>CO-OPERATIVE BANK LTD.</Title>
|
||
</Box>
|
||
</Box>
|
||
|
||
<div style={{ marginTop: '10px' }}>
|
||
{/* Movable text */}
|
||
<Box
|
||
className={styles['desktop-scroll-text']}
|
||
>
|
||
<Text
|
||
component="span"
|
||
style={{
|
||
display: "inline-block",
|
||
paddingLeft: "100%",
|
||
animation: "scroll-left 60s linear infinite",
|
||
fontWeight: "bold",
|
||
color: "#004d99",
|
||
}}
|
||
>
|
||
⚠️ Always login to our Net Banking site directly or through Banks website.
|
||
⚠️ Do not disclose your User Id and Password to any third party and keep Your User Id and Password strictly confidential.
|
||
⚠️ KCC Bank never asks for User Id,Passwords and Pins through email or phone.
|
||
⚠️ Be ware of Phishing mails with links to fake bank's websites asking for personal information are in circulation.
|
||
⚠️ Please DO NOT Click on the links given in the emails asking for personal details like bank account number, user ID and password.
|
||
⚠️ If you had shared your User Id and Password through such mails or links, please change your Password immediately.
|
||
⚠️ Inform the Bank/branch in which your account is maintained for resetting your password.
|
||
</Text>
|
||
<style>
|
||
{`
|
||
@keyframes scroll-left {
|
||
0% { transform: translateX(0%); }
|
||
100% { transform: translateX(-100%); }
|
||
}
|
||
@media (max-width: 768px) {
|
||
.desktop-scroll-text { display: none; }
|
||
}
|
||
`}
|
||
</style>
|
||
</Box>
|
||
|
||
{/* Main */}
|
||
<Box visibleFrom="md"
|
||
style={{
|
||
display: "flex", height: "75vh", overflow: "hidden", position: "relative",
|
||
background: 'linear-gradient(179deg, #3faa56ff 49%, #3aa760ff 80%)'
|
||
}}>
|
||
<div style={{ flex: 1, backgroundColor: "#c1e0f0", position: "relative" }}>
|
||
<Image
|
||
fit="cover"
|
||
src={frontPage}
|
||
component={NextImage}
|
||
alt="ebanking"
|
||
style={{ width: "100%", height: "100%" }}
|
||
/>
|
||
</div>
|
||
<Box w={{ base: "100%", md: "45%" }} p="lg">
|
||
<Card shadow="md" padding="xl" radius="md" style={{ maxWidth: 550, margin: "0 auto", height: '68vh' }}>
|
||
<form onSubmit={handleMandateLogin}>
|
||
<Text
|
||
ta="center"
|
||
fw={700}
|
||
style={{ fontSize: "18px" }}
|
||
>
|
||
E-Mandate Login
|
||
</Text>
|
||
|
||
<TextInput
|
||
label="User ID"
|
||
placeholder="Enter your CIF No"
|
||
value={CIF}
|
||
onInput={(e) => {
|
||
const input = e.currentTarget.value.replace(/\D/g, "");
|
||
if (input.length <= 11) SetCIF(input);
|
||
}}
|
||
withAsterisk
|
||
/>
|
||
<PasswordInput
|
||
label="Password"
|
||
placeholder="Enter your password"
|
||
value={psw}
|
||
onChange={(e) => SetPsw(e.currentTarget.value)}
|
||
withAsterisk
|
||
mt="sm"
|
||
/>
|
||
|
||
<Group mt="sm" align="center">
|
||
<Box style={{ backgroundColor: "#fff", fontSize: "18px", textDecoration: "line-through", padding: "4px 8px", fontFamily: "Verdana" }}>{captcha}</Box>
|
||
<Button size="xs" variant="light" onClick={regenerateCaptcha}>Refresh</Button>
|
||
</Group>
|
||
<TextInput
|
||
label="Enter CAPTCHA"
|
||
placeholder="Enter above text"
|
||
value={inputCaptcha}
|
||
onChange={(e) => setInputCaptcha(e.currentTarget.value)}
|
||
withAsterisk
|
||
mt="sm"
|
||
/>
|
||
<Button type="submit" fullWidth mt="md" disabled={isLogging}>
|
||
{isLogging ? "Logging..." : "Login"}
|
||
</Button>
|
||
</form>
|
||
</Card>
|
||
</Box>
|
||
</Box>
|
||
|
||
{/* Mobile layout */}
|
||
<Box
|
||
hiddenFrom="md"
|
||
style={{
|
||
marginTop: "25%",
|
||
padding: "1rem",
|
||
background: "linear-gradient(179deg, #3faa56ff 49%, #3aa760ff 80%)",
|
||
minHeight: "80vh",
|
||
display: "flex",
|
||
justifyContent: "center",
|
||
alignItems: "flex-start",
|
||
}}
|
||
>
|
||
<Card shadow="md" padding="lg" radius="md" style={{ width: "100%" }}>
|
||
<form onSubmit={handleMandateLogin}>
|
||
<Text ta="center" fw={700} style={{ fontSize: "16px" }}>
|
||
E-Mandate Login
|
||
</Text>
|
||
|
||
<TextInput
|
||
label="User ID"
|
||
placeholder="Enter your CIF No"
|
||
value={CIF}
|
||
onInput={(e) => {
|
||
const input = e.currentTarget.value.replace(/\D/g, "");
|
||
if (input.length <= 11) SetCIF(input);
|
||
}}
|
||
withAsterisk
|
||
mt="sm"
|
||
/>
|
||
|
||
<PasswordInput
|
||
label="Password"
|
||
placeholder="Enter your password"
|
||
value={psw}
|
||
onChange={(e) => SetPsw(e.currentTarget.value)}
|
||
withAsterisk
|
||
mt="sm"
|
||
/>
|
||
|
||
<Group mt="sm" align="center" grow>
|
||
<Box
|
||
style={{
|
||
backgroundColor: "#fff",
|
||
fontSize: "16px",
|
||
textDecoration: "line-through",
|
||
padding: "4px 8px",
|
||
fontFamily: "Verdana",
|
||
}}
|
||
>
|
||
{captcha}
|
||
</Box>
|
||
<Button size="xs" variant="light" onClick={regenerateCaptcha}>
|
||
Refresh
|
||
</Button>
|
||
</Group>
|
||
|
||
<TextInput
|
||
label="Enter CAPTCHA"
|
||
placeholder="Enter above text"
|
||
value={inputCaptcha}
|
||
onChange={(e) => setInputCaptcha(e.currentTarget.value)}
|
||
withAsterisk
|
||
mt="sm"
|
||
/>
|
||
|
||
<Button type="submit" fullWidth mt="md" disabled={isLogging}>
|
||
{isLogging ? "Logging..." : "Login"}
|
||
</Button>
|
||
</form>
|
||
</Card>
|
||
</Box>
|
||
|
||
{/* Footer */}
|
||
<Box
|
||
component="footer"
|
||
style={{
|
||
width: "100%",
|
||
textAlign: "center",
|
||
padding: "10px 0",
|
||
bottom: 0,
|
||
left: 0,
|
||
zIndex: 1000,
|
||
fontSize: "14px",
|
||
}}
|
||
>
|
||
<Text>
|
||
© 2025 KCC Bank. All rights reserved.
|
||
</Text>
|
||
</Box>
|
||
</div>
|
||
</div>
|
||
</Providers>
|
||
);
|
||
}
|
||
else {
|
||
return (
|
||
<div
|
||
style={{
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
height: "100vh",
|
||
backgroundColor: "#f8f9fa",
|
||
}}
|
||
>
|
||
<Text c="red" fw={600} size="lg">
|
||
⚠️ Required data not found
|
||
</Text>
|
||
<Text c="dimmed" size="sm">
|
||
Please access this page through the correct eMandate link.
|
||
</Text>
|
||
</div>
|
||
);
|
||
}
|
||
}
|
||
|
||
export default function Login() {
|
||
return (
|
||
<Suspense fallback={<div>Loading...</div>}>
|
||
<LoginEmandate />
|
||
</Suspense>
|
||
);
|
||
}
|