feat: make e-mandate screen responsive.
This commit is contained in:
@@ -266,6 +266,8 @@ export default function QuickPay() {
|
||||
setOtp("");
|
||||
setValidationStatus(null);
|
||||
setBeneficiaryName(null);
|
||||
setTimerActive(false);
|
||||
setCountdown(180);
|
||||
} else {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
@@ -293,6 +295,8 @@ export default function QuickPay() {
|
||||
setShowTxnPassword(false);
|
||||
setShowOtpField(false);
|
||||
setIsSubmitting(false);
|
||||
setTimerActive(false);
|
||||
setCountdown(180);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect, memo, useRef } from "react";
|
||||
import { Text, Button, TextInput, PasswordInput, Title, Card, Group, Flex, Box, Image, Anchor, Tooltip, Modal } from "@mantine/core";
|
||||
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";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -88,7 +88,7 @@ export default function Login() {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Login-Type': 'emandate',
|
||||
'X-Login-Type': 'emandate',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
customerNo: CIF,
|
||||
@@ -112,7 +112,7 @@ export default function Login() {
|
||||
}
|
||||
setIsLogging(true);
|
||||
if (response.ok) {
|
||||
console.log(data);
|
||||
// console.log(data);
|
||||
const token = data.token;
|
||||
localStorage.setItem("mandate_token", token);
|
||||
// localStorage.setItem("pswExpiryDate", data.loginPswExpiry);
|
||||
@@ -160,50 +160,192 @@ export default function Login() {
|
||||
<div style={{ backgroundColor: "#f8f9fa", width: "100%", height: "auto", paddingTop: "5%" }}>
|
||||
{/* Header */}
|
||||
<Box
|
||||
component="header"
|
||||
style={{
|
||||
position: 'fixed', width: '100%', height: '12%', top: 0, left: 0, zIndex: 100,
|
||||
position: "fixed",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
zIndex: 100,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
background: "linear-gradient(15deg,rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
|
||||
}}>
|
||||
padding: "0.5rem 1rem",
|
||||
background:
|
||||
"linear-gradient(15deg, rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
|
||||
}}
|
||||
>
|
||||
{/* Logo */}
|
||||
<Image
|
||||
src={logo}
|
||||
component={NextImage}
|
||||
fit="contain"
|
||||
alt="ebanking"
|
||||
style={{ width: "100%", height: "auto", flexShrink: 0 }}
|
||||
style={{
|
||||
width: "60px", // fixed height for logo
|
||||
height: "auto",
|
||||
marginRight: "0.75rem",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
<Title
|
||||
order={2}
|
||||
|
||||
{/* Bank name + address stacked */}
|
||||
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||
<Title
|
||||
order={4}
|
||||
style={{
|
||||
fontFamily: "Roboto",
|
||||
color: "white",
|
||||
fontSize: "clamp(14px, 2vw, 20px)", // auto resizes
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
>
|
||||
THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
|
||||
</Title>
|
||||
<Text
|
||||
size="xs"
|
||||
style={{
|
||||
// backgroundColor: "#1f1f14",
|
||||
fontFamily: "Roboto",
|
||||
padding: "2px 6px",
|
||||
borderRadius: "4px",
|
||||
color: "white",
|
||||
textShadow: "1px 1px 2px blue",
|
||||
fontSize: "clamp(10px, 1.5vw, 13px)", // responsive text
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
>
|
||||
Head Office: Dharmshala, District Kangra (H.P), Pin: 176215
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
component="header"
|
||||
style={{
|
||||
position: "fixed",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
zIndex: 100,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
padding: "0.5rem 1rem",
|
||||
background:
|
||||
"linear-gradient(15deg, rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
|
||||
}}
|
||||
>
|
||||
{/* Logo */}
|
||||
<Image
|
||||
src={logo}
|
||||
component={NextImage}
|
||||
fit="contain"
|
||||
alt="ebanking"
|
||||
style={{
|
||||
fontFamily: 'Roboto',
|
||||
position: 'absolute',
|
||||
top: '30%',
|
||||
left: '7%',
|
||||
color: 'White',
|
||||
transition: "opacity 0.5s ease-in-out",
|
||||
width: "60px",
|
||||
height: "auto",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Desktop: Title + Address */}
|
||||
<Box
|
||||
className="desktop-header"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
marginLeft: "1rem",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
|
||||
</Title>
|
||||
<Text size="sm" c="white"
|
||||
<Title
|
||||
order={4}
|
||||
style={{
|
||||
fontFamily: "Roboto",
|
||||
color: "white",
|
||||
fontSize: "clamp(14px, 2vw, 20px)",
|
||||
}}
|
||||
>
|
||||
THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
|
||||
</Title>
|
||||
<Text
|
||||
size="xs"
|
||||
style={{
|
||||
// backgroundColor: "#1f1f14",
|
||||
fontFamily: "Roboto",
|
||||
padding: "2px 6px",
|
||||
borderRadius: "4px",
|
||||
color: "white",
|
||||
textShadow: "1px 1px 2px blue",
|
||||
fontSize: "clamp(10px, 1.5vw, 13px)",
|
||||
}}
|
||||
>
|
||||
Head Office: Dharmshala, District Kangra (H.P), Pin: 176215
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
{/* Mobile: only Logo + Bank Name */}
|
||||
<Box
|
||||
className="mobile-header"
|
||||
style={{
|
||||
backgroundColor: '#1f1f14',
|
||||
fontFamily: 'Roboto',
|
||||
position: 'absolute',
|
||||
top: '59%',
|
||||
left: '72%',
|
||||
color: 'white',
|
||||
textShadow: '1px 1px 2px blue',
|
||||
display: "none",
|
||||
flexDirection: "column",
|
||||
alignItems: "flex-start",
|
||||
marginLeft: "0.75rem",
|
||||
}}
|
||||
>
|
||||
Head Office : Dharmshala, District: Kangra(H.P), Pin: 176215
|
||||
</Text>
|
||||
<Title
|
||||
order={5}
|
||||
style={{
|
||||
fontFamily: "Roboto",
|
||||
color: "white",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
THE KANGRA CENTRAL
|
||||
</Title>
|
||||
<Title
|
||||
order={5}
|
||||
style={{
|
||||
fontFamily: "Roboto",
|
||||
color: "white",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
CO-OPERATIVE BANK LTD.
|
||||
</Title>
|
||||
</Box>
|
||||
|
||||
<style jsx>{`
|
||||
@media (max-width: 768px) {
|
||||
.desktop-header {
|
||||
display: none;
|
||||
}
|
||||
.mobile-header {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.desktop-header {
|
||||
display: flex;
|
||||
}
|
||||
.mobile-header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</Box>
|
||||
|
||||
<div style={{ marginTop: '10px' }}>
|
||||
{/* Movable text */}
|
||||
<Box
|
||||
className="desktop-scroll-text"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "0.5%",
|
||||
@@ -232,19 +374,23 @@ export default function Login() {
|
||||
</Text>
|
||||
<style>
|
||||
{`
|
||||
@keyframes scroll-left {
|
||||
0% { transform: translateX(0%); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
`}
|
||||
@keyframes scroll-left {
|
||||
0% { transform: translateX(0%); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.desktop-scroll-text { display: none; }
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</Box>
|
||||
|
||||
{/* Main */}
|
||||
<div style={{
|
||||
display: "flex", height: "75vh", overflow: "hidden", position: "relative",
|
||||
// background: 'linear-gradient(to right, #02081eff, #0a3d91)'
|
||||
background: 'linear-gradient(179deg, #3faa56ff 49%, #3aa760ff 80%)'
|
||||
}}>
|
||||
<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"
|
||||
@@ -302,7 +448,81 @@ export default function Login() {
|
||||
</form>
|
||||
</Card>
|
||||
</Box>
|
||||
</div>
|
||||
</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: "cursive",
|
||||
}}
|
||||
>
|
||||
{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"
|
||||
|
||||
@@ -183,7 +183,7 @@ export default function MandatePage() {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mobileNumber: '7890544527',
|
||||
mobileNumber: localStorage.getItem("userMobNo"),
|
||||
type: 'EMandate'
|
||||
}),
|
||||
});
|
||||
@@ -213,20 +213,52 @@ export default function MandatePage() {
|
||||
}
|
||||
};
|
||||
|
||||
// Resend OTP
|
||||
const handleResendOtp = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/otp/send", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
mobileNumber: localStorage.getItem("userMobNo"),
|
||||
type: "EMandate",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error("Failed to resend OTP");
|
||||
|
||||
notifications.show({
|
||||
withBorder: true,
|
||||
color: "blue",
|
||||
title: "OTP Resent",
|
||||
message: "A new OTP has been sent to your registered mobile number.",
|
||||
autoClose: 4000,
|
||||
});
|
||||
} catch {
|
||||
notifications.show({
|
||||
withBorder: true,
|
||||
color: "red",
|
||||
title: "Error",
|
||||
message: "Failed to resend OTP. Please try again.",
|
||||
autoClose: 5000,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// STEP 2: Verify OTP and complete action
|
||||
const handleOtpSubmit = async () => {
|
||||
// if (!otp) {
|
||||
// notifications.show({
|
||||
// withBorder: true,
|
||||
// color: "red",
|
||||
// title: "Invalid Input",
|
||||
// message: "Please enter OTP before proceed",
|
||||
// autoClose: 5000,
|
||||
// });
|
||||
// }
|
||||
if (!otp) {
|
||||
notifications.show({
|
||||
withBorder: true,
|
||||
color: "red",
|
||||
title: "Invalid Input",
|
||||
message: "Please enter OTP before proceed",
|
||||
autoClose: 5000,
|
||||
});
|
||||
}
|
||||
if (!pendingAction) return;
|
||||
try {
|
||||
const response = await fetch(`/api/otp/verify?mobileNumber=${7890544527}`, {
|
||||
const response = await fetch(`/api/otp/verify?mobileNumber=${localStorage.getItem("userMobNo")}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -400,8 +432,8 @@ export default function MandatePage() {
|
||||
</Box>
|
||||
|
||||
{/* OTP MODAL */}
|
||||
<Modal opened={otpModalOpen} onClose={() => setOtpModalOpen(false)} title="Enter OTP" centered>
|
||||
<Text mb="sm">An OTP has been sent to your registered mobile number.</Text>
|
||||
<Modal opened={otpModalOpen} onClose={() => setOtpModalOpen(false)} title="OTP Verification" centered>
|
||||
<Text mb="sm" size="sm" ta="center" c="green">An OTP has been sent to your registered mobile number.</Text>
|
||||
<TextInput
|
||||
label="OTP"
|
||||
placeholder="Enter OTP"
|
||||
@@ -413,7 +445,19 @@ export default function MandatePage() {
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text size="xs">if you did not received the OTP in SMS,you can click click here to resend the SMS</Text>
|
||||
<Text mt="md" size="xs" c="dimmed">
|
||||
If you did not receive the OTP in SMS, you can{" "}
|
||||
<Text
|
||||
span
|
||||
c="blue"
|
||||
td="underline"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={handleResendOtp}
|
||||
>
|
||||
click here to resend the SMS
|
||||
</Text>
|
||||
.
|
||||
</Text>
|
||||
<Group mt="md" grow>
|
||||
<Button color="gray" onClick={() => setOtpModalOpen(false)}>
|
||||
Cancel
|
||||
|
||||
Reference in New Issue
Block a user