From 9520b2e851f1cd0c6a0f14d04075ce0571310b41 Mon Sep 17 00:00:00 2001 From: victorAnumudu Date: Sun, 6 Apr 2025 02:24:29 +0100 Subject: [PATCH] started layout adjusting --- src/components/DummyLogo.jsx | 4 +- src/components/Icons.jsx | 4 + src/components/breadcrumb/BreadcrumbCom.jsx | 49 +++++- src/components/layouts/DashboardHeader.jsx | 35 +--- src/components/layouts/DashboardLayout.jsx | 65 +++---- src/components/layouts/HandBurger.jsx | 6 +- src/components/layouts/_DashboardLayout.jsx | 66 +++++++ src/components/layouts/aside/AsideLink.jsx | 8 +- .../layouts/aside/AsideLinkWithSubLinks.jsx | 9 +- .../layouts/aside/DashboardAside.jsx | 84 +++++---- .../layouts/aside/__DashboardAside.jsx | 163 ++++++++++++++++++ src/context/GeneralLayoutContext.jsx | 42 ++++- src/index.css | 20 ++- src/pages/HomePage.jsx | 21 ++- tailwind.config.js | 12 +- 15 files changed, 448 insertions(+), 140 deletions(-) create mode 100644 src/components/layouts/_DashboardLayout.jsx create mode 100644 src/components/layouts/aside/__DashboardAside.jsx diff --git a/src/components/DummyLogo.jsx b/src/components/DummyLogo.jsx index 518aa4d..d46fafe 100644 --- a/src/components/DummyLogo.jsx +++ b/src/components/DummyLogo.jsx @@ -1,8 +1,8 @@ export default function DummyLogo() { return ( -
+

digiFI

-

Logo

+

logo here

) } diff --git a/src/components/Icons.jsx b/src/components/Icons.jsx index 8bb0232..0f9062d 100644 --- a/src/components/Icons.jsx +++ b/src/components/Icons.jsx @@ -5,6 +5,8 @@ import { FaEye, FaRegMoneyBill1 } from 'react-icons/fa6' import { GoDotFill } from 'react-icons/go' import { IoPeople, IoTrash } from 'react-icons/io5' import { TbPlayerTrackNext, TbPlayerTrackPrev } from 'react-icons/tb' +import { IoMdSettings } from "react-icons/io"; + export default function Icons({name, className}) { return ( @@ -29,6 +31,8 @@ export default function Icons({name, className}) { :name.toLowerCase() == 'edit' ? + :name.toLowerCase() == 'settings' ? + : null } diff --git a/src/components/breadcrumb/BreadcrumbCom.jsx b/src/components/breadcrumb/BreadcrumbCom.jsx index 9542207..b7e8ab5 100644 --- a/src/components/breadcrumb/BreadcrumbCom.jsx +++ b/src/components/breadcrumb/BreadcrumbCom.jsx @@ -1,22 +1,59 @@ +import { useEffect, useState } from 'react' import { MdKeyboardDoubleArrowRight } from 'react-icons/md' import { TiHomeOutline } from 'react-icons/ti' +import DashboardHeader from '../layouts/DashboardHeader' export default function BreadcrumbCom({title, span, paths}) { + + const [stickNav, setStickNav] = useState(false) + + useEffect(()=>{ + console.log('tru') + + // var rect = navRef?.current?.getBoundingClientRect()?.bottom; + var rect = 10; + // window.addEventListener('scroll', ()=>{ + // if(window.scrollY >= rect + 20){ + // setStickNav(true) + // console.log('tru') + // }else{ + // setStickNav(false) + // console.log('false') + // } + // }) + + // return () => window.removeEventListener('scroll', window.addEventListener('scroll', ()=>{ + // if(window.scrollY >= rect + 20){ + // setStickNav(true) + // }else{ + // setStickNav(false) + // } + // })) + },[]) + return ( -
+
+ +
+
-

{title}

+

{title}

{span && span}
-
- +
+ {paths.map((item, index) => ( -
+
-

{item}

+

{item}

))}
+
+
+ +
+
) } diff --git a/src/components/layouts/DashboardHeader.jsx b/src/components/layouts/DashboardHeader.jsx index 59ce224..c3f8410 100644 --- a/src/components/layouts/DashboardHeader.jsx +++ b/src/components/layouts/DashboardHeader.jsx @@ -11,27 +11,17 @@ import { useState } from "react"; import MainBtn from "../MainBtn"; import { TbLogout2 } from "react-icons/tb"; -export default function DashboardHeader({showAsideDrawer, setShowAsideDrawer}) { +export default function DashboardHeader() { - const {theme, handleTheme, handleDrawer, setLogoutModal} = generalLayoutContext() - - const [activeMenu, setActiveMenu] = useState('') - - const handleActiveMenu = (name) => { - if(activeMenu == name){ - setActiveMenu('') - }else{ - setActiveMenu(name) - } - } + const {theme, handleTheme, setLogoutModal, activeMenu, handleActiveMenu, showAsideDrawer, setShowAsideDrawer} = generalLayoutContext() return ( <> {/* HEADER SECTION*/} -
+
- setShowAsideDrawer(prev => !prev)} showAside={showAsideDrawer} barColor="bg-black-gray" /> + setShowAsideDrawer(prev => !prev)} showAside={showAsideDrawer} />
{/* USER AVATAR */} @@ -48,12 +38,6 @@ export default function DashboardHeader({showAsideDrawer, setShowAsideDrawer}) {
1
*/} - {/* NOTIFICATION */} - {/* */} - {/* THEME SELECTION */}
{theme == 'dark' ? @@ -63,24 +47,19 @@ export default function DashboardHeader({showAsideDrawer, setShowAsideDrawer}) { }
- {/* USER AVATRA */} - {/*
- user image -
*/} -
handleActiveMenu('avatar')} className='relative cursor-pointer w-10 h-10 rounded shadow-round_black dark:shadow-round_white'> user avatar {activeMenu == 'avatar' && -
+

Username

username@gmail.com

-
+
setLogoutModal(true)} > diff --git a/src/components/layouts/DashboardLayout.jsx b/src/components/layouts/DashboardLayout.jsx index 6133830..bb46ee2 100644 --- a/src/components/layouts/DashboardLayout.jsx +++ b/src/components/layouts/DashboardLayout.jsx @@ -1,63 +1,42 @@ import { useEffect, useState } from 'react' import { Outlet } from 'react-router-dom' -import { FaArrowRight, FaArrowLeft } from "react-icons/fa6"; -import DashboardAside from './aside/DashboardAside' import DashboardHeader from './DashboardHeader' import { generalLayoutContext } from '../../context/GeneralLayoutContext' +import DashboardAside from './aside/DashboardAside' export default function DashboardLayout() { - const [shrinkAside, setShrinkAside] = useState(false) - const [showAsideDrawer, setShowAsideDrawer] = useState(false) - - useEffect(()=>{ - window.addEventListener('resize', ()=>{ - setShrinkAside(false) - setShowAsideDrawer(false) - }) - },[]) + const {showAsideDrawer, setShowAsideDrawer} = generalLayoutContext() + return ( -
- - -
setShowAsideDrawer(prev => !prev)} - className={`${showAsideDrawer ? 'left-0' : '-left-96'} w-4/5 sm:w-72 lg:hidden fixed inset-0 z-[999] bg-black text-white-light`}> +
+
-
-
- {/* HEADER SECTION generalLayoutContext*/} - + {/*
+ +
*/} +
+
setShowAsideDrawer(prev => !prev)} >
+
+ +
+
- {/* BODY SECTION */} - {/* main takes the full width minus that of the header and footer 72 for header, 39 for footer total 111 */} -
+
+
+ +
+ + {/* main body section */} +
{/* FOOTER SECTION */} -
+

Copyright @ {new Date().getFullYear()} - Developed by digiFi. All Rights Reserved

diff --git a/src/components/layouts/HandBurger.jsx b/src/components/layouts/HandBurger.jsx index 68e6349..875202c 100644 --- a/src/components/layouts/HandBurger.jsx +++ b/src/components/layouts/HandBurger.jsx @@ -11,21 +11,21 @@ export default function HandBurger({showAside, asideDisplay, barColor}) { }`} >
*/}
{ + window.addEventListener('resize', ()=>{ + setShrinkAside(false) + setShowAsideDrawer(false) + }) + },[]) + return ( +
+ + +
setShowAsideDrawer(prev => !prev)} + className={`${showAsideDrawer ? 'left-0' : '-left-96'} w-4/5 sm:w-72 lg:hidden fixed inset-0 z-[999] bg-black text-white-light`}> + + +
+ +
+ {/* HEADER SECTION generalLayoutContext*/} + + + {/* BODY SECTION */} + {/* main takes the full width minus that of the header and footer 72 for header, 39 for footer total 111 */} +
+ +
+ + {/* FOOTER SECTION */} +
+

Copyright @ {new Date().getFullYear()} - Developed by digiFi. All Rights Reserved

+
+
+
+ ) +} diff --git a/src/components/layouts/aside/AsideLink.jsx b/src/components/layouts/aside/AsideLink.jsx index f17ab71..1612589 100644 --- a/src/components/layouts/aside/AsideLink.jsx +++ b/src/components/layouts/aside/AsideLink.jsx @@ -1,14 +1,18 @@ import { Link, useLocation } from "react-router-dom" import Icons from "../../Icons" +import { generalLayoutContext } from "../../../context/GeneralLayoutContext" -export default function AsideLink({shrinkAside, name, to, icon}) { +export default function AsideLink({name, to, icon}) { + + const {shrinkAside, setShowAsideDrawer} = generalLayoutContext() const {pathname} = useLocation() return ( setShowAsideDrawer(false)} > {icon && } {shrinkAside ? '' : name} diff --git a/src/components/layouts/aside/AsideLinkWithSubLinks.jsx b/src/components/layouts/aside/AsideLinkWithSubLinks.jsx index cfae3e9..3187cbf 100644 --- a/src/components/layouts/aside/AsideLinkWithSubLinks.jsx +++ b/src/components/layouts/aside/AsideLinkWithSubLinks.jsx @@ -2,11 +2,12 @@ import { useState } from "react"; import { useLocation } from "react-router-dom" import { FaCaretDown } from "react-icons/fa"; import Icons from "../../Icons"; +import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; -export default function AsideLinkWithSubLinks({shrinkAside, name, icon, to, children, isOpen}) { +export default function AsideLinkWithSubLinks({name, icon, to, children, isOpen}) { - // const btnName = name + const {shrinkAside} = generalLayoutContext() const {pathname} = useLocation() @@ -17,9 +18,9 @@ export default function AsideLinkWithSubLinks({shrinkAside, name, icon, to, chil return (
- diff --git a/src/components/layouts/aside/DashboardAside.jsx b/src/components/layouts/aside/DashboardAside.jsx index 6b953f1..2a6a48a 100644 --- a/src/components/layouts/aside/DashboardAside.jsx +++ b/src/components/layouts/aside/DashboardAside.jsx @@ -1,5 +1,4 @@ -import { useEffect, useState } from "react"; -import {Link, useLocation} from 'react-router-dom' +import {useLocation} from 'react-router-dom' import RouteLinks from "../../../RouteLinks"; import DummyLogo from "../../DummyLogo"; import MainBtn from "../../MainBtn"; @@ -8,45 +7,33 @@ import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks"; import { useSelector } from "react-redux"; import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { TbLogout2 } from "react-icons/tb"; +import UserAvatar from '../../../assets/user_avatar.jpg' +import Icons from "../../Icons"; - -export default function DashboardAside({shrinkAside=false}) { +export default function DashboardAside() { const {pathname} = useLocation() - const {setLogoutModal} = generalLayoutContext() + const {setLogoutModal, activeMenu, handleActiveMenu} = generalLayoutContext() const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS const {role}= userDetails - // const [hideSubMenu, setHideSubMenu] = useState('') - - // const handleHideSubMenu = (name) => { - // // e.stopPropagation() - // setHideSubMenu((prev) => { - // if(prev == name){ - // return '' - // }else{ - // return name - // } - // }) - // } - return (
-
+
-
+ {/*
*/} -
+
{asideNavLinks.map((link, index) => { let active = link.status == 1 ? true : false let hasSubLinks = (link.subLinks && link.subLinks.length > 0) ? true : false if(active && !hasSubLinks){ return (
- +
) } @@ -70,9 +57,9 @@ export default function DashboardAside({shrinkAside=false}) { return (
{link.title && -

{link.title}

+

{link.title}

} - + <> {link.subLinks.map((subItem, index)=>{ let active = subItem.status == 1 ? true : false @@ -80,7 +67,7 @@ export default function DashboardAside({shrinkAside=false}) { if(active && !hasSubLinks){ return (
- +
) }else if(active && hasSubLinks){ @@ -90,14 +77,14 @@ export default function DashboardAside({shrinkAside=false}) { } }) return( - + <> {subItem.subLinks.map((item, index)=>{ let active = item.status == 1 ? true : false if(active){ return (
- +
) } @@ -117,17 +104,40 @@ export default function DashboardAside({shrinkAside=false}) { })}
-
-
- setLogoutModal(true)} - > - - +
+
+
+ user avatar +
+

Username

+

username@gmail.com

+
+
+
+ {activeMenu == 'settings' && +
+
+
+
+

Username

+

username@gmail.com

+
+
+
+ setLogoutModal(true)} + > + + +
+
+
+ }
) diff --git a/src/components/layouts/aside/__DashboardAside.jsx b/src/components/layouts/aside/__DashboardAside.jsx new file mode 100644 index 0000000..6b953f1 --- /dev/null +++ b/src/components/layouts/aside/__DashboardAside.jsx @@ -0,0 +1,163 @@ +import { useEffect, useState } from "react"; +import {Link, useLocation} from 'react-router-dom' +import RouteLinks from "../../../RouteLinks"; +import DummyLogo from "../../DummyLogo"; +import MainBtn from "../../MainBtn"; +import AsideLink from "./AsideLink"; +import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks"; +import { useSelector } from "react-redux"; +import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; +import { TbLogout2 } from "react-icons/tb"; + + +export default function DashboardAside({shrinkAside=false}) { + + const {pathname} = useLocation() + + const {setLogoutModal} = generalLayoutContext() + + const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS + const {role}= userDetails + + // const [hideSubMenu, setHideSubMenu] = useState('') + + // const handleHideSubMenu = (name) => { + // // e.stopPropagation() + // setHideSubMenu((prev) => { + // if(prev == name){ + // return '' + // }else{ + // return name + // } + // }) + // } + + return ( +
+
+ +
+
+ +
+ {asideNavLinks.map((link, index) => { + let active = link.status == 1 ? true : false + let hasSubLinks = (link.subLinks && link.subLinks.length > 0) ? true : false + if(active && !hasSubLinks){ + return ( +
+ +
+ ) + } + if(active && hasSubLinks){ + // let subLinkList = link.subLinks.filter(value => value.to).map(item => { //any of all open + // if(item.to){ + // return item.to + // } + // }) + let subLinkList = [] + link.subLinks.forEach(item =>{ + if(item.to){ + subLinkList.push(item.to) + }else if(item.subLinks?.length > 0){ + item.subLinks.forEach(item => { + subLinkList.push(item.to) + }) + } + }) + // console.log('subLinkList', subLinkList) + return ( +
+ {link.title && +

{link.title}

+ } + + <> + {link.subLinks.map((subItem, index)=>{ + let active = subItem.status == 1 ? true : false + let hasSubLinks = (subItem.subLinks && subItem.subLinks.length > 0) ? true : false + if(active && !hasSubLinks){ + return ( +
+ +
+ ) + }else if(active && hasSubLinks){ + let subLinkList = subItem.subLinks.filter(value => value.to).map(item => { // specific open + if(item.to){ + return item.to + } + }) + return( + + <> + {subItem.subLinks.map((item, index)=>{ + let active = item.status == 1 ? true : false + if(active){ + return ( +
+ +
+ ) + } + })} + +
+ ) + }else{ + return null + } + })} + +
+
+ ) + } + })} +
+ +
+
+ setLogoutModal(true)} + > + + +
+
+
+ ) +} + +const asideNavLinks = [ + {name:'Dashboard', status:1, icon: 'dashboard', to: RouteLinks.homePage}, + {name:'Salary Loan', title:'Loan', status:1, icon: 'money', subLinks: [ + {name: 'Selected Loans', status:1, icon: 'dot', to: RouteLinks.selectedLoanPage}, + {name: 'Applications', status:1, icon: 'dot', to: RouteLinks.applicationsLoanPage}, + {name: 'Approved Loans', status:1, icon: 'dot', to: RouteLinks.approvedLoansPage}, + {name: 'Disbursements', status:1, icon: 'dot', to: RouteLinks.disbursementsLoanPage}, + {name: 'Payments', status:1, icon: 'dot', to: ''}, + {name: 'Configurations', status:1, icon: 'dot', subLinks: [ + {name: 'Loan Offers', status:1, icon: 'dot', to: RouteLinks.loanOffersPage }, + ] + }, + ], + }, + // {name:'Product 2', title:'Product 2', status:1, icon: 'product', subLinks: [ + // {name: 'Applications', status:1, icon: 'dot', to: ''}, + // ] + // }, + // {name:'Product 3', title:'Product 3', status:1, icon: 'product', subLinks: [ + // {name: 'Applications', status:1, icon: 'dot', to: ''}, + // {name: 'Configuration', status:1, icon: 'dot', to: ''}, + // ] + // }, + // {name:'Administration', title:'Admin', status:1, icon: 'people', subLinks: [ + // {name: 'Users', status:1, icon: 'dot', to: RouteLinks.usersPage}, + // ] + // }, +] diff --git a/src/context/GeneralLayoutContext.jsx b/src/context/GeneralLayoutContext.jsx index 48dc0d0..49a9d1e 100644 --- a/src/context/GeneralLayoutContext.jsx +++ b/src/context/GeneralLayoutContext.jsx @@ -14,6 +14,20 @@ export default function GeneralLayoutContext({children}) { const [logoutModal, setLogoutModal] = useState(false) // USE TO SHOW LOGOUT MODAL BOX + const [activeMenu, setActiveMenu] = useState('') + + const [shrinkAside, setShrinkAside] = useState(false) + + const [showAsideDrawer, setShowAsideDrawer] = useState(false) + + const handleActiveMenu = (name) => { + if(activeMenu == name){ + setActiveMenu('') + }else{ + setActiveMenu(name) + } + } + const handleDrawer = (drawerToOpen) => { // FUNCTION TO DETERMINE WHICH ASIDE DRAWER TO SHOW setDrawer((prev)=>{ if(!prev){ @@ -42,6 +56,10 @@ export default function GeneralLayoutContext({children}) { setAlertBox(valObj) } + const handleTheme = () => { + setTheme(theme === "dark" ? "light" : "dark"); + } + useEffect(() => { if (window.matchMedia("(prefers-color-scheme: dark)").matches) { setTheme("dark"); @@ -58,11 +76,27 @@ export default function GeneralLayoutContext({children}) { } }, [theme]); - const handleTheme = () => { - setTheme(theme === "dark" ? "light" : "dark"); - } + useEffect(()=>{ + window.addEventListener('resize', ()=>{ + setShrinkAside(false) + setShowAsideDrawer(false) + }) + return () => window.removeEventListener('resize', window.addEventListener('resize', ()=>{ + setShrinkAside(false) + setShowAsideDrawer(false) + })) + },[]) - let value = {theme, handleTheme, drawer, handleDrawer, booking, handleBooking, alertBox, handleAlertBox, logoutModal, setLogoutModal} + let value = { + theme, handleTheme, + activeMenu, handleActiveMenu, + drawer, handleDrawer, + booking, handleBooking, + alertBox, handleAlertBox, + logoutModal, setLogoutModal, + shrinkAside, setShrinkAside, + showAsideDrawer, setShowAsideDrawer + } return ( diff --git a/src/index.css b/src/index.css index 0573138..4c3cc9a 100644 --- a/src/index.css +++ b/src/index.css @@ -7,7 +7,7 @@ html{ } *{ - transition: all .3s; + transition: all .2s; } body { @@ -24,6 +24,13 @@ code { monospace; } +@layer utilities { + .aside-scroll-design { + @apply [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 [&::-webkit-scrollbar-track]:rounded-full [&::-webkit-scrollbar-thumb]:rounded-full + } +} + + @layer components { .change-text::after{ content: ''; @@ -38,6 +45,10 @@ code { animation: pop-modal .1s linear 0s forwards; } + .pop-modal-down{ + animation: pop-modal-down .1s linear 0s forwards; + } + /* ANIMATIONS */ @keyframes text-change { @@ -58,4 +69,11 @@ code { 0%{margin-top: 20px; opacity: 0;} 100%{margin-top: 0; opacity: 1;} } + + @keyframes pop-modal-down { + /* 0%{left: -200%;} + 100%{left: 0%;} */ + 0%{margin-bottom: 20px; opacity: 0;} + 100%{margin-bottom: 0; opacity: 1;} + } } diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 22e4ca5..f31355d 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -5,15 +5,22 @@ export default function HomePage() { return (
-
-
-
-
-
-
+
+
+
+
+
-
+
+
+
+

Members Statistics

+

Over 500 members

+
+ +
+
diff --git a/tailwind.config.js b/tailwind.config.js index 59a1f14..c413a09 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -9,8 +9,10 @@ module.exports = { DEFAULT: '#393536', }, black:{ - DEFAULT: '#222', - gray: '#a6a9b7' + DEFAULT: '#000', + aside: '#0D0E12', + body: '#0F1014', + box: '#15171C', }, primary: { DEFAULT: '#0284c7', @@ -21,7 +23,9 @@ module.exports = { }, white: { DEFAULT: '#fff', - light: '#f1f5f9' + light: '#f1f5f9', + body: '#f9f9f9', + aside: '#F1F1F4', } }, screens: { @@ -38,6 +42,8 @@ module.exports = { boxShadow: { round_black: '0 0px 1px 0 rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.19)', round_white: '0 0px 1px 0 rgba(255, 255, 255, 0.2), 0 1px 5px 0 rgba(255, 255, 255, 0.19)' + // round_black: '0px 0px 2px rgba(0, 0, 0, 0.19)', + // round_white: '0px 0px 2px rgba(255, 255, 255, 0)' } }, }, -- 2.34.1