fix admin
deskripsi: - ui layout admin - navbar & header responsive
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
|||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Title
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import {
|
import {
|
||||||
IconBell,
|
IconBell,
|
||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
IconLogout,
|
IconLogout,
|
||||||
IconReplaceUser,
|
IconReplaceUser,
|
||||||
IconUser,
|
IconUser,
|
||||||
IconUserCircle
|
IconUserCircle,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -30,12 +30,24 @@ import { Admin_ComponentModal } from "../_admin_global/_component/comp_admin_mod
|
|||||||
|
|
||||||
export function Admin_V3_ComponentButtonUserCircle({
|
export function Admin_V3_ComponentButtonUserCircle({
|
||||||
dataUser,
|
dataUser,
|
||||||
|
openPop,
|
||||||
|
setOpenPop,
|
||||||
|
setNavbarOpen,
|
||||||
|
setDrawerNotifikasi,
|
||||||
}: {
|
}: {
|
||||||
dataUser: MODEL_USER | null;
|
dataUser: MODEL_USER | null;
|
||||||
|
openPop: boolean;
|
||||||
|
setOpenPop: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
// setOpenPop: (open: boolean) => void;
|
||||||
|
setNavbarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
// setNavbarOpen: (open: boolean) => void;
|
||||||
|
setDrawerNotifikasi: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
// setDrawerNotifikasi: (open: boolean) => void;
|
||||||
|
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [isOpenMenuUser, setOpenMenuUser] = useState(false);
|
const [isOpenMenuUser, setOpenMenuUser] = useState(false);
|
||||||
const [openPop, setOpenPop] = useState(false);
|
// const [openPop, setOpenPop] = useState(false);
|
||||||
const [openModalLogout, setOpenModalLogout] = useState(false);
|
const [openModalLogout, setOpenModalLogout] = useState(false);
|
||||||
const [openModalReplaceUser, setOpenModalReplaceUser] = useState(false);
|
const [openModalReplaceUser, setOpenModalReplaceUser] = useState(false);
|
||||||
const [loadingLogout, setLoadingLogout] = useState(false);
|
const [loadingLogout, setLoadingLogout] = useState(false);
|
||||||
@@ -62,7 +74,7 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
icon: IconBell,
|
icon: IconBell,
|
||||||
label: "Notifikasi",
|
label: "Notifikasi",
|
||||||
color: "",
|
color: "",
|
||||||
onClick: () => console.log("Notifikasi"),
|
onClick: () => setDrawerNotifikasi(true),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: IconReplaceUser,
|
icon: IconReplaceUser,
|
||||||
@@ -100,6 +112,7 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
variant="transparent"
|
variant="transparent"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenPop((o) => !o);
|
setOpenPop((o) => !o);
|
||||||
|
setNavbarOpen(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconUserCircle color={dataUser ? "white" : "gray"} />
|
<IconUserCircle color={dataUser ? "white" : "gray"} />
|
||||||
@@ -131,58 +144,10 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
</Center>
|
</Center>
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
|
|
||||||
{/* <SimpleGrid cols={2}>
|
|
||||||
<Button
|
|
||||||
radius={"xl"}
|
|
||||||
onClick={() => router.push("/dev/home", { scroll: false })}
|
|
||||||
>
|
|
||||||
User Access
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
radius={"xl"}
|
|
||||||
color="red"
|
|
||||||
onClick={() => setOpenModal(true)}
|
|
||||||
>
|
|
||||||
Keluar
|
|
||||||
</Button>
|
|
||||||
</SimpleGrid> */}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Popover.Dropdown>
|
</Popover.Dropdown>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
||||||
{/* <Modal
|
|
||||||
opened={openModal}
|
|
||||||
onClose={() => setOpenModal(false)}
|
|
||||||
centered
|
|
||||||
withCloseButton={false}
|
|
||||||
closeOnClickOutside={false}
|
|
||||||
>
|
|
||||||
<Stack>
|
|
||||||
<Title order={6}>Anda yakin ingin keluar ?</Title>
|
|
||||||
<Group align="center" position="center">
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setOpenModal(false);
|
|
||||||
}}
|
|
||||||
radius={50}
|
|
||||||
>
|
|
||||||
Batal
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
loaderPosition="center"
|
|
||||||
loading={loadingLogout ? true : false}
|
|
||||||
radius={50}
|
|
||||||
bg={Warna.merah}
|
|
||||||
color="red"
|
|
||||||
onClick={() => onClickLogout()}
|
|
||||||
>
|
|
||||||
Keluar
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
</Stack>
|
|
||||||
</Modal> */}
|
|
||||||
|
|
||||||
<Admin_ComponentModal
|
<Admin_ComponentModal
|
||||||
opened={openModalLogout}
|
opened={openModalLogout}
|
||||||
onClose={() => setOpenModalLogout(false)}
|
onClose={() => setOpenModalLogout(false)}
|
||||||
@@ -205,7 +170,7 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
loaderPosition="center"
|
loaderPosition="center"
|
||||||
loading={loadingLogout ? true : false}
|
loading={loadingLogout}
|
||||||
radius={50}
|
radius={50}
|
||||||
bg={Warna.merah}
|
bg={Warna.merah}
|
||||||
color="red"
|
color="red"
|
||||||
@@ -225,7 +190,7 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
>
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Title order={5} c={AccentColor.white}>
|
<Title order={5} c={AccentColor.white}>
|
||||||
Anda yakin ingin keluar ?
|
Anda yakin ingin pindah ke tampilan user ?
|
||||||
</Title>
|
</Title>
|
||||||
<Group align="center" position="center">
|
<Group align="center" position="center">
|
||||||
<Button
|
<Button
|
||||||
@@ -239,15 +204,16 @@ export function Admin_V3_ComponentButtonUserCircle({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
loaderPosition="center"
|
loaderPosition="center"
|
||||||
loading={loadingLogout ? true : false}
|
loading={loadingReplaceUser}
|
||||||
radius={50}
|
radius={50}
|
||||||
bg={AccentColor.softblue}
|
bg={AccentColor.softblue}
|
||||||
color="blue"
|
color="blue"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
router.push("/dev/home", { scroll: false });
|
router.push("/dev/home", { scroll: false });
|
||||||
|
setLoadingReplaceUser(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
User Akses
|
Ke Tampilan User
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
AppShell,
|
AppShell,
|
||||||
Burger,
|
Burger,
|
||||||
Divider,
|
Divider,
|
||||||
|
Drawer,
|
||||||
Group,
|
Group,
|
||||||
Header,
|
Header,
|
||||||
MediaQuery,
|
MediaQuery,
|
||||||
@@ -16,7 +17,7 @@ import {
|
|||||||
ScrollArea,
|
ScrollArea,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
useMantineTheme
|
useMantineTheme,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||||
import {
|
import {
|
||||||
@@ -24,20 +25,19 @@ import {
|
|||||||
IconCoin,
|
IconCoin,
|
||||||
IconHome,
|
IconHome,
|
||||||
IconMessage,
|
IconMessage,
|
||||||
IconUser
|
IconUser,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { usePathname, useRouter } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import { Admin_UiNavbar } from "../_admin_global";
|
||||||
Admin_UiNavbar
|
|
||||||
} from "../_admin_global";
|
|
||||||
import {
|
import {
|
||||||
gs_admin_navbar_menu,
|
gs_admin_navbar_menu,
|
||||||
gs_admin_navbar_subMenu,
|
gs_admin_navbar_subMenu,
|
||||||
} from "../_admin_global/new_global_state";
|
} from "../_admin_global/new_global_state";
|
||||||
import { Admin_V3_ComponentButtonUserCircle } from "./comp_button_user_circle";
|
import { Admin_V3_ComponentButtonUserCircle } from "./comp_button_user_circle";
|
||||||
|
import { Admin_V3_SkeletonNavbar } from "./skeleton_navbar";
|
||||||
|
|
||||||
export function Admin_V3_MainLayout({
|
export function Admin_V3_MainLayout({
|
||||||
children,
|
children,
|
||||||
@@ -52,7 +52,6 @@ export function Admin_V3_MainLayout({
|
|||||||
listNotifikasi: MODEL_NOTIFIKASI[];
|
listNotifikasi: MODEL_NOTIFIKASI[];
|
||||||
version: string;
|
version: string;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
|
||||||
const [dataUser, setDataUser] = useState<MODEL_USER | null>(null);
|
const [dataUser, setDataUser] = useState<MODEL_USER | null>(null);
|
||||||
const userRoleId = dataUser?.masterUserRoleId;
|
const userRoleId = dataUser?.masterUserRoleId;
|
||||||
const [activeId, setActiveId] = useAtom(gs_admin_navbar_menu);
|
const [activeId, setActiveId] = useAtom(gs_admin_navbar_menu);
|
||||||
@@ -61,7 +60,6 @@ export function Admin_V3_MainLayout({
|
|||||||
useState<MODEL_NOTIFIKASI[]>(listNotifikasi);
|
useState<MODEL_NOTIFIKASI[]>(listNotifikasi);
|
||||||
|
|
||||||
// Notifikasi
|
// Notifikasi
|
||||||
const [isDrawerNotifikasi, setDrawerNotifikasi] = useState(false);
|
|
||||||
const [countNtf, setCountNtf] = useState(countNotifikasi);
|
const [countNtf, setCountNtf] = useState(countNotifikasi);
|
||||||
const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf);
|
const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf);
|
||||||
|
|
||||||
@@ -82,11 +80,27 @@ export function Admin_V3_MainLayout({
|
|||||||
console.error("Error fetching user data", error);
|
console.error("Error fetching user data", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const [openPop, setOpenPop] = useState(false);
|
||||||
|
const [opened, handlers] = useDisclosure(false);
|
||||||
|
const [openedDrawer, handlersDrawer] = useDisclosure(false);
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
const [opened, { toggle, close }] = useDisclosure(false);
|
const navLinks = [
|
||||||
|
{ icon: IconHome, label: "Home", path: "/" },
|
||||||
|
{ icon: IconBriefcase, label: "Portfolio", path: "/portfolio" },
|
||||||
|
{ icon: IconUser, label: "About Me", path: "/about" },
|
||||||
|
{ icon: IconCoin, label: "Price List", path: "/pricing" },
|
||||||
|
{ icon: IconMessage, label: "Contact", path: "/contact" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const isActive = (path: string) => {
|
||||||
|
if (path === "/" && pathname === "/") return true;
|
||||||
|
if (path !== "/" && pathname.startsWith(path)) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<AppShell
|
<AppShell
|
||||||
bg={MainColor.darkblue}
|
bg={MainColor.darkblue}
|
||||||
padding={"md"}
|
padding={"md"}
|
||||||
@@ -108,6 +122,9 @@ export function Admin_V3_MainLayout({
|
|||||||
style={{ color: "white", transition: "1s" }}
|
style={{ color: "white", transition: "1s" }}
|
||||||
>
|
>
|
||||||
<Stack style={{ color: "white" }} mb={"lg"}>
|
<Stack style={{ color: "white" }} mb={"lg"}>
|
||||||
|
{!dataUser ? (
|
||||||
|
<Admin_V3_SkeletonNavbar />
|
||||||
|
) : (
|
||||||
<Admin_UiNavbar
|
<Admin_UiNavbar
|
||||||
userRoleId={userRoleId as any}
|
userRoleId={userRoleId as any}
|
||||||
activeId={activeId as any}
|
activeId={activeId as any}
|
||||||
@@ -115,6 +132,7 @@ export function Admin_V3_MainLayout({
|
|||||||
setActiveId={setActiveId}
|
setActiveId={setActiveId}
|
||||||
setActiveChildId={setActiveChildId}
|
setActiveChildId={setActiveChildId}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Navbar.Section>
|
</Navbar.Section>
|
||||||
|
|
||||||
@@ -163,36 +181,16 @@ export function Admin_V3_MainLayout({
|
|||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box> */}
|
</Box> */}
|
||||||
|
|
||||||
{/* <Box mt="auto">
|
|
||||||
<Divider my="sm" />
|
|
||||||
<Group position="center" mt="md">
|
|
||||||
<ThemeIcon size={36} radius="xl" color="blue">
|
|
||||||
<IconBrandGithub size={18} />
|
|
||||||
</ThemeIcon>
|
|
||||||
<ThemeIcon size={36} radius="xl" color="blue">
|
|
||||||
<IconBrandLinkedin size={18} />
|
|
||||||
</ThemeIcon>
|
|
||||||
<ThemeIcon size={36} radius="xl" color="blue">
|
|
||||||
<IconMail size={18} />
|
|
||||||
</ThemeIcon>
|
|
||||||
</Group>
|
|
||||||
</Box> */}
|
|
||||||
</Navbar>
|
</Navbar>
|
||||||
}
|
}
|
||||||
header={
|
header={
|
||||||
<Header
|
<Header height={"7vh"} px="md" bg={AccentColor.darkblue}>
|
||||||
height={"7vh"}
|
|
||||||
px="md"
|
|
||||||
bg={AccentColor.darkblue}
|
|
||||||
// style={{ border: "none" }}
|
|
||||||
>
|
|
||||||
<Group style={{ height: "100%" }} position="apart">
|
<Group style={{ height: "100%" }} position="apart">
|
||||||
<MediaQuery largerThan="md" styles={{ display: "none" }}>
|
<MediaQuery largerThan="md" styles={{ display: "none" }}>
|
||||||
<Burger
|
<Burger
|
||||||
disabled={!dataUser}
|
disabled={!dataUser}
|
||||||
opened={opened}
|
opened={opened}
|
||||||
onClick={toggle}
|
onClick={handlers.toggle}
|
||||||
size="sm"
|
size="sm"
|
||||||
color={!dataUser ? "gray" : AccentColor.white}
|
color={!dataUser ? "gray" : AccentColor.white}
|
||||||
/>
|
/>
|
||||||
@@ -202,12 +200,66 @@ export function Admin_V3_MainLayout({
|
|||||||
HIMPI DASHBOARD
|
HIMPI DASHBOARD
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Admin_V3_ComponentButtonUserCircle dataUser={dataUser as any} />
|
<Admin_V3_ComponentButtonUserCircle
|
||||||
|
dataUser={dataUser as any}
|
||||||
|
openPop={openPop}
|
||||||
|
setOpenPop={setOpenPop}
|
||||||
|
setNavbarOpen={handlers.close}
|
||||||
|
setDrawerNotifikasi={handlersDrawer.toggle}
|
||||||
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Header>
|
</Header>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AppShell>
|
</AppShell>
|
||||||
|
|
||||||
|
<Drawer
|
||||||
|
styles={{
|
||||||
|
content: {
|
||||||
|
backgroundColor: AccentColor.blue,
|
||||||
|
color: AccentColor.white,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
backgroundColor: AccentColor.darkblue,
|
||||||
|
color: AccentColor.white,
|
||||||
|
},
|
||||||
|
close: {
|
||||||
|
color: AccentColor.white,
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: AccentColor.blue,
|
||||||
|
color: AccentColor.white,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
<Group position="apart">
|
||||||
|
<Text fw={"bold"} fz={"lg"}>
|
||||||
|
Notifikasi
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
opened={openedDrawer}
|
||||||
|
onClose={handlersDrawer.toggle}
|
||||||
|
position="right"
|
||||||
|
size={"sm"}
|
||||||
|
>
|
||||||
|
On Maintenance . . .
|
||||||
|
{/* <ComponentAdmin_UIDrawerNotifikasi
|
||||||
|
newAdminNtf={newAdminNtf}
|
||||||
|
listNotifikasi={dataNotifikasi}
|
||||||
|
onChangeNavbar={(val: { id: string; childId: string }) => {
|
||||||
|
setActiveId(val.id as any);
|
||||||
|
setActiveChildId(val.childId);
|
||||||
|
}}
|
||||||
|
onToggleNavbar={(val: any) => {
|
||||||
|
setDrawerNotifikasi(val);
|
||||||
|
}}
|
||||||
|
onLoadCountNotif={(val: any) => {
|
||||||
|
setCountNtf(val);
|
||||||
|
}}
|
||||||
|
/> */}
|
||||||
|
</Drawer>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/app_modules/admin/_components_v3/skeleton_navbar.tsx
Normal file
32
src/app_modules/admin/_components_v3/skeleton_navbar.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { Box, NavLink, Text } from "@mantine/core";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { newListAdminPage } from "../new_list_page";
|
||||||
|
|
||||||
|
export function Admin_V3_SkeletonNavbar() {
|
||||||
|
const listPage = newListAdminPage.slice(0, -1);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{listPage.map((parent) => (
|
||||||
|
<Box key={parent.id}>
|
||||||
|
<NavLink
|
||||||
|
disabled
|
||||||
|
style={{
|
||||||
|
color: "gray",
|
||||||
|
transition: "0.5s",
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
":hover": {
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
label={<Text>{parent.name}</Text>}
|
||||||
|
icon={parent.icon}
|
||||||
|
>
|
||||||
|
{!_.isEmpty(parent.child) &&
|
||||||
|
parent.child.map((child) => <Box key={child.id} />)}
|
||||||
|
</NavLink>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -16,18 +16,15 @@ export default function AdminMain() {
|
|||||||
const [countUser, setCountUser] = useState<number | null>(null);
|
const [countUser, setCountUser] = useState<number | null>(null);
|
||||||
const [countPortofolio, setCountPortofolio] = useState<number | null>(null);
|
const [countPortofolio, setCountPortofolio] = useState<number | null>(null);
|
||||||
|
|
||||||
// useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
// onLoadDataUser();
|
onLoadDataUser();
|
||||||
// onLoadDataPortofolio();
|
onLoadDataPortofolio();
|
||||||
// }, []);
|
}, []);
|
||||||
|
|
||||||
async function onLoadDataUser() {
|
async function onLoadDataUser() {
|
||||||
try {
|
try {
|
||||||
const response = await apiGetCountUserActive();
|
const response = await apiGetCountUserActive();
|
||||||
if (response) {
|
if (response) {
|
||||||
// console.log(response.data);
|
|
||||||
// console.log(typeof response.data);
|
|
||||||
// console.log( response);
|
|
||||||
setCountUser(response.data);
|
setCountUser(response.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user