Fix Menu Lingkungan Darmasaba User

This commit is contained in:
2025-08-26 17:49:33 +08:00
parent b21e1f0c2e
commit 3a726a3334
36 changed files with 2509 additions and 1977 deletions

View File

@@ -1,112 +1,97 @@
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import colors from '@/con/colors';
import { ActionIcon, BackgroundImage, Box, Center, Container, Flex, Group, SimpleGrid, Stack, Text } from '@mantine/core';
import { IconDownload } from '@tabler/icons-react';
import BackButton from '../../(pages)/desa/layanan/_com/BackButto';
import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes';
import { useProxy } from 'valtio/utils';
import { useEffect, useState } from 'react';
import { Link } from 'next-view-transitions';
import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes'
import colors from '@/con/colors'
import { ActionIcon, BackgroundImage, Box, Center, Container, Group, Loader, SimpleGrid, Stack, Text, Title } from '@mantine/core'
import { IconDownload } from '@tabler/icons-react'
import { Link } from 'next-view-transitions'
import { useEffect, useState } from 'react'
import { useProxy } from 'valtio/utils'
import BackButton from '../../(pages)/desa/layanan/_com/BackButto'
function Page() {
const state = useProxy(apbdes);
const [loading, setLoading] = useState(false);
const state = useProxy(apbdes)
const [loading, setLoading] = useState(false)
useEffect(() => {
const loadData = async () => {
try {
setLoading(true);
await state.findMany.load();
setLoading(true)
await state.findMany.load()
} catch (error) {
console.error('Error loading data:', error);
console.error(error)
} finally {
setLoading(false);
setLoading(false)
}
}
loadData();
loadData()
}, [])
const data = state.findMany.data || [];
const data = state.findMany.data || []
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={22}>
<Box px={{ base: "md", md: 100 }}><BackButton /></Box>
<Container w={{ base: "100%", md: "50%" }}>
<Stack align="center" gap={0}>
<Text fz={"3.4rem"} fw={"bold"}>
APBDes
</Text>
<Text
py={10}
ta={"justify"}
>
Transparansi APBDes Darmasaba adalah langkah nyata menuju tata kelola pemerintahan desa yang bersih dan bertanggung jawab. Adapun APBDes sebagai berikut:
<Stack pos="relative" bg={colors.Bg} py="xl" gap={32}>
<Box px={{ base: 'md', md: 100 }}>
<BackButton />
</Box>
<Container w={{ base: '100%', md: '60%' }}>
<Stack align="center" gap="sm">
<Title order={1} fz={{ base: '2.4rem', md: '3.2rem' }} fw="bold" ta="center">
Anggaran Pendapatan & Belanja Desa (APBDes)
</Title>
<Text fz="md" c="dimmed" ta="center">
Laporan transparansi APBDes Desa Darmasaba sebagai bentuk keterbukaan dan akuntabilitas pengelolaan anggaran desa.
</Text>
</Stack>
</Container>
<SimpleGrid
px={{ base: "md", md: 100 }}
cols={{
base: 1,
sm: 3,
}}
>
{loading ? (
<Center>
<Text fz={"2.4rem"}>Memuat Data...</Text>
</Center>
) : (
data.map((v, k) => {
return (
<BackgroundImage
key={k}
src={v.image?.link || ''}
h={350}
radius={16}
pos={"relative"}
>
<Box
style={{
borderRadius: 16,
zIndex: 0
}}
pos={"absolute"}
w={"100%"}
h={"100%"}
bg={colors.trans.dark[2]}
/>
<Stack justify='space-between' h={"100%"} gap={0} p={"lg"} pos={"relative"}>
<Box p={"lg"}>
<Text
c={"white"}
size={"1.5rem"}
style={{
textAlign: "center",
}}>{v.name}</Text>
</Box>
<Text
fw={"bold"}
c={"white"}
size={"3.5rem"}
style={{
textAlign: "center",
}}>{v.jumlah}</Text>
<Group justify="center">
<ActionIcon px={70} py={20} radius={"xl"} size="md" bg={colors["blue-button"]} component={Link} href={v.file?.link || ''}>
<Flex gap={"md"}>
<IconDownload size={20} />
<Text fz={"sm"} c={"white"}>Download</Text>
</Flex>
</ActionIcon>
</Group>
</Stack>
</BackgroundImage>
)
})
)}
</SimpleGrid>
{loading ? (
<Center mih={200}>
<Stack align="center" gap="sm">
<Loader size="lg" color="blue" />
<Text fz="lg" c="dimmed">Sedang memuat data APBDes...</Text>
</Stack>
</Center>
) : data.length === 0 ? (
<Center mih={200}>
<Stack align="center" gap="xs">
<Text fz="xl" fw={600} c="dimmed">Belum ada data APBDes tersedia</Text>
<Text fz="sm" c="dimmed">Data akan ditampilkan jika sudah diunggah oleh admin desa</Text>
</Stack>
</Center>
) : (
<SimpleGrid px={{ base: 'md', md: 100 }} cols={{ base: 1, sm: 2, md: 3 }} spacing="xl">
{data.map((v: any, k: number) => (
<BackgroundImage key={k} src={v.image?.link || ''} h={360} radius="xl" pos="relative">
<Box pos="absolute" inset={0} bg="rgba(0,0,0,0.45)" style={{ borderRadius: 16 }} />
<Stack justify="space-between" h="100%" p="lg" pos="relative">
<Box>
<Text fz="lg" fw={600} c="white" ta="center">
{v.name}
</Text>
</Box>
<Text fz="2.6rem" fw="bold" c="white" ta="center">
{v.jumlah}
</Text>
<Group justify="center">
<ActionIcon
component={Link}
href={v.file?.link || '#'}
radius="xl"
size="lg"
bg={colors['blue-button']}
variant="filled"
>
<IconDownload size={20} color="white" />
</ActionIcon>
</Group>
</Stack>
</BackgroundImage>
))}
</SimpleGrid>
)}
</Stack>
);
)
}
export default Page;
export default Page

View File

@@ -1,137 +1,136 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client';
import React, { useEffect, useState } from 'react';
import korupsiState from '@/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import React, { useEffect, useState } from 'react';
import { Box, Button, Container, Flex, Paper, SimpleGrid, Stack, Text, ActionIcon } from '@mantine/core';
import { IconFile } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils';
import {
Box,
Button,
Container,
Flex,
Paper,
SimpleGrid,
Stack,
Text,
ActionIcon,
Loader,
Tooltip,
} from '@mantine/core';
import { IconFile, IconInbox } from '@tabler/icons-react';
function Lokal() {
const [selectedKategori, setSelectedKategori] = useState<string>('PENGUATAN TATA LAKSANA');
const [loading, setLoading] = useState(true);
const state = useProxy(korupsiState);
// Load data on component mount
useEffect(() => {
const loadData = async () => {
try {
setLoading(true);
await state.desaAntikorupsi.findMany.load(1, 100); // Load first 100 items
} catch (error) {
console.error('Error loading data:', error);
await state.desaAntikorupsi.findMany.load(1, 100);
} finally {
setLoading(false);
}
};
loadData();
}, []);
// Get data from state
const data = state.desaAntikorupsi.findMany.data || [];
// Debug: Log the complete data structure
console.log('Complete data:', JSON.parse(JSON.stringify(data)));
// Get unique categories
const categories = [...new Set(
data
.filter(item => item.kategori?.name) // Only include items with a category name
.map(item => item.kategori.name)
)];
// Filter data based on selected category
const filteredData = selectedKategori === 'PENGUATAN TATA LAKSANA'
? data
: data.filter(item => item.kategori?.name === selectedKategori);
// Debug: Log filtered data
console.log('Filtered data:', JSON.parse(JSON.stringify(filteredData)));
const categories = [...new Set(data.filter(i => i.kategori?.name).map(i => i.kategori.name))];
const filteredData =
selectedKategori === 'PENGUATAN TATA LAKSANA'
? data
: data.filter(i => i.kategori?.name === selectedKategori);
return (
<Stack pos="relative" bg={colors.Bg} py="xl" gap={22}>
<Box px={{ base: "md", md: 100 }}>
<Stack pos="relative" bg={colors.Bg} py="xl" gap={32}>
<Box px={{ base: 'md', md: 100 }}>
<BackButton />
</Box>
<Container w={{ base: "100%", md: "80%" }}>
<Stack align="center" gap={0}>
<Text fz={"3.4rem"} fw={"bold"}>
<Container w={{ base: '100%', md: '80%' }}>
<Stack align="center" gap={4}>
<Text fz={{ base: 32, md: 44 }} fw={700} ta="center" c={colors['blue-button']}>
Desa Anti Korupsi
</Text>
<Text
py={10}
ta={"justify"}
>
Desa antikorupsi mendorong pemerintahan jujur dan transparan. Keuangan desa dikelola terbuka dengan melibatkan warga mengawasi anggaran, sehingga digunakan tepat sasaran sesuai kebutuhan. Adapun beberapa jenis tata penguatan :
<Text ta="center" fz="md" c="dimmed" maw={700}>
Desa antikorupsi mendorong pemerintahan jujur dan transparan. Keuangan desa dikelola
terbuka dengan melibatkan warga untuk mengawasi anggaran sehingga tepat sasaran sesuai
kebutuhan.
</Text>
</Stack>
</Container>
<Container size="lg" px={{ base: "md", md: "xl" }}>
{/* Category Filter Buttons */}
<Flex gap="md" justify="center" mb="xl" wrap="wrap">
{categories.map((kategori) => (
<Container size="lg" px={{ base: 'md', md: 'xl' }}>
<Flex gap="sm" justify="center" mb="xl" wrap="wrap">
{categories.map(kategori => (
<Button
color={selectedKategori === kategori ? colors['blue-button'] : 'gray'}
key={kategori}
variant={selectedKategori === kategori ? 'filled' : 'outline'}
onClick={() => setSelectedKategori(kategori)}
size="sm"
radius="xl"
variant={selectedKategori === kategori ? 'filled' : 'outline'}
color={selectedKategori === kategori ? colors['blue-button'] : 'gray'}
>
{kategori}
</Button>
))}
</Flex>
{/* Loading State */}
{loading ? (
<Text ta="center">Memuat data...</Text>
<Flex justify="center" align="center" h={200}>
<Loader color={colors['blue-button']} size="lg" />
</Flex>
) : filteredData.length === 0 ? (
<Flex direction="column" align="center" justify="center" gap="sm" py="xl">
<IconInbox size={48} stroke={1.5} color={colors['blue-button']} />
<Text fz="lg" fw={500} c="dimmed">
Belum ada data untuk kategori ini
</Text>
</Flex>
) : (
<SimpleGrid
cols={{ base: 1, sm: 2, lg: 3 }}
spacing="xl"
verticalSpacing="xl"
>
{filteredData.map((item) => {
console.log('Item data:', item);
console.log('All item properties:', Object.keys(item).map(key => `${key}: ${item[key]}`).join(', '));
const handleDownload = async (e: React.MouseEvent) => {
<SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="xl">
{filteredData.map(item => {
const handleDownload = (e: React.MouseEvent) => {
e.stopPropagation();
if (!item?.file?.link) return;
try {
const fileUrl = item.file.link.startsWith('http')
? item.file.link
: `${window.location.origin}${item.file.link.startsWith('/') ? '' : '/'}${item.file.link}`;
window.open(fileUrl, '_blank');
} catch (error) {
console.error('Error opening file:', error);
}
const url = item.file.link.startsWith('http')
? item.file.link
: `${window.location.origin}${item.file.link.startsWith('/') ? '' : '/'}${
item.file.link
}`;
window.open(url, '_blank');
};
return (
<Paper key={item.id} p="lg" shadow="sm" radius="md" withBorder>
<Paper
key={item.id}
p="lg"
shadow="md"
radius="xl"
withBorder
style={{
background: 'linear-gradient(135deg, #ffffff, #f8fbff)',
}}
>
<Stack h="100%" justify="space-between">
<div>
<Text fz="lg" fw={600} mb="sm" c={colors["blue-button"]}>
{item.name}
</Text>
</div>
<Text fz="lg" fw={600} c={colors['blue-button']} lineClamp={2}>
{item.name}
</Text>
{item?.file && (
<ActionIcon
variant="filled"
color={colors["blue-button"]}
size="lg"
onClick={handleDownload}
style={{ marginTop: 10 }}
title="Unduh File"
>
<IconFile size={20} />
</ActionIcon>
<Tooltip label="Unduh file" withArrow>
<ActionIcon
variant="filled"
color={colors['blue-button']}
size="lg"
radius="xl"
onClick={handleDownload}
>
<IconFile size={20} />
</ActionIcon>
</Tooltip>
)}
</Stack>
</Paper>
@@ -141,9 +140,7 @@ function Lokal() {
)}
</Container>
</Stack>
)
);
}
export default Lokal;

View File

@@ -2,13 +2,12 @@
'use client'
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import { Stack, Container, Text, Image, ActionIcon, Box, Divider, Flex, Center, Skeleton } from '@mantine/core';
import { Stack, Container, Text, Image, ActionIcon, Box, Divider, Flex, Center, Skeleton, Paper, Tooltip } from '@mantine/core';
import { IconBrandFacebook, IconBrandInstagram, IconBrandTwitter, IconBrandWhatsapp } from '@tabler/icons-react';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import penghargaanState from '@/app/admin/(dashboard)/_state/desa/penghargaan';
import { useState } from 'react';
function Page() {
const params = useParams<{ id: string }>();
@@ -23,77 +22,99 @@ function Page() {
setLoading(true);
await state.findUnique.load(id);
} catch (error) {
console.error('Error loading data:', error);
console.error('Gagal memuat data:', error);
} finally {
setLoading(false);
}
}
loadData()
}, [id])
};
loadData();
}, [id]);
if (loading) {
return (
<Center>
<Skeleton height={500} />
<Center h={"70vh"}>
<Stack align="center" gap="sm">
<Skeleton height={40} width={200} radius="xl" />
<Skeleton height={300} width={300} radius="md" />
<Skeleton height={20} width="80%" radius="xl" />
</Stack>
</Center>
);
}
if (!state.findUnique.data) {
return (
<Center>
<Text>Data tidak ditemukan</Text>
<Center h={"70vh"}>
<Paper withBorder shadow="md" p="xl" radius="lg">
<Text ta="center" fz="lg" fw="bold" c="dimmed">
Data penghargaan tidak tersedia
</Text>
<Text ta="center" fz="sm" c="dimmed" mt="sm">
Silakan kembali dan pilih penghargaan lainnya
</Text>
</Paper>
</Center>
);
}
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={22}>
<Stack pos="relative" bg={colors.Bg} py="xl" gap={22}>
<Box px={{ base: "md", md: 100 }}>
<BackButton />
</Box>
<Container w={{ base: "100%", md: "50%" }}>
<Stack align="center" gap={0}>
<Text
ta={"center"}
fw={"bold"}
fz={"2.3rem"}
>
<Container w={{ base: "100%", md: "60%" }}>
<Stack align="center" gap="md">
<Text ta="center" fw="bold" fz={{ base: "1.8rem", md: "2.3rem" }} lh={1.3}>
{state.findUnique.data?.name}
</Text>
<Image py={20} src={state.findUnique.data?.image?.link || ''} alt='' />
<Image
src={state.findUnique.data?.image?.link || ''}
alt="Gambar penghargaan"
radius="lg"
fit="contain"
mah={400}
fallbackSrc="https://placehold.co/600x400?text=Tidak+Ada+Gambar"
/>
</Stack>
</Container>
<Box px={{ base: "md", md: 100 }}>
<Text
pb={20}
ta={"justify"}
fw={"bold"}
ta="justify"
fz="md"
lh={1.6}
dangerouslySetInnerHTML={{ __html: state.findUnique.data?.deskripsi || '' }}
/>
<Box py={20}>
<Divider color={colors['blue-button']} />
<Flex justify={"space-between"} py={20}>
<Text fz={"sm"}>{new Date(state.findUnique.data?.createdAt).toLocaleDateString()}</Text>
<Box>
<Flex gap={"lg"}>
<ActionIcon variant='transparent'>
<IconBrandFacebook color={colors['blue-button']} size={"30"} />
<Flex direction={{ base: "column", sm: "row" }} justify="space-between" align={{ base: "start", sm: "center" }} gap="sm" py={20}>
<Text fz="sm" c="dimmed">
Diterbitkan: {new Date(state.findUnique.data?.createdAt).toLocaleDateString('id-ID')}
</Text>
<Flex gap="md">
<Tooltip label="Bagikan ke Facebook" withArrow>
<ActionIcon variant="light" radius="xl" size="lg" color="blue">
<IconBrandFacebook size={22} />
</ActionIcon>
<ActionIcon variant='transparent'>
<IconBrandInstagram color={colors['blue-button']} size={"30"} />
</Tooltip>
<Tooltip label="Bagikan ke Instagram" withArrow>
<ActionIcon variant="light" radius="xl" size="lg" color="pink">
<IconBrandInstagram size={22} />
</ActionIcon>
<ActionIcon variant='transparent'>
<IconBrandTwitter color={colors['blue-button']} size={"30"} />
</Tooltip>
<Tooltip label="Bagikan ke Twitter" withArrow>
<ActionIcon variant="light" radius="xl" size="lg" color="cyan">
<IconBrandTwitter size={22} />
</ActionIcon>
<ActionIcon variant='transparent'>
<IconBrandWhatsapp color={colors['blue-button']} size={"30"} />
</Tooltip>
<Tooltip label="Bagikan ke WhatsApp" withArrow>
<ActionIcon variant="light" radius="xl" size="lg" color="green">
<IconBrandWhatsapp size={22} />
</ActionIcon>
</Flex>
</Box>
</Tooltip>
</Flex>
</Flex>
<Divider color={colors['blue-button']} pb={50} />
<Divider color={colors['blue-button']} />
</Box>
</Box>
</Stack>

View File

@@ -3,109 +3,131 @@
import penghargaanState from "@/app/admin/(dashboard)/_state/desa/penghargaan";
import colors from "@/con/colors";
import { Carousel, CarouselSlide } from "@mantine/carousel";
import { Box, Button, Container, Group, Paper, Stack, Text, useMantineTheme } from "@mantine/core";
import { Box, Button, Container, Group, Paper, Stack, Text, useMantineTheme, Skeleton } from "@mantine/core";
import { useMediaQuery } from "@mantine/hooks";
import Autoplay from "embla-carousel-autoplay";
import { IconAward, IconArrowRight } from "@tabler/icons-react";
import { useTransitionRouter } from "next-view-transitions";
import { useEffect, useRef } from "react";
import { useProxy } from "valtio/utils";
import BackButton from "../../(pages)/desa/layanan/_com/BackButto";
export default function Page() {
return (
<Stack pos={"relative"} bg={colors.grey[1]} py={"xl"} gap={22}>
<Box px={{ base: "md", md: 100 }}>
<BackButton />
</Box>
<Container w={{ base: "100%", md: "50%" }}>
<Stack align="center" gap={0}>
<Text fz={"3.4rem"} fw={"bold"}>
Penghargaan
</Text>
<Text
py={10}
ta={"justify"}
>
Desa Darmasaba telah berhasil meraih berbagai penghargaan bergengsi yang membuktikan dedikasi dan kerja keras seluruh elemen masyarakat dalam membangun desa yang maju dan berkelanjutan. Berikut ini adalah macam-macam penghargaan yang telah diraih oleh Desa Darmasaba:
</Text>
<Slider />
</Stack>
</Container>
return (
<Stack pos="relative" bg={colors.grey[1]} py="xl" gap={32}>
<Box px={{ base: "md", md: 100 }}>
<BackButton />
</Box>
<Container w={{ base: "100%", md: "60%" }}>
<Stack align="center" gap="sm">
<Group gap="xs">
<IconAward size={40} color={colors["blue-button"]} />
<Text fz={{ base: "2rem", md: "3.2rem" }} fw={800} variant="gradient" gradient={{ from: "#1C6EA4", to: "#69BFF8" }}>
Penghargaan Desa
</Text>
</Group>
<Text fz="lg" c="dimmed" ta="center">
Desa Darmasaba berhasil meraih beragam penghargaan bergengsi yang mencerminkan dedikasi dan kerja keras masyarakat dalam membangun desa yang maju dan berkelanjutan.
</Text>
<Slider />
</Stack>
)
</Container>
</Stack>
);
}
function Slider() {
const height = 720;
const width = 1200;
const theme = useMantineTheme();
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
const autoplay = useRef(Autoplay({ delay: 2000 }));
const state = useProxy(penghargaanState);
const roter = useTransitionRouter()
const height = 500;
const width = 1200;
const theme = useMantineTheme();
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
const autoplay = useRef(Autoplay({ delay: 3000 }));
const state = useProxy(penghargaanState);
const router = useTransitionRouter();
useEffect(() => {
const loadData = async () => {
try {
await state.findMany.load();
} catch (error) {
console.error('Error loading data:', error);
}
}
loadData();
}, [])
useEffect(() => {
state.findMany.load();
}, []);
const data = state.findMany.data || [];
const slides = data.map((item) => (
<CarouselSlide key={item.id}>
<Paper h={"100%"} pos={"relative"} style={{
backgroundImage: `url(${item.image?.link}) `,
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
}}>
<Box
style={{
borderRadius: 16,
zIndex: 0,
}}
pos={"absolute"}
w={"100%"}
h={"100%"}
bg={colors.trans.dark[2]}
/>
<Stack justify="space-between" h={"100%"} gap={0} p={"lg"} pos={"relative"} >
<Box p={"lg"}>
<Text fz={"1.5rem"} ta={"center"} c={"white"}>{item.name}</Text>
</Box>
<Group justify="center" >
<Button onClick={() => roter.push(`/darmasaba/penghargaan/${item.id}`)} px={46} radius={"100"} size="md" bg={colors["blue-button"]}>
Detail
</Button>
</Group>
</Stack>
</Paper>
</CarouselSlide>
));
const data = state.findMany.data || [];
const loading = state.findMany.loading;
if (loading) {
return (
<Carousel
c={"white"}
py={50}
plugins={[autoplay.current]}
onMouseEnter={autoplay.current.stop}
onMouseLeave={autoplay.current.reset}
w={{ base: 500, md: 800, lg: 900, xl: width }}
height={height}
slideSize={{ base: "100%", sm: "50%", md: "33.333333%" }}
slideGap={{ base: "xl", sm: "md" }}
loop
align="start"
slidesToScroll={mobile ? 1 : 2}
>
{slides}
</Carousel>
<Group justify="center" py="xl">
<Skeleton w={300} h={200} radius="lg" />
<Skeleton w={300} h={200} radius="lg" visibleFrom="sm" />
<Skeleton w={300} h={200} radius="lg" visibleFrom="md" />
</Group>
);
}
}
if (!loading && data.length === 0) {
return (
<Stack align="center" py="xl">
<IconAward size={56} color={colors["blue-button"]} />
<Text fz="lg" fw={600} c="dimmed">
Belum ada penghargaan yang ditambahkan
</Text>
</Stack>
);
}
const slides = data.map((item) => (
<CarouselSlide key={item.id}>
<Paper
h="100%"
radius="lg"
shadow="md"
pos="relative"
style={{
backgroundImage: `url(${item.image?.link})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
>
<Box
pos="absolute"
inset={0}
bg="linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0.3))"
style={{ borderRadius: 16 }}
/>
<Stack justify="flex-end" h="100%" gap="sm" p="lg" pos="relative">
<Text fz="xl" fw={700} ta="center" c="white">
{item.name}
</Text>
<Group justify="center">
<Button
onClick={() => router.push(`/darmasaba/penghargaan/${item.id}`)}
size="md"
radius="xl"
rightSection={<IconArrowRight size={18} />}
variant="gradient"
gradient={{ from: "#1C6EA4", to: "#69BFF8" }}
>
Lihat Detail
</Button>
</Group>
</Stack>
</Paper>
</CarouselSlide>
));
return (
<Carousel
py="xl"
plugins={[autoplay.current]}
onMouseEnter={autoplay.current.stop}
onMouseLeave={autoplay.current.reset}
w={{ base: "100%", sm: "90%", md: "80%", lg: width }}
h={height}
slideSize={{ base: "100%", sm: "50%", md: "33.333333%" }}
slideGap="md"
loop
align="start"
slidesToScroll={mobile ? 1 : 2}
>
{slides}
</Carousel>
);
}