tambahan menu mobile
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
"@mantine/core": "^7.16.2",
|
||||
"@mantine/hooks": "^7.16.2",
|
||||
"@prisma/client": "^6.3.1",
|
||||
"@tabler/icons-react": "^3.30.0",
|
||||
"@types/bun": "^1.2.2",
|
||||
"@types/lodash": "^4.17.15",
|
||||
"add": "^2.0.6",
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
import colors from "@/con/colors";
|
||||
import navbarListMenu from "@/con/navbar-list-menu";
|
||||
import stateNav from "@/state/state-nav";
|
||||
import { Box, Burger, Group } from "@mantine/core";
|
||||
import { ActionIcon, Box, Burger, Group, Stack, Text } from "@mantine/core";
|
||||
import { IconHome, IconSquareArrowRight } from "@tabler/icons-react";
|
||||
import { motion } from 'framer-motion';
|
||||
import { useSnapshot } from "valtio";
|
||||
import { MenuItem } from "../../types/menu-item";
|
||||
import { NavbarMainMenu } from "./NavbarMainMenu";
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
export function Navbar() {
|
||||
const { item, isSearch } = useSnapshot(stateNav);
|
||||
const { item, isSearch, mobileOpen } = useSnapshot(stateNav);
|
||||
const router = useRouter()
|
||||
return (
|
||||
<Box>
|
||||
<Box
|
||||
@@ -17,16 +22,54 @@ export function Navbar() {
|
||||
top={0}
|
||||
style={{
|
||||
zIndex: 100,
|
||||
overflow: "scroll"
|
||||
}}
|
||||
>
|
||||
<NavbarMainMenu listNavbar={navbarListMenu} />
|
||||
<Group justify="end">
|
||||
<Box hiddenFrom="sm">
|
||||
<Burger color={colors["blue-button"]} />
|
||||
</Box>
|
||||
</Group>
|
||||
<Stack hiddenFrom="sm" bg={colors.grey[2]}>
|
||||
<Group justify="space-between">
|
||||
<ActionIcon variant="transparent" onClick={() => {
|
||||
router.push("/")
|
||||
stateNav.mobileOpen = false
|
||||
}}>
|
||||
<IconHome />
|
||||
</ActionIcon>
|
||||
<Burger onClick={() => stateNav.mobileOpen = !stateNav.mobileOpen} color={colors["blue-button"]} opened={mobileOpen} />
|
||||
</Group>
|
||||
{mobileOpen && <motion.div
|
||||
initial={{ x: 300 }}
|
||||
animate={{ x: 0 }}
|
||||
transition={{ duration: 0.1 }}
|
||||
style={{
|
||||
height: "100vh",
|
||||
overflow: "scroll"
|
||||
}}
|
||||
>
|
||||
<NavbarMobile listNavbar={navbarListMenu} />
|
||||
</motion.div>}
|
||||
</Stack>
|
||||
</Box>
|
||||
{(item || isSearch) && <Box className="glass" />}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function NavbarMobile({ listNavbar }: { listNavbar: MenuItem[] }) {
|
||||
const router = useRouter()
|
||||
return <Stack p={"md"} style={{ backgroundColor: "rgba(255, 255, 255, 0.3)" }}>
|
||||
{listNavbar.map((item, k) => {
|
||||
return <Stack key={k}>
|
||||
<Group justify="space-between" onClick={() => {
|
||||
router.push(item.href)
|
||||
stateNav.mobileOpen = false
|
||||
}}>
|
||||
<Text c="dark.9"
|
||||
style={{ fontWeight: "bold" }}
|
||||
>{item.name}</Text>
|
||||
<IconSquareArrowRight />
|
||||
</Group>
|
||||
{item.children && <NavbarMobile listNavbar={item.children} />}
|
||||
</Stack>
|
||||
})}
|
||||
</Stack>
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import images from "@/con/images";
|
||||
import stateNav from "@/state/state-nav";
|
||||
import { Card, SimpleGrid } from "@mantine/core";
|
||||
import { Card, Image, SimpleGrid } from "@mantine/core";
|
||||
import { useHover } from "@mantine/hooks";
|
||||
import { useTransitionRouter } from 'next-view-transitions';
|
||||
import Image from 'next/image';
|
||||
|
||||
|
||||
const listImageModule = Object.values(images.module);
|
||||
@@ -27,12 +26,13 @@ function ModuleItem({ item }: { item: string }) {
|
||||
}}
|
||||
>
|
||||
<Image src={item} alt="icon"
|
||||
fill
|
||||
quality={10}
|
||||
objectFit="contain"
|
||||
objectPosition="center"
|
||||
priority={true}
|
||||
/>
|
||||
fit="contain"
|
||||
sizes="100%"
|
||||
style={{
|
||||
objectFit:"contain",
|
||||
objectPosition:"center"
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ import {
|
||||
Button,
|
||||
Card,
|
||||
Flex,
|
||||
Image,
|
||||
Stack,
|
||||
Text,
|
||||
Title
|
||||
} from "@mantine/core";
|
||||
import Image from 'next/image';
|
||||
import ModuleView from "./ModuleView";
|
||||
import SosmedView from "./SosmedView";
|
||||
|
||||
@@ -74,11 +74,7 @@ function Content1() {
|
||||
<Image
|
||||
src={"/assets/images/darmasaba-icon.png"}
|
||||
alt="icon"
|
||||
quality={10}
|
||||
priority={true}
|
||||
fill
|
||||
objectFit="contain"
|
||||
objectPosition="center"
|
||||
sizes="100%"
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
@@ -100,11 +96,8 @@ function Content1() {
|
||||
<Image
|
||||
src={"/assets/images/pudak-icon.png"}
|
||||
alt="icon"
|
||||
fill
|
||||
quality={10}
|
||||
priority={true}
|
||||
objectFit="contain"
|
||||
objectPosition="center"
|
||||
sizes={"100%"}
|
||||
fit="contain"
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -160,12 +153,8 @@ function Content1() {
|
||||
<Image
|
||||
src={"/assets/images/perbekel.png"}
|
||||
alt="perbekel"
|
||||
fill
|
||||
quality={70}
|
||||
objectFit="contain"
|
||||
objectPosition="bottom"
|
||||
placeholder="empty"
|
||||
priority={true}
|
||||
sizes="100%"
|
||||
fit="contain"
|
||||
/>
|
||||
<Box
|
||||
pos={"absolute"}
|
||||
|
||||
@@ -9,9 +9,12 @@ import {
|
||||
BackgroundImage,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Container,
|
||||
Divider,
|
||||
Group,
|
||||
Image,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
useMantineTheme,
|
||||
@@ -73,9 +76,14 @@ function Slider({ data }: { data: DataSlider[] }) {
|
||||
const autoplay = useRef(Autoplay({ delay: 2000 }));
|
||||
|
||||
const slides = data.map((item) => (
|
||||
<Carousel.Slide key={item.id}>
|
||||
<BackgroundImage src={images["bg-slide3"]} h={height} p="xl" radius="md">
|
||||
<Stack justify="space-between" h={"100%"} gap={0}>
|
||||
<Carousel.Slide key={item.id} >
|
||||
<Paper h={"100%"} pos={"relative"} style={{
|
||||
backgroundImage: `url(${images["bg-slide3"]}) `,
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
}}>
|
||||
<Stack justify="space-between" h={"100%"} gap={0} p={"lg"} pos={"relative"} >
|
||||
<Box p={"lg"}>
|
||||
<Text
|
||||
fw={"bold"}
|
||||
@@ -94,7 +102,7 @@ function Slider({ data }: { data: DataSlider[] }) {
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
</Paper>
|
||||
</Carousel.Slide>
|
||||
));
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ const colors = {
|
||||
}
|
||||
},
|
||||
"grey": {
|
||||
"1": "#F4F5F6"
|
||||
"1": "#F4F5F6",
|
||||
"2": "#CBCACD"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ const stateNav = proxy<{
|
||||
item: MenuItem[] | null
|
||||
isSearch: boolean,
|
||||
clear: () => void,
|
||||
module: string | null
|
||||
module: string | null,
|
||||
mobileOpen: boolean
|
||||
}>({
|
||||
hover: false,
|
||||
item: null,
|
||||
@@ -16,7 +17,8 @@ const stateNav = proxy<{
|
||||
stateNav.item = null
|
||||
stateNav.isSearch = false
|
||||
},
|
||||
module: null
|
||||
module: null,
|
||||
mobileOpen: false
|
||||
})
|
||||
|
||||
export default stateNav
|
||||
Reference in New Issue
Block a user