diff --git a/src/app/(main)/home/page.tsx b/src/app/(main)/home/page.tsx
index 4aa2a8d..bdd7bf2 100644
--- a/src/app/(main)/home/page.tsx
+++ b/src/app/(main)/home/page.tsx
@@ -143,7 +143,7 @@ export default function Home() {
{/* Loan Account Card */}
diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx
index 6b149c9..bd1baa6 100644
--- a/src/app/(main)/layout.tsx
+++ b/src/app/(main)/layout.tsx
@@ -5,7 +5,7 @@ import { IconBook, IconCurrencyRupee, IconHome, IconLogout, IconPhoneFilled, Ico
import Link from 'next/link';
import { useRouter, usePathname } from "next/navigation";
import { Providers } from '../providers';
-import logo from '@/app/image/logo.jpg';
+import logo from '@/app/image/logo1.jpg';
import NextImage from 'next/image';
import { notifications } from '@mantine/notifications';
@@ -25,7 +25,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
async function handleFetchUserName() {
try {
const token = localStorage.getItem("access_token");
- const response = await fetch('api/customer', {
+ const response = await fetch('/api/customer', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
@@ -67,7 +67,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
async function handleFetchUserDetails(e: React.FormEvent) {
e.preventDefault();
const token = localStorage.getItem("access_token");
- const response = await fetch('api/auth/user_details', {
+ const response = await fetch('/api/auth/user_details', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
@@ -124,7 +124,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
width: '100%',
display: "flex",
justifyContent: "flex-start",
- background: "linear-gradient(15deg,rgba(2, 163, 85, 1) 55%, rgba(101, 101, 184, 1) 100%)",
+ background: "linear-gradient(15deg,rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
}}
>
+
+ THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
+
}
- variant={isActive ? "light" : "subtle"}
+ variant={isActive ? "dark" : "subtle"}
color={isActive ? "blue" : undefined}
>
{item.label}
@@ -213,7 +226,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
}}
>
- © 2025 Kangra Central Co-Operative Bank
+ © 2025 The Kangra Central Co-Operative Bank
diff --git a/src/app/(main)/settings/change_login_password/page.tsx b/src/app/(main)/settings/change_login_password/page.tsx
index 7ed1335..e86ff17 100644
--- a/src/app/(main)/settings/change_login_password/page.tsx
+++ b/src/app/(main)/settings/change_login_password/page.tsx
@@ -14,7 +14,7 @@ import {
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconEye, IconEyeOff, IconLock } from "@tabler/icons-react";
-import CaptchaImage from "@/app/SetPassword/CaptchaImage";
+// import CaptchaImage from "@/app/SetPassword/CaptchaImage";
import { generateCaptcha } from "@/app/captcha";
const ChangePassword: React.FC = () => {
@@ -193,7 +193,7 @@ const ChangePassword: React.FC = () => {
{/* CAPTCHA Image */}
-
+ {/* */}
{/* Refresh Button */}
diff --git a/src/app/(main)/settings/layout.tsx b/src/app/(main)/settings/layout.tsx
index 3ae6b1c..ba3d1f4 100644
--- a/src/app/(main)/settings/layout.tsx
+++ b/src/app/(main)/settings/layout.tsx
@@ -38,7 +38,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
}}
>
-
+
Settings
diff --git a/src/app/SetPassword/CaptchaImage.tsx b/src/app/SetPassword/CaptchaImage.tsx
deleted file mode 100644
index d63d34c..0000000
--- a/src/app/SetPassword/CaptchaImage.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React, { useEffect, useRef } from 'react';
-
-const CaptchaImage = ({ text }: { text: string }) => {
- const canvasRef = useRef
(null);
-
- useEffect(() => {
- const canvas = canvasRef.current;
- const ctx = canvas?.getContext('2d');
- if (canvas && ctx) {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.font = '26px Arial';
- ctx.fillStyle = '#000';
- ctx.setTransform(1, 0.1, -0.1, 1, 0, 0);
- ctx.fillText(text, 10, 30);
- }
- }, [text]);
-
- return ;
-};
-
-export default CaptchaImage;
diff --git a/src/app/SetPassword/page.tsx b/src/app/SetPassword/page.tsx
index 1aec987..c9a3f2c 100644
--- a/src/app/SetPassword/page.tsx
+++ b/src/app/SetPassword/page.tsx
@@ -1,14 +1,15 @@
"use client";
import React, { useState, useEffect } from "react";
-import { Text, Button, TextInput, PasswordInput, Title, Card, Box, Image } from "@mantine/core";
+import { Text, Button, TextInput, PasswordInput, Title, Card, Box, Image, Group } 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/logo.jpg';
-import changePwdImage from '@/app/image/changepw.png';
-import CaptchaImage from './CaptchaImage';
-import { IconEye, IconEyeOff, IconLock, IconLogout } from '@tabler/icons-react';
+import logo from '@/app/image/logo1.jpg';
+import changePwdImage from '@/app/image/set_log_pass.jpg';
+import { IconLock, IconLogout, IconRefresh } from '@tabler/icons-react';
+import { generateCaptcha } from '@/app/captcha';
+import { generateOTP } from "../OTPGenerator";
export default function SetLoginPwd() {
const router = useRouter();
@@ -16,33 +17,35 @@ export default function SetLoginPwd() {
const [captcha, setCaptcha] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
- const [captchaInput, setCaptchaInput] = useState('');
- const [captchaError, setCaptchaError] = useState('');
- const [confirmVisible, setConfirmVisible] = useState(false);
- const toggleConfirmVisibility = () => setConfirmVisible((v) => !v);
+ const [captchaInput, setCaptchaInput] = useState("");
+ const [captchaValidate, setCaptchaValidate] = useState(false);
+ const [otp, setOtp] = useState("");
+ const [countdown, setCountdown] = useState(60);
+ const [timerActive, setTimerActive] = useState(false);
const icon = ;
+ const [generateOtp, setGenerateOtp] = useState("");
+ async function handleGenerateOtp() {
+ // const value = await generateOTP(6);
+ const value = "123456";
+ setGenerateOtp(value);
+ setCountdown(60);
+ setTimerActive(true);
+ // return value;
+ }
async function handleLogout(e: React.FormEvent) {
e.preventDefault();
localStorage.removeItem("access_token");
router.push("/login")
}
-
- useEffect(() => {
- generateCaptcha();
- }, []);
-
- const generateCaptcha = () => {
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- let result = '';
- for (let i = 0; i < 6; i++) {
- result += chars.charAt(Math.floor(Math.random() * chars.length));
- }
- setCaptcha(result);
- setCaptchaInput('');
- setCaptchaError('');
+ const regenerateCaptcha = () => {
+ const loadCaptcha = async () => {
+ const newCaptcha = await generateCaptcha();
+ setCaptcha(newCaptcha);
+ };
+ loadCaptcha();
+ setCaptchaInput("");
};
-
async function handleSetLoginPassword(e: React.FormEvent) {
e.preventDefault();
const pwdRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
@@ -50,36 +53,72 @@ export default function SetLoginPwd() {
notifications.show({
withBorder: true,
color: "red",
- title: "Both password fields are required.",
- message: "Both password fields are required.",
+ title: "Field Required",
+ message: "Password and Confirm Password Both fields are required.",
autoClose: 5000,
});
return;
- // alert("Both password fields are required.");
- } else if (password !== confirmPassword) {
- // alert("Passwords do not match.");
+ }
+ if (!captchaInput) {
notifications.show({
withBorder: true,
color: "red",
- title: "Passwords do not match.",
+ title: "Field Required",
+ message: "Please Enter Captcha details",
+ autoClose: 5000,
+ });
+ return;
+ }
+ if (password !== confirmPassword) {
+ notifications.show({
+ withBorder: true,
+ color: "red",
+ title: "Password Mismatch",
message: "Passwords do not match.",
autoClose: 5000,
});
return;
}
- else if (!pwdRegex.test(password)) {
- // alert("Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.");
+ if (!pwdRegex.test(password)) {
notifications.show({
withBorder: true,
color: "red",
- title: "Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.",
- message: "Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.",
+ title: "Invalid Password",
+ message: "Password must contain at least one capital letter, one number, one special character, and be 8-15 characters long.",
autoClose: 5000,
});
return;
}
- else if (captchaInput !== captcha) {
- setCaptchaError("Incorrect CAPTCHA.");
+ if (captchaInput !== captcha) {
+ notifications.show({
+ withBorder: true,
+ color: "red",
+ title: "Captcha Error",
+ message: "Please enter the correct captcha",
+ autoClose: 5000,
+ });
+ regenerateCaptcha();
+ return;
+ }
+ if (!captchaValidate) {
+ setCaptchaValidate(true);
+ handleGenerateOtp();
+ return;
+ }
+ if (!otp) {
+ notifications.show({
+ title: "Null Field",
+ message: "Please enter the OTP",
+ color: "red",
+ });
+ return;
+ }
+ if (otp !== generateOtp) {
+ notifications.show({
+ title: "Invalid OTP",
+ message: "The OTP entered does not match",
+ color: "red",
+ });
return;
}
const token = localStorage.getItem("access_token");
@@ -116,6 +155,29 @@ export default function SetLoginPwd() {
router.push("/login");
}
}
+ useEffect(() => {
+ const loadCaptcha = async () => {
+ const newCaptcha = await generateCaptcha();
+ setCaptcha(newCaptcha);
+ };
+ loadCaptcha();
+ }, []);
+
+ useEffect(() => {
+ let interval: number | undefined;
+ if (timerActive && countdown > 0) {
+ interval = window.setInterval(() => {
+ setCountdown((prev) => prev - 1);
+ }, 1000);
+ }
+ if (countdown === 0) {
+ if (interval) clearInterval(interval);
+ setTimerActive(false);
+ }
+ return () => {
+ if (interval) clearInterval(interval);
+ };
+ }, [timerActive, countdown]);
useEffect(() => {
const token = localStorage.getItem("access_token");
@@ -136,16 +198,28 @@ export default function SetLoginPwd() {
position: 'fixed', width: '100%', height: '12%', top: 0, left: 0, zIndex: 100,
display: "flex",
justifyContent: "flex-start",
- background: "linear-gradient(15deg,rgba(2, 163, 85, 1) 55%, rgba(101, 101, 184, 1) 100%)"
+ background: "linear-gradient(15deg,rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)"
}}>
+
+ THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
+
} variant="subtle" onClick={handleLogout}>Logout
-
-
+
+
-
-
+ Set Login Password
-
-
- Note: Password will contains minimum one alphabet, one digit, one special symbol and total 8 charecters.
+ Note: Password must contain at least one capital letter(A-Z), one digit(0-9), one special symbol(e.g.,@,#,$), and be 8-15 characters long.
@@ -247,7 +342,7 @@ export default function SetLoginPwd() {
}}
>
- © 2025 Kangra Central Co-Operative Bank
+ © 2025 The Kangra Central Co-Operative Bank
diff --git a/src/app/SetTxn/CaptchaImage.tsx b/src/app/SetTxn/CaptchaImage.tsx
deleted file mode 100644
index 007ae4d..0000000
--- a/src/app/SetTxn/CaptchaImage.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React, { useEffect, useRef } from 'react';
-
-
-const CaptchaImage = ({ text }: { text: string }) => {
- const canvasRef = useRef(null);
-
- useEffect(() => {
- const canvas = canvasRef.current;
- const ctx = canvas?.getContext('2d');
- if (canvas && ctx) {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.font = '26px Arial';
- ctx.fillStyle = '#000';
- ctx.setTransform(1, 0.1, -0.1, 1, 0, 0);
- ctx.fillText(text, 10, 30);
- }
- }, [text]);
-
- return ;
-};
-
-export default CaptchaImage;
diff --git a/src/app/SetTxn/page.tsx b/src/app/SetTxn/page.tsx
index 5a8be52..139fb54 100644
--- a/src/app/SetTxn/page.tsx
+++ b/src/app/SetTxn/page.tsx
@@ -1,14 +1,14 @@
"use client";
import React, { useState, useEffect } from "react";
-import { Text, Button, TextInput, PasswordInput, Title, Card, Box, Image } from "@mantine/core";
+import { Text, Button, TextInput, PasswordInput, Title, Card, Box, Image, Group } 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/logo.jpg';
-import changePwdImage from '@/app/image/changepw.png';
-import CaptchaImage from './CaptchaImage';
-import { IconEye, IconEyeOff, IconLock, IconLogout } from '@tabler/icons-react';
+import logo from '@/app/image/logo1.jpg';
+import changePwdImage from '@/app/image/set_tran_pass.jpg';
+import { generateCaptcha } from '@/app/captcha';
+import { IconLock, IconLogout, IconRefresh } from '@tabler/icons-react';
export default function SetTransactionPwd() {
const router = useRouter();
@@ -16,32 +16,59 @@ export default function SetTransactionPwd() {
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [captcha, setCaptcha] = useState("");
- const [captchaInput, setCaptchaInput] = useState('');
- const [captchaError, setCaptchaError] = useState('');
- const [confirmVisible, setConfirmVisible] = useState(false);
- const toggleConfirmVisibility = () => setConfirmVisible((v) => !v);
+ const [captchaInput, setCaptchaInput] = useState("");
+ const [captchaValidate, setCaptchaValidate] = useState(false);
+ const [otp, setOtp] = useState("");
+ const [countdown, setCountdown] = useState(60);
+ const [timerActive, setTimerActive] = useState(false);
const icon = ;
+ const [generateOtp, setGenerateOtp] = useState("");
+
+ async function handleGenerateOtp() {
+ // const value = await generateOTP(6);
+ const value = "123456";
+ setGenerateOtp(value);
+ setCountdown(60);
+ setTimerActive(true);
+ }
async function handleLogout(e: React.FormEvent) {
e.preventDefault();
localStorage.removeItem("access_token");
router.push("/login")
}
+ const regenerateCaptcha = () => {
+ const loadCaptcha = async () => {
+ const newCaptcha = await generateCaptcha();
+ setCaptcha(newCaptcha);
+ };
+ loadCaptcha();
+ setCaptchaInput("");
+ };
useEffect(() => {
- generateCaptcha();
+ const loadCaptcha = async () => {
+ const newCaptcha = await generateCaptcha();
+ setCaptcha(newCaptcha);
+ };
+ loadCaptcha();
}, []);
- const generateCaptcha = () => {
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- let result = '';
- for (let i = 0; i < 6; i++) {
- result += chars.charAt(Math.floor(Math.random() * chars.length));
+ useEffect(() => {
+ let interval: number | undefined;
+ if (timerActive && countdown > 0) {
+ interval = window.setInterval(() => {
+ setCountdown((prev) => prev - 1);
+ }, 1000);
}
- setCaptcha(result);
- setCaptchaInput('');
- setCaptchaError('');
- };
+ if (countdown === 0) {
+ if (interval) clearInterval(interval);
+ setTimerActive(false);
+ }
+ return () => {
+ if (interval) clearInterval(interval);
+ };
+ }, [timerActive, countdown]);
async function handleSetTransactionPassword(e: React.FormEvent) {
e.preventDefault();
@@ -50,36 +77,72 @@ export default function SetTransactionPwd() {
notifications.show({
withBorder: true,
color: "red",
- title: "Both password fields are required.",
+ title: "Field Required",
message: "Both password fields are required.",
autoClose: 5000,
});
return;
- // alert("Both password fields are required.");
- } else if (password !== confirmPassword) {
- // alert("Passwords do not match.");
+ }
+ if (!captchaInput) {
notifications.show({
withBorder: true,
color: "red",
- title: "Passwords do not match.",
+ title: "Field Required",
+ message: "Please Enter Captcha details",
+ autoClose: 5000,
+ });
+ return;
+ }
+ if (password !== confirmPassword) {
+ notifications.show({
+ withBorder: true,
+ color: "red",
+ title: "Password Mismatch",
message: "Passwords do not match.",
autoClose: 5000,
});
return;
}
- else if (!pwdRegex.test(password)) {
- // alert("Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.");
+ if (!pwdRegex.test(password)) {
notifications.show({
withBorder: true,
color: "red",
- title: "Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.",
- message: "Password must contain at least 1 capital letter, 1 number, 1 special character, and be at least 8 characters long.",
+ title: "Invalid Password",
+ message: "Password must contain at least one capital letter, one number, one special character, and be 8-15 characters long.",
autoClose: 5000,
});
return;
}
- else if (captchaInput !== captcha) {
- setCaptchaError("Incorrect CAPTCHA.");
+ if (captchaInput !== captcha) {
+ notifications.show({
+ withBorder: true,
+ color: "red",
+ title: "Captcha Error",
+ message: "Please enter the correct captcha",
+ autoClose: 5000,
+ });
+ regenerateCaptcha();
+ return;
+ }
+ if (!captchaValidate) {
+ setCaptchaValidate(true);
+ handleGenerateOtp();
+ return;
+ }
+ if (!otp) {
+ notifications.show({
+ title: "Null Field",
+ message: "Please enter the OTP",
+ color: "red",
+ });
+ return;
+ }
+ if (otp !== generateOtp) {
+ notifications.show({
+ title: "Invalid OTP",
+ message: "The OTP entered does not match",
+ color: "red",
+ });
return;
}
const token = localStorage.getItem("access_token");
@@ -116,7 +179,6 @@ export default function SetTransactionPwd() {
router.push("/login");
}
}
-
useEffect(() => {
const token = localStorage.getItem("access_token");
if (!token) {
@@ -136,16 +198,28 @@ export default function SetTransactionPwd() {
position: 'fixed', width: '100%', height: '12%', top: 0, left: 0, zIndex: 100,
display: "flex",
justifyContent: "flex-start",
- background: "linear-gradient(15deg,rgba(2, 163, 85, 1) 55%, rgba(101, 101, 184, 1) 100%)"
+ background: "linear-gradient(15deg,rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)"
}}>
+
+ THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
+