Fix UI Admin Keamanan Lingkungan
This commit is contained in:
@@ -11,15 +11,21 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
Title
|
Title,
|
||||||
|
Tooltip,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconArrowBack, IconImageInPicture, IconPhoto, IconUpload, IconX } from "@tabler/icons-react";
|
import {
|
||||||
|
IconArrowBack,
|
||||||
|
IconImageInPicture,
|
||||||
|
IconPhoto,
|
||||||
|
IconUpload,
|
||||||
|
IconX,
|
||||||
|
} from "@tabler/icons-react";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import { useProxy } from "valtio/utils";
|
import { useProxy } from "valtio/utils";
|
||||||
|
|
||||||
|
|
||||||
import EditEditor from "@/app/admin/(dashboard)/_com/editEditor";
|
import EditEditor from "@/app/admin/(dashboard)/_com/editEditor";
|
||||||
import colors from "@/con/colors";
|
import colors from "@/con/colors";
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
@@ -34,24 +40,24 @@ function EditKeamananLingkungan() {
|
|||||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
name: keamananState.edit.form.name || '',
|
name: keamananState.edit.form.name || "",
|
||||||
deskripsi: keamananState.edit.form.deskripsi || '',
|
deskripsi: keamananState.edit.form.deskripsi || "",
|
||||||
imageId: keamananState.edit.form.imageId || ''
|
imageId: keamananState.edit.form.imageId || "",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load berita by id saat pertama kali
|
// Load data by id
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadBerita = async () => {
|
const loadData = async () => {
|
||||||
const id = params?.id as string;
|
const id = params?.id as string;
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await keamananState.edit.load(id); // akses langsung, bukan dari proxy
|
const data = await keamananState.edit.load(id);
|
||||||
if (data) {
|
if (data) {
|
||||||
setFormData({
|
setFormData({
|
||||||
name: data.name || '',
|
name: data.name || "",
|
||||||
deskripsi: data.deskripsi || '',
|
deskripsi: data.deskripsi || "",
|
||||||
imageId: data.imageId || '',
|
imageId: data.imageId || "",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data?.image?.link) {
|
if (data?.image?.link) {
|
||||||
@@ -64,30 +70,29 @@ function EditKeamananLingkungan() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadBerita();
|
loadData();
|
||||||
}, [params?.id]); // ✅ hapus beritaState dari dependency
|
}, [params?.id]);
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update global state with form data
|
|
||||||
keamananState.edit.form = {
|
keamananState.edit.form = {
|
||||||
...keamananState.edit.form,
|
...keamananState.edit.form,
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
deskripsi: formData.deskripsi,
|
deskripsi: formData.deskripsi,
|
||||||
imageId: formData.imageId // Keep existing imageId if not changed
|
imageId: formData.imageId,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Jika ada file baru, upload
|
|
||||||
if (file) {
|
if (file) {
|
||||||
const res = await ApiFetch.api.fileStorage.create.post({ file, name: file.name });
|
const res = await ApiFetch.api.fileStorage.create.post({
|
||||||
|
file,
|
||||||
|
name: file.name,
|
||||||
|
});
|
||||||
const uploaded = res.data?.data;
|
const uploaded = res.data?.data;
|
||||||
|
|
||||||
if (!uploaded?.id) {
|
if (!uploaded?.id) {
|
||||||
return toast.error("Gagal upload gambar");
|
return toast.error("Gagal upload gambar");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update imageId in global state
|
|
||||||
keamananState.edit.form.imageId = uploaded.id;
|
keamananState.edit.form.imageId = uploaded.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,36 +106,72 @@ function EditKeamananLingkungan() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box px={{ base: "sm", md: "lg" }} py="md">
|
||||||
<Box mb={10}>
|
{/* Header */}
|
||||||
<Button variant="subtle" onClick={() => router.back()}>
|
<Group mb="md">
|
||||||
<IconArrowBack color={colors["blue-button"]} size={30} />
|
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
|
||||||
|
<Button
|
||||||
|
variant="subtle"
|
||||||
|
onClick={() => router.back()}
|
||||||
|
p="xs"
|
||||||
|
radius="md"
|
||||||
|
>
|
||||||
|
<IconArrowBack color={colors["blue-button"]} size={24} />
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Tooltip>
|
||||||
<Paper bg={"white"} p={"md"} w={{ base: "100%", md: "50%" }}>
|
<Title order={4} ml="sm" c="dark">
|
||||||
<Stack gap={"xs"}>
|
Edit Keamanan Lingkungan
|
||||||
<Title order={3}>Edit Keamanan Lingkungan</Title>
|
</Title>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
{/* Form */}
|
||||||
|
<Paper
|
||||||
|
w={{ base: "100%", md: "50%" }}
|
||||||
|
bg={colors["white-1"]}
|
||||||
|
p="lg"
|
||||||
|
radius="md"
|
||||||
|
shadow="sm"
|
||||||
|
style={{ border: "1px solid #e0e0e0" }}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
<Dropzone
|
<Dropzone
|
||||||
onDrop={(files) => {
|
onDrop={(files) => {
|
||||||
const selectedFile = files[0]; // Ambil file pertama
|
const selectedFile = files[0];
|
||||||
if (selectedFile) {
|
if (selectedFile) {
|
||||||
setFile(selectedFile);
|
setFile(selectedFile);
|
||||||
setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview
|
setPreviewImage(URL.createObjectURL(selectedFile));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onReject={() => toast.error('File tidak valid.')}
|
onReject={() => toast.error("File tidak valid.")}
|
||||||
maxSize={5 * 1024 ** 2} // Maks 5MB
|
maxSize={5 * 1024 ** 2}
|
||||||
accept={{ 'image/*': [] }}
|
accept={{ "image/*": [] }}
|
||||||
|
>
|
||||||
|
<Group
|
||||||
|
justify="center"
|
||||||
|
gap="xl"
|
||||||
|
mih={220}
|
||||||
|
style={{ pointerEvents: "none" }}
|
||||||
>
|
>
|
||||||
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: 'none' }}>
|
|
||||||
<Dropzone.Accept>
|
<Dropzone.Accept>
|
||||||
<IconUpload size={52} color="var(--mantine-color-blue-6)" stroke={1.5} />
|
<IconUpload
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-blue-6)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Accept>
|
</Dropzone.Accept>
|
||||||
<Dropzone.Reject>
|
<Dropzone.Reject>
|
||||||
<IconX size={52} color="var(--mantine-color-red-6)" stroke={1.5} />
|
<IconX
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-red-6)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Reject>
|
</Dropzone.Reject>
|
||||||
<Dropzone.Idle>
|
<Dropzone.Idle>
|
||||||
<IconPhoto size={52} color="var(--mantine-color-dimmed)" stroke={1.5} />
|
<IconPhoto
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-dimmed)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Idle>
|
</Dropzone.Idle>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -151,15 +192,21 @@ function EditKeamananLingkungan() {
|
|||||||
<IconImageInPicture />
|
<IconImageInPicture />
|
||||||
</Center>
|
</Center>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
value={formData.name}
|
value={formData.name}
|
||||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
onChange={(e) =>
|
||||||
label={<Text fz={"sm"} fw={"bold"}>Judul Keamanan Lingkungan</Text>}
|
setFormData({ ...formData, name: e.target.value })
|
||||||
placeholder="masukkan judul"
|
}
|
||||||
|
label="Judul Keamanan Lingkungan"
|
||||||
|
placeholder="Masukkan judul"
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text fz={"sm"} fw={"bold"}>Deskripsi</Text>
|
<Text fz="sm" fw="bold">
|
||||||
|
Deskripsi
|
||||||
|
</Text>
|
||||||
<EditEditor
|
<EditEditor
|
||||||
value={formData.deskripsi}
|
value={formData.deskripsi}
|
||||||
onChange={(htmlContent) => {
|
onChange={(htmlContent) => {
|
||||||
@@ -169,7 +216,20 @@ function EditKeamananLingkungan() {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Button onClick={handleSubmit}>Simpan</Button>
|
<Group justify="right">
|
||||||
|
<Button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
radius="md"
|
||||||
|
size="md"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(135deg, ${colors["blue-button"]}, #4facfe)`,
|
||||||
|
color: "#fff",
|
||||||
|
boxShadow: "0 4px 15px rgba(79, 172, 254, 0.4)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Simpan
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
|
|
||||||
import { Box, Button, Flex, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
|
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
|
||||||
import { useParams, useRouter } from 'next/navigation';
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
@@ -36,64 +36,95 @@ function DetailKeamananLingkungan() {
|
|||||||
if (!keamananState.findUnique.data) {
|
if (!keamananState.findUnique.data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={40} />
|
<Skeleton height={500} radius="md" />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data = keamananState.findUnique.data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box py={10}>
|
||||||
<Box mb={10}>
|
{/* Tombol Back */}
|
||||||
<Button variant="subtle" onClick={() => router.back()}>
|
|
||||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
<Paper bg={colors['white-1']} w={{ base: "100%", md: "100%", lg: "50%" }} p={'md'}>
|
|
||||||
<Stack>
|
|
||||||
<Text fz={"xl"} fw={"bold"}>Detail Keamanan Lingkungan</Text>
|
|
||||||
{keamananState.findUnique.data ? (
|
|
||||||
<Paper key={keamananState.findUnique.data.id} bg={colors['BG-trans']} p={'md'}>
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"} fz={"lg"}>Gambar</Text>
|
|
||||||
<Image w={{ base: 150, md: 490}} src={keamananState.findUnique.data?.image?.link} alt="gambar" />
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"} fz={"lg"}>Judul Keamanan Lingkungan</Text>
|
|
||||||
<Text fz={"lg"}>{keamananState.findUnique.data?.name}</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"} fz={"lg"}>Deskripsi</Text>
|
|
||||||
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: keamananState.findUnique.data?.deskripsi }} />
|
|
||||||
</Box>
|
|
||||||
<Flex gap={"xs"} mt={10}>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
variant="subtle"
|
||||||
if (keamananState.findUnique.data) {
|
onClick={() => router.back()}
|
||||||
setSelectedId(keamananState.findUnique.data.id);
|
leftSection={<IconArrowBack size={24} color={colors['blue-button']} />}
|
||||||
setModalHapus(true);
|
mb={15}
|
||||||
}
|
|
||||||
}}
|
|
||||||
disabled={keamananState.delete.loading || !keamananState.findUnique.data}
|
|
||||||
color={"red"}
|
|
||||||
>
|
>
|
||||||
<IconX size={20} />
|
Kembali
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Wrapper Detail */}
|
||||||
|
<Paper
|
||||||
|
withBorder
|
||||||
|
w={{ base: "100%", md: "50%" }}
|
||||||
|
bg={colors['white-1']}
|
||||||
|
p="lg"
|
||||||
|
radius="md"
|
||||||
|
shadow="sm"
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Text fz="2xl" fw="bold" c={colors['blue-button']}>
|
||||||
|
Detail Keamanan Lingkungan
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Paper bg="#ECEEF8" p="md" radius="md" shadow="xs">
|
||||||
|
<Stack gap="sm">
|
||||||
|
<Box>
|
||||||
|
<Text fz="lg" fw="bold">Gambar</Text>
|
||||||
|
<Image
|
||||||
|
w={{ base: 150, md: 490 }}
|
||||||
|
src={data?.image?.link}
|
||||||
|
alt="gambar keamanan lingkungan"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box>
|
||||||
|
<Text fz="lg" fw="bold">Judul Keamanan Lingkungan</Text>
|
||||||
|
<Text fz="md" c="dimmed">{data?.name || '-'}</Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box>
|
||||||
|
<Text fz="lg" fw="bold">Deskripsi</Text>
|
||||||
|
<Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data?.deskripsi }} />
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Aksi */}
|
||||||
|
<Group gap="sm">
|
||||||
|
<Tooltip label="Hapus Data" withArrow position="top">
|
||||||
<Button
|
<Button
|
||||||
|
color="red"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (keamananState.findUnique.data) {
|
setSelectedId(data.id);
|
||||||
router.push(`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${keamananState.findUnique.data.id}/edit`);
|
setModalHapus(true);
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
disabled={!keamananState.findUnique.data}
|
variant="light"
|
||||||
color={"green"}
|
radius="md"
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
<IconTrash size={20} />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Tooltip label="Edit Data" withArrow position="top">
|
||||||
|
<Button
|
||||||
|
color="green"
|
||||||
|
onClick={() =>
|
||||||
|
router.push(
|
||||||
|
`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${data.id}/edit`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
variant="light"
|
||||||
|
radius="md"
|
||||||
|
size="md"
|
||||||
>
|
>
|
||||||
<IconEdit size={20} />
|
<IconEdit size={20} />
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
) : null}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
@@ -102,7 +133,7 @@ function DetailKeamananLingkungan() {
|
|||||||
opened={modalHapus}
|
opened={modalHapus}
|
||||||
onClose={() => setModalHapus(false)}
|
onClose={() => setModalHapus(false)}
|
||||||
onConfirm={handleHapus}
|
onConfirm={handleHapus}
|
||||||
text='Apakah anda yakin ingin menghapus keamanan lingkungan ini?'
|
text="Apakah anda yakin ingin menghapus keamanan lingkungan ini?"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,25 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import ApiFetch from '@/lib/api-fetch';
|
import ApiFetch from '@/lib/api-fetch';
|
||||||
import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Group,
|
||||||
|
Image,
|
||||||
|
Paper,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
} from '@mantine/core';
|
||||||
import { Dropzone } from '@mantine/dropzone';
|
import { Dropzone } from '@mantine/dropzone';
|
||||||
import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react';
|
import {
|
||||||
|
IconArrowBack,
|
||||||
|
IconPhoto,
|
||||||
|
IconUpload,
|
||||||
|
IconX,
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
@@ -11,37 +27,36 @@ import { useProxy } from 'valtio/utils';
|
|||||||
import CreateEditor from '../../../_com/createEditor';
|
import CreateEditor from '../../../_com/createEditor';
|
||||||
import keamananLingkunganState from '../../../_state/keamanan/keamanan-lingkungan';
|
import keamananLingkunganState from '../../../_state/keamanan/keamanan-lingkungan';
|
||||||
|
|
||||||
|
|
||||||
function CreateKeamananLingkungan() {
|
function CreateKeamananLingkungan() {
|
||||||
const keamananState = useProxy(keamananLingkunganState)
|
const keamananState = useProxy(keamananLingkunganState);
|
||||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
keamananState.create.form = {
|
keamananState.create.form = {
|
||||||
name: "",
|
name: '',
|
||||||
deskripsi: "",
|
deskripsi: '',
|
||||||
imageId: "",
|
imageId: '',
|
||||||
}
|
};
|
||||||
setPreviewImage(null);
|
setPreviewImage(null);
|
||||||
setFile(null);
|
setFile(null);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return toast.warn("Pilih file gambar terlebih dahulu");
|
return toast.warn('Pilih file gambar terlebih dahulu');
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await ApiFetch.api.fileStorage.create.post({
|
const res = await ApiFetch.api.fileStorage.create.post({
|
||||||
file,
|
file,
|
||||||
name: file.name,
|
name: file.name,
|
||||||
})
|
});
|
||||||
|
|
||||||
const uploaded = res.data?.data;
|
const uploaded = res.data?.data;
|
||||||
|
|
||||||
if (!uploaded?.id) {
|
if (!uploaded?.id) {
|
||||||
return toast.error("Gagal mengupload file");
|
return toast.error('Gagal mengupload file');
|
||||||
}
|
}
|
||||||
|
|
||||||
keamananState.create.form.imageId = uploaded.id;
|
keamananState.create.form.imageId = uploaded.id;
|
||||||
@@ -49,44 +64,81 @@ function CreateKeamananLingkungan() {
|
|||||||
await keamananState.create.create();
|
await keamananState.create.create();
|
||||||
|
|
||||||
resetForm();
|
resetForm();
|
||||||
router.push("/admin/keamanan/keamanan-lingkungan-pecalang-patwal")
|
router.push('/admin/keamanan/keamanan-lingkungan-pecalang-patwal');
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box px={{ base: 'sm', md: 'lg' }} py="md">
|
||||||
<Box mb={10}>
|
{/* Header */}
|
||||||
<Button onClick={() => router.back()} variant='subtle' color={'blue'}>
|
<Group mb="md">
|
||||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
|
||||||
|
<Button
|
||||||
|
variant="subtle"
|
||||||
|
onClick={() => router.back()}
|
||||||
|
p="xs"
|
||||||
|
radius="md"
|
||||||
|
>
|
||||||
|
<IconArrowBack color={colors['blue-button']} size={24} />
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Tooltip>
|
||||||
|
<Title order={4} ml="sm" c="dark">
|
||||||
|
Tambah Data Keamanan Lingkungan
|
||||||
|
</Title>
|
||||||
|
</Group>
|
||||||
|
|
||||||
<Paper w={{ base: '100%', md: '50%' }} bg={colors['white-1']} p={'md'}>
|
{/* Form */}
|
||||||
<Stack gap={"xs"}>
|
<Paper
|
||||||
<Title order={4}>Create Keamanan Lingkungan</Title>
|
w={{ base: '100%', md: '50%' }}
|
||||||
<Box>
|
bg={colors['white-1']}
|
||||||
<Text fz={"md"} fw={"bold"}>Gambar</Text>
|
p="lg"
|
||||||
|
radius="md"
|
||||||
|
shadow="sm"
|
||||||
|
style={{ border: '1px solid #e0e0e0' }}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
{/* Upload Gambar */}
|
||||||
<Box>
|
<Box>
|
||||||
|
<Text fz="sm" fw="bold">
|
||||||
|
Gambar
|
||||||
|
</Text>
|
||||||
<Dropzone
|
<Dropzone
|
||||||
onDrop={(files) => {
|
onDrop={(files) => {
|
||||||
const selectedFile = files[0]; // Ambil file pertama
|
const selectedFile = files[0];
|
||||||
if (selectedFile) {
|
if (selectedFile) {
|
||||||
setFile(selectedFile);
|
setFile(selectedFile);
|
||||||
setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview
|
setPreviewImage(URL.createObjectURL(selectedFile));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onReject={() => toast.error('File tidak valid.')}
|
onReject={() => toast.error('File tidak valid.')}
|
||||||
maxSize={5 * 1024 ** 2} // Maks 5MB
|
maxSize={5 * 1024 ** 2}
|
||||||
accept={{ 'image/*': [] }}
|
accept={{ 'image/*': [] }}
|
||||||
>
|
>
|
||||||
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: 'none' }}>
|
<Group
|
||||||
|
justify="center"
|
||||||
|
gap="xl"
|
||||||
|
mih={220}
|
||||||
|
style={{ pointerEvents: 'none' }}
|
||||||
|
>
|
||||||
<Dropzone.Accept>
|
<Dropzone.Accept>
|
||||||
<IconUpload size={52} color="var(--mantine-color-blue-6)" stroke={1.5} />
|
<IconUpload
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-blue-6)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Accept>
|
</Dropzone.Accept>
|
||||||
<Dropzone.Reject>
|
<Dropzone.Reject>
|
||||||
<IconX size={52} color="var(--mantine-color-red-6)" stroke={1.5} />
|
<IconX
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-red-6)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Reject>
|
</Dropzone.Reject>
|
||||||
<Dropzone.Idle>
|
<Dropzone.Idle>
|
||||||
<IconPhoto size={52} color="var(--mantine-color-dimmed)" stroke={1.5} />
|
<IconPhoto
|
||||||
|
size={52}
|
||||||
|
color="var(--mantine-color-dimmed)"
|
||||||
|
stroke={1.5}
|
||||||
|
/>
|
||||||
</Dropzone.Idle>
|
</Dropzone.Idle>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -100,7 +152,6 @@ function CreateKeamananLingkungan() {
|
|||||||
</Group>
|
</Group>
|
||||||
</Dropzone>
|
</Dropzone>
|
||||||
|
|
||||||
{/* Tampilkan preview kalau ada */}
|
|
||||||
{previewImage && (
|
{previewImage && (
|
||||||
<Box mt="sm">
|
<Box mt="sm">
|
||||||
<Image
|
<Image
|
||||||
@@ -116,19 +167,24 @@ function CreateKeamananLingkungan() {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
</Box>
|
{/* Input Nama */}
|
||||||
</Box>
|
|
||||||
<TextInput
|
<TextInput
|
||||||
value={keamananState.create.form.name}
|
value={keamananState.create.form.name}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
keamananState.create.form.name = val.target.value;
|
keamananState.create.form.name = val.target.value;
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nama Keamanan Lingkungan</Text>}
|
label={<Text fw="bold" fz="sm">Nama Keamanan Lingkungan</Text>}
|
||||||
placeholder='Masukkan nama Keamanan Lingkungan'
|
placeholder="Masukkan nama Keamanan Lingkungan"
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Input Deskripsi */}
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={"bold"} fz={"sm"}>Deskripsi Keamanan Lingkungan</Text>
|
<Text fw="bold" fz="sm">
|
||||||
|
Deskripsi Keamanan Lingkungan
|
||||||
|
</Text>
|
||||||
<CreateEditor
|
<CreateEditor
|
||||||
value={keamananState.create.form.deskripsi}
|
value={keamananState.create.form.deskripsi}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
@@ -136,8 +192,21 @@ function CreateKeamananLingkungan() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Group>
|
|
||||||
<Button onClick={handleSubmit} bg={colors['blue-button']}>Submit</Button>
|
{/* Tombol Submit */}
|
||||||
|
<Group justify="right">
|
||||||
|
<Button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
radius="md"
|
||||||
|
size="md"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||||
|
color: '#fff',
|
||||||
|
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Simpan
|
||||||
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|||||||
@@ -1,26 +1,46 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
import {
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
Box,
|
||||||
import HeaderSearch from '../../_com/header';
|
Button,
|
||||||
import JudulList from '../../_com/judulList';
|
Center,
|
||||||
import { useRouter } from 'next/navigation';
|
Group,
|
||||||
import { useProxy } from 'valtio/utils';
|
Pagination,
|
||||||
import keamananLingkunganState from '../../_state/keamanan/keamanan-lingkungan';
|
Paper,
|
||||||
|
Skeleton,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
TableTbody,
|
||||||
|
TableTd,
|
||||||
|
TableTh,
|
||||||
|
TableThead,
|
||||||
|
TableTr,
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
} from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import HeaderSearch from '../../_com/header';
|
||||||
|
import keamananLingkunganState from '../../_state/keamanan/keamanan-lingkungan';
|
||||||
|
|
||||||
function KeamananLingkungan() {
|
function KeamananLingkungan() {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
{/* Header Search */}
|
||||||
<HeaderSearch
|
<HeaderSearch
|
||||||
title='Keamanan Lingkungan'
|
title='Keamanan Lingkungan'
|
||||||
placeholder='pencarian'
|
placeholder='Cari nama atau deskripsi...'
|
||||||
searchIcon={<IconSearch size={20} />}
|
searchIcon={<IconSearch size={20} />}
|
||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ListKeamananLingkungan search={search} />
|
<ListKeamananLingkungan search={search} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@@ -47,54 +67,94 @@ function ListKeamananLingkungan({ search }: { search: string }) {
|
|||||||
if (loading || !data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton height={600} radius="md" />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box py={10}>
|
<Box py={10}>
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
|
||||||
<JudulList
|
{/* Judul + Tombol Tambah */}
|
||||||
title='List Keamanan Lingkungan'
|
<Group justify="space-between" mb="md">
|
||||||
href='/admin/keamanan/keamanan-lingkungan-pecalang-patwal/create'
|
<Title order={4}>Daftar Keamanan Lingkungan</Title>
|
||||||
/>
|
<Tooltip label="Tambah Data Keamanan" withArrow>
|
||||||
<Table striped withTableBorder withRowBorders>
|
<Button
|
||||||
|
leftSection={<IconPlus size={18} />}
|
||||||
|
color="blue"
|
||||||
|
variant="light"
|
||||||
|
onClick={() =>
|
||||||
|
router.push('/admin/keamanan/keamanan-lingkungan-pecalang-patwal/create')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Tambah Baru
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
{/* Tabel */}
|
||||||
|
<Box style={{ overflowX: "auto" }}>
|
||||||
|
<Table highlightOnHover>
|
||||||
<TableThead>
|
<TableThead>
|
||||||
<TableTr>
|
<TableTr>
|
||||||
<TableTh>Nama Keamanan Lingkungan</TableTh>
|
<TableTh>Nama</TableTh>
|
||||||
<TableTh>Deskripsi</TableTh>
|
<TableTh>Deskripsi</TableTh>
|
||||||
<TableTh>Detail</TableTh>
|
<TableTh>Aksi</TableTh>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.length > 0 ? (
|
||||||
|
filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Box w={180}>
|
<Text fw={500} truncate="end" lineClamp={1}>
|
||||||
<Text fz={"md"} truncate={"end"} lineClamp={1}>{item.name}</Text>
|
{item.name}
|
||||||
</Box>
|
</Text>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Box w={250}>
|
<Text fz="sm" c="dimmed" truncate lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
||||||
<Text fz={"md"} truncate={"end"} lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
|
||||||
</Box>
|
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Button onClick={() => router.push(`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${item.id}`)}>
|
<Button
|
||||||
<IconDeviceImac size={20} />
|
variant="light"
|
||||||
|
color="blue"
|
||||||
|
onClick={() => router.push(`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${item.id}`)}
|
||||||
|
>
|
||||||
|
<IconDeviceImacCog size={20} />
|
||||||
|
<Text ml={5}>Detail</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
))}
|
))
|
||||||
|
) : (
|
||||||
|
<TableTr>
|
||||||
|
<TableTd colSpan={3}>
|
||||||
|
<Center py={20}>
|
||||||
|
<Text color="dimmed">
|
||||||
|
Tidak ada data keamanan lingkungan yang cocok
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
</TableTd>
|
||||||
|
</TableTr>
|
||||||
|
)}
|
||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
|
{/* Pagination */}
|
||||||
<Center>
|
<Center>
|
||||||
<Pagination
|
<Pagination
|
||||||
value={page}
|
value={page}
|
||||||
onChange={(newPage) => load(newPage)}
|
onChange={(newPage) => {
|
||||||
|
load(newPage, 10);
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}}
|
||||||
total={totalPages}
|
total={totalPages}
|
||||||
my={"md"}
|
mt="md"
|
||||||
|
mb="md"
|
||||||
|
color="blue"
|
||||||
|
radius="md"
|
||||||
/>
|
/>
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,26 +1,45 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Group,
|
||||||
|
Pagination,
|
||||||
|
Paper,
|
||||||
|
Skeleton,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
TableTbody,
|
||||||
|
TableTd,
|
||||||
|
TableTh,
|
||||||
|
TableThead,
|
||||||
|
TableTr,
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
} from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { useState } from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import HeaderSearch from '../../_com/header';
|
import HeaderSearch from '../../_com/header';
|
||||||
import JudulList from '../../_com/judulList';
|
|
||||||
import polsekTerdekat from '../../_state/keamanan/polsek-terdekat';
|
import polsekTerdekat from '../../_state/keamanan/polsek-terdekat';
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
function PolsekTerdekat() {
|
function PolsekTerdekat() {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<HeaderSearch
|
<HeaderSearch
|
||||||
title='Polsek Terdekat'
|
title='Polsek Terdekat'
|
||||||
placeholder='pencarian'
|
placeholder='Cari nama atau alamat...'
|
||||||
searchIcon={<IconSearch size={20} />}
|
searchIcon={<IconSearch size={20} />}
|
||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ListPolsekTerdekat search={search} />
|
<ListPolsekTerdekat search={search} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@@ -47,60 +66,90 @@ function ListPolsekTerdekat({ search }: { search: string }) {
|
|||||||
if (loading || !data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton height={600} radius="md" />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box py={10}>
|
<Box py={10}>
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
|
||||||
<JudulList
|
<Group justify="space-between" mb="md">
|
||||||
title='List Polsek Terdekat'
|
<Title order={4}>Daftar Polsek Terdekat</Title>
|
||||||
href='/admin/keamanan/polsek-terdekat/create'
|
<Tooltip label="Tambah Polsek" withArrow>
|
||||||
/>
|
<Button
|
||||||
<Table striped withTableBorder withRowBorders>
|
leftSection={<IconPlus size={18} />}
|
||||||
|
color="blue"
|
||||||
|
variant="light"
|
||||||
|
onClick={() => router.push('/admin/keamanan/polsek-terdekat/create')}
|
||||||
|
>
|
||||||
|
Tambah Baru
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Box style={{ overflowX: "auto" }}>
|
||||||
|
<Table highlightOnHover>
|
||||||
<TableThead>
|
<TableThead>
|
||||||
<TableTr>
|
<TableTr>
|
||||||
<TableTh>Nama Polsek Terdekat</TableTh>
|
<TableTh>Nama Polsek</TableTh>
|
||||||
<TableTh>Jarak Polsek</TableTh>
|
<TableTh>Jarak</TableTh>
|
||||||
<TableTh>Alamat</TableTh>
|
<TableTh>Alamat</TableTh>
|
||||||
<TableTh>Detail</TableTh>
|
<TableTh>Aksi</TableTh>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.length > 0 ? (
|
||||||
|
filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Box w={180}>
|
<Text fw={500} truncate="end" lineClamp={1}>
|
||||||
<Text fz='md' truncate={"end"} lineClamp={1}>{item.nama}</Text>
|
{item.nama}
|
||||||
</Box>
|
</Text>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
|
<TableTd>{item.jarakKeDesa}</TableTd>
|
||||||
|
<TableTd>{item.alamat}</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Box w={180}>
|
<Button
|
||||||
<Text fz='md' truncate={"end"} lineClamp={1}>{item.jarakKeDesa}</Text>
|
variant="light"
|
||||||
</Box>
|
color="blue"
|
||||||
</TableTd>
|
onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${item.id}`)}
|
||||||
<TableTd>
|
>
|
||||||
<Box w={250}>
|
<IconDeviceImac size={18} />
|
||||||
<Text fz='md' truncate={"end"} lineClamp={1}>{item.alamat}</Text>
|
<Text ml={5}>Detail</Text>
|
||||||
</Box>
|
|
||||||
</TableTd>
|
|
||||||
<TableTd>
|
|
||||||
<Button onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${item.id}`)}>
|
|
||||||
<IconDeviceImac size={20} />
|
|
||||||
</Button>
|
</Button>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
))}
|
))
|
||||||
|
) : (
|
||||||
|
<TableTr>
|
||||||
|
<TableTd colSpan={4}>
|
||||||
|
<Center py={20}>
|
||||||
|
<Text color="dimmed">
|
||||||
|
Tidak ada data Polsek yang cocok
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
</TableTd>
|
||||||
|
</TableTr>
|
||||||
|
)}
|
||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
|
{/* Pagination */}
|
||||||
<Center>
|
<Center>
|
||||||
<Pagination
|
<Pagination
|
||||||
value={page}
|
value={page}
|
||||||
onChange={(newPage) => load(newPage)}
|
onChange={(newPage) => {
|
||||||
|
load(newPage, 10, search);
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}}
|
||||||
total={totalPages}
|
total={totalPages}
|
||||||
my="md"
|
mt="md"
|
||||||
|
mb="md"
|
||||||
|
color="blue"
|
||||||
|
radius="md"
|
||||||
/>
|
/>
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user