changes : Changes the design of IB

This commit is contained in:
2025-11-24 18:07:06 +05:30
parent f4b1752fe2
commit 7460157b46
11 changed files with 724 additions and 427 deletions

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { Box, Burger, Button, Divider, Drawer, Stack, Text } from '@mantine/core'; import { Box, Burger, Button, Divider, Drawer, ScrollArea, SegmentedControl, Stack, Text } from '@mantine/core';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';
import Link from 'next/link'; import Link from 'next/link';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@@ -33,55 +33,62 @@ export default function Layout({ children }: { children: React.ReactNode }) {
if (authorized) { if (authorized) {
return ( return (
<Box style={{ display: "flex", height: "100%", flexDirection: isMobile ? "column" : "row" }}> <Box style={{ display: "flex", height: "100%", flexDirection: "column" }}>
{/* Desktop Sidebar */} {/* ---------------- DESKTOP SIDEBAR ---------------- */}
{!isMobile && ( {!isMobile && (
<Box <>
style={{ {/* Segmented Tabs */}
width: "16%", <Box mb="1rem">
backgroundColor: "#c5e4f9", <ScrollArea type="never" offsetScrollbars>
borderRight: "1px solid #ccc", <SegmentedControl
}} fullWidth
> value={pathname}
<Stack style={{ background: "#228be6", height: "10%", alignItems: "center" }}> onChange={(value) => router.push(value)}
<Text fw={700} c="white" style={{ textAlign: "center", marginTop: "10px" }}> data={links.map((link) => ({
My Accounts label: link.label,
</Text> value: link.href,
</Stack> }))}
styles={{
root: {
backgroundColor: "#e9ecef",
borderRadius: 999,
padding: 4,
},
control: {
borderRadius: 999,
transition: "0.3s",
},
<Stack gap="sm" justify="flex-start" style={{ padding: "1rem" }}> indicator: {
{links.map((link) => { borderRadius: 999,
const isActive = pathname === link.href; background: "linear-gradient(90deg, #02a355 0%, #5483c9ff 100%)",
return ( boxShadow: "0 3px 8px rgba(0,0,0,0.15)",
<Text },
key={link.href}
component={Link} label: {
href={link.href} fontSize: 13,
c={isActive ? "darkblue" : "blue"} padding: "6px 10px",
style={{ textAlign: "center",
textDecoration: isActive ? "underline" : "none", fontWeight: 600,
fontWeight: isActive ? 600 : 400, color: "#000",
}} },
> }}
{link.label} />
</Text> </ScrollArea>
); </Box>
})} </>
</Stack>
</Box>
)} )}
{/* Mobile: Burger & Drawer */} {/* ---------------- MOBILE TOP BAR ---------------- */}
{isMobile && ( {isMobile && (
<> <>
{/* Top header with burger and title */}
<Box <Box
style={{ style={{
backgroundColor: "#228be6", background: "linear-gradient(135deg, #1e88e5 0%, #1565c0 100%)",
// padding: "0.5rem 1rem",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", justifyContent: "space-between",
padding: "0.7rem 1rem",
}} }}
> >
<Burger <Burger
@@ -90,11 +97,12 @@ export default function Layout({ children }: { children: React.ReactNode }) {
size="sm" size="sm"
color="white" color="white"
/> />
<Text fw={500} c="white"> <Text fw={600} c="white">
My Accounts Send Money
</Text> </Text>
</Box> </Box>
{/* MOBILE DRAWER */}
<Drawer <Drawer
opened={drawerOpened} opened={drawerOpened}
onClose={() => setDrawerOpened(false)} onClose={() => setDrawerOpened(false)}
@@ -103,27 +111,31 @@ export default function Layout({ children }: { children: React.ReactNode }) {
overlayProps={{ color: "black", opacity: 0.55, blur: 3 }} overlayProps={{ color: "black", opacity: 0.55, blur: 3 }}
styles={{ styles={{
root: { root: {
backgroundColor: "#e6f5ff", // soft background for drawer backgroundColor: "#eaf4ff",
// borderLeft: "4px solid #228be6",
// borderRadius: "8px",
}, },
}} }}
> >
{/* Logo and Drawer Header */} {/* Drawer Header */}
<Box style={{ display: "flex", alignItems: "center", marginBottom: "1rem" }}> <Box
<> style={{
<Image src={logo} alt="KCCB Logo" width={40} height={40} style={{ borderRadius: "50%" }} /> display: "flex",
<Text alignItems: "center",
fw={700} marginBottom: "1rem",
ml="10px" }}
style={{ fontSize: "18px", color: "#228be6" }} >
> <Image
My Accounts src={logo}
</Text> alt="KCCB Logo"
</> width={45}
height={45}
style={{ borderRadius: "50%" }}
/>
<Text fw={700} ml="10px" style={{ fontSize: "19px", color: "#1565c0" }}>
Send Money
</Text>
</Box> </Box>
{/* Menu Items */} {/* Drawer Items */}
<Stack gap="sm"> <Stack gap="sm">
{links.map((link) => { {links.map((link) => {
const isActive = pathname === link.href; const isActive = pathname === link.href;
@@ -138,22 +150,11 @@ export default function Layout({ children }: { children: React.ReactNode }) {
style={{ style={{
justifyContent: "flex-start", justifyContent: "flex-start",
fontWeight: isActive ? 600 : 400, fontWeight: isActive ? 600 : 400,
textDecoration: isActive ? "underline" : "none", color: isActive ? "#fff" : "#1565c0",
color: isActive ? "#fff" : "#228be6", backgroundColor: isActive ? "#1565c0" : "#dceeff",
backgroundColor: isActive ? "#228be6" : "#dceeff",
borderRadius: "8px", borderRadius: "8px",
padding: "10px 12px", padding: "10px 12px",
transition: "0.3s", transition: "0.2s",
}}
onMouseEnter={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = "#228be6";
target.style.color = "#fff";
}}
onMouseLeave={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = isActive ? "#228be6" : "#dceeff";
target.style.color = isActive ? "#fff" : "#228be6";
}} }}
onClick={() => setDrawerOpened(false)} onClick={() => setDrawerOpened(false)}
> >
@@ -166,9 +167,14 @@ export default function Layout({ children }: { children: React.ReactNode }) {
</> </>
)} )}
{/* ---------------- CONTENT AREA ---------------- */}
{/* Content Area */} <Box
<Box style={{ flex: 1, padding: isMobile ? "0.5rem" : "1rem", overflowY: "auto" }}> style={{
flex: 1,
padding: isMobile ? "0.5rem" : "1rem",
overflowY: "auto",
}}
>
{children} {children}
</Box> </Box>
</Box> </Box>

View File

@@ -0,0 +1,182 @@
"use client";
import {
Box,
Stack,
Text,
SegmentedControl,
ScrollArea,
Burger,
Drawer,
Button,
} from "@mantine/core";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
import { useMediaQuery } from "@mantine/hooks";
import Image from "next/image";
import logo from "@/app/image/logo1.jpg";
export default function Layout({ children }: { children: React.ReactNode }) {
const [authorized, SetAuthorized] = useState<boolean | null>(null);
const router = useRouter();
const pathname = usePathname();
const isMobile = useMediaQuery("(max-width: 768px)");
const [drawerOpened, setDrawerOpened] = useState(false);
/* Beneficiary Options */
const links = [
{ label: "Add Beneficiary", href: "/beneficiary/add_beneficiary" },
{ label: "View Beneficiary", href: "/beneficiary/view_beneficiary" },
];
useEffect(() => {
const token = localStorage.getItem("access_token");
if (!token) {
SetAuthorized(false);
router.push("/login");
} else {
SetAuthorized(true);
}
}, []);
if (!authorized) return null;
return (
<Box style={{ display: "flex", height: "100%", flexDirection: "column" }}>
{/* ---------------- DESKTOP HEADER ---------------- */}
{!isMobile && (
<>
{/* Segmented Tabs */}
<Box mb="1rem">
<ScrollArea type="never" offsetScrollbars>
<SegmentedControl
fullWidth
value={pathname}
onChange={(value) => router.push(value)}
data={links.map((link) => ({
label: link.label,
value: link.href,
}))}
styles={{
root: {
backgroundColor: "#e9ecef",
borderRadius: 999,
padding: 4,
},
control: {
borderRadius: 999,
transition: "0.3s",
},
indicator: {
borderRadius: 999,
background: "linear-gradient(90deg, #02a355 0%, #5483c9ff 100%)",
boxShadow: "0 3px 8px rgba(0,0,0,0.15)",
},
label: {
fontSize: 13,
padding: "6px 10px",
textAlign: "center",
fontWeight: 600,
color: "#000",
},
}}
/>
</ScrollArea>
</Box>
</>
)}
{/* ---------------- MOBILE HEADER ---------------- */}
{isMobile && (
<>
<Box
style={{
backgroundColor: "#228be6",
padding: "0.8rem 1rem",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Burger
opened={drawerOpened}
onClick={() => setDrawerOpened(true)}
size="sm"
color="white"
/>
<Text fw={600} c="white">
Beneficiary
</Text>
</Box>
{/* Drawer for Mobile */}
<Drawer
opened={drawerOpened}
onClose={() => setDrawerOpened(false)}
padding="md"
size="75%"
overlayProps={{ color: "black", opacity: 0.55, blur: 3 }}
>
{/* Drawer Header */}
<Box style={{ display: "flex", alignItems: "center", marginBottom: "1rem" }}>
<Image
src={logo}
alt="KCCB Logo"
width={40}
height={40}
style={{ borderRadius: "50%" }}
/>
<Text fw={700} ml="10px" style={{ color: "#228be6", fontSize: "18px" }}>
Beneficiary
</Text>
</Box>
{/* Drawer Menu Items */}
<Stack gap="sm">
{links.map((link) => {
const isActive = pathname === link.href;
return (
<Button
key={link.href}
component={Link}
href={link.href}
fullWidth
variant="light"
style={{
justifyContent: "flex-start",
backgroundColor: isActive ? "#228be6" : "#e2efff",
color: isActive ? "#fff" : "#1b69c7",
fontWeight: isActive ? 600 : 400,
borderRadius: 10,
padding: "10px",
}}
onClick={() => setDrawerOpened(false)}
>
{link.label}
</Button>
);
})}
</Stack>
</Drawer>
</>
)}
{/* ---------------- CONTENT BODY ---------------- */}
<Box
style={{
flex: 1,
padding: isMobile ? "0.8rem" : "1rem",
overflowY: "auto",
}}
>
{children}
</Box>
</Box >
);
}

View File

@@ -1,12 +1,12 @@
"use client"; "use client";
import { Box, Burger, Button, Divider, Drawer, Stack, Text } from '@mantine/core'; import { Box, Burger, Button, Drawer, ScrollArea, SegmentedControl, Stack, Text } from "@mantine/core";
import { usePathname } from 'next/navigation'; import { usePathname } from "next/navigation";
import Link from 'next/link'; import Link from "next/link";
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import Image from "next/image"; import Image from "next/image";
import logo from "@/app/image/logo1.jpg"; import logo from "@/app/image/logo1.jpg";
import { useMediaQuery } from '@mantine/hooks'; import { useMediaQuery } from "@mantine/hooks";
export default function Layout({ children }: { children: React.ReactNode }) { export default function Layout({ children }: { children: React.ReactNode }) {
const [authorized, SetAuthorized] = useState<boolean | null>(null); const [authorized, SetAuthorized] = useState<boolean | null>(null);
@@ -16,163 +16,167 @@ export default function Layout({ children }: { children: React.ReactNode }) {
const [drawerOpened, setDrawerOpened] = useState(false); const [drawerOpened, setDrawerOpened] = useState(false);
const links = [ const links = [
{ label: " Quick Pay", href: "/funds_transfer" }, { label: "Quick Pay", href: "/funds_transfer" },
{ label: "Add Beneficiary", href: "/funds_transfer/add_beneficiary" }, { label: "Bank Transfer", href: "/funds_transfer/send_beneficiary" },
{ label: "View Beneficiary ", href: "/funds_transfer/view_beneficiary" },
{ label: "Send to Beneficiary", href: "/funds_transfer/send_beneficiary" },
]; ];
useEffect(() => { useEffect(() => {
const token = localStorage.getItem("access_token"); const token = localStorage.getItem("access_token");
if (!token) { if (!token) {
SetAuthorized(false); SetAuthorized(false);
router.push("/login"); router.push("/login");
} } else {
else {
SetAuthorized(true); SetAuthorized(true);
} }
}, []); }, []);
if (authorized) { if (!authorized) return null;
return (
<Box style={{ display: "flex", height: "100%", flexDirection: isMobile ? "column" : "row" }}> return (
{/* Desktop Sidebar */} <Box style={{ display: "flex", height: "100%", flexDirection: "column" }}>
{!isMobile && ( {/* ---------------- DESKTOP SIDEBAR ---------------- */}
{!isMobile && (
<>
{/* Segmented Tabs */}
<Box mb="1rem">
<ScrollArea type="never" offsetScrollbars>
<SegmentedControl
fullWidth
value={pathname}
onChange={(value) => router.push(value)}
data={links.map((link) => ({
label: link.label,
value: link.href,
}))}
styles={{
root: {
backgroundColor: "#e9ecef",
borderRadius: 999,
padding: 4,
},
control: {
borderRadius: 999,
transition: "0.3s",
},
indicator: {
borderRadius: 999,
background: "linear-gradient(90deg, #02a355 0%, #5483c9ff 100%)",
boxShadow: "0 3px 8px rgba(0,0,0,0.15)",
},
label: {
fontSize: 13,
padding: "6px 10px",
textAlign: "center",
fontWeight: 600,
color: "#000",
},
}}
/>
</ScrollArea>
</Box>
</>
)}
{/* ---------------- MOBILE TOP BAR ---------------- */}
{isMobile && (
<>
<Box <Box
style={{ style={{
width: "16%", background: "linear-gradient(135deg, #1e88e5 0%, #1565c0 100%)",
backgroundColor: "#c5e4f9", display: "flex",
borderRight: "1px solid #ccc", alignItems: "center",
justifyContent: "space-between",
padding: "0.7rem 1rem",
}} }}
> >
<Stack style={{ background: "#228be6", height: "10%", alignItems: "center" }}> <Burger
<Text fw={700} c="white" style={{ textAlign: "center", marginTop: "10px" }}> opened={drawerOpened}
Send Money onClick={() => setDrawerOpened(!drawerOpened)}
</Text> size="sm"
</Stack> color="white"
/>
<Stack gap="sm" justify="flex-start" style={{ padding: "1rem" }}> <Text fw={600} c="white">
{links.map((link) => { Send Money
const isActive = pathname === link.href; </Text>
return (
<Text
key={link.href}
component={Link}
href={link.href}
c={isActive ? "darkblue" : "blue"}
style={{
textDecoration: isActive ? "underline" : "none",
fontWeight: isActive ? 600 : 400,
}}
>
{link.label}
</Text>
);
})}
</Stack>
</Box> </Box>
)}
{/* Mobile: Burger & Drawer */} {/* MOBILE DRAWER */}
{isMobile && ( <Drawer
<> opened={drawerOpened}
{/* Top header with burger and title */} onClose={() => setDrawerOpened(false)}
padding="md"
size="75%"
overlayProps={{ color: "black", opacity: 0.55, blur: 3 }}
styles={{
root: {
backgroundColor: "#eaf4ff",
},
}}
>
{/* Drawer Header */}
<Box <Box
style={{ style={{
backgroundColor: "#228be6",
// padding: "0.5rem 1rem",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", marginBottom: "1rem",
}} }}
> >
<Burger <Image
opened={drawerOpened} src={logo}
onClick={() => setDrawerOpened(!drawerOpened)} alt="KCCB Logo"
size="sm" width={45}
color="white" height={45}
style={{ borderRadius: "50%" }}
/> />
<Text fw={500} c="white"> <Text fw={700} ml="10px" style={{ fontSize: "19px", color: "#1565c0" }}>
Send Money Send Money
</Text> </Text>
</Box> </Box>
<Drawer {/* Drawer Items */}
opened={drawerOpened} <Stack gap="sm">
onClose={() => setDrawerOpened(false)} {links.map((link) => {
padding="md" const isActive = pathname === link.href;
size="75%"
overlayProps={{ color: "black", opacity: 0.55, blur: 3 }} return (
styles={{ <Button
root: { key={link.href}
backgroundColor: "#e6f5ff", // soft background for drawer variant="subtle"
// borderLeft: "4px solid #228be6", component={Link}
// borderRadius: "8px", href={link.href}
}, fullWidth
}} style={{
> justifyContent: "flex-start",
{/* Logo and Drawer Header */} fontWeight: isActive ? 600 : 400,
<Box style={{ display: "flex", alignItems: "center", marginBottom: "1rem" }}> color: isActive ? "#fff" : "#1565c0",
<> backgroundColor: isActive ? "#1565c0" : "#dceeff",
<Image src={logo} alt="KCCB Logo" width={40} height={40} style={{ borderRadius: "50%" }} /> borderRadius: "8px",
<Text padding: "10px 12px",
fw={700} transition: "0.2s",
ml="10px" }}
style={{ fontSize: "18px", color: "#228be6" }} onClick={() => setDrawerOpened(false)}
> >
Send Money {link.label}
</Text> </Button>
</> );
</Box> })}
</Stack>
</Drawer>
</>
)}
{/* Menu Items */} {/* ---------------- CONTENT AREA ---------------- */}
<Stack gap="sm"> <Box
{links.map((link) => { style={{
const isActive = pathname === link.href; flex: 1,
padding: isMobile ? "0.5rem" : "1rem",
return ( overflowY: "auto",
<Button }}
key={link.href} >
variant="subtle" {children}
component={Link}
href={link.href}
fullWidth
style={{
justifyContent: "flex-start",
fontWeight: isActive ? 600 : 400,
textDecoration: isActive ? "underline" : "none",
color: isActive ? "#fff" : "#228be6",
backgroundColor: isActive ? "#228be6" : "#dceeff",
borderRadius: "8px",
padding: "10px 12px",
transition: "0.3s",
}}
onMouseEnter={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = "#228be6";
target.style.color = "#fff";
}}
onMouseLeave={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = isActive ? "#228be6" : "#dceeff";
target.style.color = isActive ? "#fff" : "#228be6";
}}
onClick={() => setDrawerOpened(false)}
>
{link.label}
</Button>
);
})}
</Stack>
</Drawer>
</>
)}
{/* Content Area */}
<Box style={{ flex: 1, padding: isMobile ? "0.5rem" : "1rem", overflowY: "auto" }}>
{children}
</Box>
</Box> </Box>
); </Box>
} );
} }

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Box, Button, Divider, Group, Image, Modal, Popover, Stack, Switch, Text, Title } from '@mantine/core'; import { Anchor, Box, Button, Container, Divider, Group, Image, Modal, Popover, Stack, Switch, Text, Title, Grid } from '@mantine/core';
import { IconBook, IconCurrencyRupee, IconHome, IconLogout, IconMoon, IconPhoneFilled, IconSettings, IconSun, IconUserCircle } from '@tabler/icons-react'; import { IconHome, IconLogout, IconMoon, IconSend, IconSettings, IconSun, IconUserCircle, IconUsers, IconWallet } from '@tabler/icons-react';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter, usePathname } from "next/navigation"; import { useRouter, usePathname } from "next/navigation";
import { Providers } from '../providers'; import { Providers } from '../providers';
@@ -181,8 +181,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
const navItems = [ const navItems = [
{ href: "/home", label: "Home", icon: IconHome }, { href: "/home", label: "Home", icon: IconHome },
{ href: "/accounts", label: "Accounts", icon: IconBook }, { href: "/accounts", label: "Accounts", icon: IconWallet },
{ href: "/funds_transfer", label: "Send Money", icon: IconCurrencyRupee }, { href: "/funds_transfer", label: "Fund Transfer", icon: IconSend },
{ href: "/beneficiary/add_beneficiary", label: "Beneficiaries", icon: IconUsers },
{ href: "/settings", label: "Settings", icon: IconSettings }, { href: "/settings", label: "Settings", icon: IconSettings },
]; ];
@@ -191,7 +192,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<html lang="en"> <html lang="en">
<body> <body>
<Providers> <Providers>
<Box style={{ backgroundColor: "#e6ffff", minHeight: "100vh", display: "flex", flexDirection: "column", padding: 0, margin: 0 }}> <Box style={{ minHeight: "100%", display: "flex", flexDirection: "column" }}>
{/* HEADER */} {/* HEADER */}
<Box <Box
@@ -202,7 +203,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
padding: "0.8rem 2rem", padding: "0.8rem 2rem",
background: darkMode background: darkMode
? "linear-gradient(15deg, rgba(229, 101, 22, 1) 55%, rgba(28, 28, 30, 1) 100%)" // Dark Mode Gradient ? "linear-gradient(15deg, rgba(229, 101, 22, 1) 55%, rgba(28, 28, 30, 1) 100%)" // Dark Mode Gradient
: "linear-gradient(15deg, rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)", // Light Mode Gradient : "linear-gradient(deg, rgba(10, 114, 40, 1) 55%, rgba(101, 101, 184, 1) 100%)", // Light Mode Gradient
alignItems: "center", alignItems: "center",
justifyContent: "space-between", justifyContent: "space-between",
color: "white", color: "white",
@@ -272,7 +273,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<Button <Button
leftSection={<IconLogout size={18} />} leftSection={<IconLogout size={18} />}
onClick={doLogout} onClick={handleLogout}
> >
Logout Logout
</Button> </Button>
@@ -284,79 +285,78 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</Box> </Box>
{/* WELCOME + NAV */} {/* WELCOME + NAV */}
<Box <Group
style={{ style={{
flexShrink: 0, // padding: "0.8rem",
padding: isMobile ? "0.5rem" : "0.5rem 1rem", background: "#d3f3bcff",
display: "flex", // borderRadius: 8,
flexDirection: isMobile ? "column" : "row", boxShadow: "0 6px 6px rgba(0,0,0,0.06)",
justifyContent: "space-between", position:'sticky',
alignItems: isMobile ? "flex-start" : "center", top: 85,
gap: isMobile ? "0.5rem" : 0, zIndex: 100,
}} }}
> >
<Stack gap={isMobile ? 2 : 0} align={isMobile ? "flex-start" : "flex-start"}>
<Title order={isMobile ? 5 : 4} style={{ fontFamily: "inter", fontSize: isMobile ? "18px" : "22px" }}>
Welcome, {custname ?? null}
</Title>
<Text size="xs" c="gray" style={{ fontFamily: "inter", fontSize: isMobile ? "11px" : "13px" }}>
Last logged in at {userLastLoginDetails ? new Date(userLastLoginDetails).toLocaleString() : "N/A"}
</Text>
</Stack>
<Group mt={isMobile ? "sm" : "md"} gap="sm" style={{ flexWrap: isMobile ? "wrap" : "nowrap" }}> {navItems.map((item) => {
{navItems.map((item) => { const isActive = pathname.startsWith(item.href);
const isActive = pathname.startsWith(item.href); const Icon = item.icon;
const Icon = item.icon;
return ( return (
<Link key={item.href} href={item.href}> <Link
<Button key={item.href}
leftSection={<Icon size={isMobile ? 16 : 20} />} href={item.href}
variant={isActive ? "dark" : "subtle"} style={{ textDecoration: "none" }}
color={isActive ? "blue" : undefined} >
size={isMobile ? "xs" : "sm"} <Group
> gap={8}
style={{
padding: "12px 24px",
// borderRadius: 10,
width: "100%",
transition: "0.2s ease",
background: isActive ? "rgba(50, 159, 81, 1)" : "transparent",
color: isActive ? "#10a44bff" : "#3b3b3b",
fontWeight: isActive ? 600 : 500,
}}
>
<Icon
size={18}
color={isActive ? "#0f100fea" : "#3b3b3b"}
/>
<Text size="sm" c='black' fw={500}>
{item.label} {item.label}
</Button> </Text>
</Link>
);
})}
{/* <Popover opened={opened} onChange={close} position="bottom-end" withArrow shadow="md">
<Popover.Target>
<Button leftSection={<IconLogout size={isMobile ? 16 : 20} />} variant="subtle" size={isMobile ? "xs" : "sm"} onClick={open}>
Logout
</Button>
</Popover.Target>
<Popover.Dropdown>
<Text size="sm" mb="sm">
Are you sure you want to logout?
</Text>
<Group justify="flex-end" gap="sm">
<Button variant="default" onClick={close}>
Cancel
</Button>
<Button onClick={handleLogout}>Logout</Button>
</Group> </Group>
</Popover.Dropdown> </Link>
</Popover> */}
</Group>
</Box>
<Divider size="xs" color="#99c2ff" /> );
})}
</Group>
{/* CHILDREN */} {/* CHILDREN */}
<Box <Box
style={{ style={{
flex: 1, flex: 1,
overflowY: "auto", backgroundColor: "#f5f7fa",
borderTop: "1px solid #ddd", padding: "1.5rem",
borderBottom: "1px solid #ddd",
// padding: isMobile ? "0.5rem" : "1rem",
}} }}
> >
{children} <Box
style={{
// maxWidth: "1200px",
margin: "0 auto",
background: "white",
padding: "1.8rem",
borderRadius: "12px",
boxShadow: "0 4px 12px rgba(0,0,0,0.08)",
minHeight: "75vh",
}}
>
{children}
</Box>
</Box> </Box>
{/* this model for session logout */} {/* this model for session logout */}
<Modal <Modal
opened={sessionModal} opened={sessionModal}
@@ -384,22 +384,111 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</Stack> </Stack>
</Modal> </Modal>
<Divider size="xs" color="blue" />
{/* FOOTER */} {/* FOOTER */}
<Box <Box
style={{ component="footer"
flexShrink: 0, style={(theme) => ({
display: "flex", borderTop: `1px solid `,
justifyContent: "center", backgroundColor: 'rgba(60, 54, 74, 1)',
alignItems: "center", paddingTop: '2rem',
backgroundColor: "#f8f9fa", paddingBottom: '2rem',
// padding: isMobile ? "0.25rem" : "0.5rem", })}
}}
> >
<Text c="dimmed" size={isMobile ? "xs" : "sm"}> <Container size="xl">
© 2025 The Kangra Central Co-Operative Bank Ltd. <Grid>
</Text> <Grid.Col span={{ base: 12, md: 4 }}>
<Group mb="md">
<Box
style={{
width: 40,
height: 40,
background: 'linear-gradient(135deg, #16a34a 0%, #10b981 100%)',
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: 8,
}}
>
<Image
src={logo}
component={NextImage}
fit="cover" // This ensures the image covers the circle
alt="ebanking"
style={{
width: "100%",
height: "100%",
objectFit: "cover", // Ensures the logo covers the whole circular area
borderRadius: '50%',
}}
/>
</Box>
<div>
<Text size="sm" fw={500}>
The Kangra Central
</Text>
<Text size="xs">Co-operative Bank Ltd</Text>
</div>
</Group>
<Text size="sm" c="dimmed">
Serving the community since inception. We are committed to providing quality
banking services with personalized care and customer satisfaction.
</Text>
</Grid.Col>
<Grid.Col span={{ base: 12, md: 4 }}>
<Text size="sm" fw={500} mb="md">
Quick Links
</Text>
<Stack gap="xs">
<Anchor href="#" size="sm" c="dimmed">
About Us
</Anchor>
<Anchor href="#" size="sm" c="dimmed">
Products & Services
</Anchor>
<Anchor href="#" size="sm" c="dimmed">
Help & Support
</Anchor>
<Anchor href="#" size="sm" c="dimmed">
Terms & Conditions
</Anchor>
</Stack>
</Grid.Col>
<Grid.Col span={{ base: 12, md: 4 }}>
<Text size="sm" fw={500} mb="md">
Contact Us
</Text>
<Stack gap="xs">
<Text size="sm" c="dimmed">
Phone: +91-1800-1808008
</Text>
<Text size="sm" c="dimmed">
Hours: Mon-Fri 10:00 AM - 4:00 PM
</Text>
<Text size="sm" c="dimmed">
Sat 10:00 AM - 2:00 PM
</Text>
</Stack>
</Grid.Col>
</Grid>
<Text
size="sm"
c="dimmed"
ta="center"
// mt="xl"
// pt="xl"
style={(theme) => ({
borderTop: `1px solid `
})}
>
© 2025 The Kangra Central Co-operative Bank Ltd. All rights reserved. | Privacy Policy |
Security
</Text>
</Container>
</Box> </Box>
</Box> </Box>
</Providers> </Providers>

View File

@@ -58,10 +58,6 @@ export default function ChangePassword() {
} }
} }
useEffect(() => { useEffect(() => {
regenerateCaptcha(); regenerateCaptcha();
}, []); }, []);
@@ -232,7 +228,7 @@ export default function ChangePassword() {
}; };
return ( return (
<Paper shadow="sm" radius="md" p="md" withBorder h={400}> <Paper shadow="sm" radius="md" p="md" withBorder h={500}>
<Title order={3} mb="sm"> <Title order={3} mb="sm">
Change Login Password Change Login Password
</Title> </Title>

View File

@@ -1,15 +1,24 @@
"use client"; "use client";
import { Box, Burger, Button, Divider, Drawer, Stack, Text } from '@mantine/core';
import { usePathname } from 'next/navigation'; import {
import Link from 'next/link'; Box,
import React, { useEffect, useState } from 'react'; Stack,
import { useRouter } from "next/navigation"; Text,
import { useMediaQuery } from '@mantine/hooks'; SegmentedControl,
ScrollArea,
Burger,
Drawer,
Button,
} from "@mantine/core";
import { usePathname, useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
import { useMediaQuery } from "@mantine/hooks";
import Image from "next/image"; import Image from "next/image";
import logo from "@/app/image/logo1.jpg"; import logo from "@/app/image/logo1.jpg";
import Link from "next/link";
export default function Layout({ children }: { children: React.ReactNode }) { export default function Layout({ children }: { children: React.ReactNode }) {
const [authorized, SetAuthorized] = useState<boolean | null>(null); const [authorized, setAuthorized] = useState<boolean | null>(null);
const router = useRouter(); const router = useRouter();
const pathname = usePathname(); const pathname = usePathname();
const isMobile = useMediaQuery("(max-width: 768px)"); const isMobile = useMediaQuery("(max-width: 768px)");
@@ -21,159 +30,164 @@ export default function Layout({ children }: { children: React.ReactNode }) {
{ 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_name" }, { label: "Preferred Name", href: "/settings/user_name" },
{ label: "Set Transaction Limit ", href: "/settings/set_txn_limit" }, { label: "Set Transaction Limit", href: "/settings/set_txn_limit" },
]; ];
useEffect(() => { useEffect(() => {
const token = localStorage.getItem("access_token"); const token = localStorage.getItem("access_token");
if (!token) { if (!token) {
SetAuthorized(false); setAuthorized(false);
router.push("/login"); router.push("/login");
} } else {
else { setAuthorized(true);
SetAuthorized(true);
} }
}, []); }, []);
if (authorized) { if (!authorized) return null;
return (
<Box style={{ display: "flex", height: "100%", flexDirection: isMobile ? "column" : "row" }}> return (
{/* Desktop Sidebar */} <Box
{!isMobile && ( style={{
display: "flex",
flexDirection: "column",
height: "100%",
}}
>
{/* ---------------- DESKTOP HEADER ---------------- */}
{!isMobile && (
<>
<Box mb="1rem">
<ScrollArea type="never" offsetScrollbars>
<SegmentedControl
fullWidth
value={pathname}
onChange={(value) => router.push(value)}
data={links.map((link) => ({
label: link.label,
value: link.href,
}))}
styles={{
root: {
backgroundColor: "#e9ecef",
borderRadius: 999,
padding: 4,
},
control: {
borderRadius: 999,
transition: "0.3s",
},
indicator: {
borderRadius: 999,
background: "linear-gradient(90deg, #02a355 0%, #5483c9ff 100%)",
boxShadow: "0 3px 8px rgba(0,0,0,0.15)",
},
label: {
fontSize: 13,
padding: "6px 10px",
textAlign: "center",
fontWeight: 600,
color: "#000",
},
}}
/>
</ScrollArea>
</Box>
</>
)}
{/* ---------------- MOBILE HEADER ---------------- */}
{isMobile && (
<>
{/* Mobile Header */}
<Box <Box
style={{ style={{
width: "16%", backgroundColor: "#228be6",
backgroundColor: "#c5e4f9", padding: "0.8rem 1rem",
borderRight: "1px solid #ccc", display: "flex",
alignItems: "center",
justifyContent: "space-between",
}} }}
> >
<Stack style={{ background: "#228be6", height: "10%", alignItems: "center" }}> <Burger
<Text fw={700} c="white" style={{ textAlign: "center", marginTop: "10px" }}> opened={drawerOpened}
Settings onClick={() => setDrawerOpened(true)}
</Text> size="sm"
</Stack> color="white"
/>
<Stack gap="sm" justify="flex-start" style={{ padding: "1rem" }}> <Text fw={600} c="white">
{links.map((link) => { Settings
const isActive = pathname === link.href; </Text>
return (
<Text
key={link.href}
component={Link}
href={link.href}
c={isActive ? "darkblue" : "blue"}
style={{
textDecoration: isActive ? "underline" : "none",
fontWeight: isActive ? 600 : 400,
}}
>
{link.label}
</Text>
);
})}
</Stack>
</Box> </Box>
)}
{/* Mobile: Burger & Drawer */} {/* Mobile Drawer */}
{isMobile && ( <Drawer
<> opened={drawerOpened}
{/* Top header with burger and title */} onClose={() => setDrawerOpened(false)}
padding="md"
size="75%"
overlayProps={{ color: "black", opacity: 0.55, blur: 2 }}
>
<Box <Box
style={{ style={{
backgroundColor: "#228be6",
// padding: "0.5rem 1rem",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", marginBottom: "1.2rem",
}} }}
> >
<Burger <Image
opened={drawerOpened} src={logo}
onClick={() => setDrawerOpened(!drawerOpened)} alt="Logo"
size="sm" width={40}
color="white" height={40}
style={{ borderRadius: "50%" }}
/> />
<Text fw={500} c="white"> <Text fw={700} ml="10px" style={{ color: "#228be6", fontSize: "18px" }}>
Settings Settings
</Text> </Text>
</Box> </Box>
<Drawer <Stack gap="xs">
opened={drawerOpened} {links.map((link) => {
onClose={() => setDrawerOpened(false)} const isActive = pathname === link.href;
padding="md"
size="75%" return (
overlayProps={{ color: "black", opacity: 0.55, blur: 3 }} <Button
styles={{ key={link.href}
root: { component={Link}
backgroundColor: "#e6f5ff", // soft background for drawer href={link.href}
}, fullWidth
}} variant="light"
> style={{
{/* Logo and Drawer Header */} justifyContent: "flex-start",
<Box style={{ display: "flex", alignItems: "center", marginBottom: "1rem" }}> backgroundColor: isActive ? "#228be6" : "#e2efff",
<> color: isActive ? "#fff" : "#1b69c7",
<Image src={logo} alt="KCCB Logo" width={40} height={40} style={{ borderRadius: "50%" }} /> fontWeight: isActive ? 600 : 400,
<Text borderRadius: 10,
fw={700} padding: "10px",
ml="10px" }}
style={{ fontSize: "18px", color: "#228be6" }} onClick={() => setDrawerOpened(false)}
> >
Settings {link.label}
</Text> </Button>
</> );
</Box> })}
</Stack>
</Drawer>
</>
)}
{/* Menu Items */} {/* ---------------- CONTENT AREA ---------------- */}
<Stack gap="sm"> <Box
{links.map((link) => { style={{
const isActive = pathname === link.href; flex: 1,
padding: isMobile ? "0.8rem" : "1rem",
return ( overflowY: "auto",
<Button }}
key={link.href} >
variant="subtle" {children}
component={Link}
href={link.href}
fullWidth
style={{
justifyContent: "flex-start",
fontWeight: isActive ? 600 : 400,
textDecoration: isActive ? "underline" : "none",
color: isActive ? "#fff" : "#228be6",
backgroundColor: isActive ? "#228be6" : "#dceeff",
borderRadius: "8px",
padding: "10px 12px",
transition: "0.3s",
}}
onMouseEnter={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = "#228be6";
target.style.color = "#fff";
}}
onMouseLeave={(e) => {
const target = e.currentTarget as unknown as HTMLElement;
target.style.backgroundColor = isActive ? "#228be6" : "#dceeff";
target.style.color = isActive ? "#fff" : "#228be6";
}}
onClick={() => setDrawerOpened(false)}
>
{link.label}
</Button>
);
})}
</Stack>
</Drawer>
</>
)}
{/* Content Area */}
<Box style={{ flex: 1, padding: isMobile ? "0.5rem" : "1rem", overflowY: "auto" }}>
{children}
</Box>
</Box> </Box>
); </Box>
} );
} }

View File

@@ -6,6 +6,11 @@ const KccbColors: MantineColorsTuple = [
"#e3f2fd", "#bbdefb", "#90caf9", "#64b5f6", "#42a5f5", "#e3f2fd", "#bbdefb", "#90caf9", "#64b5f6", "#42a5f5",
"#2196f3", "#1e88e5", "#1976d2", "#1565c0", "#0d47a1" "#2196f3", "#1e88e5", "#1976d2", "#1565c0", "#0d47a1"
]; ];
// const KccbColors: MantineColorsTuple = [
// "#e8f5e9", "#c8e6c9", "#a5d6a7", "#81c784", "#66bb6a", // Lighter greens
// "#4caf50", "#43a047", "#388e3c", "#2c6f2c", "#1b5e20" // Darker greens
// ];
export const KccbTheme = createTheme({ export const KccbTheme = createTheme({
/* Put your mantine theme override here */ /* Put your mantine theme override here */

View File

@@ -46,7 +46,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: "7890544527" }); const maskedCIF = CIF?.replace(/.(?=.{3})/g, '*');
await sendOtp({ type: 'LOGIN_OTP', username: maskedCIF, mobileNumber: "7890544527" });
notifications.show({ notifications.show({
color: 'orange', color: 'orange',
title: 'OTP Required', title: 'OTP Required',