Feat : Fetching daily limit is working

This commit is contained in:
2025-10-29 12:40:38 +05:30
parent 8bf603544f
commit ded4a2edc9
8 changed files with 195 additions and 52 deletions

View File

@@ -4,21 +4,6 @@ const isWindows = os.platform() === "win32";
// Security headers
const securityHeaders = [
{
key: "Content-Security-Policy",
value: `
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self' http://localhost:8080 https://yourdomain.com;
frame-ancestors 'none';
object-src 'none';
base-uri 'self';
form-action 'self';
`.replace(/\n/g, ""), // remove newlines
},
{
key: "Referrer-Policy",
value: "strict-origin-when-cross-origin",

View File

@@ -8,6 +8,7 @@ import { IconRefresh } from "@tabler/icons-react";
import Image from "next/image";
import img from '@/app/image/logo1.jpg'
import { sendOtp, verifyOtp } from "@/app/_util/otp";
import { getDailyLimit } from "@/app/_util/transactionLimit";
interface accountData {
stAccountNo: string;
@@ -38,6 +39,26 @@ export default function QuickPay() {
const [countdown, setCountdown] = useState(180);
const [timerActive, setTimerActive] = useState(false);
const [otp, setOtp] = useState("");
const [dailyLimit, setDailyLimit] = useState<number | null>(null);
const [usedLimit, setUsedLimit] = useState<number | null>(null);
const FetchDailyLimit = async () => {
try {
const token = localStorage.getItem("access_token");
if (!token) return;
const data = await getDailyLimit(token);
if (data) {
setDailyLimit(data.dailyLimit);
setUsedLimit(data.usedLimit);
} else {
setDailyLimit(null);
setUsedLimit(null);
}
} catch {
setDailyLimit(null);
setUsedLimit(null);
}
};
async function handleSendOtp() {
const mobileNumber = localStorage.getItem('remitter_mobile_no');
@@ -121,6 +142,7 @@ export default function QuickPay() {
useEffect(() => {
if (authorized) {
FetchAccountDetails();
FetchDailyLimit();
}
}, [authorized]);
@@ -286,6 +308,7 @@ export default function QuickPay() {
message: "Transaction successful",
color: "green",
});
await FetchDailyLimit();
return;
} else {
notifications.show({
@@ -544,12 +567,21 @@ export default function QuickPay() {
<Text size="xs" c="green">
Minimum Transfer Amount on this Day is Rs. 1.00
</Text>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. 500000.00
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs. 500000.00
</Text>
{dailyLimit !== null ? (
<>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. {dailyLimit.toFixed(2)}
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs.{" "}
{usedLimit?.toFixed(2)}
</Text>
</>
) : (
<Text size="xs" c="red">
No daily limit set for this user
</Text>
)}
</Stack>
</div>
</Paper>

View File

@@ -9,6 +9,7 @@ import Image from "next/image";
import img from '@/app/image/logo1.jpg';
import { IconRefresh } from "@tabler/icons-react";
import { sendOtp, verifyOtp } from '@/app/_util/otp';
import { getDailyLimit } from "@/app/_util/transactionLimit";
interface accountData {
@@ -39,6 +40,26 @@ export default function SendToBeneficiaryOwn() {
const [otp, setOtp] = useState("");
const [countdown, setCountdown] = useState(180);
const [timerActive, setTimerActive] = useState(false);
const [dailyLimit, setDailyLimit] = useState<number | null>(null);
const [usedLimit, setUsedLimit] = useState<number | null>(null);
const FetchDailyLimit = async () => {
try {
const token = localStorage.getItem("access_token");
if (!token) return;
const data = await getDailyLimit(token);
if (data) {
setDailyLimit(data.dailyLimit);
setUsedLimit(data.usedLimit);
} else {
setDailyLimit(null);
setUsedLimit(null);
}
} catch {
setDailyLimit(null);
setUsedLimit(null);
}
};
async function handleSendOtp() {
const mobileNumber = localStorage.getItem('remitter_mobile_no');
@@ -150,6 +171,7 @@ export default function SendToBeneficiaryOwn() {
if (authorized) {
FetchAccountDetails();
FetchBeneficiaryDetails();
FetchDailyLimit();
}
}, [authorized]);
@@ -289,6 +311,7 @@ export default function SendToBeneficiaryOwn() {
setShowOtpField(false);
setOtp("");
setBeneficiaryName('');
await FetchDailyLimit();
} else {
notifications.show({
title: "Error",
@@ -526,15 +549,21 @@ export default function SendToBeneficiaryOwn() {
<Text size="xs" c="green">
Minimum Transfer Amount on this Day is Rs. 1.00
</Text>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. 500000.00
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs. 500000.00
</Text>
<Text size="xs" c="red" fw={700}>
NOTE : Funds Transfer can be done only to previous added Beneficiary Accounts.
</Text>
{dailyLimit !== null ? (
<>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. {dailyLimit.toFixed(2)}
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs.{" "}
{usedLimit?.toFixed(2)}
</Text>
</>
) : (
<Text size="xs" c="red">
No daily limit set for this user
</Text>
)}
</Stack>
</Stack>
</div>

View File

@@ -8,6 +8,7 @@ import { IconAlertTriangle, IconRefresh } from "@tabler/icons-react";
import Image from "next/image";
import img from '@/app/image/logo1.jpg'
import { sendOtp, verifyOtp } from "@/app/_util/otp";
import { getDailyLimit } from "@/app/_util/transactionLimit";
interface accountData {
@@ -38,6 +39,26 @@ export default function SendToBeneficiaryOthers() {
const [otp, setOtp] = useState("");
const [countdown, setCountdown] = useState(180);
const [timerActive, setTimerActive] = useState(false);
const [dailyLimit, setDailyLimit] = useState<number | null>(null);
const [usedLimit, setUsedLimit] = useState<number | null>(null);
const FetchDailyLimit = async () => {
try {
const token = localStorage.getItem("access_token");
if (!token) return;
const data = await getDailyLimit(token);
if (data) {
setDailyLimit(data.dailyLimit);
setUsedLimit(data.usedLimit);
} else {
setDailyLimit(null);
setUsedLimit(null);
}
} catch {
setDailyLimit(null);
setUsedLimit(null);
}
};
async function handleSendOtp() {
const mobileNumber = localStorage.getItem('remitter_mobile_no');
@@ -207,6 +228,7 @@ export default function SendToBeneficiaryOthers() {
if (authorized) {
FetchAccountDetails();
FetchBeneficiaryDetails();
FetchDailyLimit();
}
}, [authorized]);
@@ -337,6 +359,7 @@ export default function SendToBeneficiaryOthers() {
setShowOtpField(false);
setOtp("");
setBeneficiaryName('');
await FetchDailyLimit();
}
else {
notifications.show({
@@ -436,7 +459,7 @@ export default function SendToBeneficiaryOthers() {
<Divider my="sm" variant="dashed" />
<Text size="xs" c="blue">
{/* <Text size="xs" c="blue">
• Minimum Transfer Amount on this Day is Rs. 1.00
</Text>
<Text size="xs" c="blue">
@@ -444,7 +467,27 @@ export default function SendToBeneficiaryOthers() {
</Text>
<Text size="xs" c="blue">
• Available Transfer Amount on this Day is Rs. 500000.00
</Text>
</Text> */}
<Stack gap={1} mt="xs">
<Text size="xs" c="green">
Minimum Transfer Amount on this Day is Rs. 1.00
</Text>
{dailyLimit !== null ? (
<>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. {dailyLimit.toFixed(2)}
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs.{" "}
{usedLimit?.toFixed(2)}
</Text>
</>
) : (
<Text size="xs" c="red">
No daily limit set for this user
</Text>
)}
</Stack>
<Group justify="flex-end" mt="md">
<Button color="blue" onClick={() => setShowIntroModal(false)}>
@@ -682,15 +725,26 @@ export default function SendToBeneficiaryOthers() {
</List>
</>
}
<Text size="xs" c="dimmed">
Minimum Transfer Limit per Day is Rs. 1.00
</Text>
<Text size="xs" c="dimmed">
Maximum Transfer Limit per Day is Rs. 500000.00
</Text>
<Text size="xs" c="dimmed">
Available Transfer Amount on this Day is Rs. 500000.00
</Text>
<Stack gap={1} mt="xs">
<Text size="xs" c="green">
Minimum Transfer Amount on this Day is Rs. 1.00
</Text>
{dailyLimit !== null ? (
<>
<Text size="xs" c="green">
Maximum Transfer Limit per Day is Rs. {dailyLimit.toFixed(2)}
</Text>
<Text size="xs" c="green">
Available Transfer Amount on this Day is Rs.{" "}
{usedLimit?.toFixed(2)}
</Text>
</>
) : (
<Text size="xs" c="red">
No daily limit set for this user
</Text>
)}
</Stack>
</Stack>
</Stack>
@@ -699,3 +753,5 @@ export default function SendToBeneficiaryOthers() {
</>
);
}

View File

@@ -14,8 +14,8 @@ interface SendOtpPayload {
}
function getStoredMobileNumber(): string {
const mobileNumber = localStorage.getItem('remitter_mobile_no');
// const mobileNumber = "7890544527";
// const mobileNumber = localStorage.getItem('remitter_mobile_no');
const mobileNumber = "7890544527";
if (!mobileNumber) throw new Error('Mobile number not found.');
return mobileNumber;
}

View File

@@ -0,0 +1,30 @@
export async function getDailyLimit(token: string) {
try {
const response = await fetch("/api/customer/daily-limit", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"X-Login-Type": "IB",
},
});
if (response.status === 400) {
const errorData = await response.json();
if (errorData?.error === "NO DAILY LIMIT SET FOR USER") {
return null;
} else {
throw new Error(errorData?.error || "Bad Request");
}
}
if (!response.ok) {
throw new Error(`Failed to fetch daily limit: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error("Error fetching daily limit:", error);
throw error;
}
}

View File

@@ -1,5 +1,6 @@
"use client";
import React, { useState, useEffect, memo, useRef } from "react";
import React, { useState, useEffect } from "react";
import { Text, Button, TextInput, PasswordInput, Title, Card, Group, Flex, Box, Image, Anchor, Tooltip, Modal, Stack } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { Providers } from "@/app/providers";
@@ -9,6 +10,7 @@ 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";
export default function Login() {
@@ -18,7 +20,15 @@ export default function Login() {
const [captcha, setCaptcha] = useState("");
const [inputCaptcha, setInputCaptcha] = useState("");
const [isLogging, setIsLogging] = useState(false);
const searchParams = useSearchParams();
const data = searchParams.get("data");
useEffect(() => {
if (data) {
console.log("URL parameter 'data':", data);
localStorage.setItem("Emendate_data",data);
}
}, [data]);
useEffect(() => {
const loadCaptcha = async () => {

View File

@@ -45,8 +45,8 @@ export default function Login() {
}
try {
await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile });
// await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "7890544527" });
// await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile });
await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "7890544527" });
notifications.show({
color: 'orange',
title: 'OTP Required',
@@ -67,8 +67,8 @@ export default function Login() {
async function handleVerifyOtp(mobile?: string) {
try {
if (mobile) {
await verifyLoginOtp(otp, mobile);
// await verifyLoginOtp(otp, '7890544527');
// await verifyLoginOtp(otp, mobile);
await verifyLoginOtp(otp, '7890544527');
return true;
}
}
@@ -296,10 +296,11 @@ export default function Login() {
message: "Internal Server Error, Please try again later",
autoClose: 5000,
});
} finally {
// Ensure we always stop loader if still active
setIsLogging(false);
}
}
// finally {
// // Ensure we always stop loader if still active
// setIsLogging(false);
// }
}