tambahan menu mobile

This commit is contained in:
bipproduction
2025-02-17 21:14:47 +08:00
parent 333f575693
commit b6dbd18b89
8 changed files with 83 additions and 39 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -17,6 +17,7 @@
"@mantine/core": "^7.16.2", "@mantine/core": "^7.16.2",
"@mantine/hooks": "^7.16.2", "@mantine/hooks": "^7.16.2",
"@prisma/client": "^6.3.1", "@prisma/client": "^6.3.1",
"@tabler/icons-react": "^3.30.0",
"@types/bun": "^1.2.2", "@types/bun": "^1.2.2",
"@types/lodash": "^4.17.15", "@types/lodash": "^4.17.15",
"add": "^2.0.6", "add": "^2.0.6",

View File

@@ -2,12 +2,17 @@
import colors from "@/con/colors"; import colors from "@/con/colors";
import navbarListMenu from "@/con/navbar-list-menu"; import navbarListMenu from "@/con/navbar-list-menu";
import stateNav from "@/state/state-nav"; 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 { useSnapshot } from "valtio";
import { MenuItem } from "../../types/menu-item";
import { NavbarMainMenu } from "./NavbarMainMenu"; import { NavbarMainMenu } from "./NavbarMainMenu";
import { useRouter } from 'next/navigation'
export function Navbar() { export function Navbar() {
const { item, isSearch } = useSnapshot(stateNav); const { item, isSearch, mobileOpen } = useSnapshot(stateNav);
const router = useRouter()
return ( return (
<Box> <Box>
<Box <Box
@@ -17,16 +22,54 @@ export function Navbar() {
top={0} top={0}
style={{ style={{
zIndex: 100, zIndex: 100,
overflow: "scroll"
}} }}
> >
<NavbarMainMenu listNavbar={navbarListMenu} /> <NavbarMainMenu listNavbar={navbarListMenu} />
<Group justify="end"> <Stack hiddenFrom="sm" bg={colors.grey[2]}>
<Box hiddenFrom="sm"> <Group justify="space-between">
<Burger color={colors["blue-button"]} /> <ActionIcon variant="transparent" onClick={() => {
</Box> router.push("/")
</Group> 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> </Box>
{(item || isSearch) && <Box className="glass" />} {(item || isSearch) && <Box className="glass" />}
</Box> </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>
}

View File

@@ -1,9 +1,8 @@
import images from "@/con/images"; import images from "@/con/images";
import stateNav from "@/state/state-nav"; 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 { useHover } from "@mantine/hooks";
import { useTransitionRouter } from 'next-view-transitions'; import { useTransitionRouter } from 'next-view-transitions';
import Image from 'next/image';
const listImageModule = Object.values(images.module); const listImageModule = Object.values(images.module);
@@ -27,12 +26,13 @@ function ModuleItem({ item }: { item: string }) {
}} }}
> >
<Image src={item} alt="icon" <Image src={item} alt="icon"
fill fit="contain"
quality={10} sizes="100%"
objectFit="contain" style={{
objectPosition="center" objectFit:"contain",
priority={true} objectPosition:"center"
/> }}
/>
</Card> </Card>
); );
} }

View File

@@ -5,11 +5,11 @@ import {
Button, Button,
Card, Card,
Flex, Flex,
Image,
Stack, Stack,
Text, Text,
Title Title
} from "@mantine/core"; } from "@mantine/core";
import Image from 'next/image';
import ModuleView from "./ModuleView"; import ModuleView from "./ModuleView";
import SosmedView from "./SosmedView"; import SosmedView from "./SosmedView";
@@ -74,11 +74,7 @@ function Content1() {
<Image <Image
src={"/assets/images/darmasaba-icon.png"} src={"/assets/images/darmasaba-icon.png"}
alt="icon" alt="icon"
quality={10} sizes="100%"
priority={true}
fill
objectFit="contain"
objectPosition="center"
/> />
</Box> </Box>
<Box <Box
@@ -100,11 +96,8 @@ function Content1() {
<Image <Image
src={"/assets/images/pudak-icon.png"} src={"/assets/images/pudak-icon.png"}
alt="icon" alt="icon"
fill sizes={"100%"}
quality={10} fit="contain"
priority={true}
objectFit="contain"
objectPosition="center"
/> />
</Box> </Box>
</Flex> </Flex>
@@ -160,12 +153,8 @@ function Content1() {
<Image <Image
src={"/assets/images/perbekel.png"} src={"/assets/images/perbekel.png"}
alt="perbekel" alt="perbekel"
fill sizes="100%"
quality={70} fit="contain"
objectFit="contain"
objectPosition="bottom"
placeholder="empty"
priority={true}
/> />
<Box <Box
pos={"absolute"} pos={"absolute"}

View File

@@ -9,9 +9,12 @@ import {
BackgroundImage, BackgroundImage,
Box, Box,
Button, Button,
Card,
Container, Container,
Divider, Divider,
Group, Group,
Image,
Paper,
Stack, Stack,
Text, Text,
useMantineTheme, useMantineTheme,
@@ -73,9 +76,14 @@ function Slider({ data }: { data: DataSlider[] }) {
const autoplay = useRef(Autoplay({ delay: 2000 })); const autoplay = useRef(Autoplay({ delay: 2000 }));
const slides = data.map((item) => ( const slides = data.map((item) => (
<Carousel.Slide key={item.id}> <Carousel.Slide key={item.id} >
<BackgroundImage src={images["bg-slide3"]} h={height} p="xl" radius="md"> <Paper h={"100%"} pos={"relative"} style={{
<Stack justify="space-between" h={"100%"} gap={0}> 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"}> <Box p={"lg"}>
<Text <Text
fw={"bold"} fw={"bold"}
@@ -94,7 +102,7 @@ function Slider({ data }: { data: DataSlider[] }) {
</Button> </Button>
</Group> </Group>
</Stack> </Stack>
</BackgroundImage> </Paper>
</Carousel.Slide> </Carousel.Slide>
)); ));

View File

@@ -12,7 +12,8 @@ const colors = {
} }
}, },
"grey": { "grey": {
"1": "#F4F5F6" "1": "#F4F5F6",
"2": "#CBCACD"
} }
} }

View File

@@ -6,7 +6,8 @@ const stateNav = proxy<{
item: MenuItem[] | null item: MenuItem[] | null
isSearch: boolean, isSearch: boolean,
clear: () => void, clear: () => void,
module: string | null module: string | null,
mobileOpen: boolean
}>({ }>({
hover: false, hover: false,
item: null, item: null,
@@ -16,7 +17,8 @@ const stateNav = proxy<{
stateNav.item = null stateNav.item = null
stateNav.isSearch = false stateNav.isSearch = false
}, },
module: null module: null,
mobileOpen: false
}) })
export default stateNav export default stateNav