wip: E-mandate home screen

This commit is contained in:
2025-09-24 13:23:07 +05:30
parent 050244291a
commit 960624f934
4 changed files with 297 additions and 6 deletions

View File

@@ -22,6 +22,6 @@
- >view rights
- Forget Password
- >For Migration if user not have password
- E-mandate

View File

@@ -5,14 +5,46 @@
- Download **AWS Session Manager Plugin**
- Generate **Key for KCCB**
____________________________________________________________
### Production: (Run in systemctl)
- cd /etc/systemd/system
<!-- IB is the service name -->
- vi IB.service
```
[Unit]
Description= Internet Banking Frontened Application in Node
After=network.target
[Service]
# Use absolute path for node or npm
User=ib
Group=ib
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/ib/IB
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
<All value are changed as per domain>
```
- sudo systemctl status IB
- sudo systemctl start IB
- sudo systemctl stop IB
- sudo systemctl restart IB
---
## Machine
```bash
UAT (IB- frontend) : i-0b55435e15425f1c3
Linux : i-0c850dcf8b85b1447
Prod : i-088e64c3435cb5078
UAT (IB- frontend Test) : i-0b55435e15425f1c3
Linux : i-0c850dcf8b85b1447 (Test)
Prod : i-088e64c3435cb5078 (For IB & MB)
```
## 2. Port Forwarding

View File

@@ -108,12 +108,12 @@ export default function AccountStatementPage() {
});
return;
}
if (end.diff(start, "day") > 90) {
if (end.diff(start, "day") > 30) {
notifications.show({
withBorder: true,
color: "red",
title: "Invalid Date range",
message: "End date must be within 90 days from start date",
message: "End date must be within 30 days from start date",
autoClose: 4000,
});
return;
@@ -179,12 +179,16 @@ export default function AccountStatementPage() {
value={startDate}
onChange={setStartDate}
placeholder="Enter start date"
minDate={dayjs("1920-01-01").toDate()}
maxDate={dayjs().toDate()}
/>
<DateInput
label="End Date"
value={endDate}
onChange={setEndDate}
placeholder="Enter end date"
minDate={dayjs("1920-01-01").toDate()}
maxDate={dayjs().toDate()}
/>
<Button fullWidth mt="md" onClick={handleAccountTransaction}>
Proceed

View File

@@ -0,0 +1,255 @@
"use client";
import React, { useState } from "react";
import {
Text,
Title,
Box,
Image,
Card,
Checkbox,
Button,
Group,
Grid,
Container,
ActionIcon,
Divider,
} from "@mantine/core";
import { Providers } from "@/app/providers";
import { useRouter } from "next/navigation";
import NextImage from "next/image";
import logo from "@/app/image/logo1.jpg";
import { IconLogout } from "@tabler/icons-react";
type Mandate = {
id: string;
category: string;
amount: number;
maxAmount: number;
name: string;
frequency: string;
firstCollection: string;
finalCollection: string;
};
const MandateCard = ({
mandate,
onAccept,
onReject,
}: {
mandate: Mandate;
onAccept: (id: string) => void;
onReject: (id: string) => void;
}) => {
const [agreed, setAgreed] = useState(false);
return (
<Card shadow="sm" radius="md" p="lg" withBorder>
<Text fw={600}>{mandate.category}</Text>
<Text size="sm" mt="xs">
Amount: {mandate.amount}
</Text>
<Text size="sm">Max Amount: {mandate.maxAmount}</Text>
<Text size="sm">Name: {mandate.name}</Text>
<Text size="sm">Frequency: {mandate.frequency}</Text>
<Text size="sm">First Collection: {mandate.firstCollection}</Text>
<Text size="sm">Final Collection: {mandate.finalCollection}</Text>
<Checkbox
mt="md"
label="I agree for the debit of mandate processing charges"
checked={agreed}
onChange={(e) => setAgreed(e.currentTarget.checked)}
/>
<Group mt="md" grow>
<Button
variant="outline"
color="red"
disabled={!agreed}
onClick={() => onReject(mandate.id)}
>
Reject
</Button>
<Button
color="green"
disabled={!agreed}
onClick={() => onAccept(mandate.id)}
>
Accept
</Button>
</Group>
</Card>
);
};
export default function MandatePage() {
const router = useRouter();
const [mandates] = useState<Mandate[]>([
{
id: "1",
category: "Insurance Premium",
amount: 11743,
maxAmount: 11743,
name: "LIFE INSURANCE CORPORATION",
frequency: "YEAR",
firstCollection: "2025-09-20",
finalCollection: "2038-03-28",
},
{
id: "2",
category: "Loan EMI",
amount: 8500,
maxAmount: 8500,
name: "XYZ BANK",
frequency: "MONTH",
firstCollection: "2025-10-01",
finalCollection: "2030-10-01",
},
]);
const handleAccept = (id: string) => {
alert(`Accepted mandate ${id}`);
};
const handleReject = (id: string) => {
alert(`Rejected mandate ${id}`);
};
const handleLogout = () => {
localStorage.removeItem("access_token");
router.push("/eMandate/login"); // redirect to login page
};
return (
<Providers>
<div
style={{
backgroundColor: "#f8f9fa",
minHeight: "100vh",
display: "flex",
flexDirection: "column",
}}
>
{/* HEADER */}
<Box
style={{
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "12%",
zIndex: 100,
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "0 0.5rem",
background:
"linear-gradient(15deg, rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)",
borderBottom: "1px solid black",
}}
>
<Box style={{ display: "flex", alignItems: "center" }}>
<Image
src={logo}
component={NextImage}
fit="contain"
alt="ebanking"
style={{ width: "70px", height: "70px", flexShrink: 0 }}
/>
<Title
order={2}
style={{
fontFamily: "Roboto",
marginLeft: "1rem",
color: "white",
}}
>
THE KANGRA CENTRAL CO-OPERATIVE BANK LTD.
</Title>
</Box>
{/* Logout Icon */}
<ActionIcon
variant="subtle"
color="white"
size="lg"
onClick={handleLogout}
title="Logout"
>
<IconLogout size={28} stroke={1.5} />
</ActionIcon>
</Box>
{/* WELCOME BAR */}
<Box
style={{
position: "fixed",
top: "70px", // directly below header
left: 0,
width: "100%",
padding: "0.3rem 1rem",
backgroundColor: "#e6ffff",
zIndex: 90,
}}
>
<Text fw={500} style={{ fontFamily: "inter", fontSize: "20px" }}>
Welcome, John Doe
</Text>
<Text size="xs" c="dimmed" style={{ marginBottom: "4px" }}>
Login Time: 9/24/2025, 12:52:05 PM
</Text>
<Title order={4} ta="center" style={{ margin: 0 }}>
KCCB E-Mandate
</Title>
<Divider size="xs" color='#99c2ff' />
</Box>
{/* CONTENT */}
<Box
style={{
flex: 1,
marginTop: "160px", // header + welcome bar height
marginBottom: "40px", // leave space for footer
// padding: "1rem",
backgroundColor: "#e6ffff",
overflowY: "auto",
}}
>
<Container size="lg">
<Grid>
{mandates.map((mandate) => (
<Grid.Col span={{ base: 12, sm: 6 }} key={mandate.id}>
<MandateCard
mandate={mandate}
onAccept={handleAccept}
onReject={handleReject}
/>
</Grid.Col>
))}
</Grid>
</Container>
</Box>
{/* FOOTER */}
<Box
style={{
position: "fixed",
bottom: 0,
left: 0,
width: "100%",
height: "40px",
backgroundColor: "#f8f9fa",
display: "flex",
justifyContent: "center",
alignItems: "center",
borderTop: "1px solid #ddd",
}}
>
<Text c="dimmed" size="xs">
© 2025 The Kangra Central Co-Operative Bank
</Text>
</Box>
</div>
</Providers>
);
}