Fix Tampilab DesaAntiKorupsi Landing Page Mobile
This commit is contained in:
@@ -6,7 +6,6 @@ import { Box, Center, Container, Image, Skeleton, Stack, Text } from '@mantine/c
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../../layanan/_com/BackButto';
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +49,6 @@ function Page() {
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"} px={{ base: "md", md: 0 }}>
|
||||
<Box px={{ base: "md", md: 100 }}><BackButton /></Box>
|
||||
<Container w={{ base: "100%", md: "50%" }} >
|
||||
<Box pb={20}>
|
||||
<Text ta={"center"} fz={"2.4rem"} c={colors["blue-button"]} fw={"bold"}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Container, Grid, GridCol, Stack, Tabs, TabsList, TabsTab, Text, TextInput } from '@mantine/core';
|
||||
import { Box, Container, Grid, GridCol, ScrollArea, Stack, Tabs, TabsList, TabsTab, Text, TextInput } from '@mantine/core';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
@@ -22,15 +22,15 @@ function LayoutTabsBerita({
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
|
||||
// Get active tab from URL path
|
||||
const activeTab = pathname.split('/').pop() || 'semua';
|
||||
|
||||
|
||||
// Get initial search value from URL
|
||||
const initialSearch = searchParams.get('search') || '';
|
||||
const [searchValue, setSearchValue] = useState(initialSearch);
|
||||
const [searchTimeout, setSearchTimeout] = useState<number | null>(null);
|
||||
|
||||
|
||||
// Update active tab state when pathname changes
|
||||
const [activeTabState, setActiveTabState] = useState(activeTab);
|
||||
useEffect(() => {
|
||||
@@ -50,28 +50,28 @@ function LayoutTabsBerita({
|
||||
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value;
|
||||
setSearchValue(value);
|
||||
|
||||
|
||||
// Clear previous timeout
|
||||
if (searchTimeout !== null) {
|
||||
clearTimeout(searchTimeout);
|
||||
}
|
||||
|
||||
|
||||
// Set new timeout
|
||||
const newTimeout = window.setTimeout(() => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
|
||||
|
||||
if (value) {
|
||||
params.set('search', value);
|
||||
} else {
|
||||
params.delete('search');
|
||||
}
|
||||
|
||||
|
||||
// Only update URL if the search value has actually changed
|
||||
if (params.toString() !== searchParams.toString()) {
|
||||
router.push(`/darmasaba/desa/berita/${activeTab}?${params.toString()}`);
|
||||
}
|
||||
}, 500); // 500ms debounce delay
|
||||
|
||||
|
||||
setSearchTimeout(newTimeout);
|
||||
};
|
||||
const tabs = [
|
||||
@@ -147,17 +147,19 @@ function LayoutTabsBerita({
|
||||
<Box px={{ base: "md", md: 100 }} py="md" bg={colors['BG-trans']}>
|
||||
<Grid>
|
||||
<GridCol span={{ base: 12, md: 9, lg: 8, xl: 9 }}>
|
||||
<TabsList>
|
||||
{tabs.map((tab, index) => (
|
||||
<TabsTab
|
||||
key={index}
|
||||
value={tab.value}
|
||||
onClick={() => router.push(tab.href)}
|
||||
>
|
||||
{tab.label}
|
||||
</TabsTab>
|
||||
))}
|
||||
</TabsList>
|
||||
<ScrollArea type="auto" offsetScrollbars>
|
||||
<TabsList>
|
||||
{tabs.map((tab, index) => (
|
||||
<TabsTab
|
||||
key={index}
|
||||
value={tab.value}
|
||||
onClick={() => router.push(tab.href)}
|
||||
>
|
||||
{tab.label}
|
||||
</TabsTab>
|
||||
))}
|
||||
</TabsList>
|
||||
</ScrollArea>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3, lg: 4, xl: 3 }}>
|
||||
<TextInput
|
||||
|
||||
@@ -35,12 +35,12 @@ function Apbdes() {
|
||||
|
||||
return (
|
||||
<Stack p="lg" gap="4rem" bg={colors.Bg}>
|
||||
<Box w={{ base: '100%', sm: '70%' }}>
|
||||
<Box>
|
||||
<Stack gap="sm">
|
||||
<Text fz={{ base: '2.4rem', sm: '4rem' }} fw="bold" lh={1.2}>
|
||||
<Text ta={"center"} fz={{ base: '2.4rem', sm: '4rem' }} fw="bold" lh={1.2}>
|
||||
{textHeading.title}
|
||||
</Text>
|
||||
<Text fz={{ base: '1rem', sm: '1.3rem' }} c="dimmed">
|
||||
<Text ta={"center"} fz={{ base: '1rem', sm: '1.3rem' }} c="dimmed">
|
||||
{textHeading.des}
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import korupsiState from "@/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi";
|
||||
import colors from "@/con/colors";
|
||||
import { Box, Button, Center, Container, Flex, Paper, SimpleGrid, Stack, Text, useMantineTheme } from "@mantine/core";
|
||||
import { useMediaQuery } from "@mantine/hooks";
|
||||
import { Button, Center, Container, Flex, Paper, SimpleGrid, Stack, Text } from "@mantine/core";
|
||||
import { IconClipboardText } from "@tabler/icons-react";
|
||||
import Link from "next/link";
|
||||
import korupsiState from "@/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi";
|
||||
import { useProxy } from "valtio/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useProxy } from "valtio/utils";
|
||||
|
||||
function DesaAntiKorupsi() {
|
||||
const state = useProxy(korupsiState);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const theme = useMantineTheme();
|
||||
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
@@ -31,7 +29,7 @@ function DesaAntiKorupsi() {
|
||||
|
||||
const data = (state.desaAntikorupsi.findMany.data || []).slice(0, 6);
|
||||
return (
|
||||
<Stack gap={"0"} bg={colors.Bg} p={"sm"} h={mobile ? 2000 : 1050}>
|
||||
<Stack gap={"0"} bg={colors.Bg} p={"sm"}>
|
||||
<Container w={{ base: "100%", md: "80%" }} p={"xl"} >
|
||||
<Center>
|
||||
<Text fz={{ base: "2.4rem", md: "3.4rem" }}>Desa Anti Korupsi</Text>
|
||||
@@ -41,51 +39,60 @@ function DesaAntiKorupsi() {
|
||||
<Button radius={"lg"} fz={"h4"} bg={colors["blue-button"]} component={Link} href={"/darmasaba/desa-anti-korupsi/detail"}>Selengkapnya</Button>
|
||||
</Center>
|
||||
</Container>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
sm: 2,
|
||||
|
||||
}}>
|
||||
<Container w="100%" maw="80rem" px="md">
|
||||
{loading ? (
|
||||
<Center>
|
||||
<Text fz={"2.4rem"}>Memuat Data...</Text>
|
||||
<Center mih={200}>
|
||||
<Text fz="lg">Memuat Data...</Text>
|
||||
</Center>
|
||||
) : (
|
||||
data.map((v, k) => {
|
||||
return (
|
||||
<Box
|
||||
<SimpleGrid
|
||||
cols={{ base: 1, sm: 2, md: 3 }}
|
||||
spacing="lg"
|
||||
mt="lg"
|
||||
>
|
||||
{data.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
p="md"
|
||||
withBorder
|
||||
shadow="sm"
|
||||
radius="md"
|
||||
h="100%"
|
||||
>
|
||||
<Paper
|
||||
p={"lg"}
|
||||
withBorder
|
||||
shadow="sm"
|
||||
h={{ base: 250, md: 210 }}
|
||||
>
|
||||
<Flex gap={"lg"} align={"center"}>
|
||||
<Box>
|
||||
<Flex justify={"center"} align={"center"}>
|
||||
<Box>
|
||||
<IconClipboardText color={colors["blue-button"]} size={50} />
|
||||
</Box>
|
||||
<Box px={20} >
|
||||
<Stack gap={"xs"}>
|
||||
<Text fz={{ base: "1.2rem", md: "lg" }} ta={"center"} c={colors["blue-button"]} fw={500}>
|
||||
{v.kategori?.name || v.name || 'Kategori'}
|
||||
</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: v.name || 'Name' }} fz={{ base: "1rem", md: "lg" }} ta={"center"} c={colors["blue-button"]} fw={500} />
|
||||
</Stack>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Paper>
|
||||
</Box>
|
||||
)
|
||||
})
|
||||
<Flex gap="md" align="flex-start">
|
||||
<IconClipboardText
|
||||
color={colors["blue-button"]}
|
||||
size={40}
|
||||
style={{ flexShrink: 0 }} // biar icon nggak ketekan
|
||||
/>
|
||||
<Stack gap={2} style={{ flex: 1, minWidth: 0 }}>
|
||||
<Text
|
||||
fz={{ base: "sm", sm: "md", md: "lg", lg: "xl" }} // lebih besar di desktop
|
||||
c={colors["blue-button"]}
|
||||
fw={600}
|
||||
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
|
||||
>
|
||||
{v.kategori?.name || "Kategori"}
|
||||
</Text>
|
||||
<Text
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: v.name || "Name",
|
||||
}}
|
||||
fz={{ base: "sm", sm: "md", md: "lg", lg: "xl" }} // sama, scaling responsif
|
||||
c="dark"
|
||||
style={{
|
||||
wordBreak: "break-word",
|
||||
whiteSpace: "normal",
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</Flex>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
)}
|
||||
</SimpleGrid>
|
||||
</Container>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ function ModuleView() {
|
||||
<ScrollArea h={280} // ✅ tinggi fixed, bisa disesuaikan
|
||||
scrollbarSize={8}
|
||||
offsetScrollbars
|
||||
type="auto"
|
||||
type="never"
|
||||
styles={{
|
||||
viewport: { paddingRight: 8 }, // kasih jarak biar scroll nggak dempet
|
||||
}}
|
||||
|
||||
@@ -49,11 +49,11 @@ function Potensi() {
|
||||
|
||||
return (
|
||||
<Stack p="sm" gap="4rem">
|
||||
<Box w={{ base: "100%", sm: "60%" }}>
|
||||
<Text fz="4.4rem" fw={700} c={colors["blue-button"]}>
|
||||
<Box>
|
||||
<Text ta={"center"} fz={{ base: "2.4rem", md: "3.4rem" }} fw={700} c={colors["blue-button"]}>
|
||||
{textHeading.title}
|
||||
</Text>
|
||||
<Text size="1.4rem" c="black">
|
||||
<Text ta={"center"} fz={{ base: "1.4rem", md: "1.6rem" }} c="black">
|
||||
{textHeading.des}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user