feat : user can login with user name..
fix: username should be one special character and one alphabet.
This commit is contained in:
@@ -20,7 +20,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
|||||||
{ label: "Change Login Password", href: "/settings/change_login_password" },
|
{ label: "Change Login Password", href: "/settings/change_login_password" },
|
||||||
{ label: "Change transaction Password", href: "/settings/change_txn_password" },
|
{ label: "Change transaction Password", href: "/settings/change_txn_password" },
|
||||||
{ label: "Set transaction Password", href: "/settings/set_txn_password" },
|
{ label: "Set transaction Password", href: "/settings/set_txn_password" },
|
||||||
{ label: "Preferred Name", href: "/settings/user_id" },
|
{ label: "Preferred Name", href: "/settings/user_name" },
|
||||||
];
|
];
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem("access_token");
|
const token = localStorage.getItem("access_token");
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ export default function SetPreferredNameSimple() {
|
|||||||
|
|
||||||
const icon = <IconUser size={18} stroke={1.5} />;
|
const icon = <IconUser size={18} stroke={1.5} />;
|
||||||
|
|
||||||
// 🟢 Fetch name + generate captcha on mount
|
// Fetch name + generate captcha on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkPreferredName();
|
checkPreferredName();
|
||||||
regenerateCaptcha();
|
regenerateCaptcha();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 🟢 OTP timer
|
// OTP timer
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let interval: number | undefined;
|
let interval: number | undefined;
|
||||||
if (timerActive && countdown > 0) {
|
if (timerActive && countdown > 0) {
|
||||||
@@ -55,7 +55,7 @@ export default function SetPreferredNameSimple() {
|
|||||||
};
|
};
|
||||||
}, [timerActive, countdown]);
|
}, [timerActive, countdown]);
|
||||||
|
|
||||||
// 🟢 API: Fetch preferred name
|
// API: Fetch preferred name
|
||||||
async function checkPreferredName() {
|
async function checkPreferredName() {
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem("access_token");
|
const token = localStorage.getItem("access_token");
|
||||||
@@ -77,20 +77,23 @@ export default function SetPreferredNameSimple() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 Captcha
|
// Captcha
|
||||||
const regenerateCaptcha = async () => {
|
const regenerateCaptcha = async () => {
|
||||||
const newCaptcha = await generateCaptcha();
|
const newCaptcha = await generateCaptcha();
|
||||||
setCaptcha(newCaptcha);
|
setCaptcha(newCaptcha);
|
||||||
setCaptchaInput("");
|
setCaptchaInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 🟢 Live Validation (kept from your previous version)
|
|
||||||
function onPreferredNameChange(value: string) {
|
function onPreferredNameChange(value: string) {
|
||||||
const sanitized = value.replace(/[^A-Za-z0-9@_]/g, "").slice(0, 11);
|
const sanitized = value.replace(/[^A-Za-z0-9@_]/g, "").slice(0, 11);
|
||||||
setPreferredName(sanitized);
|
setPreferredName(sanitized);
|
||||||
|
|
||||||
if (sanitized.length > 0 && (sanitized.length < 5 || sanitized.length > 11)) {
|
if (sanitized.length > 0 && (sanitized.length < 5 || sanitized.length > 11)) {
|
||||||
setPreferredNameError("Preferred Name must be 5–11 characters.");
|
setPreferredNameError("Preferred Name must be 5–11 characters.");
|
||||||
|
} else if (!/[A-Za-z]/.test(sanitized)) {
|
||||||
|
setPreferredNameError("Preferred Name must contain at least one letter.");
|
||||||
|
} else if (!/[@_]/.test(sanitized)) {
|
||||||
|
setPreferredNameError("Preferred Name must contain at least one special character (@ or _).");
|
||||||
} else {
|
} else {
|
||||||
setPreferredNameError(null);
|
setPreferredNameError(null);
|
||||||
}
|
}
|
||||||
@@ -107,7 +110,7 @@ export default function SetPreferredNameSimple() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 OTP
|
// OTP
|
||||||
async function handleSendOtp() {
|
async function handleSendOtp() {
|
||||||
try {
|
try {
|
||||||
await sendOtp({ type: "USERNAME_UPDATED" });
|
await sendOtp({ type: "USERNAME_UPDATED" });
|
||||||
@@ -147,7 +150,7 @@ export default function SetPreferredNameSimple() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 Update Preferred Name API
|
// Update Preferred Name API
|
||||||
async function handleUpdatePreferredName() {
|
async function handleUpdatePreferredName() {
|
||||||
const token = localStorage.getItem("access_token");
|
const token = localStorage.getItem("access_token");
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@@ -199,7 +202,7 @@ export default function SetPreferredNameSimple() {
|
|||||||
regenerateCaptcha();
|
regenerateCaptcha();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 🟢 Main Submit
|
// Main Submit
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (step === "form") {
|
if (step === "form") {
|
||||||
if (!preferredName || !confirmName || !captchaInput) {
|
if (!preferredName || !confirmName || !captchaInput) {
|
||||||
@@ -210,6 +213,14 @@ export default function SetPreferredNameSimple() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(preferredName !== confirmName){
|
||||||
|
notifications.show({
|
||||||
|
title: "Mismatch Input",
|
||||||
|
message: "Preferred name and Confirm preferred name not same.",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (preferredNameError || confirmNameError) {
|
if (preferredNameError || confirmNameError) {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
@@ -286,7 +297,11 @@ export default function SetPreferredNameSimple() {
|
|||||||
mb="xs"
|
mb="xs"
|
||||||
rightSection={icon}
|
rightSection={icon}
|
||||||
readOnly={step !== "form"}
|
readOnly={step !== "form"}
|
||||||
|
onCopy={(e) => e.preventDefault()}
|
||||||
|
onPaste={(e) => e.preventDefault()}
|
||||||
|
onCut={(e) => e.preventDefault()}
|
||||||
error={confirmNameError || undefined}
|
error={confirmNameError || undefined}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
@@ -396,6 +411,10 @@ export default function SetPreferredNameSimple() {
|
|||||||
<List.Item>
|
<List.Item>
|
||||||
You can change your username a maximum of 5 times.
|
You can change your username a maximum of 5 times.
|
||||||
</List.Item>
|
</List.Item>
|
||||||
|
<List.Item>
|
||||||
|
Preferred Name must contain at least one alphabet and one special character (@ or _).
|
||||||
|
</List.Item>
|
||||||
|
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
</Paper>
|
</Paper>
|
||||||
@@ -14,8 +14,8 @@ interface SendOtpPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getStoredMobileNumber(): string {
|
function getStoredMobileNumber(): string {
|
||||||
// const mobileNumber = localStorage.getItem('remitter_mobile_no');
|
const mobileNumber = localStorage.getItem('remitter_mobile_no');
|
||||||
const mobileNumber = "6297421727";
|
// const mobileNumber = "7890544527";
|
||||||
if (!mobileNumber) throw new Error('Mobile number not found.');
|
if (!mobileNumber) throw new Error('Mobile number not found.');
|
||||||
return mobileNumber;
|
return mobileNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile });
|
await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile });
|
||||||
await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "6297421727" });
|
// await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "7890544527" });
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'orange',
|
color: 'orange',
|
||||||
title: 'OTP Required',
|
title: 'OTP Required',
|
||||||
@@ -67,8 +67,8 @@ export default function Login() {
|
|||||||
async function handleVerifyOtp(mobile?: string) {
|
async function handleVerifyOtp(mobile?: string) {
|
||||||
try {
|
try {
|
||||||
if (mobile) {
|
if (mobile) {
|
||||||
// await verifyLoginOtp(otp, mobile);
|
await verifyLoginOtp(otp, mobile);
|
||||||
await verifyLoginOtp(otp, '6297421727');
|
// await verifyLoginOtp(otp, '7890544527');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,14 +124,15 @@ export default function Login() {
|
|||||||
try {
|
try {
|
||||||
// --- Validation (before any API call) ---
|
// --- Validation (before any API call) ---
|
||||||
if (!otpRequired && !otpVerified) {
|
if (!otpRequired && !otpVerified) {
|
||||||
const onlyDigit = /^\d{11}$/;
|
// const onlyDigit = /^\d{11}$/;
|
||||||
|
const onlyDigit = /^[A-Za-z0-9@_]{5,11}$/;
|
||||||
|
|
||||||
if (!onlyDigit.test(CIF)) {
|
if (!onlyDigit.test(CIF)) {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
withBorder: true,
|
withBorder: true,
|
||||||
color: "red",
|
color: "red",
|
||||||
title: "Invalid UserId",
|
title: "Invalid UserId",
|
||||||
message: "UserID must be 11 digit",
|
message: "The User ID or Username must contain 5 to 11 alphanumeric characters.",
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
setIsLogging(false);
|
setIsLogging(false);
|
||||||
@@ -178,6 +179,7 @@ export default function Login() {
|
|||||||
|
|
||||||
// --- LOGIN API FLOW ---
|
// --- LOGIN API FLOW ---
|
||||||
if (!otpRequired || otpVerified) {
|
if (!otpRequired || otpVerified) {
|
||||||
|
const isNumeric = /^\d+$/.test(CIF);
|
||||||
const response = await fetch("api/auth/login", {
|
const response = await fetch("api/auth/login", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
@@ -185,7 +187,8 @@ export default function Login() {
|
|||||||
"X-Login-Type": "IB",
|
"X-Login-Type": "IB",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
customerNo: CIF,
|
customerNo: isNumeric ? CIF : null,
|
||||||
|
userName: isNumeric ? null : CIF,
|
||||||
password: psw,
|
password: psw,
|
||||||
otp: otp,
|
otp: otp,
|
||||||
}),
|
}),
|
||||||
@@ -522,14 +525,15 @@ export default function Login() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Box w={{ base: "100%", md: "45%" }} p="lg">
|
<Box w={{ base: "100%", md: "45%" }} p="lg">
|
||||||
<Card shadow="md" padding="xl" radius="md" style={{ maxWidth: 550, height: '70vh' }}>
|
<Card shadow="md" padding="xl" radius="md" style={{ maxWidth: 550, height: '70vh', justifyContent: 'space-between' }} >
|
||||||
<form onSubmit={handleLogin}>
|
<form onSubmit={handleLogin}>
|
||||||
<TextInput
|
<TextInput
|
||||||
label="User ID"
|
label="User ID / User Name"
|
||||||
placeholder="Enter your CIF No"
|
placeholder="Enter your CIF No / User Name"
|
||||||
value={CIF}
|
value={CIF}
|
||||||
onInput={(e) => {
|
onInput={(e) => {
|
||||||
const input = e.currentTarget.value.replace(/\D/g, "");
|
// const input = e.currentTarget.value.replace(/\D/g, "");
|
||||||
|
const input = e.currentTarget.value.replace(/[^A-Za-z0-9@_]/g, "");
|
||||||
if (input.length <= 11) SetCIF(input);
|
if (input.length <= 11) SetCIF(input);
|
||||||
}}
|
}}
|
||||||
withAsterisk
|
withAsterisk
|
||||||
@@ -609,10 +613,17 @@ export default function Login() {
|
|||||||
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button type="submit" fullWidth mt="md" loading={isLogging} disabled={isLogging}>
|
<Button type="submit" fullWidth mt="sm" loading={isLogging} disabled={isLogging}>
|
||||||
{isLogging ? "Processing..." : buttonLabel}
|
{isLogging ? "Processing..." : buttonLabel}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Box mt="xs">
|
||||||
|
<Text size="sm">
|
||||||
|
<Text component="span" c="red" fw={600}>Note: </Text>
|
||||||
|
<Text component="span" c="black">
|
||||||
|
Existing users logging in to the new Internet Banking for the first time should use their CIF number to avoid login issues.
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
</form>
|
</form>
|
||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user