Fix Seeder Image, Menu Landing Page - Desa
This commit is contained in:
@@ -61,7 +61,7 @@ function Semua() {
|
||||
<Grid gutter={0}>
|
||||
<GridCol span={{ base: 12, md: 6 }}>
|
||||
<Image
|
||||
src={featuredData.image?.link || '/images/placeholder.jpg'}
|
||||
src={featuredData.image?.link || '/images/placeholderx.jpg'}
|
||||
alt={featuredData.judul || 'Berita Utama'}
|
||||
height={400}
|
||||
fit="cover"
|
||||
|
||||
@@ -83,7 +83,7 @@ function MaskotDesa() {
|
||||
className="hover:scale-105 hover:shadow-lg"
|
||||
>
|
||||
<Image
|
||||
src={img.image.link}
|
||||
src={img.image?.link || '/no-image.jpg'}
|
||||
alt={img.label}
|
||||
w="100%"
|
||||
h={200}
|
||||
|
||||
@@ -19,20 +19,58 @@ interface APBDesProgressProps {
|
||||
function APBDesProgress({ apbdesData }: APBDesProgressProps) {
|
||||
// Return null if apbdesData is not available yet
|
||||
if (!apbdesData) {
|
||||
return null;
|
||||
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
|
||||
</Title>
|
||||
<Text ta="center">Tidak ada data APBDes tersedia.</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
const items = Array.isArray(apbdesData.items) ? apbdesData.items : [];
|
||||
|
||||
// Show message if no items exist
|
||||
if (items.length === 0) {
|
||||
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 {apbdesData.tahun || 'N/A'}
|
||||
</Title>
|
||||
<Text ta="center">Tidak ada rincian anggaran tersedia untuk tahun ini.</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
const items = apbdesData.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');
|
||||
|
||||
|
||||
// Items without a type (should be filtered out from calculations)
|
||||
const untypedItems = sortedItems.filter(item => !item.tipe);
|
||||
|
||||
|
||||
if (untypedItems.length > 0) {
|
||||
console.warn(`Found ${untypedItems.length} items without a type. These will be excluded from calculations.`);
|
||||
}
|
||||
@@ -99,7 +137,7 @@ function APBDesProgress({ apbdesData }: APBDesProgressProps) {
|
||||
>
|
||||
<Stack gap="lg">
|
||||
<Title order={4} c={colors['blue-button']} ta="center">
|
||||
Grafik Pelaksanaan APBDes Tahun {apbdesData.tahun}
|
||||
Grafik Pelaksanaan APBDes Tahun {apbdesData.tahun || 'N/A'}
|
||||
</Title>
|
||||
|
||||
<Text ta="center" fw="bold" fz="sm" c="dimmed">
|
||||
|
||||
@@ -34,7 +34,36 @@ interface APBDesTableProps {
|
||||
}
|
||||
|
||||
function APBDesTable({ apbdesData }: APBDesTableProps) {
|
||||
// Handle case where apbdesData is null or undefined
|
||||
if (!apbdesData) {
|
||||
return (
|
||||
<Box pt={"xs"} pb="md" px={{ base: 'md', md: 100 }}>
|
||||
<Title order={4} c={colors['blue-button']} mb="sm">
|
||||
Rincian APBDes
|
||||
</Title>
|
||||
<Paper withBorder radius="md" shadow="xs" p="md">
|
||||
<Text>Tidak ada data APBDes tersedia.</Text>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const items = Array.isArray(apbdesData.items) ? apbdesData.items : [];
|
||||
|
||||
// Show message if no items exist
|
||||
if (items.length === 0) {
|
||||
return (
|
||||
<Box pt={"xs"} pb="md" px={{ base: 'md', md: 100 }}>
|
||||
<Title order={4} c={colors['blue-button']} mb="sm">
|
||||
Rincian APBDes Tahun {apbdesData.tahun || 'N/A'}
|
||||
</Title>
|
||||
<Paper withBorder radius="md" shadow="xs" p="md">
|
||||
<Text>Tidak ada rincian anggaran tersedia untuk tahun ini.</Text>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const sortedItems = [...items].sort((a, b) => a.kode.localeCompare(b.kode));
|
||||
|
||||
// Calculate totals
|
||||
@@ -46,7 +75,7 @@ function APBDesTable({ apbdesData }: APBDesTableProps) {
|
||||
return (
|
||||
<Box pt={"xs"} pb="md" px={{ base: 'md', md: 100 }}>
|
||||
<Title order={4} c={colors['blue-button']} mb="sm">
|
||||
Rincian APBDes Tahun {apbdesData.tahun}
|
||||
Rincian APBDes Tahun {apbdesData.tahun || 'N/A'}
|
||||
</Title>
|
||||
|
||||
<Paper withBorder radius="md" shadow="xs" p="md">
|
||||
|
||||
@@ -32,11 +32,38 @@ export interface APBDesData {
|
||||
}
|
||||
|
||||
export function transformAPBDesData(data: any): APBDesData {
|
||||
if (!data) {
|
||||
return {
|
||||
id: '',
|
||||
tahun: null,
|
||||
items: [],
|
||||
image: null,
|
||||
file: null
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
items: data.items.map((item: any) => ({
|
||||
...item,
|
||||
tipe: isAPBDesTipe(item.tipe) ? item.tipe : null
|
||||
}))
|
||||
id: data.id || '',
|
||||
tahun: data.tahun || null,
|
||||
items: Array.isArray(data.items)
|
||||
? data.items.map((item: any) => ({
|
||||
id: item.id || '',
|
||||
kode: item.kode || '',
|
||||
uraian: item.uraian || '',
|
||||
anggaran: typeof item.anggaran === 'number' ? item.anggaran : 0,
|
||||
realisasi: typeof item.realisasi === 'number' ? item.realisasi : 0,
|
||||
selisih: typeof item.selisih === 'number' ? item.selisih : 0,
|
||||
persentase: typeof item.persentase === 'number' ? item.persentase : 0,
|
||||
level: typeof item.level === 'number' ? item.level : 1,
|
||||
tipe: isAPBDesTipe(item.tipe) ? item.tipe : null,
|
||||
createdAt: item.createdAt || undefined,
|
||||
updatedAt: item.updatedAt || undefined,
|
||||
deletedAt: item.deletedAt || null,
|
||||
isActive: item.isActive !== undefined ? item.isActive : true,
|
||||
apbdesId: item.apbdesId || undefined
|
||||
}))
|
||||
: [],
|
||||
image: data.image ? { id: data.image.id || '', url: data.image.url || '' } : null,
|
||||
file: data.file ? { id: data.file.id || '', url: data.file.url || '' } : null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { IconDownload } from '@tabler/icons-react'
|
||||
import { Link } from 'next-view-transitions'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useProxy } from 'valtio/utils'
|
||||
import { toast } from 'react-toastify'
|
||||
import BackButton from '../../(pages)/desa/layanan/_com/BackButto'
|
||||
import APBDesTable from './lib/apbDesaTable'
|
||||
import APBDesProgress from './lib/apbDesaProgress'
|
||||
@@ -19,6 +20,7 @@ function Page() {
|
||||
const paDesaState = useProxy(PendapatanAsliDesa.ApbDesa)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [selectedYear, setSelectedYear] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
@@ -26,7 +28,8 @@ function Page() {
|
||||
await state.findMany.load()
|
||||
await paDesaState.findMany.load()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error('Error loading APBDes data:', error)
|
||||
toast.error('Gagal memuat data APBDes')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
@@ -37,7 +40,13 @@ function Page() {
|
||||
const dataAPBDes = state.findMany.data || []
|
||||
|
||||
// Buat daftar tahun unik dari data
|
||||
const years = Array.from(new Set(dataAPBDes.map((item: any) => item.tahun)))
|
||||
const years = Array.from(
|
||||
new Set(
|
||||
dataAPBDes
|
||||
.filter((item: any) => item?.tahun != null) // Filter out items with null/undefined tahun
|
||||
.map((item: any) => item.tahun)
|
||||
)
|
||||
)
|
||||
.sort((a, b) => b - a) // urutkan descending
|
||||
.map(year => ({ value: year.toString(), label: `Tahun ${year}` }))
|
||||
|
||||
@@ -49,9 +58,16 @@ function Page() {
|
||||
}, [years, selectedYear])
|
||||
|
||||
// Transform and filter data based on selected year
|
||||
const currentApbdes = dataAPBDes.length > 0
|
||||
? transformAPBDesData(dataAPBDes.find(item => item?.tahun?.toString() === selectedYear) || dataAPBDes[0])
|
||||
: null
|
||||
let currentApbdes = null;
|
||||
if (dataAPBDes.length > 0 && selectedYear) {
|
||||
const selectedData = dataAPBDes.find((item: any) => item?.tahun?.toString() === selectedYear);
|
||||
if (selectedData) {
|
||||
currentApbdes = transformAPBDesData(selectedData);
|
||||
}
|
||||
} else if (dataAPBDes.length > 0 && !selectedYear && years.length > 0) {
|
||||
// If no year is selected but data exists, use the first item
|
||||
currentApbdes = transformAPBDesData(dataAPBDes[0]);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap={32}>
|
||||
|
||||
@@ -143,29 +143,29 @@ function Apbdes() {
|
||||
)}
|
||||
|
||||
{/* GRID */}
|
||||
<SimpleGrid
|
||||
mx={{ base: 'md', md: 100 }}
|
||||
cols={{ base: 1, sm: 3 }}
|
||||
spacing="lg"
|
||||
pb="xl"
|
||||
>
|
||||
{loading ? (
|
||||
<Center mih={200}>
|
||||
<Loader size="lg" color="blue" />
|
||||
</Center>
|
||||
) : data.length === 0 ? (
|
||||
<Center mih={200}>
|
||||
<Stack align="center" gap="xs">
|
||||
<Text fz="lg" c="dimmed" lh={1.4}>
|
||||
Belum ada data APBDes yang tersedia
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed" lh={1.4}>
|
||||
Data akan ditampilkan di sini setelah diunggah
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
data.map((v, k) => (
|
||||
{loading ? (
|
||||
<Center mx={{ base: 'md', md: 100 }} mih={200} pb="xl">
|
||||
<Loader size="lg" color="blue" />
|
||||
</Center>
|
||||
) : data.length === 0 ? (
|
||||
<Center mx={{ base: 'md', md: 100 }} mih={200} pb="xl">
|
||||
<Stack align="center" gap="xs">
|
||||
<Text fz="lg" c="dimmed" lh={1.4}>
|
||||
Belum ada data APBDes yang tersedia
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed" lh={1.4}>
|
||||
Data akan ditampilkan di sini setelah diunggah
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid
|
||||
mx={{ base: 'md', md: 100 }}
|
||||
cols={{ base: 1, sm: 3 }}
|
||||
spacing="lg"
|
||||
pb="xl"
|
||||
>
|
||||
{data.map((v, k) => (
|
||||
<BackgroundImage
|
||||
key={k}
|
||||
src={v.image?.link || ''}
|
||||
@@ -213,9 +213,9 @@ function Apbdes() {
|
||||
</Center>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
))
|
||||
)}
|
||||
</SimpleGrid>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user