Feat : View User Configuration page is up

This commit is contained in:
2025-09-08 17:33:08 +05:30
parent 833453241c
commit e089e95ce8
6 changed files with 190 additions and 13 deletions

12
TODO.md
View File

@@ -8,18 +8,18 @@
### Feature ### Feature
- Password Expiry Logic - Password Expiry Logic
- login -> check password Expiry -> Change password -> login screen - login -> check password Expiry -> Change password -> login screen
- Logout popup : - >Logout popup :
- Are you sure want to logout? - >Are you sure want to logout?
- >Home page password Expiry message - >Home page password Expiry message
- Set userId and login with userID - Set userId and login with userID
- Limit of transaction daily - Limit of transaction daily
- >Statement Download - >Statement Download
- In Every OTP page "Resend button" & 5 min timing of expiry. - >In Every OTP page "Resend button" & 3 min timing of expiry.
- OTP binding with actual mobile number. - OTP binding with actual mobile number.
- IN settings page NOTE position Fixing. - IN settings page NOTE position Fixing.
- Admin page - >Admin page
- give rights - >give rights
- view rights (Pending) - >view rights
- Forget Password - Forget Password

View File

@@ -88,5 +88,6 @@ scp -P 9022 Smsservice/smsserviceapplication.jar <username>@localhost:/home/<use
- **0** → Disabled - **0** → Disabled
- **1** → Transaction - **1** → Transaction
- **2** → Read Only - **2** → Read Only
-**null** → not configured consider as disabled

View File

@@ -14,9 +14,9 @@ export default function UserConfiguration() {
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" | "">(""); const [ibAccess, setIbAccess] = useState<"2" | "1" | null>(null);
const [mbEnabled, setMbEnabled] = useState(false); const [mbEnabled, setMbEnabled] = useState(false);
const [mbAccess, setMbAccess] = useState<"2" | "1" | "">(""); const [mbAccess, setMbAccess] = useState<"2" | "1" | null>(null);
const isValidated = !!userDetails; const isValidated = !!userDetails;
const canSubmit = isValidated && !!savingsAccount && confirmedPreview; const canSubmit = isValidated && !!savingsAccount && confirmedPreview;
@@ -47,7 +47,7 @@ export default function UserConfiguration() {
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); // console.log(saAccount);
if (saAccount) { if (saAccount) {
setSavingsAccount(saAccount.stAccountNo); setSavingsAccount(saAccount.stAccountNo);
} else { } else {
@@ -297,7 +297,7 @@ export default function UserConfiguration() {
checked={ibEnabled} checked={ibEnabled}
onChange={(e) => { onChange={(e) => {
setIbEnabled(e.currentTarget.checked); setIbEnabled(e.currentTarget.checked);
if (!e.currentTarget.checked) setIbAccess(""); if (!e.currentTarget.checked) setIbAccess(null);
}} }}
/> />
</Box> </Box>
@@ -328,7 +328,7 @@ export default function UserConfiguration() {
checked={mbEnabled} checked={mbEnabled}
onChange={(e) => { onChange={(e) => {
setMbEnabled(e.currentTarget.checked); setMbEnabled(e.currentTarget.checked);
if (!e.currentTarget.checked) setMbAccess(""); if (!e.currentTarget.checked) setMbAccess(null);
}} }}
/> />
</Box> </Box>

View File

@@ -0,0 +1,175 @@
"use client";
import React, { useState } from "react";
import {
TextInput,
Button,
Title,
Stack,
Group,
Text,
Divider,
LoadingOverlay,
Box,
Paper,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
interface UserRights {
customer_no: string;
created_at: string;
last_login: Date;
is_first_login: boolean;
ibAccess: "1" | "2" | "0" | null;
mbAccess: "1" | "2" | "0" | null;
}
export default function ViewUserRights() {
const [CIFNo, setCIFNo] = useState("");
const [loading, setLoading] = useState(false);
const [userData, setUserData] = useState<UserRights | null>(null);
const [detailsExpanded, setDetailsExpanded] = useState(true);
const handleSearch = async () => {
if (!CIFNo) {
notifications.show({
color: "red",
title: "Required",
message: "Please enter CIF Number.",
});
return;
}
setLoading(true);
setUserData(null);
try {
const token = localStorage.getItem("admin_access_token");
const response = await fetch(
`/api/auth/admin/user/rights?CIF=${CIFNo}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
}
);
const data = await response.json();
if (response.ok && data) {
setUserData({
customer_no: data.customer_no,
created_at: data.created_at,
last_login: data.last_login,
is_first_login: data.is_first_login,
ibAccess: data.ib_access_level,
mbAccess: data.mb_access_level,
});
} else {
notifications.show({
color: "red",
title: "Not Found",
message: "No user rights found for this identifier.",
});
}
} catch (err) {
notifications.show({
color: "red",
title: "Failed",
message: "Error fetching user rights",
});
} finally {
setLoading(false);
}
};
return (
<Box>
<LoadingOverlay visible={loading} zIndex={1000} />
<Title order={4}>View User Rights</Title>
<Group mt="sm">
<TextInput
// label="Enter CIF No"
placeholder="Enter CIF Number"
value={CIFNo}
onInput={(e) => {
const input = e.currentTarget.value.replace(/\D/g, "");
if (input.length <= 11) {
setCIFNo(input);
setUserData(null)
};
}}
style={{ flex: 1 }}
/>
<Button onClick={handleSearch} disabled={loading}>
Search
</Button>
</Group>
{userData && (
<>
<Divider size="xs" label="User Info" mt="md" />
<Paper
style={{
border: "1px solid #47C44D",
borderRadius: 8,
padding: 12,
marginTop: 8,
}}
>
<Stack gap="sm">
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed" w={150}>CIF Number:</Text>
<Text size="md">{userData.customer_no}</Text>
</Group>
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed">User Created :</Text>
<Text size="md">{new Date(userData.created_at).toLocaleString()}</Text>
</Group>
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed">User Active Status:</Text>
<Text size="md" c="green">Active</Text>
</Group>
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed">User Registered Status:</Text>
<Text size="md" c={userData.is_first_login ? "orange" : "green"}>
{userData.is_first_login ? "Not Registered" : "Registered"}
</Text>
</Group>
</Stack>
</Paper>
<Divider label="Rights" size="xs" mt="md" />
<Paper style={{
border: "1px solid #47C44D",
borderRadius: 8,
padding: 12,
marginTop: 8,
}}>
<Stack gap="sm" mt="sm">
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed" w={150}>Internet Banking Rights:</Text>
<Text size="md">
{userData.ibAccess === "1"
? "Transaction Mode"
: userData.ibAccess === "2"
? "Read Mode"
: "Not Declared"}
</Text>
</Group>
<Group justify="space-between">
<Text size="sm" fw={500} c="dimmed" w={150}>Mobile Banking Rights:</Text>
<Text size="md">
{userData.mbAccess === "1"
? "Transaction Mode"
: userData.mbAccess === "2"
? "Read Mode"
: "Not Declared"}
</Text>
</Group>
</Stack>
</Paper>
</>
)
}
</Box >
);
}

View File

@@ -8,6 +8,7 @@ import NextImage from "next/image";
import logo from '@/app/image/logo1.jpg'; import logo from '@/app/image/logo1.jpg';
import { IconEye, IconLogout, IconPhoneFilled, IconUsers, IconUserScreen } from "@tabler/icons-react"; import { IconEye, IconLogout, IconPhoneFilled, IconUsers, IconUserScreen } from "@tabler/icons-react";
import UserConfiguration from "./UserConfiguration"; import UserConfiguration from "./UserConfiguration";
import ViewUserConfiguration from "./ViewUserConfiguration";
export default function Login() { export default function Login() {
const router = useRouter(); const router = useRouter();
@@ -165,7 +166,7 @@ export default function Login() {
</Box> </Box>
<Box> <Box>
{view === 'userConf' && <UserConfiguration />} {view === 'userConf' && <UserConfiguration />}
{view === 'view' && <Text size="xl">Feature will be available soon ....</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>
} }

View File

@@ -73,7 +73,7 @@ export default function Login() {
const data = await response.json(); const data = await response.json();
setIsLogging(true); setIsLogging(true);
if (response.ok) { if (response.ok) {
console.log(data); // console.log(data);
const token = data.token; const token = data.token;
localStorage.setItem("admin_access_token", token); localStorage.setItem("admin_access_token", token);
router.push("/administrator/home"); router.push("/administrator/home");