feat : update rights from admin user.
This commit is contained in:
@@ -62,7 +62,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|||||||
if (response.ok && Array.isArray(data)) {
|
if (response.ok && Array.isArray(data)) {
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
const name = data[0].custname;
|
const name = data[0].custname;
|
||||||
|
const mobileNumber = data[0].mobileno;
|
||||||
localStorage.setItem("remitter_name", name);
|
localStorage.setItem("remitter_name", name);
|
||||||
|
localStorage.setItem("remitter_mobile_no", mobileNumber);
|
||||||
setCustname(name);
|
setCustname(name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -249,7 +251,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|||||||
<Popover
|
<Popover
|
||||||
opened={opened}
|
opened={opened}
|
||||||
onChange={close}
|
onChange={close}
|
||||||
position="bottom-end" // 👈 Logout button ke niche right align
|
position="bottom-end"
|
||||||
withArrow
|
withArrow
|
||||||
shadow="md"
|
shadow="md"
|
||||||
>
|
>
|
||||||
@@ -277,11 +279,6 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|||||||
</Group>
|
</Group>
|
||||||
</Popover.Dropdown>
|
</Popover.Dropdown>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Group>
|
</Group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +1,91 @@
|
|||||||
import React, { useState } from 'react';
|
"use client";
|
||||||
import { TextInput, Button, Title, Stack, Group, Text, Divider, LoadingOverlay, Box, Modal, Checkbox } from '@mantine/core';
|
import React, { useState } from "react";
|
||||||
import { notifications } from '@mantine/notifications';
|
import {
|
||||||
|
TextInput,
|
||||||
|
Button,
|
||||||
|
Title,
|
||||||
|
Stack,
|
||||||
|
Group,
|
||||||
|
Text,
|
||||||
|
Divider,
|
||||||
|
LoadingOverlay,
|
||||||
|
Box,
|
||||||
|
Modal,
|
||||||
|
Checkbox,
|
||||||
|
Paper,
|
||||||
|
Tabs,
|
||||||
|
ScrollArea,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { notifications } from "@mantine/notifications";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { IconGavel, IconUser } from "@tabler/icons-react";
|
||||||
|
|
||||||
export default function UserConfiguration() {
|
export default function UserConfiguration() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [CIF, setCIF] = useState('');
|
const [CIF, setCIF] = useState("");
|
||||||
const [userDetails, setUserDetails] = useState<any>(null);
|
const [userDetails, setUserDetails] = useState<any>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [savingsAccount, setSavingsAccount] = useState<string | null>(null);
|
const [savingsAccount, setSavingsAccount] = useState<string | null>(null);
|
||||||
const [accountError, setAccountError] = useState<string>('');
|
|
||||||
const [detailsExpanded, setDetailsExpanded] = useState(true);
|
|
||||||
const [showPreviewModal, setShowPreviewModal] = useState(false);
|
const [showPreviewModal, setShowPreviewModal] = useState(false);
|
||||||
const [confirmedPreview, setConfirmedPreview] = useState(false);
|
const [confirmedPreview, setConfirmedPreview] = useState(false);
|
||||||
const [ibEnabled, setIbEnabled] = useState(false);
|
const [ibEnabled, setIbEnabled] = useState(false);
|
||||||
const [ibAccess, setIbAccess] = useState<"2" | "1" | null>(null);
|
const [ibAccess, setIbAccess] = useState<"2" | "1" | null>(null);
|
||||||
const [mbEnabled, setMbEnabled] = useState(false);
|
const [mbEnabled, setMbEnabled] = useState(false);
|
||||||
const [mbAccess, setMbAccess] = useState<"2" | "1" | null>(null);
|
const [mbAccess, setMbAccess] = useState<"2" | "1" | null>(null);
|
||||||
|
|
||||||
const isValidated = !!userDetails;
|
const isValidated = !!userDetails;
|
||||||
const canSubmit = isValidated && !!savingsAccount && confirmedPreview;
|
const canSubmit =
|
||||||
|
isValidated && savingsAccount && userDetails?.mobile && confirmedPreview;
|
||||||
|
|
||||||
const handleValidate = async () => {
|
const handleValidate = async () => {
|
||||||
if (!CIF) {
|
if (!CIF) {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: "red",
|
||||||
title: 'CIF Missing',
|
title: "CIF Missing",
|
||||||
message: 'Please enter a CIF number to proceed.'
|
message: "Please enter a CIF number to proceed.",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setAccountError('');
|
|
||||||
setSavingsAccount(null);
|
|
||||||
setUserDetails(null);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem("admin_access_token");
|
const token = localStorage.getItem("admin_access_token");
|
||||||
const response = await fetch(`/api/auth/admin/fetch/customer_details?CIF=${CIF}`, {
|
const response = await fetch(
|
||||||
method: 'GET',
|
`/api/auth/admin/fetch/customer_details?CIF=${CIF}`,
|
||||||
headers: {
|
{
|
||||||
'Content-Type': 'application/json',
|
method: "GET",
|
||||||
'Authorization': `Bearer ${token}`
|
headers: {
|
||||||
},
|
"Content-Type": "application/json",
|
||||||
});
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (response.ok && Array.isArray(data) && data.length > 0) {
|
if (response.ok && Array.isArray(data) && data.length > 0) {
|
||||||
const saAccount = data.find(acc => acc.stAccountType === 'SA');
|
const saAccount = data.find((acc) => acc.stAccountType === "SA");
|
||||||
// console.log(saAccount);
|
setSavingsAccount(saAccount?.stAccountNo ?? null);
|
||||||
if (saAccount) {
|
|
||||||
setSavingsAccount(saAccount.stAccountNo);
|
|
||||||
} else {
|
|
||||||
setAccountError('At least one savings account is required for requesting.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = data[0];
|
const user = data[0];
|
||||||
setUserDetails({
|
setUserDetails({
|
||||||
name: user.custname,
|
name: user.custname,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
mobile: user.mobileno,
|
mobile: user.mobileno ?? null,
|
||||||
address: user.custaddress,
|
address: user.custaddress,
|
||||||
activeAccount: user.activeAccounts,
|
activeAccount: user.activeAccounts,
|
||||||
});
|
});
|
||||||
if (!user.mobileno) {
|
|
||||||
localStorage.setItem("user_mob_no", user.mobileno);
|
|
||||||
setAccountError('User not have any registered Mobile Number');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('User not found or data format incorrect');
|
notifications.show({
|
||||||
|
color: "red",
|
||||||
|
title: "Validation Failed",
|
||||||
|
message: "User not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: "red",
|
||||||
title: 'Validation Failed',
|
title: "Validation Failed",
|
||||||
message: 'User not found',
|
message: "User not found",
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -81,22 +93,14 @@ export default function UserConfiguration() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePreview = () => {
|
const handlePreview = () => {
|
||||||
const hasRight = ibAccess || mbAccess;
|
if (!savingsAccount || !userDetails?.mobile) {
|
||||||
const hasSavings = savingsAccount;
|
|
||||||
|
|
||||||
if (!hasRight) {
|
|
||||||
notifications.show({
|
|
||||||
title: "Rights Required",
|
|
||||||
message: "Please select at least one rights (Internet Banking or Mobile Banking).",
|
|
||||||
color: "red",
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!ibAccess && !mbAccess) {
|
||||||
if (!hasSavings) {
|
|
||||||
notifications.show({
|
notifications.show({
|
||||||
title: "Savings Account Required",
|
title: "Rights Required",
|
||||||
message: "User must have at least one Savings account.",
|
message:
|
||||||
|
"Please select at least one right (Internet Banking or Mobile Banking).",
|
||||||
color: "red",
|
color: "red",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -105,302 +109,310 @@ export default function UserConfiguration() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!canSubmit) {
|
if (!canSubmit) return;
|
||||||
notifications.show({
|
|
||||||
color: 'red',
|
|
||||||
title: 'Required',
|
|
||||||
message: 'One savings account is required for enable rights',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
const token = localStorage.getItem("admin_access_token");
|
|
||||||
const response = await fetch('/api/auth/admin/user/rights', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${token}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
CIF: CIF,
|
|
||||||
ib_access_level: ibAccess,
|
|
||||||
mb_access_level: mbAccess
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
if (response.ok) {
|
|
||||||
if (data?.otp) {
|
|
||||||
const otp = data.otp;
|
|
||||||
try {
|
|
||||||
const otp_response = await fetch('/api/otp/send', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
mobileNumber: localStorage.getItem("user_mob_no"),
|
|
||||||
type: "REGISTRATION",
|
|
||||||
userOtp: otp
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
// const otp_result = await otp_response.json();
|
|
||||||
if (otp_response.ok) {
|
|
||||||
notifications.show({
|
|
||||||
color: 'blue',
|
|
||||||
title: 'Submitted',
|
|
||||||
message: `User ${CIF} rights submitted successfully. The password has been sent to the user as an OTP.`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err: any) {
|
|
||||||
notifications.show({
|
|
||||||
color: 'red',
|
|
||||||
title: 'Failed to Send',
|
|
||||||
message: `Rights for User ${CIF} saved successfully. Message delivery failed.`,
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(data?.message){
|
|
||||||
try {
|
|
||||||
const otp_response = await fetch('/api/otp/send', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
mobileNumber: localStorage.getItem("user_mob_no"),
|
|
||||||
type: "RIGHT_UPDATE",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
if (otp_response.ok) {
|
|
||||||
notifications.show({
|
|
||||||
color: 'blue',
|
|
||||||
title: 'Submitted',
|
|
||||||
message: `User ${CIF} rights updated successfully. The confirmation has been sent to the user.`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err: any) {
|
|
||||||
notifications.show({
|
|
||||||
color: 'red',
|
|
||||||
title: 'Failed to Send',
|
|
||||||
message: `Rights for User ${CIF} saved successfully. Message delivery failed.`,
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (response.status === 401 || data.message === 'invalid or expired token') {
|
|
||||||
localStorage.removeItem("admin_access_token");
|
|
||||||
localStorage.clear();
|
|
||||||
sessionStorage.clear();
|
|
||||||
router.push('/administrator/login');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err: any) {
|
|
||||||
notifications.show({
|
|
||||||
color: 'red',
|
|
||||||
title: 'Failed -Right',
|
|
||||||
message: `Can not Processed user -${CIF} rights.`,
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = localStorage.getItem("admin_access_token");
|
||||||
|
const response = await fetch("/api/auth/admin/user/rights", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
CIF,
|
||||||
|
ib_access_level: ibAccess,
|
||||||
|
mb_access_level: mbAccess,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (response.ok) {
|
||||||
|
if (data?.otp) {
|
||||||
|
// Registration case
|
||||||
|
await fetch('/api/otp/send', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
mobileNumber: userDetails.mobile,
|
||||||
|
type: 'REGISTRATION',
|
||||||
|
userOtp: data.otp,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
notifications.show({
|
||||||
|
color: 'blue',
|
||||||
|
title: 'Submitted',
|
||||||
|
message: `User ${CIF} rights submitted successfully. OTP sent to the user.`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (data?.message) {
|
||||||
|
// Rights update case
|
||||||
|
await fetch('/api/otp/send', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
mobileNumber: userDetails.mobile,
|
||||||
|
type: 'RIGHT_UPDATE',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
notifications.show({
|
||||||
|
color: 'blue',
|
||||||
|
title: 'Submitted',
|
||||||
|
message: `User ${CIF} rights updated successfully. Confirmation sent to the user.`,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally {
|
else if (response.status === 401 || data.message === "invalid or expired token") {
|
||||||
setSavingsAccount(null);
|
localStorage.clear();
|
||||||
setUserDetails(null);
|
sessionStorage.clear();
|
||||||
setCIF('');
|
router.push("/administrator/login");
|
||||||
setConfirmedPreview(false);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
notifications.show({
|
||||||
|
color: "red",
|
||||||
|
title: "Failed - Right",
|
||||||
|
message: `Cannot process user ${CIF} rights.`,
|
||||||
|
autoClose: false,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
handleReset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setSavingsAccount(null);
|
||||||
|
setUserDetails(null);
|
||||||
|
setCIF("");
|
||||||
|
setConfirmedPreview(false);
|
||||||
|
setIbEnabled(false);
|
||||||
|
setIbAccess(null);
|
||||||
|
setMbEnabled(false);
|
||||||
|
setMbAccess(null);
|
||||||
|
};
|
||||||
|
|
||||||
const handleMainAction = () => {
|
const handleMainAction = () => {
|
||||||
if (!isValidated) {
|
if (!isValidated) {
|
||||||
handleValidate();
|
handleValidate();
|
||||||
} else if (!confirmedPreview) {
|
} else if (!confirmedPreview) {
|
||||||
handlePreview();
|
handlePreview();
|
||||||
} else if (isValidated && confirmedPreview) {
|
} else {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<>
|
||||||
<LoadingOverlay visible={loading} zIndex={1000} />
|
|
||||||
<Title order={4}>User Configuration</Title>
|
<Title order={4}>User Configuration</Title>
|
||||||
<TextInput
|
|
||||||
label="Enter CIF No"
|
<Box
|
||||||
placeholder="Enter your CIF No"
|
style={{
|
||||||
value={CIF}
|
height: "65vh",
|
||||||
onChange={(e) => {
|
maxHeight: "65vh",
|
||||||
const input = e.currentTarget.value.replace(/\D/g, '');
|
// overflowY: "auto",
|
||||||
if (input.length <= 11) setCIF(input);
|
|
||||||
}}
|
}}
|
||||||
disabled={isValidated}
|
|
||||||
withAsterisk />
|
|
||||||
|
|
||||||
{isValidated && (
|
|
||||||
<>
|
|
||||||
<Divider size="xs" label="User Info" />
|
|
||||||
<Box style={{ overflowX: 'auto', border: '1px solid #eee', borderRadius: 8, padding: 12 }}>
|
|
||||||
<Group p="apart">
|
|
||||||
<Text fw={500}>Preview User Details</Text>
|
|
||||||
<Button variant="subtle" size="xs" onClick={() => setDetailsExpanded((v) => !v)}>
|
|
||||||
{detailsExpanded ? '▲' : '▼'}
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
|
|
||||||
{detailsExpanded && (
|
|
||||||
<>
|
|
||||||
<Group grow>
|
|
||||||
<TextInput label="User ID" value={userDetails.userId} readOnly disabled />
|
|
||||||
<TextInput label="Name" value={userDetails.name} readOnly disabled />
|
|
||||||
<TextInput label="Mobile" value={userDetails.mobile} readOnly disabled />
|
|
||||||
</Group>
|
|
||||||
<Group grow>
|
|
||||||
<TextInput label="Address" value={userDetails.address} readOnly disabled />
|
|
||||||
<TextInput label="Savings Account" value={savingsAccount || ''} readOnly disabled />
|
|
||||||
<TextInput label="Active Accounts" value={userDetails.activeAccount} readOnly disabled />
|
|
||||||
</Group>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Divider label='Rights' size="xs" />
|
|
||||||
<Stack gap="sm">
|
|
||||||
{/* Header row */}
|
|
||||||
<Group gap="xl">
|
|
||||||
<Box w={150}>
|
|
||||||
<Text fw={500}>Services</Text>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Text fw={500}>Enable</Text>
|
|
||||||
</Box>
|
|
||||||
<Box w={120}>
|
|
||||||
<Text fw={500}>Transaction</Text>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Text fw={500}>Read</Text>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
|
|
||||||
{/* Internet Banking row */}
|
|
||||||
<Group gap="xl" align="center">
|
|
||||||
<Box w={150}>
|
|
||||||
<Text>Internet Banking</Text>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={isValidated && confirmedPreview}
|
|
||||||
checked={ibEnabled}
|
|
||||||
onChange={(e) => {
|
|
||||||
setIbEnabled(e.currentTarget.checked);
|
|
||||||
if (!e.currentTarget.checked) setIbAccess(null);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box w={120}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={!ibEnabled || isValidated && confirmedPreview}
|
|
||||||
checked={ibAccess === "1"}
|
|
||||||
onChange={() => setIbAccess("1")}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={!ibEnabled || isValidated && confirmedPreview}
|
|
||||||
checked={ibAccess === "2"}
|
|
||||||
onChange={() => setIbAccess("2")}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
|
|
||||||
{/* Mobile Banking row */}
|
|
||||||
<Group gap="xl" align="center">
|
|
||||||
<Box w={150}>
|
|
||||||
<Text>Mobile Banking</Text>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={isValidated && confirmedPreview}
|
|
||||||
checked={mbEnabled}
|
|
||||||
onChange={(e) => {
|
|
||||||
setMbEnabled(e.currentTarget.checked);
|
|
||||||
if (!e.currentTarget.checked) setMbAccess(null);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box w={120}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={!mbEnabled || isValidated && confirmedPreview}
|
|
||||||
checked={mbAccess === "1"}
|
|
||||||
onChange={() => setMbAccess("1")}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box w={100}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={!mbEnabled || isValidated && confirmedPreview}
|
|
||||||
checked={mbAccess === "2"}
|
|
||||||
onChange={() => setMbAccess("2")}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
</Stack>
|
|
||||||
{accountError && (
|
|
||||||
<Text c="red" size="sm" mt="xs">{accountError}</Text>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button mt="lg" onClick={handleMainAction} disabled={loading}>
|
|
||||||
{!isValidated ? 'Validate' : !confirmedPreview ? 'Preview' : 'Submit'}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
opened={showPreviewModal}
|
|
||||||
onClose={() => setShowPreviewModal(false)}
|
|
||||||
title="Confirm User Rights"
|
|
||||||
centered
|
|
||||||
>
|
>
|
||||||
<Stack>
|
<LoadingOverlay visible={loading} zIndex={1000} />
|
||||||
<Text><strong>CIF:</strong> {CIF}</Text>
|
|
||||||
<Text><strong>Savings Account:</strong> {savingsAccount}</Text>
|
|
||||||
<Text><strong>Mobile Number:</strong> {userDetails?.mobile ?? "N/A"}</Text>
|
|
||||||
<Divider label='Rights' size="xs" />
|
|
||||||
<TextInput
|
|
||||||
label="Internet Banking"
|
|
||||||
value={
|
|
||||||
ibAccess === "1"
|
|
||||||
? "Transaction"
|
|
||||||
: ibAccess === "2"
|
|
||||||
? "Read"
|
|
||||||
: "No Rights"
|
|
||||||
}
|
|
||||||
readOnly
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label="Mobile Banking"
|
|
||||||
value={
|
|
||||||
mbAccess === "1"
|
|
||||||
? "Transaction"
|
|
||||||
: mbAccess === "2"
|
|
||||||
? "Read"
|
|
||||||
: "No Rights"
|
|
||||||
}
|
|
||||||
readOnly
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
<Group p="right" mt="md">
|
|
||||||
<Button variant="default" onClick={() => setShowPreviewModal(false)}>Cancel</Button>
|
|
||||||
<Button onClick={() => { setConfirmedPreview(true); setShowPreviewModal(false); }}>OK</Button>
|
|
||||||
</Group>
|
|
||||||
</Modal>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
label="Enter CIF No"
|
||||||
|
placeholder="Enter your CIF No"
|
||||||
|
value={CIF}
|
||||||
|
onChange={(e) => {
|
||||||
|
const input = e.currentTarget.value.replace(/\D/g, "");
|
||||||
|
if (input.length <= 11) setCIF(input);
|
||||||
|
}}
|
||||||
|
disabled={isValidated}
|
||||||
|
withAsterisk
|
||||||
|
/>
|
||||||
|
|
||||||
|
{isValidated && (
|
||||||
|
<Tabs defaultValue="details" mt="md" variant="outline">
|
||||||
|
<Tabs.List>
|
||||||
|
<Tabs.Tab value="details" leftSection={<IconUser size={12} />}>User Details</Tabs.Tab>
|
||||||
|
<Tabs.Tab value="rights" leftSection={<IconGavel size={12} />}>Rights</Tabs.Tab>
|
||||||
|
</Tabs.List>
|
||||||
|
|
||||||
|
<Tabs.Panel value="details" pt="xs">
|
||||||
|
<ScrollArea h={250} type="auto" offsetScrollbars>
|
||||||
|
<Paper withBorder p="md" radius="md">
|
||||||
|
<Stack>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700} >User ID:</Text>
|
||||||
|
<Text c="dimmed">{userDetails?.userId ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700} >User Name:</Text>
|
||||||
|
<Text>{userDetails?.name ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700} >Mobile Number:</Text>
|
||||||
|
<Text c="dimmed">{userDetails?.mobile ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700} >User Address:</Text>
|
||||||
|
<Text>{userDetails?.address ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700} >Savings Account:</Text>
|
||||||
|
<Text c="blue">{savingsAccount ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
<Group grow>
|
||||||
|
<Text fw={700}>Active Accounts:</Text>
|
||||||
|
<Text c="Green">{userDetails?.activeAccount ?? "N/A"}</Text>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
</ScrollArea>
|
||||||
|
</Tabs.Panel>
|
||||||
|
|
||||||
|
<Tabs.Panel value="rights" pt="xs">
|
||||||
|
<Stack gap="sm">
|
||||||
|
<Group gap="xl" align="center">
|
||||||
|
<Box w={150}>
|
||||||
|
<Text fw={700}>Internet Banking</Text>
|
||||||
|
</Box>
|
||||||
|
<Box w={100}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={confirmedPreview}
|
||||||
|
checked={ibEnabled}
|
||||||
|
onChange={(e) => {
|
||||||
|
setIbEnabled(e.currentTarget.checked);
|
||||||
|
if (!e.currentTarget.checked) setIbAccess(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={120}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={!ibEnabled || confirmedPreview}
|
||||||
|
checked={ibAccess === "1"}
|
||||||
|
onChange={() => setIbAccess("1")}
|
||||||
|
label="Transaction"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={100}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={!ibEnabled || confirmedPreview}
|
||||||
|
checked={ibAccess === "2"}
|
||||||
|
onChange={() => setIbAccess("2")}
|
||||||
|
label="Read"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group gap="xl" align="center">
|
||||||
|
<Box w={150}>
|
||||||
|
<Text fw={700}>Mobile Banking</Text>
|
||||||
|
</Box>
|
||||||
|
<Box w={100}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={confirmedPreview}
|
||||||
|
checked={mbEnabled}
|
||||||
|
onChange={(e) => {
|
||||||
|
setMbEnabled(e.currentTarget.checked);
|
||||||
|
if (!e.currentTarget.checked) setMbAccess(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={120}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={!mbEnabled || confirmedPreview}
|
||||||
|
checked={mbAccess === "1"}
|
||||||
|
onChange={() => setMbAccess("1")}
|
||||||
|
label="Transaction"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={100}>
|
||||||
|
<Checkbox
|
||||||
|
disabled={!mbEnabled || confirmedPreview}
|
||||||
|
checked={mbAccess === "2"}
|
||||||
|
onChange={() => setMbAccess("2")}
|
||||||
|
label="Read"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Tabs.Panel>
|
||||||
|
</Tabs>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
opened={showPreviewModal}
|
||||||
|
onClose={() => setShowPreviewModal(false)}
|
||||||
|
title="Confirm User Rights"
|
||||||
|
centered
|
||||||
|
>
|
||||||
|
<Stack>
|
||||||
|
<Text>
|
||||||
|
<strong>CIF:</strong> {CIF}
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
<strong>Savings Account:</strong> {savingsAccount ?? "N/A"}
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
<strong>Mobile Number:</strong> {userDetails?.mobile ?? "N/A"}
|
||||||
|
</Text>
|
||||||
|
<Divider label="Rights" size="xs" />
|
||||||
|
<TextInput
|
||||||
|
label="Internet Banking"
|
||||||
|
value={
|
||||||
|
ibAccess === "1"
|
||||||
|
? "Transaction"
|
||||||
|
: ibAccess === "2"
|
||||||
|
? "Read"
|
||||||
|
: "No Rights"
|
||||||
|
}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label="Mobile Banking"
|
||||||
|
value={
|
||||||
|
mbAccess === "1"
|
||||||
|
? "Transaction"
|
||||||
|
: mbAccess === "2"
|
||||||
|
? "Read"
|
||||||
|
: "No Rights"
|
||||||
|
}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Group justify="right" mt="md">
|
||||||
|
<Button variant="default" onClick={() => setShowPreviewModal(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setConfirmedPreview(true);
|
||||||
|
setShowPreviewModal(false);
|
||||||
|
}}
|
||||||
|
disabled={!savingsAccount || !userDetails?.mobile}
|
||||||
|
>
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Modal>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Group>
|
||||||
|
<Button
|
||||||
|
onClick={handleMainAction}
|
||||||
|
disabled={
|
||||||
|
loading ||
|
||||||
|
(!isValidated && !CIF) ||
|
||||||
|
(isValidated &&
|
||||||
|
!confirmedPreview &&
|
||||||
|
(!savingsAccount || !userDetails?.mobile))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{!isValidated ? "Validate" : !confirmedPreview ? "Preview" : "Submit"}
|
||||||
|
</Button>
|
||||||
|
{isValidated && (
|
||||||
|
<Button color="red" variant="light" onClick={handleReset}>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Group>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,19 +145,19 @@ export default function Login() {
|
|||||||
<Divider my="xs" label="Menu" labelPosition="center" />
|
<Divider my="xs" label="Menu" labelPosition="center" />
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={() => handleClick('UserConf')}>
|
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={() => handleClick('UserConf')}>
|
||||||
<IconUsers size ="15"/> User Configuration
|
<IconUsers size="15" /> User Configuration
|
||||||
</Text>
|
</Text>
|
||||||
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={() => handleClick('ViewUser')}>
|
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={() => handleClick('ViewUser')}>
|
||||||
<IconEye size ="15"/> View User Configuration
|
<IconEye size="15" /> View User Configuration
|
||||||
</Text>
|
</Text>
|
||||||
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={handleLogout}>
|
<Text td="underline" variant="light" style={{ cursor: 'pointer' }} onClick={handleLogout}>
|
||||||
<IconLogout size ="15"/> Logout
|
<IconLogout size="15" /> Logout
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Main Content Area */}
|
{/* Main Content Area */}
|
||||||
<Stack style={{ flex: 1, padding: '1rem'}}>
|
<Stack style={{ flex: 1, padding: '1rem' }}>
|
||||||
<Box>
|
<Box>
|
||||||
<Text c="Blue" size="lg" fs='italic'>Welcome ,{name} </Text>
|
<Text c="Blue" size="lg" fs='italic'>Welcome ,{name} </Text>
|
||||||
<Text size="xs" c="gray" style={{ fontFamily: "inter", fontSize: '13px' }}>
|
<Text size="xs" c="gray" style={{ fontFamily: "inter", fontSize: '13px' }}>
|
||||||
@@ -166,14 +166,15 @@ export default function Login() {
|
|||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
{view === 'userConf' && <UserConfiguration />}
|
{view === 'userConf' && <UserConfiguration />}
|
||||||
{view === 'view' && <Text size="xl"><ViewUserConfiguration/></Text>}
|
{view === 'view' && <Text size="xl"><ViewUserConfiguration /></Text>}
|
||||||
{!view &&
|
{!view &&
|
||||||
<Text size="xl">Welcome To The Admin Portal</Text>
|
<Text size="xl">Welcome To The Admin Portal</Text>
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
<Text size="sm" style={{textAlign:"center"}}>© 2025 The Kangra Central Co-Operative Bank</Text>
|
<Divider size="xs" color='#99c2ff' />
|
||||||
|
<Text size="sm" style={{ textAlign: "center" }}>© 2025 The Kangra Central Co-Operative Bank</Text>
|
||||||
</div>
|
</div>
|
||||||
</Providers>
|
</Providers>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user