Fix SDGs Desa Barchart sudah responsive, tabel dan bar progress di menu apbdes sudah sesuai dengan data
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Group, Image, Modal, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Stepper, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Center, Divider, Group, Image, Modal, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Stepper, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useDisclosure, useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react';
|
||||
import { useTransitionRouter } from 'next-view-transitions';
|
||||
@@ -23,18 +23,17 @@ function Page() {
|
||||
const resetForm = () => {
|
||||
beasiswaDesa.create.form = {
|
||||
namaLengkap: "",
|
||||
nik: "",
|
||||
nis: "",
|
||||
kelas: "",
|
||||
jenisKelamin: "",
|
||||
alamatDomisili: "",
|
||||
tempatLahir: "",
|
||||
tanggalLahir: "",
|
||||
jenisKelamin: "",
|
||||
kewarganegaraan: "WNI",
|
||||
agama: "",
|
||||
alamatKTP: "",
|
||||
alamatDomisili: "",
|
||||
namaOrtu: "",
|
||||
nik: "",
|
||||
pekerjaanOrtu: "",
|
||||
penghasilan: "",
|
||||
noHp: "",
|
||||
email: "",
|
||||
statusPernikahan: "",
|
||||
ukuranBaju: "",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -189,9 +188,22 @@ function Page() {
|
||||
onChange={(val) => { beasiswaDesa.create.form.namaLengkap = val.target.value }} />
|
||||
<TextInput
|
||||
type="number"
|
||||
label="NIK"
|
||||
placeholder="Masukkan NIK"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||
label="NIS"
|
||||
placeholder="Masukkan NIS"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nis = val.target.value }} />
|
||||
<TextInput
|
||||
label="Kelas"
|
||||
placeholder="Masukkan kelas"
|
||||
onChange={(val) => { beasiswaDesa.create.form.kelas = val.target.value }} />
|
||||
<Select
|
||||
label="Jenis Kelamin"
|
||||
placeholder="Pilih jenis kelamin"
|
||||
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||
<TextInput
|
||||
label="Alamat Domisili"
|
||||
placeholder="Masukkan alamat domisili"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||
<TextInput
|
||||
label="Tempat Lahir"
|
||||
placeholder="Masukkan tempat lahir"
|
||||
@@ -201,52 +213,29 @@ function Page() {
|
||||
label="Tanggal Lahir"
|
||||
placeholder="Pilih tanggal lahir"
|
||||
onChange={(val) => { beasiswaDesa.create.form.tanggalLahir = val.target.value }} />
|
||||
<Select
|
||||
label="Jenis Kelamin"
|
||||
placeholder="Pilih jenis kelamin"
|
||||
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||
<Box pt={15} pb={10}>
|
||||
<Divider />
|
||||
</Box>
|
||||
<TextInput
|
||||
label="Kewarganegaraan"
|
||||
placeholder="Masukkan kewarganegaraan"
|
||||
value={beasiswaDesa.create.form.kewarganegaraan || "WNI"} // tampilkan WNI kalau kosong
|
||||
onChange={(e) => {
|
||||
beasiswaDesa.create.form.kewarganegaraan = e.target.value;
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Agama"
|
||||
placeholder="Pilih agama"
|
||||
data={[{ value: "ISLAM", label: "Islam" }, { value: "KRISTEN_PROTESTAN", label: "Kristen Protestan" }, { value: "KRISTEN_KATOLIK", label: "Kristen Katolik" }, { value: "HINDU", label: "Hindu" }, { value: "BUDDHA", label: "Buddha" }, { value: "KONGHUCU", label: "Konghucu" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.agama = val }} />
|
||||
label="Nama Orang Tua / Wali"
|
||||
placeholder="Masukkan nama orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.namaOrtu = val.target.value }} />
|
||||
<TextInput
|
||||
label="Alamat KTP"
|
||||
placeholder="Masukkan alamat sesuai KTP"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatKTP = val.target.value }} />
|
||||
label="NIK Orang Tua / Wali"
|
||||
placeholder="Masukkan NIK orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||
<TextInput
|
||||
label="Alamat Domisili"
|
||||
placeholder="Masukkan alamat domisili"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||
label="Pekerjaan Orang Tua / Wali"
|
||||
placeholder="Masukkan pekerjaan orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.pekerjaanOrtu = val.target.value }} />
|
||||
<TextInput
|
||||
type="number"
|
||||
label="Nomor HP"
|
||||
placeholder="Masukkan nomor HP"
|
||||
label="Penghasilan Orang Tua / Wali"
|
||||
placeholder="Masukkan penghasilan orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.penghasilan = val.target.value }} />
|
||||
<TextInput
|
||||
label="No HP"
|
||||
placeholder="Masukkan no hp"
|
||||
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
||||
<TextInput
|
||||
type="email"
|
||||
label="Email"
|
||||
placeholder="Masukkan alamat email"
|
||||
onChange={(val) => { beasiswaDesa.create.form.email = val.target.value }} />
|
||||
<Select
|
||||
label="Status Pernikahan"
|
||||
placeholder="Pilih status pernikahan"
|
||||
data={[{ value: "BELUM_MENIKAH", label: "Belum Menikah" }, { value: "MENIKAH", label: "Menikah" }, { value: "JANDA_DUDA", label: "Janda/Duda" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.statusPernikahan = val }} />
|
||||
<Select
|
||||
label="Ukuran Baju"
|
||||
placeholder="Pilih ukuran baju"
|
||||
data={[{ value: "S", label: "S" }, { value: "M", label: "M" }, { value: "L", label: "L" }, { value: "XL", label: "XL" }, { value: "XXL", label: "XXL" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.ukuranBaju = val }} />
|
||||
<Group justify="flex-end" mt="md">
|
||||
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
||||
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
Divider,
|
||||
Group,
|
||||
Modal,
|
||||
Paper,
|
||||
@@ -30,18 +31,17 @@ export default function BeasiswaPage() {
|
||||
const resetForm = () => {
|
||||
beasiswaDesa.create.form = {
|
||||
namaLengkap: "",
|
||||
nik: "",
|
||||
nis: "",
|
||||
kelas: "",
|
||||
jenisKelamin: "",
|
||||
alamatDomisili: "",
|
||||
tempatLahir: "",
|
||||
tanggalLahir: "",
|
||||
jenisKelamin: "",
|
||||
kewarganegaraan: "WNI",
|
||||
agama: "",
|
||||
alamatKTP: "",
|
||||
alamatDomisili: "",
|
||||
namaOrtu: "",
|
||||
nik: "",
|
||||
pekerjaanOrtu: "",
|
||||
penghasilan: "",
|
||||
noHp: "",
|
||||
email: "",
|
||||
statusPernikahan: "",
|
||||
ukuranBaju: "",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -248,9 +248,22 @@ export default function BeasiswaPage() {
|
||||
onChange={(val) => { beasiswaDesa.create.form.namaLengkap = val.target.value }} />
|
||||
<TextInput
|
||||
type="number"
|
||||
label="NIK"
|
||||
placeholder="Masukkan NIK"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||
label="NIS"
|
||||
placeholder="Masukkan NIS"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nis = val.target.value }} />
|
||||
<TextInput
|
||||
label="Kelas"
|
||||
placeholder="Masukkan kelas"
|
||||
onChange={(val) => { beasiswaDesa.create.form.kelas = val.target.value }} />
|
||||
<Select
|
||||
label="Jenis Kelamin"
|
||||
placeholder="Pilih jenis kelamin"
|
||||
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||
<TextInput
|
||||
label="Alamat Domisili"
|
||||
placeholder="Masukkan alamat domisili"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||
<TextInput
|
||||
label="Tempat Lahir"
|
||||
placeholder="Masukkan tempat lahir"
|
||||
@@ -260,52 +273,29 @@ export default function BeasiswaPage() {
|
||||
label="Tanggal Lahir"
|
||||
placeholder="Pilih tanggal lahir"
|
||||
onChange={(val) => { beasiswaDesa.create.form.tanggalLahir = val.target.value }} />
|
||||
<Select
|
||||
label="Jenis Kelamin"
|
||||
placeholder="Pilih jenis kelamin"
|
||||
data={[{ value: "LAKI_LAKI", label: "Laki-laki" }, { value: "PEREMPUAN", label: "Perempuan" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.jenisKelamin = val }} />
|
||||
<Box pt={15} pb={10}>
|
||||
<Divider />
|
||||
</Box>
|
||||
<TextInput
|
||||
label="Kewarganegaraan"
|
||||
placeholder="Masukkan kewarganegaraan"
|
||||
value={beasiswaDesa.create.form.kewarganegaraan || "WNI"} // tampilkan WNI kalau kosong
|
||||
onChange={(e) => {
|
||||
beasiswaDesa.create.form.kewarganegaraan = e.target.value;
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Agama"
|
||||
placeholder="Pilih agama"
|
||||
data={[{ value: "ISLAM", label: "Islam" }, { value: "KRISTEN_PROTESTAN", label: "Kristen Protestan" }, { value: "KRISTEN_KATOLIK", label: "Kristen Katolik" }, { value: "HINDU", label: "Hindu" }, { value: "BUDDHA", label: "Buddha" }, { value: "KONGHUCU", label: "Konghucu" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.agama = val }} />
|
||||
label="Nama Orang Tua / Wali"
|
||||
placeholder="Masukkan nama orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.namaOrtu = val.target.value }} />
|
||||
<TextInput
|
||||
label="Alamat KTP"
|
||||
placeholder="Masukkan alamat sesuai KTP"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatKTP = val.target.value }} />
|
||||
label="NIK Orang Tua / Wali"
|
||||
placeholder="Masukkan NIK orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.nik = val.target.value }} />
|
||||
<TextInput
|
||||
label="Alamat Domisili"
|
||||
placeholder="Masukkan alamat domisili"
|
||||
onChange={(val) => { beasiswaDesa.create.form.alamatDomisili = val.target.value }} />
|
||||
label="Pekerjaan Orang Tua / Wali"
|
||||
placeholder="Masukkan pekerjaan orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.pekerjaanOrtu = val.target.value }} />
|
||||
<TextInput
|
||||
type="number"
|
||||
label="Nomor HP"
|
||||
placeholder="Masukkan nomor HP"
|
||||
label="Penghasilan Orang Tua / Wali"
|
||||
placeholder="Masukkan penghasilan orang tua / wali"
|
||||
onChange={(val) => { beasiswaDesa.create.form.penghasilan = val.target.value }} />
|
||||
<TextInput
|
||||
label="No HP"
|
||||
placeholder="Masukkan no hp"
|
||||
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
||||
<TextInput
|
||||
type="email"
|
||||
label="Email"
|
||||
placeholder="Masukkan alamat email"
|
||||
onChange={(val) => { beasiswaDesa.create.form.email = val.target.value }} />
|
||||
<Select
|
||||
label="Status Pernikahan"
|
||||
placeholder="Pilih status pernikahan"
|
||||
data={[{ value: "BELUM_MENIKAH", label: "Belum Menikah" }, { value: "MENIKAH", label: "Menikah" }, { value: "JANDA_DUDA", label: "Janda/Duda" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.statusPernikahan = val }} />
|
||||
<Select
|
||||
label="Ukuran Baju"
|
||||
placeholder="Pilih ukuran baju"
|
||||
data={[{ value: "S", label: "S" }, { value: "M", label: "M" }, { value: "L", label: "L" }, { value: "XL", label: "XL" }, { value: "XXL", label: "XXL" }, { value: "LAINNYA", label: "Lainnya" }]}
|
||||
onChange={(val) => { if (val) beasiswaDesa.create.form.ukuranBaju = val }} />
|
||||
<Group justify="flex-end" mt="md">
|
||||
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
||||
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
||||
|
||||
208
src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaProgress.tsx
Normal file
208
src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaProgress.tsx
Normal file
@@ -0,0 +1,208 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
// src/app/admin/(dashboard)/landing-page/APBDes/APBDesProgress.tsx
|
||||
'use client';
|
||||
|
||||
import { Box, Paper, Progress, Stack, Text, Title } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
|
||||
|
||||
function formatRupiah(value: number) {
|
||||
return new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
minimumFractionDigits: 2,
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
function APBDesProgress() {
|
||||
const state = useProxy(apbdes);
|
||||
const data = state.findMany.data || [];
|
||||
|
||||
// Ambil APBDes pertama (misalnya, jika hanya satu tahun ditampilkan)
|
||||
const apbdesItem = data[0]; // 👈 sesuaikan logika jika ada banyak APBDes
|
||||
|
||||
if (!apbdesItem) {
|
||||
return (
|
||||
<Box py="md" px={{ base: 'md', md: 100 }}>
|
||||
<Text c="dimmed">Belum ada data APBDes untuk ditampilkan.</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const items = apbdesItem.items || [];
|
||||
const sortedItems = [...items].sort((a, b) => a.kode.localeCompare(b.kode));
|
||||
|
||||
// Kelompokkan berdasarkan tipe
|
||||
const pendapatanItems = sortedItems.filter(item => item.tipe === 'pendapatan');
|
||||
const belanjaItems = sortedItems.filter(item => item.tipe === 'belanja');
|
||||
const pembiayaanItems = sortedItems.filter(item => item.tipe === 'pembiayaan'); // jika ada
|
||||
|
||||
// Hitung total per kategori
|
||||
const calcTotal = (items: any[]) => {
|
||||
const anggaran = items.reduce((sum, item) => sum + item.anggaran, 0);
|
||||
const realisasi = items.reduce((sum, item) => sum + item.realisasi, 0);
|
||||
const persen = anggaran > 0 ? (realisasi / anggaran) * 100 : 0;
|
||||
return { anggaran, realisasi, persen };
|
||||
};
|
||||
|
||||
const pendapatan = calcTotal(pendapatanItems);
|
||||
const belanja = calcTotal(belanjaItems);
|
||||
const pembiayaan = calcTotal(pembiayaanItems); // bisa kosong
|
||||
|
||||
// Render satu progress bar
|
||||
const renderProgress = (label: string, dataset: any) => {
|
||||
const isPembiayaan = label.includes('Pembiayaan');
|
||||
|
||||
return (
|
||||
<Box key={label}>
|
||||
<Text fw={600} fz="sm">{label}</Text>
|
||||
<Text fw={700} mb="xs">
|
||||
{formatRupiah(dataset.realisasi)} | {formatRupiah(dataset.anggaran)}
|
||||
</Text>
|
||||
<Progress
|
||||
value={dataset.persen}
|
||||
size="xl"
|
||||
radius="xl"
|
||||
striped={false}
|
||||
styles={{
|
||||
root: { backgroundColor: '#d7e3f1' },
|
||||
section: {
|
||||
backgroundColor: isPembiayaan
|
||||
? 'green' // warna hijau untuk pembiayaan
|
||||
: colors['blue-button'], // biru untuk pendapatan/belanja
|
||||
position: 'relative',
|
||||
'&::after': {
|
||||
content: `'${dataset.persen.toFixed(2)}%'`,
|
||||
position: 'absolute',
|
||||
right: 10,
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
color: 'white',
|
||||
fontWeight: 700,
|
||||
fontSize: '0.8rem',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper
|
||||
mx={{ base: 'md', md: 100 }}
|
||||
p="xl"
|
||||
radius="md"
|
||||
shadow="sm"
|
||||
withBorder
|
||||
bg={colors['white-1']}
|
||||
>
|
||||
<Stack gap="lg">
|
||||
<Title order={4} c={colors['blue-button']} ta="center">
|
||||
Grafik Pelaksanaan APBDes Tahun {apbdesItem.tahun}
|
||||
</Title>
|
||||
|
||||
<Text ta="center" fw="bold" fz="sm" c="dimmed">
|
||||
Realisasi | Anggaran
|
||||
</Text>
|
||||
|
||||
{renderProgress('Pendapatan Desa', pendapatan)}
|
||||
{renderProgress('Belanja Desa', belanja)}
|
||||
{renderProgress('Pembiayaan Desa', pembiayaan)}
|
||||
{pembiayaanItems.length > 0 && renderProgress('Pembiayaan Desa', pembiayaan)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default APBDesProgress;
|
||||
|
||||
// /* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
// 'use client';
|
||||
|
||||
// import { Box, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
// import { BarChart } from '@mantine/charts';
|
||||
// import { useProxy } from 'valtio/utils';
|
||||
// import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes';
|
||||
// import colors from '@/con/colors';
|
||||
|
||||
// function APBDesProgress() {
|
||||
// const state = useProxy(apbdes);
|
||||
// const data = state.findMany.data || [];
|
||||
|
||||
// const apbdesItem = data[0];
|
||||
// if (!apbdesItem) {
|
||||
// return (
|
||||
// <Box py="md" px={{ base: 'md', md: 100 }}>
|
||||
// <Text c="dimmed">Belum ada data APBDes untuk ditampilkan.</Text>
|
||||
// </Box>
|
||||
// );
|
||||
// }
|
||||
|
||||
// const items = apbdesItem.items || [];
|
||||
// const sortedItems = [...items].sort((a, b) => a.kode.localeCompare(b.kode));
|
||||
|
||||
// const pendapatanItems = sortedItems.filter(i => i.tipe === 'pendapatan');
|
||||
// const belanjaItems = sortedItems.filter(i => i.tipe === 'belanja');
|
||||
// const pembiayaanItems = sortedItems.filter(i => i.tipe === 'pembiayaan');
|
||||
|
||||
// const total = (rows: any[]) => {
|
||||
// const anggaran = rows.reduce((s, i) => s + i.anggaran, 0);
|
||||
// const realisasi = rows.reduce((s, i) => s + i.realisasi, 0);
|
||||
// return anggaran === 0 ? 0 : (realisasi / anggaran) * 100;
|
||||
// };
|
||||
|
||||
// const chartData = [
|
||||
// { name: 'Pendapatan', persen: total(pendapatanItems) },
|
||||
// { name: 'Belanja', persen: total(belanjaItems) },
|
||||
// ];
|
||||
|
||||
// if (pembiayaanItems.length > 0) {
|
||||
// chartData.push({ name: 'Pembiayaan', persen: total(pembiayaanItems) });
|
||||
// }
|
||||
|
||||
// return (
|
||||
// <Paper
|
||||
// mx={{ base: 'md', md: 100 }}
|
||||
// p="xl"
|
||||
// radius="md"
|
||||
// shadow="sm"
|
||||
// withBorder
|
||||
// bg={colors['white-1']}
|
||||
// >
|
||||
// <Stack gap="lg">
|
||||
// <Title order={4} c={colors['blue-button']} ta="center">
|
||||
// Grafik Pelaksanaan APBDes Tahun {apbdesItem.tahun}
|
||||
// </Title>
|
||||
|
||||
// <Text ta="center" fw="bold" fz="sm" c="dimmed">
|
||||
// Persentase Realisasi (%) dari Anggaran
|
||||
// </Text>
|
||||
|
||||
// <BarChart
|
||||
// h={200}
|
||||
// data={chartData}
|
||||
// orientation="vertical"
|
||||
// dataKey="name"
|
||||
// barProps={{ radius: 6 }}
|
||||
// series={[
|
||||
// {
|
||||
// name: 'persen',
|
||||
// label: 'Persentase',
|
||||
// color: colors['blue-button'],
|
||||
// },
|
||||
// ]}
|
||||
// yAxisProps={{
|
||||
// domain: [0, 100],
|
||||
// }}
|
||||
// valueFormatter={(v) => `${v.toFixed(1)}%`}
|
||||
// />
|
||||
// </Stack>
|
||||
// </Paper>
|
||||
// );
|
||||
// }
|
||||
|
||||
// export default APBDesProgress;
|
||||
160
src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx
Normal file
160
src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
// src/app/admin/(dashboard)/landing-page/APBDes/APBDesTable.tsx
|
||||
'use client';
|
||||
|
||||
import { Box, Paper, Table, Text, Title, Badge, Group } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
interface APBDesItem {
|
||||
id: string;
|
||||
kode: string;
|
||||
uraian: string;
|
||||
anggaran: number;
|
||||
realisasi: number;
|
||||
selisih: number;
|
||||
persentase: number;
|
||||
level: number;
|
||||
tipe: 'pendapatan' | 'belanja' | 'pembiayaan';
|
||||
}
|
||||
|
||||
interface APBDesData {
|
||||
id: string;
|
||||
tahun: number;
|
||||
items: APBDesItem[];
|
||||
image?: { id: string; url: string } | null;
|
||||
file?: { id: string; url: string } | null;
|
||||
}
|
||||
|
||||
// Helper: Format Rupiah, tapi jika 0 → tampilkan '-'
|
||||
function formatRupiahOrEmpty(value: number): string {
|
||||
if (value === 0 || value === null || value === undefined) {
|
||||
return '-';
|
||||
}
|
||||
return new Intl.NumberFormat('id-ID', {
|
||||
minimumFractionDigits: 2,
|
||||
style: 'decimal',
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
// Helper: Format Persentase, tapi jika 0 → tampilkan '-'
|
||||
function formatPersentaseOrEmpty(value: number): string {
|
||||
if (value === 0 || value === null || value === undefined) {
|
||||
return '-';
|
||||
}
|
||||
return `${value.toFixed(2)}%`;
|
||||
}
|
||||
|
||||
function getIndent(level: number) {
|
||||
return {
|
||||
paddingLeft: `${(level - 1) * 20}px`,
|
||||
};
|
||||
}
|
||||
|
||||
function APBDesTable() {
|
||||
const state = useProxy(apbdes);
|
||||
const data = state.findMany.data || [];
|
||||
|
||||
// Get the first APBDes item
|
||||
const apbdesItem = data[0] as unknown as APBDesData | undefined;
|
||||
|
||||
if (!apbdesItem) {
|
||||
return (
|
||||
<Box py="md" px={{ base: 'md', md: 100 }}>
|
||||
<Text c="dimmed">Belum ada data APBDes untuk ditampilkan.</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const items = Array.isArray(apbdesItem.items) ? apbdesItem.items : [];
|
||||
const sortedItems = [...items].sort((a, b) => a.kode.localeCompare(b.kode));
|
||||
|
||||
// Calculate totals
|
||||
const totalAnggaran = items.reduce((sum, item) => sum + (item.anggaran || 0), 0);
|
||||
const totalRealisasi = items.reduce((sum, item) => sum + (item.realisasi || 0), 0);
|
||||
const totalSelisih = totalAnggaran - totalRealisasi;
|
||||
const totalPersentase = totalAnggaran > 0 ? (totalRealisasi / totalAnggaran) * 100 : 0;
|
||||
|
||||
return (
|
||||
<Box py="md" px={{ base: 'md', md: 100 }}>
|
||||
<Title order={4} c={colors['blue-button']} mb="sm">
|
||||
Rincian APBDes Tahun {apbdesItem.tahun}
|
||||
</Title>
|
||||
|
||||
<Paper withBorder radius="md" shadow="xs" p="md">
|
||||
<Box style={{overflowY: 'auto' }}>
|
||||
<Table withColumnBorders highlightOnHover>
|
||||
<Table.Thead bg="#2c5f78">
|
||||
<Table.Tr>
|
||||
<Table.Th c="white" style={{ width: '40%' }}>
|
||||
Uraian
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="right" style={{ width: '15%' }}>
|
||||
Anggaran (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="right" style={{ width: '15%' }}>
|
||||
Realisasi (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="right" style={{ width: '15%' }}>
|
||||
Lebih/(Kurang) (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="center" style={{ width: '15%' }}>
|
||||
Persentase (%)
|
||||
</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{sortedItems.map((item) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td style={getIndent(item.level)}>
|
||||
<Group gap="xs" align="flex-start">
|
||||
<Text fw={item.level === 1 ? 'bold' : 'normal'}>{item.kode}</Text>
|
||||
<Text fz="sm" >
|
||||
{item.uraian}
|
||||
</Text>
|
||||
</Group>
|
||||
</Table.Td>
|
||||
<Table.Td ta="right">{formatRupiahOrEmpty(item.anggaran)}</Table.Td>
|
||||
<Table.Td ta="right">{formatRupiahOrEmpty(item.realisasi)}</Table.Td>
|
||||
<Table.Td ta="right">
|
||||
<Text c={item.selisih >= 0 ? 'green' : 'red'}>
|
||||
{formatRupiahOrEmpty(item.selisih)}
|
||||
</Text>
|
||||
</Table.Td>
|
||||
<Table.Td ta="center">
|
||||
<Badge color={item.persentase >= 100 ? 'teal' : 'yellow'} size="sm">
|
||||
{formatPersentaseOrEmpty(item.persentase)}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
<Table.Tfoot bg="#e6f0f7">
|
||||
<Table.Tr>
|
||||
<Table.Th colSpan={1}>
|
||||
<Text fw={700}>JUMLAH PENDAPATAN</Text>
|
||||
</Table.Th>
|
||||
<Table.Th ta="right">
|
||||
<Text fw={700}>{formatRupiahOrEmpty(totalAnggaran)}</Text>
|
||||
</Table.Th>
|
||||
<Table.Th ta="right">
|
||||
<Text fw={700}>{formatRupiahOrEmpty(totalRealisasi)}</Text>
|
||||
</Table.Th>
|
||||
<Table.Th ta="right">
|
||||
<Text fw={700} c={totalSelisih >= 0 ? 'green' : 'red'}>
|
||||
{formatRupiahOrEmpty(totalSelisih)}
|
||||
</Text>
|
||||
</Table.Th>
|
||||
<Table.Th ta="center">
|
||||
<Text fw={700}>{formatPersentaseOrEmpty(totalPersentase)}</Text>
|
||||
</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Tfoot>
|
||||
</Table>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default APBDesTable;
|
||||
@@ -4,12 +4,14 @@
|
||||
import PendapatanAsliDesa from '@/app/admin/(dashboard)/_state/ekonomi/PADesa'
|
||||
import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes'
|
||||
import colors from '@/con/colors'
|
||||
import { ActionIcon, BackgroundImage, Box, Center, Container, Group, Loader, Paper, Progress, SimpleGrid, Stack, Table, Text, Title } from '@mantine/core'
|
||||
import { ActionIcon, BackgroundImage, Box, Center, Container, Group, Loader, SimpleGrid, Stack, Text, Title } from '@mantine/core'
|
||||
import { IconDownload } from '@tabler/icons-react'
|
||||
import { Link } from 'next-view-transitions'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useProxy } from 'valtio/utils'
|
||||
import BackButton from '../../(pages)/desa/layanan/_com/BackButto'
|
||||
import APBDesProgress from './lib/apbDesaProgress'
|
||||
import APBDesTable from './lib/apbDesaTable'
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(apbdes)
|
||||
@@ -92,200 +94,10 @@ function Page() {
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
<DetailAPBDesaTable />
|
||||
<APBDesaProgress />
|
||||
<APBDesTable />
|
||||
<APBDesProgress />
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
function DetailAPBDesaTable() {
|
||||
// 🔹 Dummy data
|
||||
const data = {
|
||||
tahun: 2024,
|
||||
pendapatan: [
|
||||
{ id: 1, nama: 'Pendapatan Asli Desa', anggaran: 32000000, realisasi: 6500000 },
|
||||
{ id: 2, nama: 'Dana Desa', anggaran: 125000000, realisasi: 120000000 },
|
||||
{ id: 3, nama: 'Bagi Hasil Pajak dan Retribusi', anggaran: 10000000, realisasi: 9000000 },
|
||||
],
|
||||
belanja: [
|
||||
{ id: 1, nama: 'Belanja Pegawai', anggaran: 80000000, realisasi: 75000000 },
|
||||
{ id: 2, nama: 'Belanja Barang & Jasa', anggaran: 50000000, realisasi: 42000000 },
|
||||
],
|
||||
pembiayaan: [
|
||||
{ id: 1, nama: 'Penerimaan Pembiayaan', anggaran: 15000000, realisasi: 15000000 },
|
||||
{ id: 2, nama: 'Pengeluaran Pembiayaan', anggaran: 10000000, realisasi: 8000000 },
|
||||
],
|
||||
};
|
||||
|
||||
const formatRupiah = (value: number) =>
|
||||
new Intl.NumberFormat('id-ID', {
|
||||
minimumFractionDigits: 2,
|
||||
style: 'decimal',
|
||||
}).format(value);
|
||||
|
||||
// 🔹 Helper buat render satu kategori (Pendapatan, Belanja, Pembiayaan)
|
||||
const renderSection = (title: string, items: any[]) => {
|
||||
const totalAnggaran = items.reduce((sum, i) => sum + Number(i.anggaran || 0), 0);
|
||||
const totalRealisasi = items.reduce((sum, i) => sum + Number(i.realisasi || 0), 0);
|
||||
const totalSelisih = totalAnggaran - totalRealisasi;
|
||||
const totalPersen = totalAnggaran
|
||||
? (totalRealisasi / totalAnggaran) * 100
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<Paper withBorder radius="md" shadow="xs" p="md">
|
||||
<Title order={5} mb="sm" c={colors['blue-button']}>
|
||||
{title.toUpperCase()}
|
||||
</Title>
|
||||
<Table withColumnBorders highlightOnHover>
|
||||
<Table.Thead bg={colors['blue-button']}>
|
||||
<Table.Tr>
|
||||
<Table.Th c="white">Uraian</Table.Th>
|
||||
<Table.Th c="white" ta="right">
|
||||
Anggaran (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="right">
|
||||
Realisasi (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="right">
|
||||
Lebih/(Kurang) (Rp)
|
||||
</Table.Th>
|
||||
<Table.Th c="white" ta="center">
|
||||
Persentase (%)
|
||||
</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{items.map((item, index) => {
|
||||
const selisih = Number(item.anggaran) - Number(item.realisasi);
|
||||
const persen = item.anggaran
|
||||
? (item.realisasi / item.anggaran) * 100
|
||||
: 0;
|
||||
return (
|
||||
<Table.Tr key={item.id || index}>
|
||||
<Table.Td>
|
||||
<strong>{`${index + 1}. ${item.nama}`}</strong>
|
||||
</Table.Td>
|
||||
<Table.Td ta="right">{formatRupiah(item.anggaran)}</Table.Td>
|
||||
<Table.Td ta="right">{formatRupiah(item.realisasi)}</Table.Td>
|
||||
<Table.Td ta="right">{formatRupiah(selisih)}</Table.Td>
|
||||
<Table.Td ta="center">{persen.toFixed(2)}</Table.Td>
|
||||
</Table.Tr>
|
||||
);
|
||||
})}
|
||||
</Table.Tbody>
|
||||
<Table.Tfoot bg="#f1f5fb">
|
||||
<Table.Tr>
|
||||
<Table.Th>Total {title}</Table.Th>
|
||||
<Table.Th ta="right">{formatRupiah(totalAnggaran)}</Table.Th>
|
||||
<Table.Th ta="right">{formatRupiah(totalRealisasi)}</Table.Th>
|
||||
<Table.Th ta="right">{formatRupiah(totalSelisih)}</Table.Th>
|
||||
<Table.Th ta="center">{totalPersen.toFixed(2)}</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Tfoot>
|
||||
</Table>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box py="md" px={{ base: 'md', md: 100 }}>
|
||||
<Stack gap="xl">
|
||||
<Title order={4} c={colors['blue-button']}>
|
||||
APB Desa Tahun {data.tahun}
|
||||
</Title>
|
||||
|
||||
{renderSection('Pendapatan', data.pendapatan)}
|
||||
{renderSection('Belanja', data.belanja)}
|
||||
{renderSection('Pembiayaan', data.pembiayaan)}
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function APBDesaProgress() {
|
||||
const data = {
|
||||
tahun: 2024,
|
||||
pendapatan: [
|
||||
{ id: 1, nama: 'Pendapatan Asli Desa', anggaran: 32000000, realisasi: 6500000 },
|
||||
{ id: 2, nama: 'Dana Desa', anggaran: 125000000, realisasi: 120000000 },
|
||||
{ id: 3, nama: 'Bagi Hasil Pajak dan Retribusi', anggaran: 10000000, realisasi: 9000000 },
|
||||
],
|
||||
belanja: [
|
||||
{ id: 1, nama: 'Belanja Pegawai', anggaran: 80000000, realisasi: 75000000 },
|
||||
{ id: 2, nama: 'Belanja Barang & Jasa', anggaran: 50000000, realisasi: 42000000 },
|
||||
],
|
||||
pembiayaan: [
|
||||
{ id: 1, nama: 'Penerimaan Pembiayaan', anggaran: 15000000, realisasi: 15000000 },
|
||||
{ id: 2, nama: 'Pengeluaran Pembiayaan', anggaran: 10000000, realisasi: 8000000 },
|
||||
],
|
||||
};
|
||||
|
||||
const formatRupiah = (value: number) =>
|
||||
new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
minimumFractionDigits: 2,
|
||||
}).format(value);
|
||||
|
||||
const calcProgress = (items: any[]) => {
|
||||
const anggaran = items.reduce((sum, i) => sum + i.anggaran, 0);
|
||||
const realisasi = items.reduce((sum, i) => sum + i.realisasi, 0);
|
||||
const persen = anggaran ? (realisasi / anggaran) * 100 : 0;
|
||||
return { anggaran, realisasi, persen };
|
||||
};
|
||||
|
||||
const pendapatan = calcProgress(data.pendapatan);
|
||||
const belanja = calcProgress(data.belanja);
|
||||
const pembiayaan = calcProgress(data.pembiayaan);
|
||||
|
||||
const renderProgress = (label: string, dataset: any) => (
|
||||
<Box>
|
||||
<Text fw={600}>{label}</Text>
|
||||
<Text fw={700} mb="xs">
|
||||
{formatRupiah(dataset.realisasi)} | {formatRupiah(dataset.anggaran)}
|
||||
</Text>
|
||||
<Progress
|
||||
value={dataset.persen}
|
||||
size="xl"
|
||||
radius="xl"
|
||||
striped={false}
|
||||
styles={{
|
||||
root: { backgroundColor: '#d7e3f1' },
|
||||
section: {
|
||||
backgroundColor: colors['blue-button'],
|
||||
position: 'relative',
|
||||
'&::after': {
|
||||
content: `'${dataset.persen.toFixed(2)}%'`,
|
||||
position: 'absolute',
|
||||
right: 10,
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
color: 'white',
|
||||
fontWeight: 700,
|
||||
fontSize: '0.8rem',
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<Paper mx={{ base: 'md', md: 100 }} p="xl" radius="md" shadow="sm" withBorder bg={colors['white-1']}>
|
||||
<Stack gap="lg">
|
||||
<Title order={4} c={colors['blue-button']}>
|
||||
Grafik APB Desa Tahun {data.tahun}
|
||||
</Title>
|
||||
|
||||
{renderProgress('Pendapatan Desa', pendapatan)}
|
||||
{renderProgress('Belanja Desa', belanja)}
|
||||
{renderProgress('Pembiayaan Desa', pembiayaan)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default Page
|
||||
export default Page
|
||||
@@ -209,50 +209,57 @@ function Page() {
|
||||
) : null}
|
||||
|
||||
{/* Chart */}
|
||||
<Box mt={30} style={{ width: '100%', minHeight: 400 }}>
|
||||
<Paper bg={colors['white-1']} pt={50} pb={170} px={90} mb={"xl"} radius="md" withBorder>
|
||||
<Stack gap={"xs"}>
|
||||
<Title ta={"center"} pb={10} order={2}>
|
||||
Grafik APBDes
|
||||
</Title>
|
||||
<Box mt={30} style={{ width: '100%' }}>
|
||||
<Paper
|
||||
bg={colors['white-1']}
|
||||
py={90}
|
||||
px={{ base: 12, sm: 24, md: 50 }}
|
||||
radius="md"
|
||||
withBorder
|
||||
>
|
||||
<Stack gap="lg">
|
||||
<Title ta="center" order={2}>Grafik SDGs Desa</Title>
|
||||
|
||||
{mounted && chartData.length > 0 ? (
|
||||
<Box style={{ padding: '0 30px' }}> {/* Tambahkan padding horizontal agar label tidak keluar */}
|
||||
<BarChart
|
||||
h={500}
|
||||
data={chartData}
|
||||
dataKey="name"
|
||||
type="stacked"
|
||||
withBarValueLabel
|
||||
series={[
|
||||
{
|
||||
name: 'jumlah',
|
||||
color: colors['blue-button'],
|
||||
// label: 'Jumlah', → HAPUS INI AGAR LEGEND TIDAK MUNCUL
|
||||
},
|
||||
]}
|
||||
withTooltip
|
||||
tooltipProps={{
|
||||
labelFormatter: (value) => value,
|
||||
formatter: (value) => `${value}%`,
|
||||
}}
|
||||
xAxisProps={{
|
||||
angle: -45,
|
||||
textAnchor: 'end',
|
||||
interval: 0,
|
||||
fontSize: 12,
|
||||
dy: 10,
|
||||
}}
|
||||
yAxisProps={{
|
||||
domain: [0, 100],
|
||||
tickCount: 6,
|
||||
}}
|
||||
style={{
|
||||
overflowX: 'visible',
|
||||
paddingBottom: 40, // Tambahkan ruang di bawah untuk label
|
||||
}}
|
||||
// Hilangkan legend secara eksplisit
|
||||
withLegend={false} // ⭐ Ini yang menghilangkan kotak biru + teks "Jumlah"
|
||||
/>
|
||||
<Box
|
||||
style={{
|
||||
width: "100%",
|
||||
overflowX: "auto",
|
||||
paddingBottom: 185,
|
||||
}}
|
||||
>
|
||||
<Box style={{ minWidth: 900 }}> {/* ⭐ batas minimum biar bisa scroll */}
|
||||
<BarChart
|
||||
h={350}
|
||||
data={chartData}
|
||||
dataKey="name"
|
||||
type="stacked"
|
||||
withBarValueLabel
|
||||
series={[
|
||||
{
|
||||
name: 'jumlah',
|
||||
color: colors['blue-button'],
|
||||
},
|
||||
]}
|
||||
withTooltip
|
||||
tooltipProps={{
|
||||
labelFormatter: (value) => value,
|
||||
formatter: (value) => `${value}%`,
|
||||
}}
|
||||
xAxisProps={{
|
||||
angle: -45,
|
||||
textAnchor: 'end',
|
||||
interval: 0,
|
||||
fontSize: 12,
|
||||
dy: 10,
|
||||
}}
|
||||
yAxisProps={{
|
||||
domain: [0, 100],
|
||||
tickCount: 6,
|
||||
}}
|
||||
withLegend={false}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
) : (
|
||||
<Text c="dimmed">Belum ada data untuk ditampilkan dalam grafik</Text>
|
||||
@@ -260,6 +267,7 @@ function Page() {
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
@@ -125,7 +125,6 @@ export default function ModernNewsNotification({
|
||||
position: "fixed",
|
||||
bottom: "24px",
|
||||
right: "24px",
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
@@ -147,20 +146,20 @@ export default function ModernNewsNotification({
|
||||
<IconBell size={28} />
|
||||
{hasNewNotifications && news.length > 0 && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
color="red"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-5px",
|
||||
right: "-5px",
|
||||
minWidth: "22px",
|
||||
height: "22px",
|
||||
padding: "0 6px",
|
||||
}}
|
||||
>
|
||||
{news.length}
|
||||
</Badge>
|
||||
size="sm"
|
||||
variant="filled"
|
||||
color="red"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "6px",
|
||||
right: "6px",
|
||||
minWidth: "22px",
|
||||
height: "22px",
|
||||
padding: "0 6px",
|
||||
}}
|
||||
>
|
||||
{news.length}
|
||||
</Badge>
|
||||
)}
|
||||
</ActionIcon>
|
||||
</Box>
|
||||
@@ -178,7 +177,6 @@ export default function ModernNewsNotification({
|
||||
right: "24px",
|
||||
width: "380px",
|
||||
maxHeight: "500px",
|
||||
zIndex: 999,
|
||||
boxShadow: "0 8px 32px rgba(0,0,0,0.12)",
|
||||
borderRadius: "16px",
|
||||
overflow: "hidden",
|
||||
@@ -274,7 +272,6 @@ export default function ModernNewsNotification({
|
||||
bottom: "100px",
|
||||
right: "24px",
|
||||
width: "380px",
|
||||
zIndex: 1001,
|
||||
boxShadow: "0 8px 32px rgba(0,0,0,0.15)",
|
||||
borderRadius: "12px",
|
||||
overflow: "hidden",
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Box, Card, Image, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { IconUserCircle } from '@tabler/icons-react';
|
||||
import React from 'react';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Card, Image, Stack, Text } from '@mantine/core';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { IconUserCircle } from '@tabler/icons-react';
|
||||
|
||||
interface ProfileViewProps {
|
||||
data: Prisma.PejabatDesaGetPayload<{ include: { image: true } }> | null;
|
||||
@@ -95,7 +94,6 @@ export default function ProfileView({ data }: ProfileViewProps) {
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
||||
}}
|
||||
>
|
||||
<Tooltip label="Jabatan Resmi" withArrow>
|
||||
<Text
|
||||
fz={{ base: 'xs', sm: 'sm' }}
|
||||
c="dimmed"
|
||||
@@ -103,7 +101,6 @@ export default function ProfileView({ data }: ProfileViewProps) {
|
||||
>
|
||||
{data.position || 'Tidak ada jabatan'}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
fw={700}
|
||||
|
||||
Reference in New Issue
Block a user