Skip to content

Commit

Permalink
admin page side bar and layout added
Browse files Browse the repository at this point in the history
  • Loading branch information
sinanptm committed Aug 17, 2024
1 parent cda21ec commit bb9185d
Show file tree
Hide file tree
Showing 11 changed files with 395 additions and 48 deletions.
16 changes: 16 additions & 0 deletions client/app/admin/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client'
import React from "react";
import SideBar from "@/components/SideBar";
import { usePathname } from "next/navigation";

const AdminLayoutWrapper = ({ children }: { children: React.ReactNode }) => {
const pathname = usePathname();
return (
<div className="flex">
{!pathname.includes("/signin") && <SideBar />}
<main className="flex-1">{children}</main>
</div>
);
};

export default AdminLayoutWrapper;
33 changes: 27 additions & 6 deletions client/app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
'use server'
import React from 'react'

const page = () => {
return (
<div>page</div>
)
}
const Dashboard = () => {
return (
<div className="flex flex-1">
<div className="p-2 md:p-10 rounded-tl-2xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 flex flex-col gap-2 flex-1 w-full h-full">
<div className="flex gap-2">
{[...new Array(4)].map((i) => (
<div
key={"first-array" + i}
className="h-20 w-full rounded-lg bg-gray-100 dark:bg-neutral-800 animate-pulse"
></div>
))}
</div>
<div className="flex gap-2 flex-1">
{[...new Array(2)].map((i) => (
<div
key={"second-array" + i}
className="h-full w-full rounded-lg bg-gray-100 dark:bg-neutral-800 animate-pulse"
></div>
))}
</div>
</div>
</div>
);
};


export default page
export default Dashboard
10 changes: 5 additions & 5 deletions client/app/admin/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use server'
import SigninForm from "@/components/forms/admin/SigninForm";
import Image from "next/image";
import Link from "next/link";
const SignIn = ()=> {

const SignIn = () => {
return (
<div className="flex h-screen max-h-screen">
<section className="remove-scrollbar container my-auto">
Expand All @@ -17,7 +17,7 @@ const SignIn = ()=> {
<SigninForm />
<div className="text-14-regular mt-20 flex justify-between">
<p className="justify-items-end text-dark-600 xl:text-left">
© 2024 AVM Ayurveda&apos;s
© 2024 AVM Ayurveda&apos;s
</p>
<Link href={"/patient/signin"} className="text-green-500">
Patient
Expand All @@ -35,6 +35,6 @@ const SignIn = ()=> {
/>
</div>
);
}
};

export default SignIn
export default SignIn;
4 changes: 2 additions & 2 deletions client/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default function RootLayout({
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem
disableTransitionOnChange
// enableSystem
// disableTransitionOnChange
>
{children}
</ThemeProvider>
Expand Down
61 changes: 61 additions & 0 deletions client/components/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";
import React, { useState } from "react";
import { Sidebar, SidebarBody, SidebarLink } from "@/components/ui/sidebar";
import Link from "next/link";
import Image from "next/image";
import { AdminSideBarLinks } from "@/constants";

const SideBar= () =>{
const [open, setOpen] = useState(true);

return (
<div className="flex h-screen">
<Sidebar open={open} setOpen={setOpen} animate>
<SidebarBody className="justify-between gap-10 h-full">
<div className="flex flex-col flex-1 overflow-y-auto overflow-x-hidden">
<Logo />
<div className="mt-8 flex flex-col gap-2">
{AdminSideBarLinks.map((link, idx) => (
<SidebarLink key={idx} link={link} />
))}
</div>
</div>
<div>
<SidebarLink
link={{
label: "Manu Arora",
href: "#",
icon: (
<Image
src="/assets/images/admin.png"
className="h-7 w-7 flex-shrink-0 rounded-full"
width={50}
height={50}
alt="Avatar"
/>
),
}}
/>
</div>
</SidebarBody>
</Sidebar>

</div>
);
}

export const Logo = () => {
return (
<Link href="#" className="flex items-center space-x-2 py-2">
<Image
src={'/assets/icons/logo-icon.svg'}
alt="Logo"
width={30}
height={30}
/>
<span className="font-medium text-black dark:text-white">AVM Ayurveda</span>
</Link>
);
};

export default SideBar
34 changes: 0 additions & 34 deletions client/components/modles/OtpVerificationModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,37 +93,3 @@ const OtpVerificationModel = () => {

export default OtpVerificationModel;


// GET /patient/signin 200 in 354ms
// ✓ Compiled in 730ms (1527 modules)

// <--- Last few GCs --->

// [8600:0000023A945E0B90] 2025911 ms: Mark-Compact (reduce) 391.6 (410.8) -> 390.8 (410.0) MB, 448.11 / 0.00 ms (average mu = 0.899, current mu = 0.000) external memory pressure; GC in old space requested
// [8600:0000023A945E0B90] 2026075 ms: Scavenge 391.8 (410.0) -> 391.3 (411.0) MB, 5.93 / 0.00 ms (average mu = 0.899, current mu = 0.000) allocation failure;


// <--- JS stacktrace --->

// FATAL ERROR: NewSpace::EnsureCurrentCapacity Allocation failed - JavaScript heap out of memory
// 1: 00007FF7083A436F
// 2: 00007FF70831C686
// 3: 00007FF70831E471
// 4: 00007FF708D8B281
// 5: 00007FF708D74A18
// 6: 00007FF708BD60A0
// 7: 00007FF708BAF580
// 8: 00007FF708BDCCEA
// 9: 00007FF708BDF7AC
// 10: 00007FF708BD2DC0
// 11: 00007FF708BD0913
// 12: 00007FF708AD2682
// 13: 00007FF708D38BC4
// 14: 00007FF708D38351
// 15: 00007FF708D37DD0
// 16: 00007FF708E3C74E
// 17: 00007FF708DAB4C3
// 18: 00007FF708EC3A16
// 19: 00007FF708E2D7CF
// 20: 00007FF708DAB4C3
// 21: 00007FF68A4F4B64
189 changes: 189 additions & 0 deletions client/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
"use client";
import { cn } from "@/lib/utils";
import Link, { LinkProps } from "next/link";
import React, { useState, createContext, useContext } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { IconMenu2, IconX } from "@tabler/icons-react";

interface Links {
label: string;
href: string;
icon: React.JSX.Element | React.ReactNode;
}

interface SidebarContextProps {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
animate: boolean;
}

const SidebarContext = createContext<SidebarContextProps | undefined>(
undefined
);

export const useSidebar = () => {
const context = useContext(SidebarContext);
if (!context) {
throw new Error("useSidebar must be used within a SidebarProvider");
}
return context;
};

export const SidebarProvider = ({
children,
open: openProp,
setOpen: setOpenProp,
animate = true,
}: {
children: React.ReactNode;
open?: boolean;
setOpen?: React.Dispatch<React.SetStateAction<boolean>>;
animate?: boolean;
}) => {
const [openState, setOpenState] = useState(false);
const open = openProp !== undefined ? openProp : openState;
const setOpen = setOpenProp !== undefined ? setOpenProp : setOpenState;

return (
<SidebarContext.Provider value={{ open, setOpen, animate }}>
{children}
</SidebarContext.Provider>
);
};

export const Sidebar = ({
children,
open,
setOpen,
animate,
}: {
children: React.ReactNode;
open?: boolean;
setOpen?: React.Dispatch<React.SetStateAction<boolean>>;
animate?: boolean;
}) => {
return (
<SidebarProvider open={open} setOpen={setOpen} animate={animate}>
{children}
</SidebarProvider>
);
};

export const SidebarBody = (props: React.ComponentProps<typeof motion.div>) => {
return (
<>
<DesktopSidebar {...props} />
<MobileSidebar {...(props as React.ComponentProps<"div">)} />
</>
);
};

export const DesktopSidebar = ({
className,
children,
...props
}: React.ComponentProps<typeof motion.div>) => {
const { open, setOpen, animate } = useSidebar();
return (
<>
<motion.div
className={cn(
"h-full px-4 py-4 hidden md:flex md:flex-col bg-neutral-100 dark:bg-neutral-800 w-[300px] flex-shrink-0",
className
)}
animate={{
width: animate ? (open ? "300px" : "60px") : "300px",
}}
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
{...props}
>
{children}
</motion.div>
</>
);
};

export const MobileSidebar = ({
className,
children,
...props
}: React.ComponentProps<"div">) => {
const { open, setOpen } = useSidebar();
return (
<>
<div
className={cn(
"h-10 px-4 py-4 flex flex-row md:hidden items-center justify-between bg-neutral-100 dark:bg-neutral-800 w-full"
)}
{...props}
>
<div className="flex justify-end z-20 w-full">
<IconMenu2
className="text-neutral-800 dark:text-neutral-200"
onClick={() => setOpen(!open)}
/>
</div>
<AnimatePresence>
{open && (
<motion.div
initial={{ x: "-100%", opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: "-100%", opacity: 0 }}
transition={{
duration: 0.3,
ease: "easeInOut",
}}
className={cn(
"fixed h-full w-full inset-0 bg-white dark:bg-neutral-900 p-10 z-[100] flex flex-col justify-between",
className
)}
>
<div
className="absolute right-10 top-10 z-50 text-neutral-800 dark:text-neutral-200"
onClick={() => setOpen(!open)}
>
<IconX />
</div>
{children}
</motion.div>
)}
</AnimatePresence>
</div>
</>
);
};

export const SidebarLink = ({
link,
className,
...props
}: {
link: Links;
className?: string;
props?: LinkProps;
}) => {
const { open, animate } = useSidebar();
return (
<Link
href={link.href}
className={cn(
"flex items-center justify-start gap-2 group/sidebar py-2",
className
)}
{...props}
>
{link.icon}

<motion.span
animate={{
display: animate ? (open ? "inline-block" : "none") : "inline-block",
opacity: animate ? (open ? 1 : 0) : 1,
}}
className="text-neutral-700 dark:text-neutral-200 text-sm group-hover/sidebar:translate-x-1 transition duration-150 whitespace-pre inline-block !p-0 !m-0"
>
{link.label}
</motion.span>
</Link>
);
};
Loading

0 comments on commit bb9185d

Please sign in to comment.