changes : Changes the design of IB
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
182
src/app/(main)/beneficiary/layout.tsx
Normal file
182
src/app/(main)/beneficiary/layout.tsx
Normal 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 >
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user