Fix Menu Lingkungan Darmasaba User
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user