Revisi QC Kak Inno tanggal 20
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
import { IconKey, IconMapper } from '@/app/admin/(dashboard)/_com/iconMap';
|
||||||
import programKreatifState from '@/app/admin/(dashboard)/_state/inovasi/program-kreatif';
|
import programKreatifState from '@/app/admin/(dashboard)/_state/inovasi/program-kreatif';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
import { Box, Button, Center, Grid, GridCol, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
|
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { IconSearch } from '@tabler/icons-react';
|
||||||
import { useTransitionRouter } from 'next-view-transitions';
|
import { useTransitionRouter } from 'next-view-transitions';
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
import { IconSearch } from '@tabler/icons-react';
|
|
||||||
import { IconKey, IconMapper } from '@/app/admin/(dashboard)/_com/iconMap';
|
|
||||||
|
|
||||||
// const data = [
|
// const data = [
|
||||||
// {
|
// {
|
||||||
@@ -75,17 +75,23 @@ function Page() {
|
|||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: 'md', md: 100 }} >
|
<Box px={{ base: 'md', md: 100 }} >
|
||||||
<Group justify="space-between" mb="md" align='center'>
|
<Grid align='center'>
|
||||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
<GridCol span={{ base: 12, md: 9 }}>
|
||||||
Program Kreatif Desa
|
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||||
</Text>
|
Program Kreatif Desa
|
||||||
<TextInput
|
</Text>
|
||||||
placeholder="Cari program kreatif..."
|
</GridCol>
|
||||||
leftSection={<IconSearch size={20} />}
|
<GridCol span={{ base: 12, md: 3 }}>
|
||||||
value={search}
|
<TextInput
|
||||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
radius={"lg"}
|
||||||
/>
|
placeholder='Cari Program Kreatif'
|
||||||
</Group>
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w={{ base: "50%", md: "100%" }}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
<Stack gap={'lg'} justify='center'>
|
<Stack gap={'lg'} justify='center'>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
|
import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
|
||||||
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
|
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { ActionIcon, Anchor, AspectRatio, Badge, Box, Button, Card, Chip, CopyButton, Divider, Grid, Group, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, ThemeIcon, Title, Tooltip } from '@mantine/core';
|
import { ActionIcon, AspectRatio, Badge, Box, Button, Card, CopyButton, Divider, Grid, Group, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, ThemeIcon, Title, Tooltip } from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconBrandWhatsapp, IconCheck, IconCopy, IconDeviceLandlinePhone, IconHeart, IconInfoCircle, IconMail, IconMapPin, IconMoodEmpty, IconSearch, IconStethoscope, IconUser, IconUsersGroup, IconWallet } from '@tabler/icons-react';
|
import { IconBrandWhatsapp, IconCheck, IconCopy, IconDeviceLandlinePhone, IconHeart, IconInfoCircle, IconMail, IconMapPin, IconMoodEmpty, IconSearch, IconUser } from '@tabler/icons-react';
|
||||||
import { useParams } from 'next/navigation';
|
import { useParams } from 'next/navigation';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
@@ -149,11 +149,6 @@ function Page() {
|
|||||||
</CopyButton>
|
</CopyButton>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Group gap="xs" mt="sm" wrap="wrap">
|
|
||||||
<Chip defaultChecked radius="xl" variant="light" icon={<IconStethoscope size={16} />}>Layanan Medis</Chip>
|
|
||||||
<Chip radius="xl" variant="light" icon={<IconUsersGroup size={16} />}>Ramah Keluarga</Chip>
|
|
||||||
<Chip radius="xl" variant="light" icon={<IconWallet size={16} />}>Pembayaran Non-Tunai</Chip>
|
|
||||||
</Group>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -210,7 +205,6 @@ function Page() {
|
|||||||
<Button variant="light" leftSection={<IconBrandWhatsapp size={18} />} component="a" href={`https://wa.me/${kontak.whatsapp.replace(/\D/g, '')}`} target="_blank" aria-label="Hubungi WhatsApp">WhatsApp</Button>
|
<Button variant="light" leftSection={<IconBrandWhatsapp size={18} />} component="a" href={`https://wa.me/${kontak.whatsapp.replace(/\D/g, '')}`} target="_blank" aria-label="Hubungi WhatsApp">WhatsApp</Button>
|
||||||
<Button variant="light" leftSection={<IconMail size={18} />} component="a" href={`mailto:${kontak.email}`} aria-label="Kirim Email">Email</Button>
|
<Button variant="light" leftSection={<IconMail size={18} />} component="a" href={`mailto:${kontak.email}`} aria-label="Kirim Email">Email</Button>
|
||||||
</Group>
|
</Group>
|
||||||
<Anchor target="_blank" underline="hover">Kunjungi situs resmi</Anchor>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -108,20 +108,23 @@ function Page() {
|
|||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
aspectRatio: '16/9',
|
height: 180, // 🔥 tinggi fix biar semua seragam
|
||||||
borderRadius: '12px',
|
borderRadius: 12,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
backgroundColor: '#f0f2f5', // fallback kalau gambar loading
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={v.image.link}
|
src={v.image?.link || '/img/default.png'}
|
||||||
alt={v.name}
|
alt={v.name}
|
||||||
fit="cover"
|
fit="cover"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
objectFit: 'cover',
|
||||||
height: '100%',
|
objectPosition: 'center',
|
||||||
transition: 'transform 0.4s ease',
|
transition: 'transform 0.4s ease',
|
||||||
}}
|
}}
|
||||||
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
|
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
|
||||||
@@ -129,6 +132,7 @@ function Page() {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
</Center>
|
</Center>
|
||||||
<Stack gap={4} w="100%">
|
<Stack gap={4} w="100%">
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -233,21 +233,42 @@ function StrukturOrganisasiPPID() {
|
|||||||
return (
|
return (
|
||||||
<Stack align="center" mt="xl">
|
<Stack align="center" mt="xl">
|
||||||
{/* 🔍 Search + Zoom + Fullscreen controls */}
|
{/* 🔍 Search + Zoom + Fullscreen controls */}
|
||||||
<Group mb="md" justify="center" gap="sm">
|
<Group mb="md" justify="center" gap="sm" align="center">
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder="Cari nama atau jabatan..."
|
placeholder="Cari nama atau jabatan..."
|
||||||
leftSection={<IconSearch size={16} />}
|
leftSection={<IconSearch size={16} />}
|
||||||
onChange={(e) => debouncedSearch(e.target.value)}
|
onChange={(e) => debouncedSearch(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button variant="light" size="sm" onClick={handleZoomOut}>
|
<Button variant="light" size="sm" onClick={handleZoomOut}>
|
||||||
<IconZoomOut size={16} />
|
<IconZoomOut size={16} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="light" size="sm" onClick={resetZoom}>
|
|
||||||
100%
|
{/* 🔍 Tambahkan indikator zoom di sini */}
|
||||||
</Button>
|
{/* Floating Zoom Indicator */}
|
||||||
|
<Box
|
||||||
|
bg="#C3D0E8"
|
||||||
|
c="blue"
|
||||||
|
px={9}
|
||||||
|
py={8}
|
||||||
|
style={{
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 600,
|
||||||
|
borderRadius: '5px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Math.round(scale * 100)}%
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
<Button variant="light" size="sm" onClick={handleZoomIn}>
|
<Button variant="light" size="sm" onClick={handleZoomIn}>
|
||||||
<IconZoomIn size={16} />
|
<IconZoomIn size={16} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
<Button variant="light" size="sm" onClick={resetZoom}>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="light"
|
variant="light"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -260,6 +281,7 @@ function StrukturOrganisasiPPID() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
|
|
||||||
{/* Chart Container */}
|
{/* Chart Container */}
|
||||||
<Box
|
<Box
|
||||||
ref={chartContainerRef}
|
ref={chartContainerRef}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import penghargaanState from "@/app/admin/(dashboard)/_state/desa/penghargaan";
|
import penghargaanState from "@/app/admin/(dashboard)/_state/desa/penghargaan";
|
||||||
import colors from "@/con/colors";
|
import colors from "@/con/colors";
|
||||||
import { Carousel, CarouselSlide } from "@mantine/carousel";
|
import { Carousel } from "@mantine/carousel";
|
||||||
import { Box, Button, Container, Group, Paper, Stack, Text, useMantineTheme, Skeleton } from "@mantine/core";
|
import { Box, Button, Container, Group, Paper, Skeleton, Stack, Text, useMantineTheme } from "@mantine/core";
|
||||||
import { useMediaQuery } from "@mantine/hooks";
|
import { useMediaQuery } from "@mantine/hooks";
|
||||||
|
import { IconArrowRight, IconAward } from "@tabler/icons-react";
|
||||||
import Autoplay from "embla-carousel-autoplay";
|
import Autoplay from "embla-carousel-autoplay";
|
||||||
import { IconAward, IconArrowRight } from "@tabler/icons-react";
|
|
||||||
import { useTransitionRouter } from "next-view-transitions";
|
import { useTransitionRouter } from "next-view-transitions";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { useProxy } from "valtio/utils";
|
import { useProxy } from "valtio/utils";
|
||||||
@@ -18,7 +18,8 @@ export default function Page() {
|
|||||||
<Box px={{ base: "md", md: 100 }}>
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Container w={{ base: "100%", md: "60%" }}>
|
<Container w={{ base: "100%", md: "90%", lg: "60%" }}>
|
||||||
|
|
||||||
<Stack align="center" gap="sm">
|
<Stack align="center" gap="sm">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<IconAward size={40} color={colors["blue-button"]} />
|
<IconAward size={40} color={colors["blue-button"]} />
|
||||||
@@ -37,11 +38,10 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Slider() {
|
function Slider() {
|
||||||
const height = 500;
|
|
||||||
const width = 1200;
|
|
||||||
const theme = useMantineTheme();
|
const theme = useMantineTheme();
|
||||||
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
|
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
|
||||||
const autoplay = useRef(Autoplay({ delay: 3000 }));
|
const tablet = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
|
||||||
|
const autoplay = useRef(Autoplay({ delay: 3000, stopOnInteraction: false }));
|
||||||
const state = useProxy(penghargaanState);
|
const state = useProxy(penghargaanState);
|
||||||
const router = useTransitionRouter();
|
const router = useTransitionRouter();
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ function Slider() {
|
|||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<Group justify="center" py="xl">
|
<Group justify="center" py="xl" gap="md">
|
||||||
<Skeleton w={300} h={200} radius="lg" />
|
<Skeleton w={300} h={200} radius="lg" />
|
||||||
<Skeleton w={300} h={200} radius="lg" visibleFrom="sm" />
|
<Skeleton w={300} h={200} radius="lg" visibleFrom="sm" />
|
||||||
<Skeleton w={300} h={200} radius="lg" visibleFrom="md" />
|
<Skeleton w={300} h={200} radius="lg" visibleFrom="md" />
|
||||||
@@ -74,31 +74,49 @@ function Slider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const slides = data.map((item) => (
|
const slides = data.map((item) => (
|
||||||
<CarouselSlide key={item.id}>
|
<Carousel.Slide key={item.id}>
|
||||||
<Paper
|
<Paper
|
||||||
h="100%"
|
|
||||||
radius="lg"
|
radius="lg"
|
||||||
shadow="md"
|
shadow="md"
|
||||||
pos="relative"
|
pos="relative"
|
||||||
style={{
|
style={{
|
||||||
|
height: "100%",
|
||||||
backgroundImage: `url(${item.image?.link})`,
|
backgroundImage: `url(${item.image?.link})`,
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
|
transition: "transform 0.3s ease, box-shadow 0.3s ease",
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.currentTarget.style.transform = "translateY(-4px)";
|
||||||
|
e.currentTarget.style.boxShadow = "0 8px 20px rgba(0,0,0,0.2)";
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.transform = "translateY(0)";
|
||||||
|
e.currentTarget.style.boxShadow = "none";
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
pos="absolute"
|
pos="absolute"
|
||||||
inset={0}
|
inset={0}
|
||||||
bg="linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0.3))"
|
bg="linear-gradient(to top, rgba(0,0,0,0.8), rgba(0,0,0,0.2))"
|
||||||
style={{ borderRadius: 16 }}
|
style={{ borderRadius: 16 }}
|
||||||
/>
|
/>
|
||||||
<Stack justify="flex-end" h="100%" gap="sm" p="lg" pos="relative">
|
<Stack justify="flex-end" h="100%" gap="sm" p="lg" pos="relative">
|
||||||
<Text fz="xl" fw={700} ta="center" c="white">
|
<Text
|
||||||
|
fz={{ base: "md", sm: "lg", md: "xl" }}
|
||||||
|
fw={700}
|
||||||
|
ta="center"
|
||||||
|
c="white"
|
||||||
|
lineClamp={3}
|
||||||
|
style={{ textShadow: "0 2px 4px rgba(0,0,0,0.6)" }}
|
||||||
|
>
|
||||||
{item.name}
|
{item.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Group justify="center">
|
<Group justify="center">
|
||||||
<Button
|
<Button
|
||||||
onClick={() => router.push(`/darmasaba/penghargaan/${item.id}`)}
|
onClick={() =>
|
||||||
|
router.push(`/darmasaba/penghargaan/${item.id}`)
|
||||||
|
}
|
||||||
size="md"
|
size="md"
|
||||||
radius="xl"
|
radius="xl"
|
||||||
rightSection={<IconArrowRight size={18} />}
|
rightSection={<IconArrowRight size={18} />}
|
||||||
@@ -110,24 +128,83 @@ function Slider() {
|
|||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
</CarouselSlide>
|
</Carousel.Slide>
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Carousel
|
<Box
|
||||||
py="xl"
|
pos="relative"
|
||||||
plugins={[autoplay.current]}
|
w="100%"
|
||||||
onMouseEnter={autoplay.current.stop}
|
mx="auto"
|
||||||
onMouseLeave={autoplay.current.reset}
|
px={{ base: "md", sm: "xl", md: "2rem", lg: "3rem" }}
|
||||||
w={{ base: "100%", sm: "90%", md: "80%", lg: width }}
|
style={{
|
||||||
h={height}
|
maxWidth: 1300,
|
||||||
slideSize={{ base: "100%", sm: "50%", md: "33.333333%" }}
|
}}
|
||||||
slideGap="md"
|
|
||||||
loop
|
|
||||||
align="start"
|
|
||||||
slidesToScroll={mobile ? 1 : 2}
|
|
||||||
>
|
>
|
||||||
{slides}
|
<Carousel
|
||||||
</Carousel>
|
py="xl"
|
||||||
|
w="100%"
|
||||||
|
h={{ base: 320, sm: 380, md: 420, lg: 450 }}
|
||||||
|
slideSize={{
|
||||||
|
base: "100%", // Mobile: 1
|
||||||
|
sm: "50%", // Tablet kecil (≥768): 2
|
||||||
|
md: "50%", // 1024px: tetap 2
|
||||||
|
lg: "33.333%", // Desktop besar: 3
|
||||||
|
}}
|
||||||
|
slideGap={{ base: "md", sm: "md", md: "lg" }}
|
||||||
|
loop
|
||||||
|
align="start"
|
||||||
|
slidesToScroll={mobile ? 1 : tablet ? 2 : 3}
|
||||||
|
plugins={[autoplay.current]}
|
||||||
|
onMouseEnter={autoplay.current.stop}
|
||||||
|
onMouseLeave={autoplay.current.reset}
|
||||||
|
withControls={data.length > 3}
|
||||||
|
draggable={data.length > 1}
|
||||||
|
styles={{
|
||||||
|
root: {
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
viewport: {
|
||||||
|
overflow: "hidden",
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
alignItems: "stretch",
|
||||||
|
},
|
||||||
|
control: {
|
||||||
|
zIndex: 20,
|
||||||
|
backgroundColor: "rgba(255,255,255,0.95)",
|
||||||
|
color: colors["blue-button"],
|
||||||
|
border: `2px solid ${colors["blue-button"]}`,
|
||||||
|
width: 46,
|
||||||
|
height: 46,
|
||||||
|
borderRadius: "50%",
|
||||||
|
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: colors["blue-button"],
|
||||||
|
color: "white",
|
||||||
|
transform: "scale(1.1)",
|
||||||
|
},
|
||||||
|
'&[data-inactive]': {
|
||||||
|
opacity: 0,
|
||||||
|
cursor: 'default',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
controls: {
|
||||||
|
position: "absolute",
|
||||||
|
top: mobile ? "70%" : tablet ? "65%" : "60%",
|
||||||
|
transform: "translateY(-50%)",
|
||||||
|
width: mobile ? "100%" : tablet ? "calc(100% + 60px)" : "calc(100% + 100px)",
|
||||||
|
left: mobile ? "0" : tablet ? "-30px" : "-50px",
|
||||||
|
right: mobile ? "0" : tablet ? "-30px" : "-50px",
|
||||||
|
padding: "0",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
zIndex: 30,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{slides}
|
||||||
|
</Carousel>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,8 @@ export function NavbarMainMenu({ listNavbar }: { listNavbar: MenuItem[] }) {
|
|||||||
<MenuItemCom
|
<MenuItemCom
|
||||||
key={k}
|
key={k}
|
||||||
item={item}
|
item={item}
|
||||||
isActive={pathname === item.href ||
|
isActive={item.href && pathname.startsWith(item.href) ||
|
||||||
(item.children?.some(child => child.href === pathname))}
|
(item.children?.some(child => child.href && pathname.startsWith(child.href)))}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export function NavbarSubMenu({ item }: { item: MenuItem[] | null }) {
|
|||||||
justify="space-between"
|
justify="space-between"
|
||||||
size="lg"
|
size="lg"
|
||||||
radius="md"
|
radius="md"
|
||||||
color={pathname === link.href ? 'blue' : 'gray'}
|
color={link.href && pathname.startsWith(link.href) ? 'blue' : 'gray'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (link.href) {
|
if (link.href) {
|
||||||
router.push(link.href);
|
router.push(link.href);
|
||||||
@@ -49,12 +49,12 @@ export function NavbarSubMenu({ item }: { item: MenuItem[] | null }) {
|
|||||||
rightSection={<IconArrowRight size={18} />}
|
rightSection={<IconArrowRight size={18} />}
|
||||||
styles={(theme) => ({
|
styles={(theme) => ({
|
||||||
root: {
|
root: {
|
||||||
background: pathname === link.href ? theme.colors.blue[0] : 'transparent',
|
background: link.href && pathname.startsWith(link.href) ? theme.colors.blue[0] : 'transparent',
|
||||||
color: pathname === link.href ? theme.colors.blue[7] : colors['blue-button'],
|
color: link.href && pathname.startsWith(link.href) ? theme.colors.blue[7] : colors['blue-button'],
|
||||||
fontWeight: pathname === link.href ? 600 : 500,
|
fontWeight: link.href && pathname.startsWith(link.href) ? 600 : 500,
|
||||||
transition: "all 0.2s ease",
|
transition: "all 0.2s ease",
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
background: pathname === link.href ? theme.colors.blue[1] : theme.colors.gray[0],
|
background: link.href && pathname.startsWith(link.href) ? theme.colors.blue[1] : theme.colors.gray[0],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function Kepuasan() {
|
|||||||
const [donutDataJenisKelamin, setDonutDataJenisKelamin] = useState<ChartDataItem[]>([]);
|
const [donutDataJenisKelamin, setDonutDataJenisKelamin] = useState<ChartDataItem[]>([]);
|
||||||
const [donutDataRating, setDonutDataRating] = useState<ChartDataItem[]>([]);
|
const [donutDataRating, setDonutDataRating] = useState<ChartDataItem[]>([]);
|
||||||
const [donutDataKelompokUmur, setDonutDataKelompokUmur] = useState<ChartDataItem[]>([]);
|
const [donutDataKelompokUmur, setDonutDataKelompokUmur] = useState<ChartDataItem[]>([]);
|
||||||
const [barChartData, setBarChartData] = useState<Array<{ month: string; count: number }>>([]);
|
const [barChartData, setBarChartData] = useState<Array<{ month: string; Responden: number }>>([]);
|
||||||
const [opened, { open, close }] = useDisclosure(false)
|
const [opened, { open, close }] = useDisclosure(false)
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
@@ -121,18 +121,18 @@ function Kepuasan() {
|
|||||||
|
|
||||||
// Convert map to array and sort by date
|
// Convert map to array and sort by date
|
||||||
const barData = Array.from(monthYearMap.entries())
|
const barData = Array.from(monthYearMap.entries())
|
||||||
.map(([key, count]) => {
|
.map(([key, Responden]) => {
|
||||||
const [year, month] = key.split('-');
|
const [year, month] = key.split('-');
|
||||||
const monthName = new Date(Number(year), Number(month) - 1, 1)
|
const monthName = new Date(Number(year), Number(month) - 1, 1)
|
||||||
.toLocaleString('id-ID', { month: 'long' });
|
.toLocaleString('id-ID', { month: 'long' });
|
||||||
return {
|
return {
|
||||||
month: `${monthName} ${year}`,
|
month: `${monthName} ${year}`,
|
||||||
count,
|
Responden,
|
||||||
sortKey: parseInt(`${year}${String(month).padStart(2, '0')}`, 10)
|
sortKey: parseInt(`${year}${String(month).padStart(2, '0')}`, 10)
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.sortKey - b.sortKey)
|
.sort((a, b) => a.sortKey - b.sortKey)
|
||||||
.map(({ month, count }) => ({ month, count }));
|
.map(({ month, Responden }) => ({ month, Responden }));
|
||||||
|
|
||||||
setBarChartData(barData);
|
setBarChartData(barData);
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ function Kepuasan() {
|
|||||||
h={window.innerWidth < 480 ? 200 : 300}
|
h={window.innerWidth < 480 ? 200 : 300}
|
||||||
data={barChartData}
|
data={barChartData}
|
||||||
dataKey="month"
|
dataKey="month"
|
||||||
series={[{ name: 'count', color: colors['blue-button'] }]}
|
series={[{ name: 'Responden', color: colors['blue-button'] }]}
|
||||||
tickLine="y"
|
tickLine="y"
|
||||||
xAxisLabel="Bulan"
|
xAxisLabel="Bulan"
|
||||||
yAxisLabel="Jumlah Responden"
|
yAxisLabel="Jumlah Responden"
|
||||||
@@ -448,7 +448,7 @@ function Kepuasan() {
|
|||||||
h={300}
|
h={300}
|
||||||
data={barChartData}
|
data={barChartData}
|
||||||
dataKey="month"
|
dataKey="month"
|
||||||
series={[{ name: 'count', color: colors['blue-button'] }]}
|
series={[{ name: 'Responden', color: colors['blue-button'] }]}
|
||||||
tickLine="y"
|
tickLine="y"
|
||||||
xAxisLabel="Bulan"
|
xAxisLabel="Bulan"
|
||||||
yAxisLabel="Jumlah Responden"
|
yAxisLabel="Jumlah Responden"
|
||||||
|
|||||||
Reference in New Issue
Block a user