Compare commits

...

7 Commits

Author SHA1 Message Date
db8909b9ed Fix Text to Speech Menu Landing Page && Add barchart Landing Page APBDes 2025-11-06 11:35:04 +08:00
f66a46f645 QC ToolTip Admin Keano Masih di Menu Landing Page - Keamanan, QC Dari Darmasaba Pop Up Notifikasi 2025-11-05 14:32:38 +08:00
fb57698dc9 Add Menu Musik
Add News Reader for Difable
Add Running text news / announcement
2025-11-04 15:08:48 +08:00
d128313e71 Fix QC Keano FrontEnd
Fix QC Kak Ayu Admin 29 Okt
2025-11-03 17:36:00 +08:00
7b4bb1e58e QC Kak Inno FrontEnd Done
QC Kak Ayu FrontEnd Done
QC Keano 31 Okt
2025-11-03 10:28:03 +08:00
0befe6a3f2 QC Kak Inno 28 Okt
QC Kak Ayu 28 Okt
QC Keano 28 Okt
2025-10-30 15:51:12 +08:00
a6663bbcee QC Kak Inno 27 Oct
QC Kak Ayu 27 Oct
QC Keano 27 Oct
QC Pak Jun 27 Oct
2025-10-28 17:34:38 +08:00
305 changed files with 7194 additions and 4799 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -19,6 +19,7 @@
"@elysiajs/static": "^1.3.0", "@elysiajs/static": "^1.3.0",
"@elysiajs/stream": "^1.1.0", "@elysiajs/stream": "^1.1.0",
"@elysiajs/swagger": "^1.2.0", "@elysiajs/swagger": "^1.2.0",
"@emotion/react": "^11.14.0",
"@mantine/carousel": "^7.16.2", "@mantine/carousel": "^7.16.2",
"@mantine/charts": "^7.17.1", "@mantine/charts": "^7.17.1",
"@mantine/core": "^7.17.4", "@mantine/core": "^7.17.4",
@@ -26,6 +27,7 @@
"@mantine/dropzone": "^8.1.1", "@mantine/dropzone": "^8.1.1",
"@mantine/form": "^8.1.0", "@mantine/form": "^8.1.0",
"@mantine/hooks": "^7.17.4", "@mantine/hooks": "^7.17.4",
"@mantine/modals": "^8.3.6",
"@mantine/tiptap": "^7.17.4", "@mantine/tiptap": "^7.17.4",
"@paljs/types": "^8.1.0", "@paljs/types": "^8.1.0",
"@prisma/client": "^6.3.1", "@prisma/client": "^6.3.1",
@@ -55,8 +57,9 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"elysia": "^1.3.5", "elysia": "^1.3.5",
"embla-carousel-autoplay": "^8.5.2", "embla-carousel": "^8.6.0",
"embla-carousel-react": "^7.1.0", "embla-carousel-autoplay": "^8.6.0",
"embla-carousel-react": "^8.6.0",
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
"form-data": "^4.0.2", "form-data": "^4.0.2",
"framer-motion": "^12.23.5", "framer-motion": "^12.23.5",
@@ -80,6 +83,7 @@
"prisma": "^6.3.1", "prisma": "^6.3.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-exif-orientation-img": "^0.1.5",
"react-international-phone": "^4.6.0", "react-international-phone": "^4.6.0",
"react-leaflet": "^5.0.0", "react-leaflet": "^5.0.0",
"react-simple-toasts": "^6.1.0", "react-simple-toasts": "^6.1.0",

View File

@@ -6,9 +6,9 @@ import { proxy } from "valtio";
import { z } from "zod"; import { z } from "zod";
const templateForm = z.object({ const templateForm = z.object({
name: z.string().min(1, "Nama minimal 1 karakter"), name: z.string().min(5, "Nama minimal 5 karakter"),
deskripsi: z.string().min(1, "Deskripsi minimal 1 karakter"), deskripsi: z.string().min(5, "Deskripsi minimal 5 karakter"),
slug: z.string().min(1, "Deskripsi singkat minimal 1 karakter"), slug: z.string().min(5, "Deskripsi singkat minimal 5 karakter"),
icon: z.string().min(1, "Icon minimal 1 karakter"), icon: z.string().min(1, "Icon minimal 1 karakter"),
}); });
@@ -29,26 +29,33 @@ const programKreatifState = proxy({
const err = `[${cek.error.issues const err = `[${cek.error.issues
.map((v) => `${v.path.join(".")}`) .map((v) => `${v.path.join(".")}`)
.join("\n")}] required`; .join("\n")}] required`;
return toast.error(err); toast.error(err);
return false; // ⬅️ ini penting
} }
try { try {
programKreatifState.create.loading = true; programKreatifState.create.loading = true;
const res = await ApiFetch.api.inovasi.programkreatif["create"].post( const res = await ApiFetch.api.inovasi.programkreatif["create"].post(
programKreatifState.create.form programKreatifState.create.form
); );
if (res.status === 200) { if (res.status === 200) {
programKreatifState.findMany.load(); programKreatifState.findMany.load();
return toast.success("success create"); toast.success("success create");
return true;
} }
console.log(res);
return toast.error("failed create"); toast.error("failed create");
return false;
} catch (error) { } catch (error) {
console.log((error as Error).message); console.error((error as Error).message);
toast.error("Terjadi kesalahan saat create");
return false;
} finally { } finally {
programKreatifState.create.loading = false; programKreatifState.create.loading = false;
} }
}, }
}, },
findMany: { findMany: {
data: null as any[] | null, data: null as any[] | null,

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconBuildingStore, IconFileText, IconSparkles, IconUsers, IconUsersPlus } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { IconFileText, IconBuildingStore, IconSparkles, IconUsers, IconUsersPlus } from '@tabler/icons-react';
function LayoutTabsLayanan({ children }: { children: React.ReactNode }) { function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
const router = useRouter() const router = useRouter()
@@ -14,36 +14,31 @@ function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
label: "Pelayanan Surat Keterangan", label: "Pelayanan Surat Keterangan",
value: "pelayanansuratketerangan", value: "pelayanansuratketerangan",
href: "/admin/desa/layanan/pelayanan_surat_keterangan", href: "/admin/desa/layanan/pelayanan_surat_keterangan",
icon: <IconFileText size={18} stroke={1.8} />, icon: <IconFileText size={18} stroke={1.8} />
tooltip: "Layanan terkait surat keterangan resmi desa"
}, },
{ {
label: "Pelayanan Perizinan Berusaha", label: "Pelayanan Perizinan Berusaha",
value: "pelayananperizinanusaha", value: "pelayananperizinanusaha",
href: "/admin/desa/layanan/pelayanan_perizinan_berusaha", href: "/admin/desa/layanan/pelayanan_perizinan_berusaha",
icon: <IconBuildingStore size={18} stroke={1.8} />, icon: <IconBuildingStore size={18} stroke={1.8} />
tooltip: "Layanan untuk izin usaha masyarakat"
}, },
{ {
label: "Pelayanan Telunjuk Sakti Desa", label: "Pelayanan Telunjuk Sakti Desa",
value: "pelayanantelunjuksaktidesa", value: "pelayanantelunjuksaktidesa",
href: "/admin/desa/layanan/pelayanan_telunjuk_sakti_desa", href: "/admin/desa/layanan/pelayanan_telunjuk_sakti_desa",
icon: <IconSparkles size={18} stroke={1.8} />, icon: <IconSparkles size={18} stroke={1.8} />
tooltip: "Layanan inovasi khusus desa"
}, },
{ {
label: "Pelayanan Penduduk Non-Permanent", label: "Pelayanan Penduduk Non-Permanent",
value: "pelayanannonpermanent", value: "pelayanannonpermanent",
href: "/admin/desa/layanan/pelayanan_penduduk_non_permanent", href: "/admin/desa/layanan/pelayanan_penduduk_non_permanent",
icon: <IconUsers size={18} stroke={1.8} />, icon: <IconUsers size={18} stroke={1.8} />
tooltip: "Pendataan penduduk non-permanent"
}, },
{ {
label: "Ajukan Permohonan", label: "Ajukan Permohonan",
value: "ajukanpermohonan", value: "ajukanpermohonan",
href: "/admin/desa/layanan/ajukan_permohonan", href: "/admin/desa/layanan/ajukan_permohonan",
icon: <IconUsersPlus size={18} stroke={1.8} />, icon: <IconUsersPlus size={18} stroke={1.8} />
tooltip: "Ajukan permohonan"
} }
]; ];
@@ -91,14 +86,8 @@ function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip
key={i}
label={tab.tooltip}
position="bottom"
withArrow
transitionProps={{ transition: 'pop', duration: 200 }}
>
<TabsTab <TabsTab
key={i}
value={tab.value} value={tab.value}
leftSection={tab.icon} leftSection={tab.icon}
style={{ style={{
@@ -109,7 +98,6 @@ function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
> >
{tab.label} {tab.label}
</TabsTab> </TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconCategory, IconNews } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { IconNews, IconCategory } from '@tabler/icons-react';
function LayoutTabsBerita({ children }: { children: React.ReactNode }) { function LayoutTabsBerita({ children }: { children: React.ReactNode }) {
const router = useRouter(); const router = useRouter();
@@ -15,15 +15,13 @@ function LayoutTabsBerita({ children }: { children: React.ReactNode }) {
label: "List Berita", label: "List Berita",
value: "list_berita", value: "list_berita",
href: "/admin/desa/berita/list-berita", href: "/admin/desa/berita/list-berita",
icon: <IconNews size={18} stroke={1.8} />, icon: <IconNews size={18} stroke={1.8} />
tooltip: "Lihat dan kelola semua berita desa"
}, },
{ {
label: "Kategori Berita", label: "Kategori Berita",
value: "kategori_berita", value: "kategori_berita",
href: "/admin/desa/berita/kategori-berita", href: "/admin/desa/berita/kategori-berita",
icon: <IconCategory size={18} stroke={1.8} />, icon: <IconCategory size={18} stroke={1.8} />
tooltip: "Kelola kategori berita desa"
}, },
]; ];
@@ -71,46 +69,39 @@ function LayoutTabsBerita({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip <TabsTab
key={i} key={i}
label={tab.tooltip} value={tab.value}
position="bottom" leftSection={tab.icon}
withArrow style={{
transitionProps={{ transition: 'pop', duration: 200 }} fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
> >
<TabsTab {tab.label}
value={tab.value} </TabsTab>
leftSection={tab.icon}
style={{
fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
>
{tab.label}
</TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<TabsPanel <TabsPanel
key={i} key={i}
value={tab.value} value={tab.value}
style={{ style={{
padding: "1.5rem", padding: "1.5rem",
background: "linear-gradient(180deg, #ffffff, #f5f6fa)", background: "linear-gradient(180deg, #ffffff, #f5f6fa)",
borderRadius: "1rem", borderRadius: "1rem",
boxShadow: "0 4px 16px rgba(0,0,0,0.05)", boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
}} }}
> >
{/* Konten dummy, bisa diganti sesuai routing */} {/* Konten dummy, bisa diganti sesuai routing */}
<>{children}</> <>{children}</>
</TabsPanel> </TabsPanel>
))} ))}
</Tabs> </Tabs>
</Stack> </Stack >
); );
} }

View File

@@ -10,8 +10,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -77,7 +76,6 @@ function EditKategoriBerita() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back Button + Title */} {/* Back Button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -86,7 +84,6 @@ function EditKategoriBerita() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Kategori Berita Edit Kategori Berita
</Title> </Title>

View File

@@ -8,8 +8,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -35,7 +34,6 @@ function CreateKategoriBerita() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header dengan back button */} {/* Header dengan back button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -44,7 +42,6 @@ function CreateKategoriBerita() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Kategori Berita Tambah Kategori Berita
</Title> </Title>

View File

@@ -17,8 +17,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconEdit, IconPlus, IconSearch, IconTrash } from '@tabler/icons-react'; import { IconEdit, IconPlus, IconSearch, IconTrash } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -86,7 +85,6 @@ function ListKategoriBerita({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Kategori Berita</Title> <Title order={4}>Daftar Kategori Berita</Title>
<Tooltip label="Tambah Kategori Berita" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -97,7 +95,6 @@ function ListKategoriBerita({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>
@@ -123,7 +120,6 @@ function ListKategoriBerita({ search }: { search: string }) {
</Text> </Text>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Tooltip label="Edit Kategori Berita" withArrow>
<Button <Button
variant="light" variant="light"
color="green" color="green"
@@ -135,10 +131,8 @@ function ListKategoriBerita({ search }: { search: string }) {
> >
<IconEdit size={18} /> <IconEdit size={18} />
</Button> </Button>
</Tooltip>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Tooltip label="Hapus Kategori Berita" withArrow>
<Button <Button
variant="light" variant="light"
color="red" color="red"
@@ -150,7 +144,6 @@ function ListKategoriBerita({ search }: { search: string }) {
> >
<IconTrash size={18} /> <IconTrash size={18} />
</Button> </Button>
</Tooltip>
</TableTd> </TableTd>
</TableTr> </TableTr>
)) ))

View File

@@ -15,8 +15,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { Dropzone } from "@mantine/dropzone"; import { Dropzone } from "@mantine/dropzone";
import { import {
@@ -116,7 +115,6 @@ function EditBerita() {
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -125,7 +123,6 @@ function EditBerita() {
> >
<IconArrowBack color={colors["blue-button"]} size={24} /> <IconArrowBack color={colors["blue-button"]} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Berita Edit Berita
</Title> </Title>

View File

@@ -1,14 +1,14 @@
'use client' 'use client'
import { useProxy } from 'valtio/utils'; import { Box, Button, Group, 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, IconTrash } 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';
import { useProxy } from 'valtio/utils';
import colors from '@/con/colors';
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita'; import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita';
import colors from '@/con/colors';
function DetailBerita() { function DetailBerita() {
const beritaState = useProxy(stateDashboardBerita); const beritaState = useProxy(stateDashboardBerita);
@@ -111,7 +111,6 @@ function DetailBerita() {
{/* Action Button */} {/* Action Button */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Berita" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -124,9 +123,7 @@ function DetailBerita() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Berita" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => router.push(`/admin/desa/berita/list-berita/${data.id}/edit`)} onClick={() => router.push(`/admin/desa/berita/list-berita/${data.id}/edit`)}
@@ -136,7 +133,6 @@ function DetailBerita() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -13,8 +13,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { Dropzone } from '@mantine/dropzone'; import { Dropzone } from '@mantine/dropzone';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
@@ -73,7 +72,6 @@ export default function CreateBerita() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header dengan tombol kembali */} {/* Header dengan tombol kembali */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -82,7 +80,6 @@ export default function CreateBerita() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Berita Tambah Berita
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
@@ -68,7 +67,6 @@ function ListBerita({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Berita</Title> <Title order={4}>Daftar Berita</Title>
<Tooltip label="Tambah Berita" withArrow>
<Button <Button
leftSection={<IconCircleDashedPlus size={18} />} leftSection={<IconCircleDashedPlus size={18} />}
color="blue" color="blue"
@@ -77,7 +75,6 @@ function ListBerita({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>

View File

@@ -13,8 +13,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { IconSearch, IconTrash, IconX } from "@tabler/icons-react"; import { IconSearch, IconTrash, IconX } from "@tabler/icons-react";
@@ -103,7 +102,6 @@ export default function ListImage() {
</Box> </Box>
<Group justify="space-between" align="center" pt="xs"> <Group justify="space-between" align="center" pt="xs">
<Tooltip label="Hapus foto" withArrow>
<ActionIcon <ActionIcon
variant="subtle" variant="subtle"
color="red" color="red"
@@ -116,7 +114,6 @@ export default function ListImage() {
> >
<IconTrash size={18} /> <IconTrash size={18} />
</ActionIcon> </ActionIcon>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Card> </Card>

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconPhoto, IconVideo } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { IconPhoto, IconVideo } from '@tabler/icons-react';
function LayoutTabsGallery({ children }: { children: React.ReactNode }) { function LayoutTabsGallery({ children }: { children: React.ReactNode }) {
const router = useRouter() const router = useRouter()
@@ -14,15 +14,13 @@ function LayoutTabsGallery({ children }: { children: React.ReactNode }) {
label: "Foto", label: "Foto",
value: "foto", value: "foto",
href: "/admin/desa/gallery/foto", href: "/admin/desa/gallery/foto",
icon: <IconPhoto size={18} stroke={1.8} />, icon: <IconPhoto size={18} stroke={1.8} />
tooltip: "Kelola foto-foto galeri desa"
}, },
{ {
label: "Video", label: "Video",
value: "video", value: "video",
href: "/admin/desa/gallery/video", href: "/admin/desa/gallery/video",
icon: <IconVideo size={18} stroke={1.8} />, icon: <IconVideo size={18} stroke={1.8} />
tooltip: "Kelola video galeri desa"
}, },
]; ];
@@ -70,25 +68,18 @@ function LayoutTabsGallery({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip <TabsTab
key={i} key={i}
label={tab.tooltip} value={tab.value}
position="bottom" leftSection={tab.icon}
withArrow style={{
transitionProps={{ transition: 'pop', duration: 200 }} fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
> >
<TabsTab {tab.label}
value={tab.value} </TabsTab>
leftSection={tab.icon}
style={{
fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
>
{tab.label}
</TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>

View File

@@ -10,12 +10,11 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
import { useEffect, useState, useCallback } from 'react'; import { useCallback, 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 { convertYoutubeUrlToEmbed } from '../../../lib/youtube-utils'; import { convertYoutubeUrlToEmbed } from '../../../lib/youtube-utils';
@@ -89,7 +88,6 @@ function EditVideo() {
return ( return (
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -98,7 +96,6 @@ function EditVideo() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Video Edit Video
</Title> </Title>

View File

@@ -2,7 +2,7 @@
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import stateGallery from '@/app/admin/(dashboard)/_state/desa/gallery'; import stateGallery from '@/app/admin/(dashboard)/_state/desa/gallery';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -111,7 +111,6 @@ function DetailVideo() {
{/* Tombol Aksi */} {/* Tombol Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Video" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -124,9 +123,7 @@ function DetailVideo() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Video" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -138,7 +135,6 @@ function DetailVideo() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -51,7 +50,6 @@ function CreateVideo() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header Back Button + Title */} {/* Header Back Button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -60,7 +58,6 @@ function CreateVideo() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Video Tambah Video
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -74,7 +73,6 @@ function ListVideo({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Video</Title> <Title order={4}>Daftar Video</Title>
<Tooltip label="Tambah Video Baru" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -83,7 +81,6 @@ function ListVideo({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
<Table highlightOnHover> <Table highlightOnHover>

View File

@@ -10,8 +10,7 @@ import {
Select, Select,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -87,11 +86,9 @@ function EditAjukanPermohonan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back Button */} {/* Back Button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Ajukan Permohonan Edit Ajukan Permohonan
</Title> </Title>

View File

@@ -9,8 +9,7 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
@@ -121,7 +120,6 @@ function DetailAjukanPermohonan() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Surat" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -135,9 +133,7 @@ function DetailAjukanPermohonan() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Surat" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -151,7 +147,6 @@ function DetailAjukanPermohonan() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -12,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -83,7 +82,6 @@ function EditPelayananPendudukNonPermanent() {
<Box> <Box>
<Stack gap="xs"> <Stack gap="xs">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -92,7 +90,6 @@ function EditPelayananPendudukNonPermanent() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Pelayanan Penduduk Non Permanent Edit Pelayanan Penduduk Non Permanent
</Title> </Title>

View File

@@ -11,8 +11,7 @@ import {
Skeleton, Skeleton,
Stack, Stack,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconEdit } from '@tabler/icons-react'; import { IconEdit } from '@tabler/icons-react';
@@ -51,7 +50,6 @@ function PelayananPendudukNonPermanent() {
</Title> </Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Data Pelayanan" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -65,7 +63,6 @@ function PelayananPendudukNonPermanent() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -12,8 +12,7 @@ import {
Skeleton, Skeleton,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -100,7 +99,6 @@ function EditPelayananPerizinanBerusaha() {
<Stack gap="xs"> <Stack gap="xs">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -109,7 +107,6 @@ function EditPelayananPerizinanBerusaha() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Pelayanan Perizinan Berusaha Edit Pelayanan Perizinan Berusaha
</Title> </Title>

View File

@@ -16,14 +16,13 @@ import {
StepperCompleted, StepperCompleted,
StepperStep, StepperStep,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconEdit } from '@tabler/icons-react'; import { IconEdit } from '@tabler/icons-react';
import { useEffect, useState } from 'react';
import stateLayananDesa from '../../../_state/desa/layananDesa';
import { useProxy } from 'valtio/utils';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils';
import stateLayananDesa from '../../../_state/desa/layananDesa';
function PerizinanBerusaha() { function PerizinanBerusaha() {
const router = useRouter(); const router = useRouter();
@@ -85,7 +84,6 @@ function PerizinanBerusaha() {
</Title> </Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Data Perizinan" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -99,7 +97,6 @@ function PerizinanBerusaha() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -12,13 +12,12 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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 { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
import { useEffect, useState, useCallback } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
@@ -112,11 +111,9 @@ function EditSuratKeterangan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back Button */} {/* Back Button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Surat Keterangan Edit Surat Keterangan
</Title> </Title>

View File

@@ -10,8 +10,7 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
@@ -142,7 +141,6 @@ function DetailSuratKeterangan() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Surat" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -156,9 +154,7 @@ function DetailSuratKeterangan() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Surat" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -172,7 +168,6 @@ function DetailSuratKeterangan() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -13,8 +13,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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';
@@ -85,11 +84,9 @@ function CreateSuratKeterangan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Surat Keterangan Tambah Surat Keterangan
</Title> </Title>

View File

@@ -17,8 +17,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -82,7 +81,6 @@ function ListSuratKeterangan({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>List Surat Keterangan</Title> <Title order={4}>List Surat Keterangan</Title>
<Tooltip label="Tambah Surat Keterangan" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -93,7 +91,6 @@ function ListSuratKeterangan({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
<Table highlightOnHover> <Table highlightOnHover>

View File

@@ -9,8 +9,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -81,11 +80,9 @@ function EditPelayananTelunjukSakti() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back Button + Title */} {/* Back Button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Pelayanan Telunjuk Sakti Desa Edit Pelayanan Telunjuk Sakti Desa
</Title> </Title>

View File

@@ -9,8 +9,7 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
@@ -130,7 +129,6 @@ function DetailPelayananTelunjukSakti() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Layanan" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -144,9 +142,7 @@ function DetailPelayananTelunjukSakti() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Layanan" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -160,7 +156,6 @@ function DetailPelayananTelunjukSakti() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -9,8 +9,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -45,11 +44,9 @@ function CreatePelayananTelunjukDesa() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Pelayanan Telunjuk Sakti Desa Tambah Pelayanan Telunjuk Sakti Desa
</Title> </Title>

View File

@@ -1,159 +1,3 @@
// /* eslint-disable react-hooks/exhaustive-deps */
// 'use client'
// import colors from '@/con/colors';
// import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
// import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
// import { useRouter } from 'next/navigation';
// import { useEffect, useMemo, useState } from 'react';
// import { useProxy } from 'valtio/utils';
// import HeaderSearch from '../../../_com/header';
// import JudulList from '../../../_com/judulList';
// import stateLayananDesa from '../../../_state/desa/layananDesa';
// function PelayananTelunjukSakti() {
// const [search, setSearch] = useState("");
// return (
// <Box>
// <HeaderSearch
// title='Posisi Organisasi'
// placeholder='pencarian'
// searchIcon={<IconSearch size={20} />}
// value={search}
// onChange={(e) => setSearch(e.currentTarget.value)}
// />
// <ListPelayananTelunjukSakti search={search} />
// </Box>
// );
// }
// function ListPelayananTelunjukSakti({ search }: { search: string }) {
// const telunjukSaktiState = useProxy(stateLayananDesa.pelayananTelunjukSaktiDesa)
// const router = useRouter()
// const {
// data,
// page,
// totalPages,
// loading,
// load,
// } = telunjukSaktiState.findMany;
// useEffect(() => {
// load(page, 10)
// }, [])
// const filteredData = useMemo(() => {
// if (!data) return [];
// return data.filter(item => {
// const keyword = search.toLowerCase();
// return (
// item.name?.toLowerCase().includes(keyword) ||
// item.link?.toLowerCase().includes(keyword) ||
// item.deskripsi?.toLowerCase().includes(keyword)
// );
// })
// .sort((a, b) => a.posisi?.hierarki - b.posisi?.hierarki);
// }, [data, search]);
// if (loading || !data) {
// return (
// <Stack py={10}>
// <Skeleton height={300} />
// </Stack>
// );
// }
// if (data.length === 0) {
// return (
// <Box py={10}>
// <Paper bg={colors['white-1']} p={'md'}>
// <JudulList
// title='List Pelayanan Telunjuk Sakti Desa'
// href='/admin/desa/layanan/pelayanan_telunjuk_sakti_desa/create'
// />
// <Table striped withTableBorder withRowBorders>
// <TableThead>
// <TableTr>
// <TableTh>Nama</TableTh>
// <TableTh>Link</TableTh>
// <TableTh>Detail</TableTh>
// </TableTr>
// </TableThead>
// <TableTbody>
// <TableTr>
// <TableTd colSpan={3}>
// <Text fz={"sm"} color="gray.5">
// Tidak ada data
// </Text>
// </TableTd>
// </TableTr>
// </TableTbody>
// </Table>
// </Paper>
// </Box>
// );
// }
// return (
// <Box py={10}>
// <Paper bg={colors['white-1']} p={'md'}>
// <JudulList
// title='List Pelayanan Telunjuk Sakti Desa'
// href='/admin/desa/layanan/pelayanan_telunjuk_sakti_desa/create'
// />
// <Table striped withTableBorder withRowBorders>
// <TableThead>
// <TableTr>
// <TableTh>Nama</TableTh>
// <TableTh>Link</TableTh>
// <TableTh>Detail</TableTh>
// </TableTr>
// </TableThead>
// <TableTbody>
// {filteredData.map((item) => (
// <TableTr key={item.id}>
// <TableTd>
// <Box w={100}>
// <Text truncate="end" lineClamp={1} fz={"sm"} dangerouslySetInnerHTML={{ __html: item.name }} />
// </Box>
// </TableTd>
// <TableTd>
// <Box w={100}>
// <a href={item.link} target="_blank" rel="noopener noreferrer">
// <Text dangerouslySetInnerHTML={{ __html: item.deskripsi }} truncate="end" fz={"sm"} />
// </a>
// </Box>
// </TableTd>
// <TableTd>
// <Text>
// <Button onClick={() => router.push(`/admin/desa/layanan/pelayanan_telunjuk_sakti_desa/${item.id}`)}>
// <IconDeviceImac size={20} />
// </Button>
// </Text>
// </TableTd>
// </TableTr>
// ))}
// </TableTbody>
// </Table>
// </Paper>
// <Center>
// <Pagination
// value={page}
// onChange={(newPage) => {
// load(newPage, 10);
// window.scrollTo(0, 0);
// }}
// total={totalPages}
// mt="md"
// mb="md"
// />
// </Center>
// </Box>
// );
// }
// export default PelayananTelunjukSakti;
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
@@ -174,8 +18,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -225,7 +68,6 @@ function ListPelayananTelunjukSakti({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Pelayanan Telunjuk Sakti</Title> <Title order={4}>Daftar Pelayanan Telunjuk Sakti</Title>
<Tooltip label="Tambah Layanan" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -236,7 +78,6 @@ function ListPelayananTelunjukSakti({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>
<Table highlightOnHover style={{ minWidth: '700px' }}> <Table highlightOnHover style={{ minWidth: '700px' }}>

View File

@@ -13,8 +13,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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';
@@ -102,11 +101,9 @@ function EditPenghargaan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Tombol Back + Title */} {/* Tombol Back + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Penghargaan Edit Penghargaan
</Title> </Title>

View File

@@ -1,9 +1,5 @@
'use client' 'use client'
import React, { useState } from 'react'; import colors from '@/con/colors';
import penghargaanState from '../../../_state/desa/penghargaan';
import { useProxy } from 'valtio/utils';
import { useParams, useRouter } from 'next/navigation';
import { useShallowEffect } from '@mantine/hooks';
import { import {
Box, Box,
Button, Button,
@@ -12,12 +8,15 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import colors from '@/con/colors'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import penghargaanState from '../../../_state/desa/penghargaan';
function DetailPenghargaan() { function DetailPenghargaan() {
const statePenghargaan = useProxy(penghargaanState); const statePenghargaan = useProxy(penghargaanState);
@@ -127,34 +126,30 @@ function DetailPenghargaan() {
</Box> </Box>
<Group gap="sm" mt={10}> <Group gap="sm" mt={10}>
<Tooltip label="Hapus Penghargaan" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Penghargaan" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() =>
onClick={() => router.push(`/admin/desa/penghargaan/${data.id}/edit`)
router.push(`/admin/desa/penghargaan/${data.id}/edit`) }
} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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';
@@ -66,11 +65,9 @@ function CreatePenghargaan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Penghargaan Tambah Penghargaan
</Title> </Title>

View File

@@ -18,8 +18,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -69,7 +68,6 @@ function ListPenghargaan({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>List Penghargaan</Title> <Title order={4}>List Penghargaan</Title>
<Tooltip label="Tambah Penghargaan" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -78,7 +76,6 @@ function ListPenghargaan({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>
<Table highlightOnHover> <Table highlightOnHover>

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconCategory, IconListDetails } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { IconListDetails, IconCategory } from '@tabler/icons-react';
function LayoutTabsLayanan({ children }: { children: React.ReactNode }) { function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
const router = useRouter() const router = useRouter()
@@ -14,15 +14,13 @@ function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
label: "List Pengumuman", label: "List Pengumuman",
value: "listpengumuman", value: "listpengumuman",
href: "/admin/desa/pengumuman/list-pengumuman", href: "/admin/desa/pengumuman/list-pengumuman",
icon: <IconListDetails size={18} stroke={1.8} />, icon: <IconListDetails size={18} stroke={1.8} />
tooltip: "Lihat semua daftar pengumuman"
}, },
{ {
label: "Kategori Pengumuman", label: "Kategori Pengumuman",
value: "kategoripengumuman", value: "kategoripengumuman",
href: "/admin/desa/pengumuman/kategori-pengumuman", href: "/admin/desa/pengumuman/kategori-pengumuman",
icon: <IconCategory size={18} stroke={1.8} />, icon: <IconCategory size={18} stroke={1.8} />
tooltip: "Kelola kategori pengumuman"
}, },
]; ];
@@ -70,19 +68,18 @@ function LayoutTabsLayanan({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}> <TabsTab
<TabsTab key={i}
value={tab.value} value={tab.value}
leftSection={tab.icon} leftSection={tab.icon}
style={{ style={{
fontWeight: 600, fontWeight: 600,
fontSize: "0.9rem", fontSize: "0.9rem",
transition: "all 0.2s ease", transition: "all 0.2s ease",
}} }}
> >
{tab.label} {tab.label}
</TabsTab> </TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>

View File

@@ -10,8 +10,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -74,7 +73,6 @@ function EditKategoriPengumuman() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -83,7 +81,6 @@ function EditKategoriPengumuman() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Kategori Pengumuman Edit Kategori Pengumuman
</Title> </Title>

View File

@@ -8,8 +8,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -35,7 +34,6 @@ function CreateKategoriPengumuman() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header dengan back button */} {/* Header dengan back button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -44,7 +42,6 @@ function CreateKategoriPengumuman() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Kategori Pengumuman Tambah Kategori Pengumuman
</Title> </Title>

View File

@@ -2,11 +2,13 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { import {
Box, Button, Center, Paper, Skeleton, Stack, Box, Button, Center,
Pagination,
Paper, Skeleton, Stack,
Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Table, TableTbody, TableTd, TableTh, TableThead, TableTr,
Text, Title, Tooltip, Pagination Text, Title
} from '@mantine/core'; } from '@mantine/core';
import { IconEdit, IconSearch, IconTrash, IconPlus } from '@tabler/icons-react'; import { IconEdit, IconPlus, IconSearch, IconTrash } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
@@ -66,16 +68,14 @@ function ListKategoriPengumuman({ search }: { search: string }) {
<Stack> <Stack>
<Box style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 15 }}> <Box style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 15 }}>
<Title order={4}>List Kategori Pengumuman</Title> <Title order={4}>List Kategori Pengumuman</Title>
<Tooltip label="Tambah Kategori Pengumuman" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/desa/pengumuman/kategori-pengumuman/create')}
onClick={() => router.push('/admin/desa/pengumuman/kategori-pengumuman/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Box> </Box>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>
@@ -99,29 +99,25 @@ function ListKategoriPengumuman({ search }: { search: string }) {
<Text truncate lineClamp={1}>{item.name}</Text> <Text truncate lineClamp={1}>{item.name}</Text>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Tooltip label="Edit Kategori Pengumuman" withArrow> <Button
<Button variant='light'
variant='light' color='green'
color='green' onClick={() => router.push(`/admin/desa/pengumuman/kategori-pengumuman/${item.id}`)}
onClick={() => router.push(`/admin/desa/pengumuman/kategori-pengumuman/${item.id}`)} >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Tooltip label="Hapus Kategori Pengumuman" withArrow> <Button
<Button variant='light'
variant='light' color='red'
color='red' disabled={listDataState.delete.loading}
disabled={listDataState.delete.loading} onClick={() => {
onClick={() => { setSelectedId(item.id)
setSelectedId(item.id) setModalHapus(true)
setModalHapus(true) }}>
}}> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
</TableTd> </TableTd>
</TableTr> </TableTr>
)) ))

View File

@@ -13,8 +13,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { IconArrowBack } from "@tabler/icons-react"; import { IconArrowBack } from "@tabler/icons-react";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
@@ -85,16 +84,14 @@ function EditPengumuman() {
return ( return (
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors["blue-button"]} size={24} />
<IconArrowBack color={colors["blue-button"]} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Pengumuman Edit Pengumuman
</Title> </Title>

View File

@@ -1,5 +1,7 @@
'use client' 'use client'
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { import {
Box, Box,
@@ -8,16 +10,13 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useRouter, useParams } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { useShallowEffect } from '@mantine/hooks';
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
export default function DetailPengumuman() { export default function DetailPengumuman() {
const pengumumanState = useProxy(stateDesaPengumuman); const pengumumanState = useProxy(stateDesaPengumuman);
@@ -117,7 +116,6 @@ export default function DetailPengumuman() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Pengumuman" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -130,9 +128,7 @@ export default function DetailPengumuman() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Pengumuman" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -146,7 +142,6 @@ export default function DetailPengumuman() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -12,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
@@ -47,11 +46,9 @@ function CreatePengumuman() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Pengumuman Tambah Pengumuman
</Title> </Title>

View File

@@ -17,8 +17,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
@@ -69,16 +68,14 @@ function ListPengumuman({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Pengumuman</Title> <Title order={4}>Daftar Pengumuman</Title>
<Tooltip label="Tambah Pengumuman" withArrow> <Button
<Button leftSection={<IconCircleDashedPlus size={18} />}
leftSection={<IconCircleDashedPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/desa/pengumuman/list-pengumuman/create')}
onClick={() => router.push('/admin/desa/pengumuman/list-pengumuman/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>
<Table highlightOnHover style={{ minWidth: '700px' }}> <Table highlightOnHover style={{ minWidth: '700px' }}>

View File

@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconCategory, IconListCheck } from '@tabler/icons-react'; import { IconCategory, IconListCheck } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@@ -14,15 +14,13 @@ function LayoutTabsPotensi({ children }: { children: React.ReactNode }) {
label: "List Potensi", label: "List Potensi",
value: "list_potensi", value: "list_potensi",
href: "/admin/desa/potensi/list-potensi", href: "/admin/desa/potensi/list-potensi",
icon: <IconListCheck size={18} stroke={1.8} />, icon: <IconListCheck size={18} stroke={1.8} />
tooltip: "Lihat semua potensi desa"
}, },
{ {
label: "Kategori Potensi", label: "Kategori Potensi",
value: "kategori_potensi", value: "kategori_potensi",
href: "/admin/desa/potensi/kategori-potensi", href: "/admin/desa/potensi/kategori-potensi",
icon: <IconCategory size={18} stroke={1.8} />, icon: <IconCategory size={18} stroke={1.8} />
tooltip: "Kelola kategori potensi"
}, },
]; ];
@@ -70,19 +68,18 @@ function LayoutTabsPotensi({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}> <TabsTab
<TabsTab key={i}
value={tab.value} value={tab.value}
leftSection={tab.icon} leftSection={tab.icon}
style={{ style={{
fontWeight: 600, fontWeight: 600,
fontSize: "0.9rem", fontSize: "0.9rem",
transition: "all 0.2s ease", transition: "all 0.2s ease",
}} }}
> >
{tab.label} {tab.label}
</TabsTab> </TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>

View File

@@ -9,8 +9,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -76,7 +75,6 @@ function EditKategoriPotensi() {
return ( return (
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -85,7 +83,6 @@ function EditKategoriPotensi() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Kategori Potensi Edit Kategori Potensi
</Title> </Title>

View File

@@ -8,8 +8,7 @@ import {
Paper, Paper,
Stack, Stack,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -35,7 +34,6 @@ function CreateKategoriPotensi() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header dengan back button */} {/* Header dengan back button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -44,7 +42,6 @@ function CreateKategoriPotensi() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Kategori Potensi Tambah Kategori Potensi
</Title> </Title>

View File

@@ -1,14 +1,14 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Center, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title, Tooltip, Pagination, Group } from '@mantine/core'; import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { IconEdit, IconSearch, IconTrash, IconPlus } from '@tabler/icons-react'; import { IconEdit, IconPlus, IconSearch, IconTrash } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../../_com/header'; import HeaderSearch from '../../../_com/header';
import potensiDesaState from '../../../_state/desa/potensi';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import potensiDesaState from '../../../_state/desa/potensi';
function KategoriPotensi() { function KategoriPotensi() {
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
@@ -62,7 +62,6 @@ function ListKategoriPotensi({ search }: { search: string }) {
<Stack> <Stack>
<Group justify="space-between"> <Group justify="space-between">
<Title order={4}>List Kategori Potensi</Title> <Title order={4}>List Kategori Potensi</Title>
<Tooltip label="Tambah Kategori Potensi" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -71,7 +70,6 @@ function ListKategoriPotensi({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: 'auto' }}> <Box style={{ overflowX: 'auto' }}>

View File

@@ -15,8 +15,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } 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";
@@ -122,7 +121,6 @@ function EditPotensi() {
return ( return (
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -131,7 +129,6 @@ function EditPotensi() {
> >
<IconArrowBack color={colors["blue-button"]} size={24} /> <IconArrowBack color={colors["blue-button"]} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Potensi Desa Edit Potensi Desa
</Title> </Title>

View File

@@ -1,13 +1,13 @@
'use client' 'use client'
import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useRouter, useParams } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import { useShallowEffect } from '@mantine/hooks';
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi'; import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi';
import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
export default function DetailPotensi() { export default function DetailPotensi() {
const router = useRouter(); const router = useRouter();
@@ -108,7 +108,6 @@ export default function DetailPotensi() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Potensi" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -121,9 +120,7 @@ export default function DetailPotensi() {
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Potensi" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => onClick={() =>
@@ -135,7 +132,6 @@ export default function DetailPotensi() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -14,8 +14,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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';
@@ -72,11 +71,9 @@ function CreatePotensi() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Potensi Desa Tambah Potensi Desa
</Title> </Title>

View File

@@ -18,8 +18,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -76,7 +75,6 @@ function ListPotensi({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Potensi Desa</Title> <Title order={4}>Daftar Potensi Desa</Title>
<Tooltip label="Tambah Potensi" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -85,7 +83,6 @@ function ListPotensi({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
<Table highlightOnHover style={{ minWidth: '700px' }}> <Table highlightOnHover style={{ minWidth: '700px' }}>

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconCalendar, IconUser, IconUsers } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { IconUser, IconUsers, IconCalendar } from '@tabler/icons-react';
function LayoutTabsDetail({ children }: { children: React.ReactNode }) { function LayoutTabsDetail({ children }: { children: React.ReactNode }) {
const router = useRouter() const router = useRouter()
@@ -14,22 +14,19 @@ function LayoutTabsDetail({ children }: { children: React.ReactNode }) {
label: "Profile Desa", label: "Profile Desa",
value: "profiledesa", value: "profiledesa",
href: "/admin/desa/profile/profile-desa", href: "/admin/desa/profile/profile-desa",
icon: <IconUser size={18} stroke={1.8} />, icon: <IconUser size={18} stroke={1.8} />
tooltip: "Lihat dan kelola profil desa"
}, },
{ {
label: "Profile Perbekel", label: "Profile Perbekel",
value: "profileperbekel", value: "profileperbekel",
href: "/admin/desa/profile/profile-perbekel", href: "/admin/desa/profile/profile-perbekel",
icon: <IconUsers size={18} stroke={1.8} />, icon: <IconUsers size={18} stroke={1.8} />
tooltip: "Kelola data Perbekel"
}, },
{ {
label: "Profile Perbekel Dari Masa Ke Masa", label: "Profile Perbekel Dari Masa Ke Masa",
value: "profile-perbekel-dari-masa-ke-masa", value: "profile-perbekel-dari-masa-ke-masa",
href: "/admin/desa/profile/profile-perbekel-dari-masa-ke-masa", href: "/admin/desa/profile/profile-perbekel-dari-masa-ke-masa",
icon: <IconCalendar size={18} stroke={1.8} />, icon: <IconCalendar size={18} stroke={1.8} />
tooltip: "Riwayat Perbekel dari masa ke masa"
} }
]; ];
@@ -76,42 +73,41 @@ function LayoutTabsDetail({ children }: { children: React.ReactNode }) {
paddingInline: "0.5rem", // ✅ biar nggak nempel ke tepi paddingInline: "0.5rem", // ✅ biar nggak nempel ke tepi
}} }}
> >
{tabs.map((tab, i) => (
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}>
<TabsTab
value={tab.value}
leftSection={tab.icon}
style={{
fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
>
{tab.label}
</TabsTab>
</Tooltip>
))}
</TabsList>
</ScrollArea>
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<TabsPanel <TabsTab
key={i} key={i}
value={tab.value} value={tab.value}
leftSection={tab.icon}
style={{ style={{
padding: "1.5rem", fontWeight: 600,
background: "linear-gradient(180deg, #ffffff, #f5f6fa)", fontSize: "0.9rem",
borderRadius: "1rem", transition: "all 0.2s ease",
boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
}} }}
> >
{/* Konten dummy, bisa diganti sesuai routing */} {tab.label}
<>{children}</> </TabsTab>
</TabsPanel>
))} ))}
</Tabs> </TabsList>
</Stack> </ScrollArea>
);
{tabs.map((tab, i) => (
<TabsPanel
key={i}
value={tab.value}
style={{
padding: "1.5rem",
background: "linear-gradient(180deg, #ffffff, #f5f6fa)",
borderRadius: "1rem",
boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
}}
>
{/* Konten dummy, bisa diganti sesuai routing */}
<>{children}</>
</TabsPanel>
))}
</Tabs>
</Stack>
);
} }
export default LayoutTabsDetail; export default LayoutTabsDetail;

View File

@@ -3,7 +3,7 @@
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Alert, Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title, Tooltip } from '@mantine/core'; import { Alert, Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
import { IconAlertCircle, IconArrowBack } from '@tabler/icons-react'; import { IconAlertCircle, IconArrowBack } 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';
@@ -99,11 +99,9 @@ function Page() {
<Box> <Box>
<Stack gap="xs"> <Stack gap="xs">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<Button variant="subtle" onClick={handleBack} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark">Edit Lambang Desa</Title> <Title order={4} ml="sm" c="dark">Edit Lambang Desa</Title>
</Group> </Group>

View File

@@ -5,9 +5,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
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, SimpleGrid, Stack, Text, TextInput, Title, Tooltip, Center, Alert } from '@mantine/core'; import { Alert, Box, Button, Center, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
import { Dropzone } from '@mantine/dropzone'; import { Dropzone } from '@mantine/dropzone';
import { IconArrowBack, IconPhoto, IconUpload, IconX, IconAlertCircle } from '@tabler/icons-react'; import { IconAlertCircle, IconArrowBack, 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';
@@ -161,11 +161,9 @@ function Page() {
<Box> <Box>
<Stack gap="xs"> <Stack gap="xs">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={handleBack} p="xs" radius="md"> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark">Edit Maskot Desa</Title> <Title order={4} ml="sm" c="dark">Edit Maskot Desa</Title>
</Group> </Group>

View File

@@ -3,7 +3,7 @@
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Alert, Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title, Tooltip } from '@mantine/core'; import { Alert, Box, Button, Center, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
import { IconAlertCircle, IconArrowBack } from '@tabler/icons-react'; import { IconAlertCircle, IconArrowBack } 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';
@@ -100,11 +100,9 @@ function Page() {
<Box> <Box>
<Stack gap="xs"> <Stack gap="xs">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<Button variant="subtle" onClick={handleBack} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark">Edit Sejarah Desa</Title> <Title order={4} ml="sm" c="dark">Edit Sejarah Desa</Title>
</Group> </Group>

View File

@@ -3,7 +3,7 @@
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Alert, Box, Button, Center, Group, Paper, Stack, Text, Title, Tooltip } from '@mantine/core'; import { Alert, Box, Button, Center, Group, Paper, Stack, Text, Title } from '@mantine/core';
import { IconAlertCircle, IconArrowBack } from '@tabler/icons-react'; import { IconAlertCircle, IconArrowBack } 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';
@@ -100,11 +100,11 @@ function Page() {
<Box> <Box>
<Stack gap="xs"> <Stack gap="xs">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<Button variant="subtle" onClick={handleBack} p="xs" radius="md"> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip> </Button>
<Title order={4} ml="sm" c="dark">Edit Visi Misi Desa</Title> <Title order={4} ml="sm" c="dark">Edit Visi Misi Desa</Title>
</Group> </Group>

View File

@@ -1,12 +1,12 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Card, Center, Divider, Grid, GridCol, Image, Paper, SimpleGrid, Stack, Text, Title, Tooltip } from '@mantine/core'; import { Box, Button, Card, Center, Divider, Grid, GridCol, Image, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
import { useSnapshot } from 'valtio';
import stateProfileDesa from '../../../_state/desa/profile';
import { useEffect } from 'react';
import { IconEdit } from '@tabler/icons-react'; import { IconEdit } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useSnapshot } from 'valtio';
import stateProfileDesa from '../../../_state/desa/profile';
function Page() { function Page() {
const router = useRouter(); const router = useRouter();
@@ -37,7 +37,6 @@ function Page() {
<Title order={3} c={colors['blue-button']}>Preview Sejarah Desa</Title> <Title order={3} c={colors['blue-button']}>Preview Sejarah Desa</Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Sejarah Desa" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -47,7 +46,6 @@ function Page() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>
@@ -84,7 +82,6 @@ function Page() {
<Title order={3} c={colors['blue-button']}>Preview Visi Misi Desa</Title> <Title order={3} c={colors['blue-button']}>Preview Visi Misi Desa</Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Visi Misi Desa" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -94,7 +91,6 @@ function Page() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>
@@ -134,7 +130,6 @@ function Page() {
<Title order={3} c={colors['blue-button']}>Preview Lambang Desa</Title> <Title order={3} c={colors['blue-button']}>Preview Lambang Desa</Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Lambang Desa" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -144,7 +139,6 @@ function Page() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>
@@ -181,7 +175,6 @@ function Page() {
<Title order={3} c={colors['blue-button']}>Preview Maskot Desa</Title> <Title order={3} c={colors['blue-button']}>Preview Maskot Desa</Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Maskot Desa" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -191,7 +184,6 @@ function Page() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -12,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } 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';
@@ -97,11 +96,9 @@ function EditPerbekelDariMasaKeMasa() {
return ( return (
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Perbekel Dari Masa Ke Masa Edit Perbekel Dari Masa Ke Masa
</Title> </Title>

View File

@@ -2,7 +2,7 @@
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -98,7 +98,6 @@ function DetailPerbekelDariMasa() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Perbekel" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
@@ -111,9 +110,7 @@ function DetailPerbekelDariMasa() {
> >
<IconX size={20} /> <IconX size={20} />
</Button> </Button>
</Tooltip>
<Tooltip label="Edit Perbekel" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => router.push(`/admin/desa/profile/profile-perbekel-dari-masa-ke-masa/${data.id}/edit`)} onClick={() => router.push(`/admin/desa/profile/profile-perbekel-dari-masa-ke-masa/${data.id}/edit`)}
@@ -123,7 +120,6 @@ function DetailPerbekelDariMasa() {
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -2,7 +2,7 @@
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
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, Tooltip } from '@mantine/core'; import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } 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';
@@ -50,11 +50,9 @@ function CreatePerbekelDariMasaKeMasa() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back button + Title */} {/* Back button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Create Perbekel Dari Masa Ke Masa Create Perbekel Dari Masa Ke Masa
</Title> </Title>

View File

@@ -1,6 +1,6 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title, Tooltip } from '@mantine/core'; import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -49,7 +49,6 @@ function ListPerbekelDariMasaKeMasa({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify='space-between' mb="md"> <Group justify='space-between' mb="md">
<Title order={4}>List Perbekel Dari Masa Ke Masa</Title> <Title order={4}>List Perbekel Dari Masa Ke Masa</Title>
<Tooltip label="Tambah Perbekel Baru" withArrow>
<Button <Button
leftSection={<IconPlus size={18} />} leftSection={<IconPlus size={18} />}
color="blue" color="blue"
@@ -58,7 +57,6 @@ function ListPerbekelDariMasaKeMasa({ search }: { search: string }) {
> >
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>

View File

@@ -4,9 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
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, Center, Group, Image, Paper, Stack, Text, Title, Tooltip } from '@mantine/core'; import { Box, Button, Center, Group, Image, Paper, Stack, Text, Title } from '@mantine/core';
import { Dropzone } from '@mantine/dropzone'; import { Dropzone } from '@mantine/dropzone';
import { IconArrowBack, IconPhoto, IconUpload, IconX, IconImageInPicture } 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';
@@ -101,11 +101,9 @@ function ProfilePerbekel() {
<Stack gap="xs"> <Stack gap="xs">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button variant="subtle" onClick={handleBack} p="xs" radius="md"> <Button variant="subtle" onClick={handleBack} p="xs" radius="md">
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Profil Perbekel Edit Profil Perbekel
</Title> </Title>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Center, Divider, Grid, GridCol, Image, Paper, Skeleton, Stack, Text, Title, Tooltip } from '@mantine/core'; import { Box, Button, Center, Divider, Grid, GridCol, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { IconEdit } from '@tabler/icons-react'; import { IconEdit } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect } from 'react'; import { useEffect } from 'react';
@@ -36,7 +36,6 @@ function Page() {
<Title order={3} c={colors['blue-button']}>Preview Profil PPID</Title> <Title order={3} c={colors['blue-button']}>Preview Profil PPID</Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 1 }}> <GridCol span={{ base: 12, md: 1 }}>
<Tooltip label="Edit Profil Perbekel" withArrow>
<Button <Button
c="green" c="green"
variant="light" variant="light"
@@ -46,7 +45,6 @@ function Page() {
> >
Edit Edit
</Button> </Button>
</Tooltip>
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { BarChart } from '@mantine/charts'; import { BarChart } from '@mantine/charts';
@@ -85,7 +86,7 @@ function ListDemografiPekerjaan({ search }: { search: string }) {
useEffect(() => { useEffect(() => {
if (data) { if (data) {
setChartData( setChartData(
data.map((item) => ({ data.map((item: any) => ({
id: item.id, id: item.id,
pekerjaan: item.pekerjaan, pekerjaan: item.pekerjaan,
lakiLaki: Number(item.lakiLaki), lakiLaki: Number(item.lakiLaki),

View File

@@ -24,8 +24,7 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
label: "Produk Pasar Desa", label: "Produk Pasar Desa",
value: "produkpasardesa", value: "produkpasardesa",
href: "/admin/ekonomi/pasar-desa/produk-pasar-desa", href: "/admin/ekonomi/pasar-desa/produk-pasar-desa",
icon: <IconShoppingBag size={18} stroke={1.8} />, icon: <IconShoppingBag size={18} stroke={1.8} />
tooltip: "Kelola data produk yang ada di pasar desa",
}, },
{ {
label: "Kategori Produk", label: "Kategori Produk",

View File

@@ -5,7 +5,6 @@ import {
Box, Box,
Button, Button,
Group, Group,
Image,
Paper, Paper,
Stack, Stack,
Text, Text,
@@ -21,6 +20,7 @@ import { useProxy } from 'valtio/utils';
import CreateEditor from '../../../_com/createEditor'; import CreateEditor from '../../../_com/createEditor';
import desaDigitalState from '../../../_state/inovasi/desa-digital'; import desaDigitalState from '../../../_state/inovasi/desa-digital';
import { Dropzone } from '@mantine/dropzone'; import { Dropzone } from '@mantine/dropzone';
import ExifOrientationImg from 'react-exif-orientation-img';
export default function CreateDesaDigital() { export default function CreateDesaDigital() {
const stateDesaDigital = useProxy(desaDigitalState); const stateDesaDigital = useProxy(desaDigitalState);
@@ -173,17 +173,16 @@ export default function CreateDesaDigital() {
overflow: 'hidden', overflow: 'hidden',
}} }}
> >
<Image <ExifOrientationImg
src={previewImage} src={previewImage}
alt="Preview" alt="Preview"
radius="md" style={{
style={{ maxHeight: 220,
maxHeight: 220, objectFit: 'cover',
objectFit: 'cover', border: '1px solid #e0e0e0',
border: '1px solid #e0e0e0', borderRadius: 12,
}} }}
loading="lazy" />
/>
</Box> </Box>
)} )}
</Box> </Box>

View File

@@ -54,8 +54,8 @@ function DetailInfoTeknologiTepatGuna() {
{/* Card Utama */} {/* Card Utama */}
<Paper <Paper
withBorder withBorder
w={{ base: "100%", md: "70%", lg: "60%" }} w={{ base: "100%", md: "50%" }}
bg="#ECEEF8" bg={colors['white-1']}
p="lg" p="lg"
radius="md" radius="md"
shadow="sm" shadow="sm"
@@ -65,7 +65,7 @@ function DetailInfoTeknologiTepatGuna() {
Detail Info Teknologi Tepat Guna Detail Info Teknologi Tepat Guna
</Text> </Text>
<Paper bg={colors['BG-trans']} p="md" radius="md" shadow="xs"> <Paper bg="#ECEEF8" p="md" radius="md" shadow="xs">
<Stack gap="sm"> <Stack gap="sm">
<Box> <Box>
<Text fz="lg" fw="bold">Judul</Text> <Text fz="lg" fw="bold">Judul</Text>

View File

@@ -1,6 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import { IconKey } 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 { import {
@@ -11,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -20,7 +20,6 @@ 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 SelectIconProgramEdit from '../../../../_com/selectIconEdit'; import SelectIconProgramEdit from '../../../../_com/selectIconEdit';
import { IconKey } from '@/app/admin/(dashboard)/_com/iconMap';
interface FormProgramKreatif { interface FormProgramKreatif {
name: string; name: string;
@@ -41,6 +40,15 @@ function EditProgramKreatifDesa() {
icon: '', icon: '',
}); });
const [originalData, setOriginalData] = useState<FormProgramKreatif>({
name: '',
deskripsi: '',
slug: '',
icon: '',
});
const [isDataChanged, setIsDataChanged] = useState(false);
// Load data hanya sekali berdasarkan params.id // Load data hanya sekali berdasarkan params.id
useEffect(() => { useEffect(() => {
const loadProgramKreatif = async () => { const loadProgramKreatif = async () => {
@@ -51,12 +59,14 @@ function EditProgramKreatifDesa() {
const data = await stateProgramKreatif.update.load(id); const data = await stateProgramKreatif.update.load(id);
if (data) { if (data) {
stateProgramKreatif.update.id = id; stateProgramKreatif.update.id = id;
setFormData({ const loadedData = {
name: data.name || '', name: data.name || '',
slug: data.slug || '', slug: data.slug || '',
deskripsi: data.deskripsi || '', deskripsi: data.deskripsi || '',
icon: data.icon || '', icon: data.icon || '',
}); };
setFormData(loadedData);
setOriginalData(loadedData);
} }
} catch (error) { } catch (error) {
console.error('Error loading program kreatif:', error); console.error('Error loading program kreatif:', error);
@@ -67,12 +77,49 @@ function EditProgramKreatifDesa() {
loadProgramKreatif(); loadProgramKreatif();
}, [params?.id]); }, [params?.id]);
// Deteksi perubahan data
useEffect(() => {
const hasChanged =
formData.name !== originalData.name ||
formData.slug !== originalData.slug ||
formData.deskripsi !== originalData.deskripsi ||
formData.icon !== originalData.icon;
setIsDataChanged(hasChanged);
}, [formData, originalData]);
// Prevent browser back/refresh jika ada perubahan
useEffect(() => {
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
if (isDataChanged) {
e.preventDefault();
e.returnValue = '';
}
};
window.addEventListener('beforeunload', handleBeforeUnload);
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
}, [isDataChanged]);
const handleChange = const handleChange =
(field: keyof FormProgramKreatif) => (field: keyof FormProgramKreatif) =>
(value: string) => { (value: string) => {
setFormData((prev) => ({ ...prev, [field]: value })); setFormData((prev) => ({ ...prev, [field]: value }));
}; };
const handleBackClick = () => {
if (isDataChanged) {
const confirmed = window.confirm(
'Anda memiliki perubahan yang belum disimpan. Apakah Anda yakin ingin keluar dari halaman ini? Semua perubahan akan hilang.'
);
if (confirmed) {
router.back();
}
} else {
router.back();
}
};
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
stateProgramKreatif.update.form = { stateProgramKreatif.update.form = {
@@ -82,6 +129,11 @@ function EditProgramKreatifDesa() {
icon: formData.icon.trim(), icon: formData.icon.trim(),
}; };
await stateProgramKreatif.update.submit(); await stateProgramKreatif.update.submit();
// Reset isDataChanged agar tidak muncul konfirmasi setelah save
setOriginalData(formData);
setIsDataChanged(false);
router.push('/admin/inovasi/program-kreatif-desa'); router.push('/admin/inovasi/program-kreatif-desa');
} catch (error) { } catch (error) {
console.error('Error updating program kreatif:', error); console.error('Error updating program kreatif:', error);
@@ -92,16 +144,14 @@ function EditProgramKreatifDesa() {
return ( return (
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={handleBackClick}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Program Kreatif Desa Edit Program Kreatif Desa
</Title> </Title>
@@ -172,4 +222,4 @@ function EditProgramKreatifDesa() {
); );
} }
export default EditProgramKreatifDesa; export default EditProgramKreatifDesa;

View File

@@ -32,10 +32,14 @@ function CreateProgramKreatifDesa() {
}; };
const handleSubmit = async () => { const handleSubmit = async () => {
await stateCreate.create.create(); const success = await stateCreate.create.create();
resetForm();
router.push("/admin/inovasi/program-kreatif-desa"); if (success) {
resetForm();
router.push("/admin/inovasi/program-kreatif-desa");
}
}; };
return ( return (
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { import {
IconArrowBack, IconArrowBack,
@@ -116,16 +115,14 @@ function EditKeamananLingkungan() {
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors["blue-button"]} size={24} />
<IconArrowBack color={colors["blue-button"]} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Keamanan Lingkungan Edit Keamanan Lingkungan
</Title> </Title>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -93,36 +93,32 @@ function DetailKeamananLingkungan() {
{/* Aksi */} {/* Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Data" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() =>
onClick={() => router.push(
router.push( `/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${data.id}/edit`
`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${data.id}/edit` )
) }
} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { Dropzone } from '@mantine/dropzone'; import { Dropzone } from '@mantine/dropzone';
import { import {
@@ -71,16 +70,14 @@ function CreateKeamananLingkungan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Data Keamanan Lingkungan Tambah Data Keamanan Lingkungan
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -78,18 +77,16 @@ function ListKeamananLingkungan({ search }: { search: string }) {
{/* Judul + Tombol Tambah */} {/* Judul + Tombol Tambah */}
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Keamanan Lingkungan</Title> <Title order={4}>Daftar Keamanan Lingkungan</Title>
<Tooltip label="Tambah Data Keamanan" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() =>
onClick={() => router.push('/admin/keamanan/keamanan-lingkungan-pecalang-patwal/create')
router.push('/admin/keamanan/keamanan-lingkungan-pecalang-patwal/create') }
} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
{/* Tabel */} {/* Tabel */}

View File

@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconPhone, IconTag } from '@tabler/icons-react'; import { IconPhone, IconTag } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@@ -15,15 +15,13 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
label: "Kontak Darurat Keamanan", label: "Kontak Darurat Keamanan",
value: "kontak-darurat-keamanan", value: "kontak-darurat-keamanan",
href: "/admin/keamanan/kontak-darurat/kontak-darurat-keamanan", href: "/admin/keamanan/kontak-darurat/kontak-darurat-keamanan",
icon: <IconPhone size={18} stroke={1.8} />, icon: <IconPhone size={18} stroke={1.8} />
tooltip: "Lihat dan kelola kontak darurat keamanan",
}, },
{ {
label: "Kontak Darurat Item", label: "Kontak Darurat Item",
value: "kontak-darurat-item", value: "kontak-darurat-item",
href: "/admin/keamanan/kontak-darurat/kontak-darurat-item", href: "/admin/keamanan/kontak-darurat/kontak-darurat-item",
icon: <IconTag size={18} stroke={1.8} />, icon: <IconTag size={18} stroke={1.8} />
tooltip: "Kelola data kontak darurat item",
} }
]; ];
@@ -73,19 +71,18 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip key={i} label={tab.tooltip} position="bottom" withArrow transitionProps={{ transition: 'pop', duration: 200 }}> <TabsTab
<TabsTab key={i}
value={tab.value} value={tab.value}
leftSection={tab.icon} leftSection={tab.icon}
style={{ style={{
fontWeight: 600, fontWeight: 600,
fontSize: "0.9rem", fontSize: "0.9rem",
transition: "all 0.2s ease", transition: "all 0.2s ease",
}} }}
> >
{tab.label} {tab.label}
</TabsTab> </TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>

View File

@@ -12,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -86,11 +85,9 @@ function EditKontakItem() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Kontak Darurat Item Edit Kontak Darurat Item
</Title> </Title>

View File

@@ -3,7 +3,7 @@ import { IconKey, IconMapper } from '@/app/admin/(dashboard)/_com/iconMap';
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import kontakDarurat from '@/app/admin/(dashboard)/_state/keamanan/kontak-darurat-keamanan'; import kontakDarurat from '@/app/admin/(dashboard)/_state/keamanan/kontak-darurat-keamanan';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -92,32 +92,28 @@ function DetailKontakDarurat() {
{/* Aksi */} {/* Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Data" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() => router.push(`/admin/keamanan/kontak-darurat/kontak-darurat-item/${data.id}/edit`)}
onClick={() => router.push(`/admin/keamanan/kontak-darurat/kontak-darurat-item/${data.id}/edit`)} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -38,16 +37,14 @@ function CreateKontakItem() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Kontak Darurat Item Tambah Kontak Darurat Item
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -79,16 +78,14 @@ function ListKontakItem({ search }: { search: string }) {
{/* Judul + Tombol Tambah */} {/* Judul + Tombol Tambah */}
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Kontak Darurat Item</Title> <Title order={4}>Daftar Kontak Darurat Item</Title>
<Tooltip label="Tambah Kontak Item" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/kontak-darurat/kontak-darurat-item/create')}
onClick={() => router.push('/admin/keamanan/kontak-darurat/kontak-darurat-item/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
{/* Tabel */} {/* Tabel */}

View File

@@ -14,8 +14,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { IconArrowBack } from "@tabler/icons-react"; import { IconArrowBack } from "@tabler/icons-react";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
@@ -42,7 +41,7 @@ function EditKontakDaruratKeamanan() {
try { try {
setIsLoading(true); setIsLoading(true);
await kontakDarurat.kontakDaruratItem.findMany.load(); await kontakDarurat.kontakDaruratItem.findMany.load();
const id = params?.id as string; const id = params?.id as string;
if (id) { if (id) {
const data = await kontakState.update.load(id); const data = await kontakState.update.load(id);
@@ -88,16 +87,14 @@ function EditKontakDaruratKeamanan() {
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors["blue-button"]} size={24} />
<IconArrowBack color={colors["blue-button"]} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Kontak Darurat Keamanan Edit Kontak Darurat Keamanan
</Title> </Title>

View File

@@ -3,7 +3,7 @@ import { IconKey, IconMapper } from '@/app/admin/(dashboard)/_com/iconMap';
import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
import kontakDarurat from '@/app/admin/(dashboard)/_state/keamanan/kontak-darurat-keamanan'; import kontakDarurat from '@/app/admin/(dashboard)/_state/keamanan/kontak-darurat-keamanan';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -108,32 +108,28 @@ function DetailKontakDaruratKeamanan() {
{/* Aksi */} {/* Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Data" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() => router.push(`/admin/keamanan/kontak-darurat/kontak-darurat-keamanan/${data.id}/edit`)}
onClick={() => router.push(`/admin/keamanan/kontak-darurat/kontak-darurat-keamanan/${data.id}/edit`)} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -11,8 +11,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
@@ -45,16 +44,14 @@ function CreateKontakDaruratKeamanan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Kontak Darurat Keamanan Tambah Kontak Darurat Keamanan
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -79,16 +78,14 @@ function ListKontakDaruratKeamanan({ search }: { search: string }) {
{/* Judul + Tombol Tambah */} {/* Judul + Tombol Tambah */}
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Kontak Darurat Keamanan</Title> <Title order={4}>Daftar Kontak Darurat Keamanan</Title>
<Tooltip label="Tambah Kontak Darurat Keamanan" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/kontak-darurat/kontak-darurat-keamanan/create')}
onClick={() => router.push('/admin/keamanan/kontak-darurat/kontak-darurat-keamanan/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
{/* Tabel */} {/* Tabel */}

View File

@@ -1,3 +1,4 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
import laporanPublikState from '@/app/admin/(dashboard)/_state/keamanan/laporan-publik'; import laporanPublikState from '@/app/admin/(dashboard)/_state/keamanan/laporan-publik';
@@ -11,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { DateTimePicker } from '@mantine/dates'; import { DateTimePicker } from '@mantine/dates';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
@@ -48,29 +48,29 @@ function EditLaporanPublik() {
const loadLaporanPublik = async () => { const loadLaporanPublik = async () => {
const id = params?.id as string; const id = params?.id as string;
if (!id) return; if (!id) return;
try { try {
const data = await stateLaporan.edit.load(id); const data = await stateLaporan.edit.load(id);
if (data) { if (data) {
setFormData((prev) => ({ setFormData({
...prev, judul: data.judul ?? '',
judul: data.judul ?? prev.judul, lokasi: data.lokasi ?? '',
lokasi: data.lokasi ?? prev.lokasi, tanggalWaktu: data.tanggalWaktu ?? '',
tanggalWaktu: data.tanggalWaktu ?? prev.tanggalWaktu, status: (data.status as Status) ?? 'Proses',
status: (data.status as Status) ?? prev.status, penanganan: data.penanganan?.[0]?.deskripsi ?? '',
penanganan: data.penanganan?.[0]?.deskripsi ?? prev.penanganan, kronologi: data.kronologi ?? '',
kronologi: data.kronologi ?? prev.kronologi, });
}));
} }
} catch (error) { } catch (error) {
console.error("Error loading laporan publik:", error); console.error("Error loading laporan publik:", error);
toast.error("Gagal mengambil data laporan publik"); toast.error("Gagal mengambil data laporan publik");
} }
}; };
loadLaporanPublik(); loadLaporanPublik();
}, [params?.id, stateLaporan.edit]); }, [params?.id]);
const handleChange = (field: string, value: string | Status) => { const handleChange = (field: string, value: string | Status) => {
setFormData((prev) => ({ ...prev, [field]: value })); setFormData((prev) => ({ ...prev, [field]: value }));
@@ -96,11 +96,9 @@ function EditLaporanPublik() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Laporan Publik Edit Laporan Publik
</Title> </Title>

View File

@@ -7,16 +7,15 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text, Text
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } 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 { useProxy } from 'valtio/utils';
import laporanPublikState from '../../../_state/keamanan/laporan-publik';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import laporanPublikState from '../../../_state/keamanan/laporan-publik';
function DetailLaporanPublik() { function DetailLaporanPublik() {
const [modalHapus, setModalHapus] = useState(false); const [modalHapus, setModalHapus] = useState(false);
@@ -102,12 +101,12 @@ function DetailLaporanPublik() {
padding: '4px 12px', padding: '4px 12px',
borderRadius: '16px', borderRadius: '16px',
backgroundColor: backgroundColor:
data.status === 'Selesai' ? '#94EF95FF' : data.status === 'Selesai' ? '#94EF95FF' :
data.status === 'Proses' ? '#F1D295FF' : data.status === 'Proses' ? '#F1D295FF' :
'#F38E8EFF', '#F38E8EFF',
color: color:
data.status === 'Selesai' ? '#01BA01FF' : data.status === 'Selesai' ? '#01BA01FF' :
data.status === 'Proses' ? '#B67A00FF' : data.status === 'Proses' ? '#B67A00FF' :
'#AE1700FF', '#AE1700FF',
fontWeight: 900, fontWeight: 900,
fontSize: '0.75rem', fontSize: '0.75rem',
@@ -146,35 +145,31 @@ function DetailLaporanPublik() {
{/* Tombol Aksi */} {/* Tombol Aksi */}
<Group gap="sm" mt="sm"> <Group gap="sm" mt="sm">
<Tooltip label="Hapus Laporan Publik" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" disabled={stateLaporan.delete.loading}
disabled={stateLaporan.delete.loading} >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Laporan Publik" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() =>
onClick={() => router.push(`/admin/keamanan/laporan-publik/${data.id}/edit`)
router.push(`/admin/keamanan/laporan-publik/${data.id}/edit`) }
} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -8,8 +8,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { DateTimePicker } from '@mantine/dates'; import { DateTimePicker } from '@mantine/dates';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
@@ -42,11 +41,9 @@ function CreateLaporanPublik() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header with Back Button */} {/* Header with Back Button */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Laporan Publik Tambah Laporan Publik
</Title> </Title>

View File

@@ -5,8 +5,8 @@ import {
Button, Button,
Center, Center,
Group, Group,
Paper,
Pagination, Pagination,
Paper,
Skeleton, Skeleton,
Stack, Stack,
Table, Table,
@@ -16,16 +16,15 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import laporanPublikState from '../../_state/keamanan/laporan-publik';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImac, 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 laporanPublikState from '../../_state/keamanan/laporan-publik';
function LaporanPublik() { function LaporanPublik() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -74,16 +73,14 @@ function ListLaporanPublik({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Laporan Publik</Title> <Title order={4}>Daftar Laporan Publik</Title>
<Tooltip label="Tambah Laporan Publik" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/laporan-publik/create')}
onClick={() => router.push('/admin/keamanan/laporan-publik/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
<Table highlightOnHover> <Table highlightOnHover>

View File

@@ -12,8 +12,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -96,16 +95,14 @@ function EditPencegahanKriminalitas() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Back button + Title */} {/* Back button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Pencegahan Kriminalitas Edit Pencegahan Kriminalitas
</Title> </Title>

View File

@@ -1,10 +1,10 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Flex, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useRouter, useParams } from 'next/navigation';
import { useState } from 'react';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas'; import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas';
@@ -108,32 +108,28 @@ function DetailPencegahanKriminalitas() {
{/* Tombol Aksi */} {/* Tombol Aksi */}
<Flex gap="sm" mt="sm"> <Flex gap="sm" mt="sm">
<Tooltip label="Hapus" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() => router.push(`/admin/keamanan/pencegahan-kriminalitas/${data.id}/edit`)}
onClick={() => router.push(`/admin/keamanan/pencegahan-kriminalitas/${data.id}/edit`)} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Flex> </Flex>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -9,17 +9,16 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import CreateEditor from '../../../_com/createEditor'; import CreateEditor from '../../../_com/createEditor';
import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas'; import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas';
import { useState } from 'react';
import { convertYoutubeUrlToEmbed } from '../../../desa/gallery/lib/youtube-utils'; import { convertYoutubeUrlToEmbed } from '../../../desa/gallery/lib/youtube-utils';
import { toast } from 'react-toastify';
function CreatePencegahanKriminalitas() { function CreatePencegahanKriminalitas() {
const router = useRouter(); const router = useRouter();
@@ -53,7 +52,6 @@ function CreatePencegahanKriminalitas() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header Back Button + Title */} {/* Header Back Button + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
@@ -62,7 +60,6 @@ function CreatePencegahanKriminalitas() {
> >
<IconArrowBack color={colors['blue-button']} size={24} /> <IconArrowBack color={colors['blue-button']} size={24} />
</Button> </Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Pencegahan Kriminalitas Tambah Pencegahan Kriminalitas
</Title> </Title>

View File

@@ -16,16 +16,15 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import pencegahanKriminalitasState from '../../_state/keamanan/pencegahan-kriminalitas';
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 pencegahanKriminalitasState from '../../_state/keamanan/pencegahan-kriminalitas';
function PencegahanKriminalitas() { function PencegahanKriminalitas() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -77,16 +76,14 @@ function ListPencegahanKriminalitas({ search }: { search: string }) {
{/* Judul + Tombol Tambah */} {/* Judul + Tombol Tambah */}
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Pencegahan Kriminalitas</Title> <Title order={4}>Daftar Pencegahan Kriminalitas</Title>
<Tooltip label="Tambah Program Pencegahan" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/pencegahan-kriminalitas/create')}
onClick={() => router.push('/admin/keamanan/pencegahan-kriminalitas/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
{/* Tabel */} {/* Tabel */}
@@ -106,9 +103,9 @@ function ListPencegahanKriminalitas({ search }: { search: string }) {
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Box w={200}> <Box w={200}>
<Text fw={500} truncate="end" lineClamp={1}> <Text fw={500} truncate="end" lineClamp={1}>
{item.judul} {item.judul}
</Text> </Text>
</Box> </Box>
</TableTd> </TableTd>
<TableTd> <TableTd>

View File

@@ -2,6 +2,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
"use client"; "use client";
import polsekTerdekat from "@/app/admin/(dashboard)/_state/keamanan/polsek-terdekat";
import colors from "@/con/colors"; import colors from "@/con/colors";
import { import {
Box, Box,
@@ -14,15 +15,13 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { IconArrowBack } from "@tabler/icons-react"; import { IconArrowBack } from "@tabler/icons-react";
import { useParams, useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import { useProxy } from "valtio/utils";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import polsekTerdekat from "@/app/admin/(dashboard)/_state/keamanan/polsek-terdekat"; import { useProxy } from "valtio/utils";
function EditPolsekTerdekat() { function EditPolsekTerdekat() {
const polsekState = useProxy(polsekTerdekat); const polsekState = useProxy(polsekTerdekat);
@@ -52,36 +51,36 @@ function EditPolsekTerdekat() {
layananPolsekId: "", layananPolsekId: "",
}); });
// load data untuk form edit // load data untuk form edit
useEffect(() => { useEffect(() => {
const loadPolsekTerdekat = async () => { const loadPolsekTerdekat = async () => {
const id = params?.id as string; const id = params?.id as string;
if (!id) return; if (!id) return;
try { try {
const data = await polsekState.edit.load(id); const data = await polsekState.edit.load(id);
if (data) { if (data) {
setFormData({ setFormData({
nama: data.nama || "", nama: data.nama || "",
jarakKeDesa: data.jarakKeDesa || "", jarakKeDesa: data.jarakKeDesa || "",
alamat: data.alamat || "", alamat: data.alamat || "",
nomorTelepon: data.nomorTelepon || "", nomorTelepon: data.nomorTelepon || "",
jamOperasional: data.jamOperasional || "", jamOperasional: data.jamOperasional || "",
embedMapUrl: data.embedMapUrl || "", embedMapUrl: data.embedMapUrl || "",
namaTempatMaps: data.namaTempatMaps || "", namaTempatMaps: data.namaTempatMaps || "",
alamatMaps: data.alamatMaps || "", alamatMaps: data.alamatMaps || "",
linkPetunjukArah: data.linkPetunjukArah || "", linkPetunjukArah: data.linkPetunjukArah || "",
layananPolsekId: data.layananPolsekId || "", layananPolsekId: data.layananPolsekId || "",
}); });
}
} catch (error) {
console.error("Error loading polsek terdekat:", error);
toast.error("Gagal memuat data polsek terdekat");
} }
}; } catch (error) {
console.error("Error loading polsek terdekat:", error);
loadPolsekTerdekat(); toast.error("Gagal memuat data polsek terdekat");
}, [params?.id]); }
};
loadPolsekTerdekat();
}, [params?.id]);
const fetchLayanan = async () => { const fetchLayanan = async () => {
try { try {
@@ -248,16 +247,14 @@ function EditPolsekTerdekat() {
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors["blue-button"]} size={24} />
<IconArrowBack color={colors["blue-button"]} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Polsek Terdekat Edit Polsek Terdekat
</Title> </Title>

View File

@@ -1,13 +1,13 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconEdit, IconTrash } 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 polsekTerdekat from '../../../_state/keamanan/polsek-terdekat';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import polsekTerdekat from '../../../_state/keamanan/polsek-terdekat';
function DetailPolsekTerdekat() { function DetailPolsekTerdekat() {
const router = useRouter(); const router = useRouter();
@@ -157,32 +157,28 @@ function DetailPolsekTerdekat() {
{/* Aksi */} {/* Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Data" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${data.id}/edit`)}
onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${data.id}/edit`)} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -11,15 +11,14 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react'; import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import polsekTerdekat from '../../../_state/keamanan/polsek-terdekat';
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 polsekTerdekat from '../../../_state/keamanan/polsek-terdekat';
function CreatePolsekTerdekat() { function CreatePolsekTerdekat() {
const polsekState = useProxy(polsekTerdekat); const polsekState = useProxy(polsekTerdekat);
@@ -122,16 +121,14 @@ function CreatePolsekTerdekat() {
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Polsek Terdekat Tambah Polsek Terdekat
</Title> </Title>

View File

@@ -16,8 +16,7 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -76,16 +75,14 @@ function ListPolsekTerdekat({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Polsek Terdekat</Title> <Title order={4}>Daftar Polsek Terdekat</Title>
<Tooltip label="Tambah Polsek" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/polsek-terdekat/create')}
onClick={() => router.push('/admin/keamanan/polsek-terdekat/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
@@ -110,11 +107,11 @@ function ListPolsekTerdekat({ search }: { search: string }) {
</Box> </Box>
</TableTd> </TableTd>
<TableTd>{item.jarakKeDesa}</TableTd> <TableTd>{item.jarakKeDesa}</TableTd>
<TableTd> <TableTd>
<Box w={150}> <Box w={150}>
<Text truncate="end" lineClamp={1}>{item.alamat}</Text> <Text truncate="end" lineClamp={1}>{item.alamat}</Text>
</Box> </Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button
variant="light" variant="light"

View File

@@ -9,8 +9,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { import {
IconArrowBack, IconArrowBack,
@@ -105,16 +104,14 @@ function EditTipsKeamanan() {
<Box px={{ base: "sm", md: "lg" }} py="md"> <Box px={{ base: "sm", md: "lg" }} py="md">
{/* Header */} {/* Header */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button
<Button variant="subtle"
variant="subtle" onClick={() => router.back()}
onClick={() => router.back()} p="xs"
p="xs" radius="md"
radius="md" >
> <IconArrowBack color={colors["blue-button"]} size={24} />
<IconArrowBack color={colors["blue-button"]} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Edit Tips Keamanan Edit Tips Keamanan
</Title> </Title>

View File

@@ -1,10 +1,10 @@
'use client' 'use client'
import { useProxy } from 'valtio/utils'; import { Box, Button, Group, 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, IconTrash } 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';
import { useProxy } from 'valtio/utils';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
@@ -99,33 +99,29 @@ function DetailTipsKeamanan() {
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Tips Keamanan" withArrow position="top"> <Button
<Button color="red"
color="red" onClick={() => {
onClick={() => { setSelectedId(data.id);
setSelectedId(data.id); setModalHapus(true);
setModalHapus(true); }}
}} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" disabled={stateKeamanan.delete.loading}
disabled={stateKeamanan.delete.loading} >
> <IconTrash size={20} />
<IconTrash size={20} /> </Button>
</Button>
</Tooltip>
<Tooltip label="Edit Tips Keamanan" withArrow position="top"> <Button
<Button color="green"
color="green" onClick={() => router.push(`/admin/keamanan/tips-keamanan/${data.id}/edit`)}
onClick={() => router.push(`/admin/keamanan/tips-keamanan/${data.id}/edit`)} variant="light"
variant="light" radius="md"
radius="md" size="md"
size="md" >
> <IconEdit size={20} />
<IconEdit size={20} /> </Button>
</Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -10,8 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title
Tooltip,
} from '@mantine/core'; } 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';
@@ -66,11 +65,9 @@ function CreateKeamananLingkungan() {
<Box px={{ base: 'sm', md: 'lg' }} py="md"> <Box px={{ base: 'sm', md: 'lg' }} py="md">
{/* Header Back + Title */} {/* Header Back + Title */}
<Group mb="md"> <Group mb="md">
<Tooltip label="Kembali ke halaman sebelumnya" withArrow> <Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md"> <IconArrowBack color={colors['blue-button']} size={24} />
<IconArrowBack color={colors['blue-button']} size={24} /> </Button>
</Button>
</Tooltip>
<Title order={4} ml="sm" c="dark"> <Title order={4} ml="sm" c="dark">
Tambah Tips Keamanan Tambah Tips Keamanan
</Title> </Title>

View File

@@ -16,14 +16,13 @@ import {
TableThead, TableThead,
TableTr, TableTr,
Text, Text,
Title, Title
Tooltip,
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImac, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header'; import HeaderSearch from '../../_com/header';
import tipsKeamananState from '../../_state/keamanan/tips-keamanan'; import tipsKeamananState from '../../_state/keamanan/tips-keamanan';
@@ -74,16 +73,14 @@ function ListTipsKeamanan({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p="lg" shadow="md" radius="md">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
<Title order={4}>Daftar Tips Keamanan</Title> <Title order={4}>Daftar Tips Keamanan</Title>
<Tooltip label="Tambah Tips Keamanan" withArrow> <Button
<Button leftSection={<IconPlus size={18} />}
leftSection={<IconPlus size={18} />} color="blue"
color="blue" variant="light"
variant="light" onClick={() => router.push('/admin/keamanan/tips-keamanan/create')}
onClick={() => router.push('/admin/keamanan/tips-keamanan/create')} >
> Tambah Baru
Tambah Baru </Button>
</Button>
</Tooltip>
</Group> </Group>
<Box style={{ overflowX: "auto" }}> <Box style={{ overflowX: "auto" }}>
<Table highlightOnHover> <Table highlightOnHover>

View File

@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title, Tooltip } from '@mantine/core'; import { ScrollArea, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import { IconActivity, IconBuildingHospital, IconCalendarEvent, IconGauge, IconNotes } from '@tabler/icons-react'; import { IconActivity, IconBuildingHospital, IconCalendarEvent, IconGauge, IconNotes } from '@tabler/icons-react';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@@ -17,36 +17,31 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
label: "Presentase Kelahiran & Kematian", label: "Presentase Kelahiran & Kematian",
value: "presentasekelahiran&kematian", value: "presentasekelahiran&kematian",
href: "/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian", href: "/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian",
icon: <IconActivity size={18} stroke={1.8} />, icon: <IconActivity size={18} stroke={1.8} />
tooltip: "Lihat data kelahiran dan kematian"
}, },
{ {
label: "Grafik Hasil Kepuasan Masyarakat", label: "Grafik Hasil Kepuasan Masyarakat",
value: "grafikhasilkepuasan", value: "grafikhasilkepuasan",
href: "/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan", href: "/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan",
icon: <IconGauge size={18} stroke={1.8} />, icon: <IconGauge size={18} stroke={1.8} />
tooltip: "Grafik kepuasan masyarakat terhadap pelayanan"
}, },
{ {
label: "Fasilitas Kesehatan", label: "Fasilitas Kesehatan",
value: "fasilitaskesehatan", value: "fasilitaskesehatan",
href: "/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan", href: "/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan",
icon: <IconBuildingHospital size={18} stroke={1.8} />, icon: <IconBuildingHospital size={18} stroke={1.8} />
tooltip: "Data fasilitas kesehatan desa"
}, },
{ {
label: "Jadwal Kegiatan", label: "Jadwal Kegiatan",
value: "jadwalkegiatan", value: "jadwalkegiatan",
href: "/admin/kesehatan/data-kesehatan-warga/jadwal_kegiatan", href: "/admin/kesehatan/data-kesehatan-warga/jadwal_kegiatan",
icon: <IconCalendarEvent size={18} stroke={1.8} />, icon: <IconCalendarEvent size={18} stroke={1.8} />
tooltip: "Atur jadwal kegiatan kesehatan"
}, },
{ {
label: "Artikel Kesehatan", label: "Artikel Kesehatan",
value: "artikelkesehatan", value: "artikelkesehatan",
href: "/admin/kesehatan/data-kesehatan-warga/artikel_kesehatan", href: "/admin/kesehatan/data-kesehatan-warga/artikel_kesehatan",
icon: <IconNotes size={18} stroke={1.8} />, icon: <IconNotes size={18} stroke={1.8} />
tooltip: "Artikel & informasi seputar kesehatan"
}, },
]; ];
@@ -100,46 +95,39 @@ function LayoutTabs({ children }: { children: React.ReactNode }) {
}} }}
> >
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<Tooltip <TabsTab
key={i} key={i}
label={tab.tooltip} value={tab.value}
position="bottom" leftSection={tab.icon}
withArrow style={{
transitionProps={{ transition: 'pop', duration: 200 }} fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
> >
<TabsTab {tab.label}
value={tab.value} </TabsTab>
leftSection={tab.icon}
style={{
fontWeight: 600,
fontSize: "0.9rem",
transition: "all 0.2s ease",
}}
>
{tab.label}
</TabsTab>
</Tooltip>
))} ))}
</TabsList> </TabsList>
</ScrollArea> </ScrollArea>
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<TabsPanel <TabsPanel
key={i} key={i}
value={tab.value} value={tab.value}
style={{ style={{
padding: "1.5rem", padding: "1.5rem",
background: "linear-gradient(180deg, #ffffff, #f5f6fa)", background: "linear-gradient(180deg, #ffffff, #f5f6fa)",
borderRadius: "1rem", borderRadius: "1rem",
boxShadow: "0 4px 16px rgba(0,0,0,0.05)", boxShadow: "0 4px 16px rgba(0,0,0,0.05)",
}} }}
> >
{children} {children}
</TabsPanel> </TabsPanel>
))} ))}
</Tabs> </Tabs>
</Stack> </Stack >
); );
} }

Some files were not shown because too many files have changed in this diff Show More