diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..7e257db9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": [] +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..dc9d86dc --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,167 @@ +# AGENTS.md + +This file contains essential information for agentic coding agents working in the desa-darmasaba repository. + +## Project Overview + +Desa Darmasaba is a Next.js 15 application for village management services in Badung, Bali. It uses: +- **Framework**: Next.js 15 with App Router +- **Language**: TypeScript with strict mode +- **Styling**: Mantine UI components with custom CSS +- **Backend**: Elysia.js API server integrated with Next.js +- **Database**: PostgreSQL with Prisma ORM +- **State Management**: Jotai for global state +- **Authentication**: JWT with iron-session + +## Build Commands + +```bash +# Development +npm run dev + +# Production build +npm run build + +# Start production server +npm start + +# Database seeding +bun run prisma/seed.ts + +# Linting (ESLint) +npx eslint . + +# Type checking +npx tsc --noEmit + +# Prisma operations +npx prisma generate +npx prisma db push +npx prisma studio +``` + +## Running Tests + +Currently no test framework is configured. When adding tests: +- Set up test scripts in package.json +- Consider Jest or Vitest for unit testing +- Use Playwright for E2E testing +- Update this section with specific test commands + +## Code Style Guidelines + +### Imports +- Use absolute imports with `@/` alias (configured in tsconfig.json) +- Group imports: external libraries first, then internal modules +- Keep import statements organized and remove unused imports + +```typescript +// External libraries +import { useState } from 'react' +import { Button, Stack } from '@mantine/core' + +// Internal modules +import ApiFetch from '@/lib/api-fetch' +import { MyComponent } from '@/components/my-component' +``` + +### TypeScript Configuration +- Strict mode enabled (`"strict": true`) +- Target: ES2017 +- Module resolution: bundler +- Path alias: `@/*` maps to `./src/*` + +### Naming Conventions +- **Components**: PascalCase (e.g., `UploadImage.tsx`) +- **Files**: kebab-case for utilities (e.g., `api-fetch.ts`) +- **Variables/Functions**: camelCase +- **Constants**: UPPER_SNAKE_CASE +- **Database Models**: PascalCase (Prisma convention) + +### Error Handling +- Use try-catch blocks for async operations +- Implement proper error boundaries in React components +- Log errors appropriately without exposing sensitive data +- Use Zod for runtime validation and type safety + +### API Structure +- Backend uses Elysia.js with TypeScript +- API routes are in `src/app/api/[[...slugs]]/` directory +- Use treaty client for type-safe API calls +- Follow RESTful conventions for endpoints +- Include proper HTTP status codes and error responses + +### Database Operations +- Use Prisma client from `@/lib/prisma.ts` +- Database connection includes graceful shutdown handling +- Use transactions for complex operations +- Implement proper error handling for database queries + +### Component Guidelines +- Use functional components with hooks +- Implement proper prop types with TypeScript interfaces +- Use Mantine components for UI consistency +- Follow atomic design principles when possible +- Add loading states and error states for async operations + +### State Management +- Use Jotai atoms for global state +- Keep local state in components when possible +- Use React Query (SWR) for server state caching +- Implement optimistic updates for better UX + +### Styling +- Primary: Mantine UI components +- Use Mantine theme system for customization +- Custom CSS should be minimal and scoped +- Follow responsive design principles +- Use semantic HTML5 elements + +### Environment Variables +- Use `.env.local` for development +- Prefix public variables with `NEXT_PUBLIC_` +- Never commit environment files to version control +- Use proper typing for environment variables + +### File Organization +``` +src/ +├── app/ # Next.js app router pages +├── components/ # Reusable React components +├── lib/ # Utility functions and configurations +├── state/ # Jotai atoms and state management +├── types/ # TypeScript type definitions +└── con/ # Constants and static data +``` + +### Security Practices +- Validate all user inputs with Zod schemas +- Use JWT tokens for authentication +- Implement proper CORS configuration +- Never expose database credentials or API keys +- Use HTTPS in production +- Implement rate limiting for sensitive endpoints + +### Performance Considerations +- Use Next.js Image optimization +- Implement proper caching strategies +- Use React.memo for expensive components +- Optimize bundle size with dynamic imports +- Use Prisma query optimization + +## Development Workflow + +1. Always run type checking before committing: `npx tsc --noEmit` +2. Run linting to catch style issues: `npx eslint .` +3. Test database changes with `npx prisma db push` +4. Use the integrated Swagger docs at `/api/docs` for API testing +5. Check environment variables are properly configured +6. Verify responsive design on different screen sizes + +## Important Notes + +- The application uses a custom Elysia.js server integrated with Next.js API routes +- Image uploads are handled through `/api/upl-img-single` endpoint +- Database seeding is done with Bun runtime +- The app supports Indonesian locale (id_ID) for SEO and content +- CORS is configured to allow cross-origin requests during development \ No newline at end of file diff --git a/QWEN.md b/QWEN.md new file mode 100644 index 00000000..75423026 --- /dev/null +++ b/QWEN.md @@ -0,0 +1,219 @@ +# Desa Darmasaba - Village Management System + +## Project Overview + +Desa Darmasaba is a comprehensive Next.js 15 application designed for village management services in Badung, Bali. The platform serves as a digital hub for government services, public information, news, and community engagement for the residents of Darmasaba village. + +### Key Technologies +- **Framework**: Next.js 15 with App Router +- **Language**: TypeScript with strict mode +- **Styling**: Mantine UI components with custom CSS +- **Backend**: Elysia.js API server integrated with Next.js +- **Database**: PostgreSQL with Prisma ORM +- **State Management**: Jotai for global state +- **Authentication**: JWT with iron-session +- **Runtime**: Bun (instead of Node.js) + +### Architecture +The application follows a modern full-stack architecture with: +- Frontend built with Next.js 15 and TypeScript +- Backend API endpoints using Elysia.js +- PostgreSQL database managed with Prisma ORM +- Mantine UI library for consistent design components +- File storage system for managing images and documents +- Comprehensive user authentication and authorization system + +## Features + +The application provides extensive functionality across multiple domains: + +### Government Services +- Public service information and requests +- Administrative online services +- Community announcements and news +- Village profile and governance information + +### Health Services +- Healthcare facility information +- Health programs and initiatives +- Emergency health contacts +- Health articles and education +- Posyandu (community health posts) information + +### Economic Development +- Local market information +- Job listings and employment opportunities +- Village economic statistics +- Business registration and support + +### Innovation & Technology +- Digital village initiatives +- Technology adoption programs +- Innovation proposal system +- Smart village features + +### Education +- School information and statistics +- Scholarship programs +- Educational support services +- Library and learning resources + +### Environmental Management +- Waste management systems +- Green initiatives +- Environmental conservation programs +- Community participation activities + +### Security & Safety +- Emergency contacts +- Police station information +- Crime prevention measures +- Community safety programs + +## Building and Running + +### Prerequisites +- Bun runtime (version specified in package.json) +- PostgreSQL database +- Environment variables configured + +### Setup Commands +```bash +# Install dependencies +bun install + +# Set up environment variables +cp .env.example .env.local +# Edit .env.local with your configuration + +# Database setup +bunx prisma db push +bunx prisma generate + +# Seed database (optional) +bun run prisma/seed.ts + +# Development mode +bun run dev + +# Production build +bun run build + +# Start production server +bun run start +``` + +### Additional Commands +```bash +# Linting (ESLint) +bunx eslint . + +# Type checking +bunx tsc --noEmit + +# Prisma operations +bunx prisma generate +bunx prisma db push +bunx prisma studio +``` + +## Project Structure + +``` +src/ +├── app/ # Next.js app router pages +│ ├── _com/ # Common components +│ ├── admin/ # Admin panel routes +│ ├── api/ # API routes +│ ├── darmasaba/ # Main application pages +│ ├── login/ # Authentication pages +│ └── ... # Other feature pages +├── con/ # Constants and static data +├── hooks/ # Custom React hooks +├── lib/ # Utility functions and configurations +├── middlewares/ # Middleware functions +├── state/ # Global state management +├── store/ # Additional state management +├── types/ # TypeScript type definitions +├── utils/ # Utility functions +├── middleware.ts # Application middleware +└── schema.ts # Schema definitions +``` + +## Development Guidelines + +### Code Style +- Use absolute imports with `@/` alias (configured in tsconfig.json) +- Group imports: external libraries first, then internal modules +- Follow consistent naming conventions: + - Components: PascalCase (e.g., `UploadImage.tsx`) + - Files: kebab-case for utilities (e.g., `api-fetch.ts`) + - Variables/Functions: camelCase + - Constants: UPPER_SNAKE_CASE + +### TypeScript Configuration +- Strict mode enabled (`"strict": true`) +- Target: ES2017 +- Module resolution: bundler +- Path alias: `@/*` maps to `./src/*` + +### Error Handling +- Use try-catch blocks for async operations +- Implement proper error boundaries in React components +- Log errors appropriately without exposing sensitive data +- Use Zod for runtime validation and type safety + +### Security Practices +- Validate all user inputs with Zod schemas +- Use JWT tokens for authentication +- Implement proper CORS configuration +- Never expose database credentials or API keys +- Use HTTPS in production +- Implement rate limiting for sensitive endpoints + +### Performance Considerations +- Use Next.js Image optimization +- Implement proper caching strategies +- Use React.memo for expensive components +- Optimize bundle size with dynamic imports +- Use Prisma query optimization + +## Database Schema + +The application uses a comprehensive PostgreSQL database schema with Prisma ORM, featuring: + +- **User Management**: Complete user authentication system with roles and permissions +- **Content Management**: News, announcements, and various content types +- **Service Management**: Various government and community services +- **File Storage**: Centralized file management system +- **Health Information**: Healthcare facilities and programs +- **Economic Data**: Market information and employment data +- **Educational Resources**: Schools, scholarships, and educational programs +- **Environmental Data**: Sustainability and environmental management +- **Security Information**: Emergency contacts and safety measures + +## API Structure + +- Backend uses Elysia.js with TypeScript +- API routes are in `src/app/api/[[...slugs]]/` directory +- Use treaty client for type-safe API calls +- Follow RESTful conventions for endpoints +- Include proper HTTP status codes and error responses + +## Deployment + +The application includes deployment scripts for staging environments, with: +- Automated builds using Bun +- Database migration handling +- Environment-specific configurations +- PM2 process management for production + +## Important Notes + +- The application uses a custom Elysia.js server integrated with Next.js API routes +- Image uploads are handled through `/api/upl-img-single` endpoint +- Database seeding is done with Bun runtime +- The app supports Indonesian locale (id_ID) for SEO and content +- CORS is configured to allow cross-origin requests during development +- Authentication is implemented with JWT tokens and iron-session +- The application has both public-facing and admin sections with different access controls \ No newline at end of file diff --git a/gambar.ttx b/gambar.ttx new file mode 100644 index 00000000..6fa9e10e --- /dev/null +++ b/gambar.ttx @@ -0,0 +1,99 @@ +type DirItem = { + type: "file" | "dir"; + name: string; + path: string; + size?: number; +}; + +// type FileDownloadResponse = { +// url: string; +// }; + +// const TOKEN = "20a19f4a04032215d50ce53292e6abdd38b9f806"; +// const REPO_ID = "8814bfe1-30d5-4e77-ab36-3122fa59a022"; +// const DIR_TARGET = "image"; + +// const BASE_URL = "https://cld-dkr-makuro-seafile.wibudev.com/api2"; + +const TOKEN = process.env.SEAFILE_TOKEN!; +const REPO_ID = process.env.SEAFILE_REPO_ID!; + +// ⛔ PENTING: RELATIVE PATH (tanpa slash depan) +const DIR_TARGET = "asset-web"; + +const BASE_URL = "https://cld-dkr-makuro-seafile.wibudev.com/api2"; + +const headers = { + Authorization: `Token ${TOKEN}`, +}; + +/** + * Ambil list file di directory + */ +async function getDirItems(): Promise { + const res = await fetch( + `${BASE_URL}/repos/${REPO_ID}/dir/?p=${DIR_TARGET}`, + { headers } + ); + + if (!res.ok) { + throw new Error(`Failed get dir items: ${res.statusText}`); + } + + return res.json(); +} + +/** + * Ambil download URL file + */ +async function getDownloadUrl(filePath: string): Promise { + + + const res = await fetch( + `${BASE_URL}/repos/${REPO_ID}/file/?p=${encodeURIComponent(filePath)}`, + { headers } + ); + + if (!res.ok) { + throw new Error(`Failed get file url: ${res.statusText}`); + } + + const data = await res.json(); + + return data; +} + +/** + * Ambil semua download URL dari target dir + */ +async function getAllDownloadUrls() { + const items = await getDirItems(); + + const files = items.filter((item) => item.type === "file"); + + const results = await Promise.all( + files.map(async (file) => { + const filePath = `${DIR_TARGET}/${file.name}`; + const url = await getDownloadUrl(filePath); + return { + name: file.name, + path: filePath, + downloadUrl: url, + }; + }) + ); + + return results; +} + +// contoh eksekusi +(async () => { + try { + console.log("ambil gambar") + const urls = await getAllDownloadUrls(); + await Bun.write("list_image2.json", JSON.stringify(urls)) + console.log("selesai !") + } catch (err) { + console.error(err); + } +})(); diff --git a/prisma/_seeder_list/desa/berita/seed_berita.ts b/prisma/_seeder_list/desa/berita/seed_berita.ts new file mode 100644 index 00000000..1d1fb9f0 --- /dev/null +++ b/prisma/_seeder_list/desa/berita/seed_berita.ts @@ -0,0 +1,71 @@ +import prisma from "@/lib/prisma"; +import kategoriBerita from "../../../data/desa/berita/kategori-berita.json"; +import beritaJson from "../../../data/desa/berita/berita.json"; + +export async function seedBerita() { + // ================== SUBMENU BERITA ======================== + console.log("🔄 Seeding Kategori Berita..."); + for (const k of kategoriBerita) { + await prisma.kategoriBerita.upsert({ + where: { + name: k.name, // ✅ cocok dengan @unique + }, + update: { + name: k.name, + isActive: true, + }, + create: { + id: k.id, // ✅ id tetap bisa disimpan + name: k.name, + isActive: true, + }, + }); + } + + console.log("kategori berita success ..."); + + console.log("🔄 Seeding Berita..."); + + for (const b of beritaJson) { + let imageId: string | null = null; + + if (b.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: b.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for berita "${b.judul}": ${b.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.berita.upsert({ + where: { id: b.id }, + update: { + judul: b.judul, + deskripsi: b.deskripsi, + content: b.content, + kategoriBeritaId: b.kategoriBeritaId, + imageId, + }, + create: { + id: b.id, + judul: b.judul, + deskripsi: b.deskripsi, + content: b.content, + kategoriBeritaId: b.kategoriBeritaId, + imageId, + }, + }); + + console.log(`✅ Berita seeded: ${b.judul}`); + } + + console.log("🎉 Berita seed selesai"); +} + diff --git a/prisma/_seeder_list/desa/gallery/foto/seed_foto.ts b/prisma/_seeder_list/desa/gallery/foto/seed_foto.ts new file mode 100644 index 00000000..6abf33c2 --- /dev/null +++ b/prisma/_seeder_list/desa/gallery/foto/seed_foto.ts @@ -0,0 +1,40 @@ +import prisma from "@/lib/prisma"; +import foto from "../../../../data/desa/gallery/foto/foto.json"; + +export async function seedFoto() { + console.log("🔄 Seeding Foto..."); + for (const f of foto) { + let imagesId: string | null = null; + + if (f.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: f.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for foto "${f.name}": ${f.imageName}`, + ); + } else { + imagesId = image.id; + } + } + + await prisma.galleryFoto.upsert({ + where: { id: f.id }, + update: { + name: f.name, + deskripsi: f.deskripsi, + imagesId, + }, + create: { + id: f.id, + name: f.name, + deskripsi: f.deskripsi, + imagesId, + }, + }); + } + console.log("✅ Foto seeding completed"); +} \ No newline at end of file diff --git a/prisma/_seeder_list/desa/gallery/video/seed_video.ts b/prisma/_seeder_list/desa/gallery/video/seed_video.ts new file mode 100644 index 00000000..42d97860 --- /dev/null +++ b/prisma/_seeder_list/desa/gallery/video/seed_video.ts @@ -0,0 +1,25 @@ +import prisma from "@/lib/prisma"; +import galleryVideo from "../../../../data/desa/gallery/video/video.json"; + +export async function seedVideo() { + console.log("🔄 Seeding Gallery Video..."); + for (const v of galleryVideo) { + await prisma.galleryVideo.upsert({ + where: { + id: v.id, + }, + update: { + name: v.judul, + deskripsi: v.deskripsi, + linkVideo: v.linkVideo, + }, + create: { + name: v.judul, + deskripsi: v.deskripsi, + linkVideo: v.linkVideo, + }, + }); + } + + console.log("gallery video success ..."); +} diff --git a/prisma/_seeder_list/desa/layanan/seed_layanan.ts b/prisma/_seeder_list/desa/layanan/seed_layanan.ts new file mode 100644 index 00000000..a242458c --- /dev/null +++ b/prisma/_seeder_list/desa/layanan/seed_layanan.ts @@ -0,0 +1,128 @@ +import prisma from "@/lib/prisma"; +import pelayananSuratKeterangan from "../../../data/desa/layanan/pelayananSuratKeterangan.json"; +import pelayananTelunjukSaktiDesa from "../../../data/desa/layanan/pelayananTelunjukSaktiDesa.json"; +import pelayananPerizinanBerusaha from "../../../data/desa/layanan/pelayananPerizinanBerusaha.json"; +import pelayananPendudukNonPermanen from "../../../data/desa/layanan/pelayananPendudukNonPermanen.json"; + +export async function seedLayanan() { + console.log("🔄 Seeding Pelayanan Surat Keterangan..."); + + for (const p of pelayananSuratKeterangan) { + const existing = await prisma.pelayananSuratKeterangan.findUnique({ + where: { id: p.id }, + select: { imageId: true, image2Id: true }, // 📌 tambahkan image2Id + }); + + // 1️⃣ Handle imageId + let imageId = existing?.imageId ?? null; + + if (p.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: p.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for pelayanan surat keterangan 1 "${p.name}": ${p.imageName}`, + ); + } else { + imageId = image.id; + } + } + + // 2️⃣ Handle image2Id + let image2Id = existing?.image2Id ?? null; + + if (p.image2Name) { + const image2 = await prisma.fileStorage.findUnique({ + where: { name: p.image2Name }, + select: { id: true }, + }); + + if (!image2) { + console.warn( + `⚠️ Image not found for pelayanan surat keterangan 2 "${p.name}": ${p.image2Name}`, + ); + } else { + image2Id = image2.id; + } + } + + // 3️⃣ Upsert dengan kedua image + await prisma.pelayananSuratKeterangan.upsert({ + where: { id: p.id }, + update: { + name: p.name, + deskripsi: p.deskripsi, + imageId, + image2Id, // 📌 tambahkan ini + }, + create: { + id: p.id, + name: p.name, + deskripsi: p.deskripsi, + imageId, + image2Id, // 📌 tambahkan ini + }, + }); + } + console.log("✅ Pelayanan Surat Keterangan success..."); + + for (const p of pelayananTelunjukSaktiDesa) { + await prisma.pelayananTelunjukSaktiDesa.upsert({ + where: { id: p.id }, + update: { + name: p.name, + deskripsi: p.deskripsi, + link: p.link, + }, + create: { + id: p.id, + name: p.name, + deskripsi: p.deskripsi, + link: p.link, + }, + }); + } + console.log("pelayanan telunjuk sakti desa success ..."); + + for (const l of pelayananPerizinanBerusaha) { + await prisma.pelayananPerizinanBerusaha.upsert({ + where: { + id: l.id, + }, + update: { + name: l.name, + deskripsi: l.deskripsi, + link: l.link, + }, + create: { + id: l.id, + name: l.name, + deskripsi: l.deskripsi, + link: l.link, + }, + }); + } + + console.log("pelayanan perizinan berusaha success ..."); + + for (const l of pelayananPendudukNonPermanen) { + await prisma.pelayananPendudukNonPermanen.upsert({ + where: { + id: l.id, + }, + update: { + name: l.name, + deskripsi: l.deskripsi, + }, + create: { + id: l.id, + name: l.name, + deskripsi: l.deskripsi, + }, + }); + } + console.log("pelayanan penduduk non permanen success ..."); +} diff --git a/prisma/_seeder_list/desa/penghargaan/penghargaan.ts b/prisma/_seeder_list/desa/penghargaan/penghargaan.ts new file mode 100644 index 00000000..b696ae75 --- /dev/null +++ b/prisma/_seeder_list/desa/penghargaan/penghargaan.ts @@ -0,0 +1,44 @@ +import prisma from "@/lib/prisma"; +import penghargaan from "../../../data/desa/penghargaan/penghargaan.json" + +export async function seedPenghargaan() { + console.log("🔄 Seeding Penghargaan..."); + for (const m of penghargaan) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for penghargaan "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.penghargaan.upsert({ + where: { id: m.id }, + update: { + name: m.name, + juara: m.juara, + deskripsi: m.deskripsi, + imageId, + }, + create: { + id: m.id, + name: m.name, + juara: m.juara, + deskripsi: m.deskripsi, + imageId, + }, + }); + } + + console.log("penghargaan success ..."); +} + \ No newline at end of file diff --git a/prisma/_seeder_list/desa/pengumuman/seed_pengumuman.ts b/prisma/_seeder_list/desa/pengumuman/seed_pengumuman.ts new file mode 100644 index 00000000..184fc804 --- /dev/null +++ b/prisma/_seeder_list/desa/pengumuman/seed_pengumuman.ts @@ -0,0 +1,43 @@ +import prisma from "@/lib/prisma"; +import { safeSeedUnique } from "../../../safeseedUnique"; +import kategoriPengumuman from "../../../data/desa/pengumuman/kategori-pengumuman.json"; +import pengumuman from "../../../data/desa/pengumuman/pengumuman.json"; + +export async function seedPengumuman() { + console.log("🔄 Seeding Kategori Pengumuman..."); + for (const c of kategoriPengumuman) { + await safeSeedUnique( + "categoryPengumuman", + { name: c.name }, // ✅ where clause + { + id: c.id, + name: c.name, + }, + ); + } + + console.log("kategori pengumuman success ..."); + + console.log("🔄 Seeding Pengumuman..."); + for (const p of pengumuman) { + await prisma.pengumuman.upsert({ + where: { + id: p.id, + }, + update: { + judul: p.judul, + deskripsi: p.deskripsi, + content: p.content, + categoryPengumumanId: p.categoryPengumumanId, + }, + create: { + judul: p.judul, + deskripsi: p.deskripsi, + content: p.content, + categoryPengumumanId: p.categoryPengumumanId, + }, + }); + } + + console.log("pengumuman success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/desa/potensi/seed_potensi.ts b/prisma/_seeder_list/desa/potensi/seed_potensi.ts new file mode 100644 index 00000000..7e1ad408 --- /dev/null +++ b/prisma/_seeder_list/desa/potensi/seed_potensi.ts @@ -0,0 +1,64 @@ +import prisma from "@/lib/prisma"; +import kategoriPotensi from "../../../data/desa/potensi/kategori-potensi.json"; +import potensiDesa from "../../../data/desa/potensi/potensi-desa.json"; + +export async function seedPotensi() { + console.log("🔄Seeding Kategori Potensi Desa ..."); + for (const c of kategoriPotensi) { + await prisma.kategoriPotensi.upsert({ + where: { + id: c.id, + }, + update: { + nama: c.nama, + }, + create: { + id: c.id, + nama: c.nama, + }, + }); + } + + console.log("kategori Potensi success ..."); + + console.log("🔄 Seeding Potensi Desa..."); + for (const m of potensiDesa) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for potensi desa "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.potensiDesa.upsert({ + where: { id: m.id }, + update: { + name: m.name, + deskripsi: m.deskripsi, + content: m.content, + kategoriId: m.kategoriId, + imageId, + }, + create: { + id: m.id, + name: m.name, + deskripsi: m.deskripsi, + content: m.content, + kategoriId: m.kategoriId, + imageId, + }, + }); + } + + console.log("potensi desa success ..."); +} diff --git a/prisma/_seeder_list/desa/profile-desa/seed_profile_desa.ts b/prisma/_seeder_list/desa/profile-desa/seed_profile_desa.ts new file mode 100644 index 00000000..9ab4bef3 --- /dev/null +++ b/prisma/_seeder_list/desa/profile-desa/seed_profile_desa.ts @@ -0,0 +1,147 @@ +import prisma from "@/lib/prisma"; +import lambangDesa from "../../../data/desa/profile/lambang_desa.json"; +import maskotDesa from "../../../data/desa/profile/maskot_desa.json"; +import profilePerbekel from "../../../data/desa/profile/profil_perbekel.json"; +import profileDesaImage from "../../../data/desa/profile/profileDesaImage.json"; +import sejarahDesa from "../../../data/desa/profile/sejarah_desa.json"; + +export async function seedProfileDesa() { + // =========== SEJARAH DESA =========== + for (const l of sejarahDesa) { + await prisma.sejarahDesa.upsert({ + where: { + id: l.id, + }, + update: { + judul: l.judul, + deskripsi: l.deskripsi, + }, + create: { + id: l.id, + judul: l.judul, + deskripsi: l.deskripsi, + }, + }); + } + + console.log("sejarah desa success ..."); + + // =========== MASKOT DESA =========== + for (const l of maskotDesa) { + await prisma.maskotDesa.upsert({ + where: { + id: l.id, + }, + update: { + judul: l.judul, + deskripsi: l.deskripsi, + }, + create: { + id: l.id, + judul: l.judul, + deskripsi: l.deskripsi, + }, + }); + } + + console.log("maskot desa success ..."); + + console.log("🔄 Seeding Profile Desa Image..."); + for (const m of profileDesaImage) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for profile desa image "${m.label}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.profileDesaImage.upsert({ + where: { id: m.id }, + update: { + label: m.label, + maskotDesaId: m.maskotDesaId, + imageId, + }, + create: { + id: m.id, + label: m.label, + maskotDesaId: m.maskotDesaId, + imageId, + }, + }); + } + + console.log("profile desa image success ..."); + + // =========== LAMBANG DESA =========== + for (const l of lambangDesa) { + await prisma.lambangDesa.upsert({ + where: { + id: l.id, + }, + update: { + judul: l.judul, + deskripsi: l.deskripsi, + }, + create: { + id: l.id, + judul: l.judul, + deskripsi: l.deskripsi, + }, + }); + } + + console.log("lambang desa success ..."); + + // =========== PROFILE PERBEKEL PROFILE DESA =========== + console.log("🔄 Seeding Profile Perbekel..."); + for (const m of profilePerbekel) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for profile perbekel "${m.biodata}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.profilPerbekel.upsert({ + where: { id: m.id }, + update: { + biodata: m.biodata, + pengalaman: m.pengalaman, + pengalamanOrganisasi: m.pengalamanOrganisasi, + programUnggulan: m.programUnggulan, + imageId, + }, + create: { + id: m.id, + biodata: m.biodata, + pengalaman: m.pengalaman, + pengalamanOrganisasi: m.pengalamanOrganisasi, + programUnggulan: m.programUnggulan, + imageId, + }, + }); + } + + console.log("profile perbekel desa success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/desa/profile-desa/seed_profile_perbekel.ts b/prisma/_seeder_list/desa/profile-desa/seed_profile_perbekel.ts new file mode 100644 index 00000000..1507fe32 --- /dev/null +++ b/prisma/_seeder_list/desa/profile-desa/seed_profile_perbekel.ts @@ -0,0 +1,42 @@ +import prisma from "@/lib/prisma"; +import perbekelDariMasaKeMasa from "../../../data/desa/profile/profile-perbekel-lalu.json"; + +export async function seedProfilePerbekel() { + console.log("🔄 Seeding Perbekel Dari Masa Ke Masa..."); +for (const p of perbekelDariMasaKeMasa) { + let imageId: string | null = null; + + if (p.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: p.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for Perbekel Dari Masa Ke Masa "${p.nama}": ${p.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.perbekelDariMasaKeMasa.upsert({ + where: { id: p.id }, + update: { + nama: p.nama, + periode: p.periode, + daerah: p.daerah, + imageId, + }, + create: { + id: p.id, + nama: p.nama, + periode: p.periode, + daerah: p.daerah, + imageId, + }, + }); +} +console.log("✅ Pejabat Desa seeding completed"); +} \ No newline at end of file diff --git a/prisma/_seeder_list/landing-page/desa-anti-korupsi/seed_desa_anti_korupsi.ts b/prisma/_seeder_list/landing-page/desa-anti-korupsi/seed_desa_anti_korupsi.ts new file mode 100644 index 00000000..5a1927fa --- /dev/null +++ b/prisma/_seeder_list/landing-page/desa-anti-korupsi/seed_desa_anti_korupsi.ts @@ -0,0 +1,38 @@ +import prisma from "@/lib/prisma"; +import kategoriDesaAntiKorupsi from "../../../data/landing-page/desa-anti-korupsi/kategoriDesaAntiKorupsi.json" +import desaAntiKorupsi from "../../../data/landing-page/desa-anti-korupsi/desaantiKorpusi.json" + +export async function seedDesaAntiKorupsi() { + for (const k of kategoriDesaAntiKorupsi) { + await prisma.kategoriDesaAntiKorupsi.upsert({ + where: { id: k.id }, + update: { + name: k.name, + }, + create: { + id: k.id, + name: k.name, + }, + }); + } + console.log("kategori desa anti korupsi success ..."); + + // =========== DESA ANTI KORUPSI =========== + for (const p of desaAntiKorupsi) { + await prisma.desaAntiKorupsi.upsert({ + where: { id: p.id }, + update: { + name: p.name, + deskripsi: p.deskripsi, + kategoriId: p.kategoriId, + }, + create: { + id: p.id, + name: p.name, + deskripsi: p.deskripsi, + kategoriId: p.kategoriId, + }, + }); + } + console.log("desa anti korupsi success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/landing-page/prestasi-desa/seed_prestasi_desa.ts b/prisma/_seeder_list/landing-page/prestasi-desa/seed_prestasi_desa.ts new file mode 100644 index 00000000..18129dfb --- /dev/null +++ b/prisma/_seeder_list/landing-page/prestasi-desa/seed_prestasi_desa.ts @@ -0,0 +1,61 @@ +import prisma from "@/lib/prisma"; +import prestasiDesa from "../../../data/landing-page/prestasi-desa/prestasi-desa.json" +import kategoriPrestasiDesa from "../../../data/landing-page/prestasi-desa/kategori-prestasi.json" + +export async function seedPrestasiDesa() { + + console.log("🔄 Seeding Kategori Prestasi Desa..."); +for (const c of kategoriPrestasiDesa) { + await prisma.kategoriPrestasiDesa.upsert({ + where: { id: c.id }, + update: { + name: c.name, + }, + create: { + id: c.id, + name: c.name, + }, + }); + } + console.log("kategori prestasi desa success ..."); + + console.log("🔄 Seeding Prestasi Desa..."); + for (const m of prestasiDesa) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for prestasi desa "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.prestasiDesa.upsert({ + where: { id: m.id }, + update: { + name: m.name, + deskripsi: m.deskripsi, + kategoriId: m.kategoriId, + imageId, + }, + create: { + id: m.id, + name: m.name, + deskripsi: m.deskripsi, + kategoriId: m.kategoriId, + imageId, + }, + }); + } + + console.log("prestasi desa success ..."); +} + \ No newline at end of file diff --git a/prisma/_seeder_list/landing-page/profil_landing_page/seed_media_sosial.ts b/prisma/_seeder_list/landing-page/profil_landing_page/seed_media_sosial.ts new file mode 100644 index 00000000..7636202a --- /dev/null +++ b/prisma/_seeder_list/landing-page/profil_landing_page/seed_media_sosial.ts @@ -0,0 +1,44 @@ +import prisma from "@/lib/prisma"; +import mediaSosial from "../../../data/landing-page/profile/mediaSosial.json" + +export async function seedMediaSosial() { + console.log("🔄 Seeding Media Sosial..."); + for (const m of mediaSosial) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for berita "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.mediaSosial.upsert({ + where: { id: m.id }, + update: { + name: m.name, + iconUrl: m.iconUrl, + imageId, + }, + create: { + id: m.id, + name: m.name, + iconUrl: m.iconUrl, + imageId, + }, + }); + } + + console.log("media sosial success ..."); +} + + + \ No newline at end of file diff --git a/prisma/_seeder_list/landing-page/profil_landing_page/seed_profile_lp.ts b/prisma/_seeder_list/landing-page/profil_landing_page/seed_profile_lp.ts new file mode 100644 index 00000000..a2f5f7a6 --- /dev/null +++ b/prisma/_seeder_list/landing-page/profil_landing_page/seed_profile_lp.ts @@ -0,0 +1,40 @@ +import prisma from "@/lib/prisma"; +import profilePejabatDesa from "../../../data/landing-page/profile/profile.json"; + +export async function seedProfileLP() { + console.log("🔄 Seeding Pejabat Desa..."); + for (const p of profilePejabatDesa) { + let imageId: string | null = null; + + if (p.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: p.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for profile "${p.name}": ${p.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.pejabatDesa.upsert({ + where: { id: p.id }, + update: { + name: p.name, + position: p.position, + imageId, + }, + create: { + id: p.id, + name: p.name, + position: p.position, + imageId, + }, + }); + } + console.log("✅ Pejabat Desa seeding completed"); +} diff --git a/prisma/_seeder_list/landing-page/profil_landing_page/seed_program_inovasi.ts b/prisma/_seeder_list/landing-page/profil_landing_page/seed_program_inovasi.ts new file mode 100644 index 00000000..207045b2 --- /dev/null +++ b/prisma/_seeder_list/landing-page/profil_landing_page/seed_program_inovasi.ts @@ -0,0 +1,44 @@ +import prisma from "@/lib/prisma"; +import programInovasi from "../../../data/landing-page/profile/programInovasi.json"; + +export async function seedProgramInovasi() { + console.log("🔄 Seeding Program Inovasi..."); + + for (const b of programInovasi) { + let imageId: string | null = null; + + if (b.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: b.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for program inovasi "${b.name}": ${b.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.programInovasi.upsert({ + where: { id: b.id }, + update: { + name: b.name, + description: b.description, + link: b.link, + imageId, + }, + create: { + id: b.id, + name: b.name, + description: b.description, + link: b.link, + imageId, + }, + }); + + console.log(`✅ Program Inovasi seeded: ${b.name}`); + } +} \ No newline at end of file diff --git a/prisma/_seeder_list/landing-page/sdgs/seed_sdgs.ts b/prisma/_seeder_list/landing-page/sdgs/seed_sdgs.ts new file mode 100644 index 00000000..a8aac2a1 --- /dev/null +++ b/prisma/_seeder_list/landing-page/sdgs/seed_sdgs.ts @@ -0,0 +1,41 @@ +import prisma from "@/lib/prisma"; +import sdgsDesa from "../../../data/landing-page/sdgs-desa/sdgs-desa.json"; + +export async function seedSDGSDesa() { + console.log("🔄 Seeding SDGS Desa..."); + for (const m of sdgsDesa) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for sdgs desa "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.sdgsDesa.upsert({ + where: { id: m.id }, + update: { + name: m.name, + jumlah: m.jumlah, + imageId, + }, + create: { + id: m.id, + name: m.name, + jumlah: m.jumlah, + imageId, + }, + }); + } + + console.log("sdgs desa success ..."); +} diff --git a/prisma/_seeder_list/ppid/daftar-informasi-publik-ppid/seed_daftar_informasi_publik_ppid.ts b/prisma/_seeder_list/ppid/daftar-informasi-publik-ppid/seed_daftar_informasi_publik_ppid.ts new file mode 100644 index 00000000..3bf6b77b --- /dev/null +++ b/prisma/_seeder_list/ppid/daftar-informasi-publik-ppid/seed_daftar_informasi_publik_ppid.ts @@ -0,0 +1,76 @@ +import prisma from "@/lib/prisma"; +import daftarInformasiPublik from "../../../data/ppid/daftar-informasi-publik-desa-darmasaba/daftarInformasi.json" +import jenisInformasiDiminta from "../../../data/list-jenisInfromasi.json" +import caraMemperolehInformasi from "../../../data/list-caraMemperolehInformasi.json" +import caraMemperolehSalinanInformasi from "../../../data/list-caraMemperolehSalinanInformasi.json" + +export async function seedDaftarInformasiPublikPpid() { + + for (const v of daftarInformasiPublik) { + // Convert string date to Date object + const tanggal = new Date(v.tanggal); + + await prisma.daftarInformasiPublik.upsert({ + where: { + id: v.id, + }, + update: { + jenisInformasi: v.jenisInformasi, + deskripsi: v.deskripsi, + tanggal: tanggal, + }, + create: { + id: v.id, + jenisInformasi: v.jenisInformasi, + deskripsi: v.deskripsi, + tanggal: tanggal, + }, + }); + } + console.log("daftar informasi publik PPID success ..."); + + for (const j of jenisInformasiDiminta) { + await prisma.jenisInformasiDiminta.upsert({ + where: { + name: j.name, + }, + update: { + name: j.name, + }, + create: { + name: j.name, + }, + }); + } + console.log("jenis informasi diminta success ..."); + + for (const c of caraMemperolehInformasi) { + await prisma.caraMemperolehInformasi.upsert({ + where: { + name: c.name, + }, + update: { + name: c.name, + }, + create: { + name: c.name, + }, + }); + } + console.log("cara memperoleh informasi success ..."); + + for (const c of caraMemperolehSalinanInformasi) { + await prisma.caraMemperolehSalinanInformasi.upsert({ + where: { + name: c.name, + }, + update: { + name: c.name, + }, + create: { + name: c.name, + }, + }); + } + console.log("cara memperoleh salinan informasi success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/ppid/dasar-hukum-ppid/seed_dasar_hukum_ppid.ts b/prisma/_seeder_list/ppid/dasar-hukum-ppid/seed_dasar_hukum_ppid.ts new file mode 100644 index 00000000..7d14359a --- /dev/null +++ b/prisma/_seeder_list/ppid/dasar-hukum-ppid/seed_dasar_hukum_ppid.ts @@ -0,0 +1,22 @@ +import prisma from "@/lib/prisma"; +import dasarHukumPPID from "../../../data/ppid/dasar-hukum-ppid/dasarhukumPPID.json" + +export async function seedDasarHukumPpid() { + for (const v of dasarHukumPPID) { + await prisma.dasarHukumPPID.upsert({ + where: { + id: v.id, + }, + update: { + judul: v.judul, + content: v.content, + }, + create: { + id: v.id, + judul: v.judul, + content: v.content, + }, + }); + } + console.log("dasar hukum PPID success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/ppid/ikm/seed_ikm.ts b/prisma/_seeder_list/ppid/ikm/seed_ikm.ts new file mode 100644 index 00000000..905b4f4d --- /dev/null +++ b/prisma/_seeder_list/ppid/ikm/seed_ikm.ts @@ -0,0 +1,54 @@ +import prisma from "@/lib/prisma"; +import jenisKelamin from "../../../data/ppid/ikm/jenis-kelamin/jenis-kelamin.json"; +import pilihanRatingResponden from "../../../data/ppid/ikm/pilihan-rating-responden/rating-responden.json"; +import umurResponden from "../../../data/ppid/ikm/umur-responden/umur-responden.json"; + +export async function seedIkmPpid() { + for (const j of jenisKelamin) { + await prisma.jenisKelaminResponden.upsert({ + where: { + id: j.id, + }, + update: { + name: j.name, + }, + create: { + id: j.id, + name: j.name, + }, + }); + } + console.log("jenis kelamin responden success ..."); + + for (const r of pilihanRatingResponden) { + await prisma.pilihanRatingResponden.upsert({ + where: { + id: r.id, + }, + update: { + name: r.name, + }, + create: { + id: r.id, + name: r.name, + }, + }); + } + console.log("pilihan rating responden success ..."); + + for (const u of umurResponden) { + await prisma.umurResponden.upsert({ + where: { + id: u.id, + }, + update: { + name: u.name, + }, + create: { + id: u.id, + name: u.name, + }, + }); + } + console.log("umur responden success ..."); +} \ No newline at end of file diff --git a/prisma/_seeder_list/ppid/profil-ppid/seed_profil_ppd.ts b/prisma/_seeder_list/ppid/profil-ppid/seed_profil_ppd.ts new file mode 100644 index 00000000..bf666e2d --- /dev/null +++ b/prisma/_seeder_list/ppid/profil-ppid/seed_profil_ppd.ts @@ -0,0 +1,48 @@ +import prisma from "@/lib/prisma"; +import profilPpd from "../../../data/ppid/profile-ppid/profilePPid.json" + +export async function seedProfilPpd() { + console.log("🔄 Seeding Profil PPD..."); + for (const m of profilPpd) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for berita "${m.name}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.profilePPID.upsert({ + where: { id: m.id }, + update: { + name: m.name, + biodata: m.biodata, + riwayat: m.riwayat, + pengalaman: m.pengalaman, + unggulan: m.unggulan, + imageId, + }, + create: { + id: m.id, + name: m.name, + biodata: m.biodata, + riwayat: m.riwayat, + pengalaman: m.pengalaman, + unggulan: m.unggulan, + imageId, + }, + }); + } + + console.log("profil ppd success ..."); +} + \ No newline at end of file diff --git a/prisma/_seeder_list/ppid/struktur-ppid/seed_struktur_ppid.ts b/prisma/_seeder_list/ppid/struktur-ppid/seed_struktur_ppid.ts new file mode 100644 index 00000000..e2141e91 --- /dev/null +++ b/prisma/_seeder_list/ppid/struktur-ppid/seed_struktur_ppid.ts @@ -0,0 +1,82 @@ +import prisma from "@/lib/prisma"; +import pegawaiPpid from "../../../data/ppid/struktur-ppid/pegawai-PPID.json" +import posisiOrganisasiPPID from "../../../data/ppid/struktur-ppid/posisi-organisasi-PPID.json" + +export async function seedPegawaiPpid() { + +const flattenedPosisi = posisiOrganisasiPPID.flat(); + + // ✅ Urutkan berdasarkan hierarki + const sortedPosisi = flattenedPosisi.sort((a, b) => a.hierarki - b.hierarki); + + for (const p of sortedPosisi) { + console.log(`Seeding: ${p.nama} (id: ${p.id}, parent: ${p.parentId})`); + + if (p.parentId) { + const parentExists = flattenedPosisi.some((pos) => pos.id === p.parentId); + if (!parentExists) { + console.warn( + `⚠️ Parent tidak ditemukan: ${p.parentId} untuk ${p.nama}`, + ); + continue; + } + } + + await prisma.posisiOrganisasiPPID.upsert({ + where: { id: p.id }, + update: p, + create: p, + }); + } + console.log("posisi organisasi berhasil"); + + console.log("🔄 Seeding Struktur Ppid..."); + for (const m of pegawaiPpid) { + let imageId: string | null = null; + + if (m.imageName) { + const image = await prisma.fileStorage.findUnique({ + where: { name: m.imageName }, + select: { id: true }, + }); + + if (!image) { + console.warn( + `⚠️ Image not found for pegawai ppid "${m.namaLengkap}": ${m.imageName}`, + ); + } else { + imageId = image.id; + } + } + + await prisma.pegawaiPPID.upsert({ + where: { id: m.id }, + update: { + namaLengkap: m.namaLengkap, + gelarAkademik: m.gelarAkademik, + tanggalMasuk: m.tanggalMasuk, + email: m.email, + telepon: m.telepon, + alamat: m.alamat, + imageId, + posisiId: m.posisiId, + isActive: m.isActive, + }, + create: { + id: m.id, + namaLengkap: m.namaLengkap, + gelarAkademik: m.gelarAkademik, + tanggalMasuk: m.tanggalMasuk, + email: m.email, + telepon: m.telepon, + alamat: m.alamat, + imageId, + posisiId: m.posisiId, + isActive: m.isActive, + }, + }); + } + + console.log("struktur ppid success ..."); +} + \ No newline at end of file diff --git a/prisma/_seeder_list/ppid/visi-misi-ppid/seed_visi_misi_ppid.ts b/prisma/_seeder_list/ppid/visi-misi-ppid/seed_visi_misi_ppid.ts new file mode 100644 index 00000000..e99087e3 --- /dev/null +++ b/prisma/_seeder_list/ppid/visi-misi-ppid/seed_visi_misi_ppid.ts @@ -0,0 +1,23 @@ +import prisma from "@/lib/prisma"; +import visiMisiPPID from "../../../data/ppid/visi-misi-ppid/visimisiPPID.json" + +export async function seedVisiMisiPpid() { + for (const v of visiMisiPPID) { + await prisma.visiMisiPPID.upsert({ + where: { + id: v.id, + }, + update: { + misi: v.misi, + visi: v.visi, + }, + create: { + id: v.id, + misi: v.misi, + visi: v.visi, + }, + }); + } + console.log("visi misi PPID success ..."); + +} \ No newline at end of file diff --git a/prisma/data/desa/berita/berita.json b/prisma/data/desa/berita/berita.json index 73ba5bb2..904361fc 100644 --- a/prisma/data/desa/berita/berita.json +++ b/prisma/data/desa/berita/berita.json @@ -5,7 +5,7 @@ "deskripsi": "

Kegiatan pembinaan dan bantuan kepada kader Posyandu Desa Darmasaba oleh TP Posyandu Provinsi Bali.

", "content": "

Sebanyak 50 kader posyandu mendapatkan pembinaan dan sembako sebagai dukungan terhadap peran Posyandu dalam pemberdayaan masyarakat. Kegiatan ini menunjukkan peran strategis posyandu dalam layanan publik desa.

", "kategoriBeritaId": "cmk69tghy000vvnv8xeouenv5", - "imageId": "cmk6bk2va0003vnadn9w0mxc4" + "imageName": "Wp41ccw3yma9W8i6zBr6E-mobile.webp" }, { "id": "cmk6af7vf00013b6rj2br4nv8", @@ -13,7 +13,7 @@ "deskripsi": "

Temu Sadar Hukum untuk meningkatkan kesadaran hukum warga Desa Darmasaba.

", "content": "

Kegiatan ini membahas isu kekerasan dalam rumah tangga dengan narasumber dari Kanwil Kemenkum Bali, menjadi forum penting dalam membangun masyarakat yang melek hukum.

", "kategoriBeritaId": "cmk69tghy000vvnv8xeouenv5", - "imageId": "cmk6bo3290006vnadzhgalacy" + "imageName": "IwedNmhjD_wGpY6PvYX7W-mobile.webp" }, { "id": "cmk6afo0g00033b6rjc2pae67", @@ -21,7 +21,7 @@ "deskripsi": "

Ruang dialog terbuka di Desa Darmasaba untuk membahas persoalan sampah dan partisipasi publik.

", "content": "

Forum dialog ini membantu pemerintahan desa menyusun kebijakan tepat sasaran, terutama terkait permasalahan lingkungan dan aspirasi warga.

", "kategoriBeritaId": "cmk69tghy000vvnv8xeouenv5", - "imageId": "cmk6bptid0009vnad6my1w4s1" + "imageName": "EVkMxPdoWyL3y31L7d7x1-mobile.webp" }, { "id": "cmk6ag56y00053b6rj9481z6m", @@ -29,7 +29,7 @@ "deskripsi": "

Diskusi terbuka antara pemerintah desa dan warga mengenai isu sampah.

", "content": "

Acara ini mendukung perumusan kebijakan desa yang sesuai kebutuhan warga dan meningkatkan partisipasi dalam pembangunan lingkungan.

", "kategoriBeritaId": "cmk69tghx000tvnv8g2d206wv", - "imageId": "cmk6c86dc000cvnadlh54q7xr" + "imageName": "c_5xOKUbMiD8dTAbkAv9a-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxcsj", @@ -37,7 +37,7 @@ "deskripsi": "

Penutupan program KKN-PMM yang berjalan dengan berbagai kegiatan pemberdayaan masyarakat.

", "content": "

Kegiatan KKN meliputi edukasi kesehatan, pengelolaan sampah, literasi keuangan, dan upaya ekonomi lokal sebagai bagian dari pembangunan desa berkelanjutan.

", "kategoriBeritaId": "cmk69tghx000tvnv8g2d206wv", - "imageId": "cmk6cbbtw000fvnadk862le38" + "imageName": "I9CDBqdeDXRbbzbPWhy6h-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxasj", @@ -45,7 +45,7 @@ "deskripsi": "

Desa Darmasaba mengalokasikan anggaran untuk pengelolaan sampah berbasis komunitas.

", "content": "

Pengelolaan sampah mandiri melalui TPS3R, kader penyuluh, dan inovasi CINtA menjadi strategi desa dalam penanganan sampah sesuai kebijakan provinsi dan desa.

", "kategoriBeritaId": "cmk69tghx000tvnv8g2d206wv", - "imageId": "cmk6cdmjp000ivnadeejerm59" + "imageName": "Gq-gEDaGNb-FkKasVs7i4-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxbsj", @@ -53,7 +53,7 @@ "deskripsi": "

Pembukaan festival desa untuk mendorong UMKM dan ekonomi lokal.

", "content": "

Kegiatan ini menampilkan berbagai UMKM yang membantu meningkatkan pendapatan masyarakat setempat.

", "kategoriBeritaId": "cmk69tghx000uvnv847ppcxqh", - "imageId": "cmk6crib4000lvnadqtrhnb14" + "imageName": "TymQ5xDH7vEUOA9BY63hr-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxdsj", @@ -61,7 +61,7 @@ "deskripsi": "

Program inovatif untuk memperkuat ekonomi lokal melalui ekowisata dan kuliner.

", "content": "

Kegiatan mencakup pembangunan green house, edukasi pemasaran digital, literasi bahasa Inggris, dan pengembangan potensi kuliner desa.

", "kategoriBeritaId": "cmk69tghx000uvnv847ppcxqh", - "imageId": "cmk6czfag000ovnad7kjz36lj" + "imageName": "2nUvEBsMuigIJQWZIdcEJ-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxesj", @@ -69,7 +69,7 @@ "deskripsi": "

Desa Darmasaba meraih penghargaan juara dalam evaluasi perkembangan desa untuk mendukung perekonomian dan pemerintahan lokal.

", "content": "

Prestasi desa ditandai dengan keberhasilan dalam lomba evaluasi perkembangan desa di tingkat provinsi dan kabupaten, yang berdampak positif pada ekonomi desa.

", "kategoriBeritaId": "cmk69tghx000uvnv847ppcxqh", - "imageId": "cmk6d3zow000rvnades3btqrh" + "imageName": "Hokgum3-nI_NWTWJRnWi3-mobile.webp" }, { "id": "cmk6agzxx00073b6rr3vhxfsj", @@ -77,7 +77,7 @@ "deskripsi": "

Prestasi desa dalam forum internasional mengenai penanggulangan rabies.

", "content": "

Partisipasi dalam konferensi Rabies in Borneo menunjukkan kolaborasi lintas sektor dan penggunaan data dalam pelayanan publik desa.

", "kategoriBeritaId": "cmk69tght000svnv8ok5rid2v", - "imageId": "cmk6hgl8r000uvnadwchcqigp" + "imageName": "T1fcksUoZSUqNMbzvr9WI-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp1z", @@ -85,7 +85,7 @@ "deskripsi": "

Pemasangan spanduk larangan buang hewan sebagai langkah proteksi kesehatan masyarakat.

", "content": "

Pemerintah desa bersama Tim Bajra aktif dalam kampanye dan regulasi untuk mencegah rabies di tingkat desa.

", "kategoriBeritaId": "cmk69tght000svnv8ok5rid2v", - "imageId": "cmk6hh34d000xvnadr74cs014" + "imageName": "-M_tICRVz6ZxOfvkuHQgU-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp2z", @@ -93,7 +93,7 @@ "deskripsi": "

Kolaborasi pemerintahan desa dengan TP Posyandu untuk meningkatkan layanan masyarakat.

", "content": "

Kegiatan ini menunjukkan peran pemerintahan desa dalam mendukung layanan kesehatan dan pemberdayaan masyarakat.

", "kategoriBeritaId": "cmk69tght000svnv8ok5rid2v", - "imageId": "cmk6hhl5p0010vnadx09hrg3n" + "imageName": "O11hmN9oNwFKs_ACpH9uV-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp3z", @@ -101,7 +101,7 @@ "deskripsi": "

Inisiatif pengelolaan sampah desa sebagai bagian dari inovasi teknologi lokal.

", "content": "

Penerapan metode pengelolaan sampah dan biopori menunjukkan upaya Desa Darmasaba dalam menggunakan solusi teknologi sederhana untuk masalah lingkungan.

", "kategoriBeritaId": "cmk69tghz000xvnv8kxzzt24h", - "imageId": "cmk6hz5640013vnadwdmfzyoa" + "imageName": "rrgHHUYHDuq3jW94HCRsq-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp4z", @@ -109,7 +109,7 @@ "deskripsi": "

Program BAJRA menerapkan mekanisme pelaporan cepat berbasis data untuk penanggulangan rabies.

", "content": "

Penggunaan teknologi informasi dalam pelaporan kasus rabies membantu respons cepat pemerintahan desa dan komunitas.

", "kategoriBeritaId": "cmk69tghz000xvnv8kxzzt24h", - "imageId": "cmk6hzlrg0016vnaduf57rp2i" + "imageName": "igz0V0MCoLYqAgLIBRZdG-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp5z", @@ -117,7 +117,7 @@ "deskripsi": "

Digitalisasi Desa Darmasaba Bersama PT. Bali Interaktif Perkasa.

", "content": "

Digitalisasi Desa Darmasaba Bersama PT. Bali Interaktif Perkasa

Dalam rangka mendukung transformasi digital dan inovasi desa, Desa Darmasaba bekerja sama dengan PT. Bali Interaktif Perkasa melaksanakan kegiatan Digitalisasi Desa.

Program ini bertujuan untuk memperkuat kapasitas desa dalam pemanfaatan teknologi informasi dan komunikasi, sehingga pelayanan publik menjadi lebih efektif, transparan, dan cepat. Masyarakat juga diberikan pemahaman terkait pemanfaatan platform digital untuk kegiatan administrasi, komunikasi, dan pengembangan potensi desa.

Kegiatan digitalisasi ini menjadi bagian dari komitmen Desa Darmasaba untuk mewujudkan desa cerdas (smart village) yang mampu bersaing dan beradaptasi di era digital, sekaligus meningkatkan inovasi dan pemberdayaan masyarakat.

Dengan kolaborasi ini, Desa Darmasaba menegaskan tekadnya untuk terus berinovasi, menghadirkan kemudahan bagi masyarakat, dan memperkuat tata kelola desa berbasis teknologi modern.

? Digitalisasi hari ini, kemajuan desa esok!

#DesaDarmasaba #DigitalisasiDesa #DesaCerdas #InovasiDesa #TransformasiDigital
#PemdesDarmasaba
#PerbekelDarmasaba
#DesaDarmasaba
#KitaDarmasaba
#DarmasabaBisa

@kostergubernurbali
@giri.prasta
@iwayanadiarnawa
@gus.bota
@puturasniathiadiarnawa
@yunita_oktarini
@surya.suamba
@budhi.argawakba
@pemkabbadung
@ppidbadung
@dinaspmddukcapilprovbali
@surya_prabhawa
@kecamatanabiansemal
@dpmdbadungkab
@pemprov_bali
@prokompimbadung
@seputar_darmasaba

", "kategoriBeritaId": "cmk69tghz000xvnv8kxzzt24h", - "imageId": "cmk6hzz1i0019vnadwdymqlrf" + "imageName": "DzVIfpiAP3OcCsZ_VJ02b-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp6z", @@ -125,7 +125,7 @@ "deskripsi": "

Festival Darmasaba Village Festival II melibatkan promosi digital produk UMKM.

", "content": "

Promosi dan dokumentasi digital menjadi bagian dari strategi pemasaran UMKM dalam festival desa.

", "kategoriBeritaId": "cmk69tghy000wvnv8umg2vloa", - "imageId": "cmk6i925x001cvnadm3y2m04b" + "imageName": "xzM77A6bDW2silyp_8W7n-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp7z", @@ -133,7 +133,7 @@ "deskripsi": "

Pementasan seni tradisional menjadi bagian dari Darmasaba Village Festival II.

", "content": "

Kegiatan ini mengangkat warisan budaya lokal melalui pertunjukan dan lomba di festival desa.

", "kategoriBeritaId": "cmk69tghy000wvnv8umg2vloa", - "imageId": "cmk6i9cc7001fvnadn9xnl8xq" + "imageName": "2wivBEDcVNxHGG8HUBsNH-mobile.webp" }, { "id": "cmk6aih8f00093b6rqw63yp8z", @@ -141,6 +141,6 @@ "deskripsi": "

Forum dialog desa mengangkat tema partisipasi masyarakat dalam kegiatan budaya lokal.

", "content": "

Diskusi ini memperkuat peran budaya dalam pembangunan desa melalui keterlibatan warga dalam kegiatan adat dan sosial.

", "kategoriBeritaId": "cmk69tghy000wvnv8umg2vloa", - "imageId": "cmk6i9qff001ivnadgrrghebr" + "imageName": "T1fcksUoZSUqNMbzvr9WI-mobile.webp" } ] diff --git a/prisma/data/desa/gallery/foto/foto.json b/prisma/data/desa/gallery/foto/foto.json new file mode 100644 index 00000000..f1141c30 --- /dev/null +++ b/prisma/data/desa/gallery/foto/foto.json @@ -0,0 +1,20 @@ +[ + { + "id": "cml0aiiv1000004l754ldaf2v", + "name": "Kunjungan Ibu TP PKK Kabupaten Badung", + "deskripsi": "

Dokumentasi kunjungan Ibu TP PKK Kabupaten Badung ke Desa Darmasaba pada awal tahun 2026.

", + "imageName": "foto1Gallery.webp" + }, + { + "id": "cml0aiqd4000104l7f91ee3xu", + "name": "Darmasaba Village Festival II 2024", + "deskripsi": "

Foto kegiatan Darmasaba Village Festival II Tahun 2024 yang diselenggarakan di Lapangan Umum Desa Darmasaba, menampilkan lomba, pementasan seni, dan UMKM lokal.

", + "imageName": "foto2Gallery.webp" + }, + { + "id": "cml0aiyi7000204l7f2sy657c", + "name": "Lomba Mancing Air Deras Banjar Gulingan", + "deskripsi": "

Galeri foto kegiatan lomba mancing air deras Komunitas Pemancing Gulingan di Desa Darmasaba, bagian dari pemberdayaan masyarakat.

", + "imageName": "foto3Gallery.webp" + } +] diff --git a/prisma/data/desa/layanan/pelayanaPendudukNonPermanen.json b/prisma/data/desa/layanan/pelayananPendudukNonPermanen.json similarity index 100% rename from prisma/data/desa/layanan/pelayanaPendudukNonPermanen.json rename to prisma/data/desa/layanan/pelayananPendudukNonPermanen.json diff --git a/prisma/data/desa/layanan/pelayananSuratKeterangan.json b/prisma/data/desa/layanan/pelayananSuratKeterangan.json index ccbfa85d..87ea9f17 100644 --- a/prisma/data/desa/layanan/pelayananSuratKeterangan.json +++ b/prisma/data/desa/layanan/pelayananSuratKeterangan.json @@ -3,77 +3,77 @@ "id": "cmdxyb9zi0010vniiaeyi55ui", "name": "Surat Keterangan Beda Biodata Diri", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6n68k80005vn6qtdbshoqi", - "image2": "cmk6n68vw0006vn6qv65lrdw8" + "imageName": "wFXYVHKHtU7posfhBKjZt-mobile.webp", + "image2Name": "kTiZ9uhRUEwu0WeASU00b-mobile.webp" }, { "id": "cmdxycqz40014vniidftrixvf", "name": "Surat Keterangan Yatim Piatu", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6n8rwv0007vn6q312rawvt", - "image2": "cmk6n8s9b0008vn6qwd02eyjf" + "imageName": "ZkvjJ7Zx8uBy2-d8RWNEt-mobile.webp", + "image2Name": "hHfOWKz4USZK-z0nsD7Uz-mobile.webp" }, { "id": "cmdwx3wph0003vnr74us2t7h7", "name": "Surat Keterangan Domisili Organisasi", "deskripsi": "

Persyaratan Dokumen:

Alur Pelayanan:

", - "image": "cmk6n9ti90009vn6qt48wbklu", - "image2": "cmk6n9tvx000avn6qwkguha7w" + "imageName": "03WZn5JMKffo62cKzShF4-mobile.webp", + "image2Name": "dnTcxeYQACzY5yzq-Rjoz-mobile.webp" }, { "id": "cmdxxv3i80004vniidg1mrucc", "name": "Surat Keterangan Penghasilan", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6nb69n000bvn6qx67n06ee", - "image2": "cmk6nb6nq000cvn6q75730cr3" + "imageName": "7er4OinxhuKRZUSkKeSYR-mobile.webp", + "image2Name": "8ZtJeCnKwMAcEUBU0QvE7-mobile.webp" }, { "id": "cmdxxwp070008vnii9jbdcto7", "name": "Surat Keterangan Tidak Mampu", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6nc438000dvn6q723r7phi", - "image2": "cmk6nc4aa000evn6qwl5t53h4" + "imageName": "Y7IuwpwjT3ZFYWpiXJZYw-mobile.webp", + "image2Name": "Fbi-6gnhokkwux9hvriS--mobile.webp" }, { "id": "cmdxxyfkl000cvnii1bxinnfi", "name": "Surat Keterangan Kelahiran", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6ndw2z000fvn6q3b9wxswd", - "image2": "cmk6ndwbf000gvn6qusd4mkhq" + "imageName": "qtdJ39rIbjGTJJQZflrDL-mobile.webp", + "image2Name": "ldmfJBS2ZBhIda60yU2JW-mobile.webp" }, { "id": "cmdxy23pl000gvniihsg38aq4", "name": "Surat Keterangan Usaha", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6nf4pu000hvn6qszs6xyp5", - "image2": "cmk6nf53c000ivn6qawvoxndb" + "imageName": "CAtRFHiM11gsY4ExcvGgc-mobile.webp", + "image2Name": "MLWp-38kKygXKVekCh0q7-mobile.webp" }, { "id": "cmdxy4mgt000kvniib1nemjem", "name": "Surat Keterangan Kematian", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6ng6yk000jvn6q0ditzufj", - "image2": "cmk6ng77b000kvn6q51j2s4q7" + "imageName": "C0zE5lneKa888VJDHzgh--mobile.webp", + "image2Name": "hhDK7OL0wQLik5dsh1a-L-mobile.webp" }, { "id": "cmdxy61a1000ovniif4ytb9hs", "name": "Surat Keterangan Tempat Usaha", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6nh7ez000lvn6qjfkqeufn", - "image2": "cmk6nh7pq000mvn6qor967hjh" + "imageName": "sVIfCUGBplNU8h1x99l8z-mobile.webp", + "image2Name": "MM-1CZMai3eXwbVr2HAEv-mobile.webp" }, { "id": "cmdxy754q000svniiiz8oqyo0", "name": "Surat Keterangan Belum Kawin", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6n37tp0003vn6qqyvelh5s", - "image2": "cmk6n388d0004vn6qby5fkuz8" + "imageName": "oNH9VvRPlAmTI_Ndu3slN-mobile.webp", + "image2Name": "Wze2x68vn-ShZAqgkSCMC-mobile.webp" }, { "id": "cmdxy8pi2000wvnii48fc1sxd", "name": "Surat Keterangan Kelakuan Baik", "deskripsi": "

Persyaratan Dokumen :

Alur Pelayanan :

", - "image": "cmk6mvhwh0001vn6qa6ddzqfm", - "image2": "cmk6mvi8c0002vn6q9vfyv6yt" + "imageName": "tK9T6BObEQEdYU-5y1xnJ-mobile.webp", + "image2Name": "sX9yfcM05OOx2ELhcSNWl-mobile.webp" } ] diff --git a/prisma/data/desa/penghargaan/penghargaan.json b/prisma/data/desa/penghargaan/penghargaan.json index d0e0c15c..6b073a23 100644 --- a/prisma/data/desa/penghargaan/penghargaan.json +++ b/prisma/data/desa/penghargaan/penghargaan.json @@ -4,27 +4,27 @@ "name": "Perbekel Darmasaba Terima Penghargaan pada Indonesia Alternative Dispute Resolution Awards 2025", "juara": "Penghargaan IADRA 2025", "deskripsi": "

Perbekel Darmasaba, Ida Bagus Surya Prabhawa Manuaba menerima penghargaan pada Indonesia Alternative Dispute Resolution Awards 2025 atas kontribusi dalam penyelesaian sengketa secara damai dan berkeadilan.

", - "imageId": "cmkal9d2p0000vnexf8flpunj" + "imageName": "cte_gy0V8glhDcghMa3-B-mobile.webp" }, { "id": "cmkalfbux0005vnexj8zplube", "name": "Penghargaan Bhawana Sewaka Nugraha kepada Perbekel Darmasaba", "juara": "Penghargaan Bhawana Sewaka Nugraha", "deskripsi": "

Penghargaan Bhawana Sewaka Nugraha diberikan kepada Perbekel Desa Darmasaba atas dedikasi dan komitmen dalam menjaga kelestarian lingkungan serta menginspirasi masyarakat untuk menciptakan desa yang hijau, bersih, dan berkelanjutan.

", - "imageId": "cmkalfbsn0003vnex3bbsx5ja" + "imageName": "hLoy_DjB_3Yie2vjaXDYz-mobile.webp" }, { "id": "cmkalg6hk0008vnexmsqwd3n7", "name": "Desa Darmasaba Raih Juara 1 Lomba Desa Tingkat Provinsi Bali Tahun 2025", "juara": "Juara 1 Lomba Desa Provinsi Bali 2025", "deskripsi": "

Desa Darmasaba meraih juara 1 dalam Lomba Desa Tingkat Provinsi Bali Tahun 2025 melalui sinergi elemen desa serta inovasi dalam pelayanan publik dan pemberdayaan masyarakat.

", - "imageId": "cmkalg6fh0006vnexid4z9vlg" + "imageName": "VxELyZ0ifdHOdRFu7aBSz-mobile.webp" }, { "id": "cmkalgucu000bvnexw2blt1v3", "name": "Pemerintah Desa Darmasaba Raih Peringkat IV dalam Ajang Mangupura Award Tahun 2025", "juara": "Peringkat IV Mangupura Award 2025", "deskripsi": "

Desa Darmasaba mendapatkan penghargaan Peringkat IV pada Mangupura Award 2025 dari Pemerintah Kabupaten Badung atas tata kelola pemerintahan, inovasi layanan, dan pemberdayaan masyarakat.

", - "imageId": "cmkalguac0009vnex5dpixivn" + "imageName": "xgrBxDdo8g7KA-3zNbRGj-mobile.webp" } ] diff --git a/prisma/data/desa/potensi/potensi-desa.json b/prisma/data/desa/potensi/potensi-desa.json index 284c9049..43b8dfbf 100644 --- a/prisma/data/desa/potensi/potensi-desa.json +++ b/prisma/data/desa/potensi/potensi-desa.json @@ -5,7 +5,7 @@ "deskripsi": "

Taman Beji Cengana adalah situs keagamaan dan budaya tradisional Bali

", "content": "

Taman Beji Cengana adalah situs keagamaan dan budaya tradisional Bali yang memadukan unsur spiritual, ritual pembersihan (melukat), serta nilai budaya lokal yang berpadu dengan suasana alam yang tenang dan harmonis.

", "kategoriId": "cmk3pmwq10008vn9bqdquv153", - "imageId": "cmk3rbc53000cvn9bjsywrj18" + "imageName": "yySqpA7ougpXi6cJPskg9-mobile.webp" }, { "id": "cmk3q0sez000bvn9b3iyyct5m", @@ -13,7 +13,7 @@ "deskripsi": "

Gumuh Sari merupakan tempat rekreasi nyaman di kawasan badung yang dapat dinikmati oleh semua umur dengan berbagai fasilitas hiburan, seperti Water Park, Pusat Kebugaran, Lapangan Futsal dan Restaurant.

", "content": "

Gumuh Sari merupakan tempat rekreasi nyaman di kawasan badung yang dapat dinikmati oleh semua umur dengan berbagai fasilitas hiburan, seperti Water Park, Pusat Kebugaran, Lapangan Futsal dan Restaurant.

Buka setiap hari
Senin-Jumat: pukul 10.00-18.00 WITA (Weekday)
Sabtu-Minggu: pukul 09.00-18.00 WITA (Weekend)

Wahana:
- Kolam Renang Anak
- Kolam Renang Dewasa
- Kolam Renang Olympic
- Kids Playground Indoor
- Ayunan
- ATV

Fasilitas:
- Tempat ibadah
- Area parkir
- Gazebo
- Restoran dan kantin
- WiFi gratis
- Kamar mandi dan ruang bilas
- Ruang loker

Kategori Tiket:
Senin-Sabtu
- Dewasa 35.000
- Anak-anak (3-12 tahun) 20.000

Minggu & Libur Nasional
- Dewasa 40.000
- Anak-anak (3-12 tahun) 25.000

Hari Raya
- Dewasa 45.000
- Anak-anak (3-12 tahun) 35.000

Media Sosial:
- Instagram: gumuhsari_rekreasi
https://www.instagram.com/gumuhsari_rekreasi/

- Tiktok: gumuhsari_rekreasi
https://www.tiktok.com/@gumuhsari_rekreasi

", "kategoriId": "cmk3pmwq10008vn9bqdquv153", - "imageId": "cmk3q0s8b0009vn9blvh0q5cc" + "imageName": "uki9Zy0DqrEtSg9Lrgyyk-mobile.webp" }, { "id": "cmk3rsch1000hvn9bhmyhsjqm", @@ -21,7 +21,7 @@ "deskripsi": "

Sistem pengelolaan sampah terpadu di Desa Darmasaba yang dikenal dengan TPS3R Pudak Mesari.

", "content": "

TPS3R Pudak Mesari adalah fasilitas pengelolaan sampah terpadu yang mengoptimalkan pemilahan, pengolahan dan daur ulang sampah masyarakat sehingga mendukung lingkungan yang bersih dan berkelanjutan di Desa Darmasaba.

", "kategoriId": "cmk3pmwq10008vn9bqdquv153", - "imageId": "cmk3rscb0000fvn9bq6il16ba" + "imageName": "F8SuL9DjCqLXlSwmgSJv_-mobile.webp" }, { "id": "cmk3s4kz7000mvn9b8thk98c4", @@ -29,7 +29,7 @@ "deskripsi": "

Badan Usaha Milik Desa yang bergerak dalam berbagai usaha ekonomi masyarakat Darmasaba.

", "content": "

Bumdes Pudak Mesari merupakan badan usaha milik desa yang mengembangkan kegiatan usaha produktif untuk meningkatkan perekonomian masyarakat lokal, termasuk pengelolaan usaha jasa dan komoditas lokal yang dikelola secara partisipatif.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3s4kvu000kvn9bahu2vo5f" + "imageName": "daDa40Y8dxune0l_cxULD-mobile.webp" }, { "id": "cmk3sbgge000pvn9bd3r8i0on", @@ -37,7 +37,7 @@ "deskripsi": "

Sektor pertanian sebagai salah satu potensi utama Desa Darmasaba.

", "content": "

Pertanian di Darmasaba mencakup berbagai komoditas yang ditanam oleh masyarakat termasuk padi, tanaman hortikultura dan lain-lain, yang menjadi basis mata pencaharian dan kontribusi terhadap ekonomi desa.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3sbgd8000nvn9bqooq77ix" + "imageName": "yms7mL_T6fy--Eze-mTwc-mobile.webp" }, { "id": "cmk3smnj3000svn9b2ww5hesp", @@ -45,7 +45,7 @@ "deskripsi": "

Jalur jogging dan area rekreasi alam yang dimanfaatkan masyarakat untuk aktivitas sehat dan pariwisata lokal.

", "content": "

Jogging Track Tegeh Aban, Karang Gadon dan Munduk Uma adalah area terbuka hijau yang dikembangkan sebagai fasilitas olahraga dan rekreasi, memberikan ruang beraktivitas fisik sambil menikmati suasana alam Desa Darmasaba.

", "kategoriId": "cmk3pmwq10008vn9bqdquv153", - "imageId": "cmk3smnbf000qvn9b28ma8las" + "imageName": "AFA1PZtHwKkwmWCC4M7lM-mobile.webp" }, { "id": "cmk3t8hgs000vvn9bna6pnw8r", @@ -53,7 +53,7 @@ "deskripsi": "

Bendungan lokal yang berfungsi sebagai sumber irigasi pertanian.

", "content": "

Dam Tanah Putih merupakan bendungan yang mendukung pengairan sawah dan lahan pertanian di Desa Darmasaba, yang membantu peningkatan produktivitas pertanian masyarakat setempat.

", "kategoriId": "cmk3pmwq10008vn9bqdquv153", - "imageId": "cmk3t8ha3000tvn9bkqsty6sq" + "imageName": "84pnYeV2_9f4xplh9RBXW-mobile.webp" }, { "id": "cmk3tlrkb000yvn9bo1vse4c5", @@ -61,7 +61,7 @@ "deskripsi": "

Usaha mikro, kecil, dan menengah masyarakat Desa Darmasaba.

", "content": "

UMKM di Darmasaba mencakup berbagai usaha kecil produktif seperti kuliner, kerajinan tangan, dan jasa lainnya, yang menjadi pilar kegiatan ekonomi dan pemberdayaan masyarakat lokal.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3tlrdl000wvn9b67jkppzh" + "imageName": "5VSeupjyjtam02PNJW3ZG-mobile.webp" }, { "id": "cmk3tzpku0011vn9beq2kzyen", @@ -69,7 +69,7 @@ "deskripsi": "

Wilayah yang menyediakan berbagai pilihan kuliner khas lokal Desa Darmasaba.

", "content": "

Kawasan kuliner di Darmasaba menjadi tempat berkumpul dan menikmati makanan khas lokal, mendukung kegiatan ekonomi UMKM kuliner desa serta daya tarik wisata kuliner.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3tzpd7000zvn9bu519xrjk" + "imageName": "gjwx1dcHKMJEICbLF6g88-mobile.webp" }, { "id": "cmk3u7gzh0014vn9brvlz3fjp", @@ -77,7 +77,7 @@ "deskripsi": "

Industri kecil menengah yang fokus pada pengolahan produk pangan lokal.

", "content": "

IKM berbasis pengolahan pangan di desa mencakup produksi makanan olahan yang dihasilkan oleh masyarakat setempat, memperkaya nilai tambah hasil pertanian lokal dan menciptakan peluang bisnis.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3u7gsg0012vn9bhqhsw5g6" + "imageName": "j3q1NLvwPFrxAmgMXBmq2-mobile.webp" }, { "id": "cmk3udr960017vn9bq33ce6mw", @@ -85,6 +85,6 @@ "deskripsi": "

Usaha budidaya ikan lele sebagai potensi perikanan desa.

", "content": "

Peternakan ikan lele menjadi salah satu bentuk usaha budidaya perikanan di Darmasaba, memberikan sumber pendapatan tambahan bagi petani ikan dan diversifikasi komoditas desa.

", "kategoriId": "cmk3s1ks6000ivn9bcrv960ko", - "imageId": "cmk3udr2s0015vn9bqn9hxdxx" + "imageName": "eZCq49lXnx6zKslb6hLxz-mobile.webp" } ] diff --git a/prisma/data/desa/profile/profil_perbekel.json b/prisma/data/desa/profile/profil_perbekel.json index 8d4efc34..2ce61afe 100644 --- a/prisma/data/desa/profile/profil_perbekel.json +++ b/prisma/data/desa/profile/profil_perbekel.json @@ -5,6 +5,6 @@ "pengalaman": "", "pengalamanOrganisasi": "", "programUnggulan": "

Pemberdayaan Ekonomi dan UMKM

", - "imageId": "cmk4xh3gz0000vnwqjy4zfr3w" + "imageName": "perbekel-profile-desa.webp" } ] diff --git a/prisma/data/desa/profile/profile-perbekel-lalu.json b/prisma/data/desa/profile/profile-perbekel-lalu.json index 68154e46..22f49658 100644 --- a/prisma/data/desa/profile/profile-perbekel-lalu.json +++ b/prisma/data/desa/profile/profile-perbekel-lalu.json @@ -3,63 +3,63 @@ "id": "cmk4yswiy0003vnwq97wem6t2", "nama": "Si Gede Kania", "periode": "Tahun 1943 - 1946", - "imageId": "cmk4yswge0001vnwqgfieunnm", + "imageName": "120DDmtAkWEOlu_z56EVj-mobile.webp", "daerah": "Perbekel Tegal" }, { "id": "cmk4yvuxg0006vnwqa0nk7jcx", "nama": "Si Gede Gandem", "periode": "Tahun 1946 - 1950", - "imageId": "cmk4yvuv20004vnwqqq8ifxq8", + "imageName": "bJEAL2K_DcR9AhabklcdP-mobile.webp", "daerah": "Perbekel Tegal" }, { "id": "cmk4ywml70009vnwqnnrp0cpq", "nama": "I Wayan Sama", "periode": "Tahun 1950 - 1953", - "imageId": "cmk4ywmiu0007vnwq5ea5jz1z", + "imageName": "szxGnXEFqa0k0nvZ-ALVG-mobile.webp", "daerah": "Perbekel Tegal" }, { "id": "cmk4yzix3000cvnwqn2pa57gs", "nama": "I Wayan Nambreg", "periode": "Tahun 1950 - 1960", - "imageId": "cmk4yzitx000avnwq7479tvxb", + "imageName": "ectWSAf6wfzIPzKMf3wzo-mobile.webp", "daerah": "Perbekel Darmasaba" }, { "id": "cmk4z0sgd000fvnwqlgjasqx9", "nama": "Ida Bagus Putu Oka", "periode": "Tahun 1953 - 1974", - "imageId": "cmk4z0scm000dvnwqlntylzyk", + "imageName": "VwjN6P8HyaKpNngtLCt6z-mobile.webp", "daerah": "Perbekel Tegal / Darmasaba" }, { "id": "cmk4z1w8m000ivnwqe68w5vjg", "nama": "I Nyoman Patra", "periode": "Tahun 1974 - 1991", - "imageId": "cmk4z1vqs000gvnwqj579yvnt", + "imageName": "f3tdB74WjhVVJXmAE7Sev-mobile.webp", "daerah": "Perbekel Darmasaba" }, { "id": "cmk4z2y3u000lvnwq7fbr3paz", "nama": "I Made Rudja", "periode": "Tahun 1991 - 2007", - "imageId": "cmk4z2y0r000jvnwq2jgrs565", + "imageName": "X3FbO9ns3We5GM1uAwds1-mobile.webp", "daerah": "Perbekel Darmasaba" }, { "id": "cmk4z6esm000ovnwqacek3jlx", "nama": "I Wayan Kaler, S.H., M.H.", "periode": "Tahun 2007 - 2013", - "imageId": "cmk4z6epq000mvnwq81dfq29b", + "imageName": "AO-mB9JXm0ahmNnSAEDJ3-mobile.webp", "daerah": "Perbekel Darmasaba" }, { "id": "cmk4z7e77000rvnwqo2wkmbwl", "nama": "I Made Taram, S.H.", "periode": "Tahun 2013 - 2019", - "imageId": "cmk4z7e5g000pvnwq7k45e366", + "imageName": "ropKaJjSbK_XAyxd8mEYt-mobile.webp", "daerah": "Perbekel Darmasaba" } ] diff --git a/prisma/data/desa/profile/profileDesaImage.json b/prisma/data/desa/profile/profileDesaImage.json new file mode 100644 index 00000000..678198a6 --- /dev/null +++ b/prisma/data/desa/profile/profileDesaImage.json @@ -0,0 +1,26 @@ +[ + { + "id": "cmkz5lumu0008vn5gso2vrejt", + "label": "Bunga Pudak", + "imageName": "fpovTIXnnsX5duqLeoSx6-mobile.webp", + "maskotDesaId": "edit" + }, + { + "id": "cmkz5lumu0009vn5gcn3ah0ku", + "label": "Pohon Pudak", + "imageName": "I01xTmkCZo3u8-y0w07TG-mobile.webp", + "maskotDesaId": "edit" + }, + { + "id": "cmkz5lumu000avn5grvxbmaux", + "label": "Tari Sekar Pudak", + "imageName": "MlTQffVnQ-itl-vgO0BGM-mobile.webp", + "maskotDesaId": "edit" + }, + { + "id": "cmkz5lumu000bvn5gwujxhp2r", + "label": "Klimaks Tari Pudak", + "imageName": "PdIqEFHq5Q12PEi0NRUJ3-mobile.webp", + "maskotDesaId": "edit" + } +] diff --git a/prisma/data/fetchWithRetry.ts b/prisma/data/fetchWithRetry.ts index e561ed00..e8a55d73 100644 --- a/prisma/data/fetchWithRetry.ts +++ b/prisma/data/fetchWithRetry.ts @@ -3,6 +3,9 @@ export default async function fetchWithRetry( retries = 3, timeoutMs = 20000 ) { + if (!url || url.trim() === "") { + throw new Error("fetchWithRetry called with empty URL"); + } for (let attempt = 1; attempt <= retries; attempt++) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), timeoutMs); diff --git a/prisma/data/file-storage.json b/prisma/data/file-storage.json index 052bde8a..2f5267dd 100644 --- a/prisma/data/file-storage.json +++ b/prisma/data/file-storage.json @@ -1,1560 +1,406 @@ [ { - "id": "cmk27746i0000vnso2aspwf9g", - "name": "Eqlrr1W-pK8ShMGqgPGL3-desktop.webp", - "realName": "perbekel.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Eqlrr1W-pK8ShMGqgPGL3-desktop.webp", - "category": "image" - }, - { - "id": "cmk20mg320000vnevxy0k73fr", - "name": "thpgPSJkBxUIRajZt3AVo-desktop.webp", - "realName": "bares.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/thpgPSJkBxUIRajZt3AVo-desktop.webp", - "category": "image" - }, - { - "id": "cmk20nqmu0001vnevfte29rk0", - "name": "ubna9N6r7RgVWN5plO5mq-desktop.webp", - "realName": "bicara-darma.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ubna9N6r7RgVWN5plO5mq-desktop.webp", - "category": "image" - }, - { - "id": "cmk228urs0007vnevi5b66bqn", - "name": "Z4i2RRnnlHq2iWj94ldyo-desktop.webp", - "realName": "daves.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Z4i2RRnnlHq2iWj94ldyo-desktop.webp", - "category": "image" - }, - { - "id": "cmk20nyen0002vnevd0hfr3u8", - "name": "y4yaE4XdUP1TSUGhWPW9h-desktop.webp", - "realName": "mangan.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/y4yaE4XdUP1TSUGhWPW9h-desktop.webp", - "category": "image" - }, - { - "id": "cmk20o7mf0003vnevohrksm1d", - "name": "Vr7CoaYDpk2dIkHx9PxRj-desktop.webp", - "realName": "gelah-melah.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Vr7CoaYDpk2dIkHx9PxRj-desktop.webp", - "category": "image" - }, - { - "id": "cmk20of8m0004vnev9ujy5o0l", - "name": "ceoB_sg-HOzljN8j_2nZA-desktop.webp", - "realName": "inovasi-desa-darmasaba.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ceoB_sg-HOzljN8j_2nZA-desktop.webp", - "category": "image" - }, - { - "id": "cmk20omzq0005vnevgi6f4edu", - "name": "vOy5YVUXfHXfiFOHylIN7-desktop.webp", - "realName": "pdkt.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/vOy5YVUXfHXfiFOHylIN7-desktop.webp", - "category": "image" - }, - { - "id": "cmk20pf3d0006vnev3mkoqpyy", - "name": "gE_qcqIbY0mqI6FV9V4CL-desktop.webp", - "realName": "sajjiana-dharma-raksaka.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/gE_qcqIbY0mqI6FV9V4CL-desktop.webp", - "category": "image" - }, - { - "id": "cmk2a2dl6001nvngck1n0k8qc", - "name": "Eqlrr1W-pK8ShMGqgPGL3-desktop.webp", - "realName": "perbekel.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Eqlrr1W-pK8ShMGqgPGL3-desktop.webp", - "category": "image" - }, - { - "id": "cmk2cgqgm0003vn96jun52pik", - "name": "q1G995W7cLkC_qquLTlKN-desktop.webp", - "realName": "youtube.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/q1G995W7cLkC_qquLTlKN-desktop.webp", - "category": "image" - }, - { - "id": "cmk2cmr000006vn96qepq6gvl", - "name": "I6mlQ4nRmPX26gm79C_rM-desktop.webp", - "realName": "facebook.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/I6mlQ4nRmPX26gm79C_rM-desktop.webp", - "category": "image" - }, - { - "id": "cmk2cpeba0009vn966jcrpf3u", - "name": "WArLC_yvU33MjoqEnQeQ1-desktop.webp", - "realName": "instagram.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/WArLC_yvU33MjoqEnQeQ1-desktop.webp", - "category": "image" - }, - { - "id": "cmk2crcl1000cvn96j8pmgmo5", - "name": "D3RPbNiaNSCjacLjeR_qO-desktop.webp", - "realName": "tiktok.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/D3RPbNiaNSCjacLjeR_qO-desktop.webp", - "category": "image" - }, - { - "id": "cmk3grkby0000vnxwblul7viy", - "name": "kxpXwgyx74-HkAGXML7Hv-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.23.11.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/kxpXwgyx74-HkAGXML7Hv-desktop.webp", - "category": "image" - }, - { - "id": "cmk3h87lc0001vnxwxc5sn0xc", - "name": "D0DEORcSkSWXEpY29mh_x-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.23.22.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/D0DEORcSkSWXEpY29mh_x-desktop.webp", - "category": "image" - }, - { - "id": "cmk3haaaf0002vnxwy5w07z3n", - "name": "jrUol97rV5whAUtpljbyF-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.23.32.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/jrUol97rV5whAUtpljbyF-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hdeeg0003vnxwezx6zu99", - "name": "Kh8RTS4ac1bG4ZXy3L2-y-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.23.40.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Kh8RTS4ac1bG4ZXy3L2-y-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hg3n20004vnxwxofi5ylm", - "name": "8bAk-cuzJ73W1dgj4lVqM-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.23.49.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/8bAk-cuzJ73W1dgj4lVqM-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hjdb10005vnxwjtgd6g9g", - "name": "k4zOPRqxi6PS0W_rHgiVp-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.00.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/k4zOPRqxi6PS0W_rHgiVp-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hlu6l0006vnxw9wtsaq4w", - "name": "txtX9hDmrHrRIkmpyQ6rp-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.14.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/txtX9hDmrHrRIkmpyQ6rp-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hp5ht0007vnxwakvsa7ld", - "name": "Yx7ruGLJ_0QtD5RCvYhEC-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.21.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Yx7ruGLJ_0QtD5RCvYhEC-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hrkmp0008vnxwijncfayo", - "name": "j1kZLRY4HLFBxdRt24XQw-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.32.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/j1kZLRY4HLFBxdRt24XQw-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hu2lh0009vnxw82qb8l6h", - "name": "Iqx5__9VtAQiScvvGb21S-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.43.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Iqx5__9VtAQiScvvGb21S-desktop.webp", - "category": "image" - }, - { - "id": "cmk3hwtsm000avnxwfug41t9x", - "name": "Eelib_Lr7GYv0nPj3XHVo-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.24.58.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Eelib_Lr7GYv0nPj3XHVo-desktop.webp", - "category": "image" - }, - { - "id": "cmk3i09sa000bvnxw95elyupj", - "name": "6MzAfXZyjsSTOkckqYJug-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.06.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/6MzAfXZyjsSTOkckqYJug-desktop.webp", - "category": "image" - }, - { - "id": "cmk3i2q07000cvnxwkjxqld0c", - "name": "f05zcftt1hdvkhCeN7wxk-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.16.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/f05zcftt1hdvkhCeN7wxk-desktop.webp", - "category": "image" - }, - { - "id": "cmk3i53wr000dvnxw074gyuar", - "name": "3tuC1Bq5WvH7QEBHQVDaM-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.25.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/3tuC1Bq5WvH7QEBHQVDaM-desktop.webp", - "category": "image" - }, - { - "id": "cmk3i7krz000evnxwe4uturyn", - "name": "oTKQeqAydsV5fXelI0S7Y-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.36.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/oTKQeqAydsV5fXelI0S7Y-desktop.webp", - "category": "image" - }, - { - "id": "cmk3ib07w000fvnxwsnb1hga3", - "name": "37VzhdQ6zus1WdVLcCwF5-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.45.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/37VzhdQ6zus1WdVLcCwF5-desktop.webp", - "category": "image" - }, - { - "id": "cmk3idx0t000gvnxw16urbiw5", - "name": "L8jv3Wvj0GwsQgS7JSJQO-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.25.57.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/L8jv3Wvj0GwsQgS7JSJQO-desktop.webp", - "category": "image" - }, - { - "id": "cmk3ig4ho000hvnxwewlheju3", - "name": "vSP59yLERIKB4xMv_ob5s-desktop.webp", - "realName": "Screenshot 2025-07-23 at 17.26.06.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/vSP59yLERIKB4xMv_ob5s-desktop.webp", - "category": "image" - }, - { - "id": "cmk3o5wxs0006vn9b1u5kbqyw", - "name": "t9x6bSW8WnbdPS9cx9PLC-desktop.webp", - "realName": "perbekel.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/t9x6bSW8WnbdPS9cx9PLC-desktop.webp", - "category": "image" - }, - { - "id": "cmk3q0s8b0009vn9blvh0q5cc", - "name": "uki9Zy0DqrEtSg9Lrgyyk-desktop.webp", - "realName": "Gumuh-Sari.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/uki9Zy0DqrEtSg9Lrgyyk-desktop.webp", - "category": "image" - }, - { - "id": "cmk3rbc53000cvn9bjsywrj18", - "name": "yySqpA7ougpXi6cJPskg9-desktop.webp", - "realName": "taman-beji.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/yySqpA7ougpXi6cJPskg9-desktop.webp", - "category": "image" - }, - { - "id": "cmk3rscb0000fvn9bq6il16ba", - "name": "F8SuL9DjCqLXlSwmgSJv_-desktop.webp", - "realName": "tps.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/F8SuL9DjCqLXlSwmgSJv_-desktop.webp", - "category": "image" - }, - { - "id": "cmk3s4kvu000kvn9bahu2vo5f", - "name": "daDa40Y8dxune0l_cxULD-desktop.webp", - "realName": "bumdes.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/daDa40Y8dxune0l_cxULD-desktop.webp", - "category": "image" - }, - { - "id": "cmk3sbgd8000nvn9bqooq77ix", - "name": "yms7mL_T6fy--Eze-mTwc-desktop.webp", - "realName": "pertanian.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/yms7mL_T6fy--Eze-mTwc-desktop.webp", - "category": "image" - }, - { - "id": "cmk3smnbf000qvn9b28ma8las", - "name": "AFA1PZtHwKkwmWCC4M7lM-desktop.webp", - "realName": "joging.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/AFA1PZtHwKkwmWCC4M7lM-desktop.webp", - "category": "image" - }, - { - "id": "cmk3t8ha3000tvn9bkqsty6sq", - "name": "84pnYeV2_9f4xplh9RBXW-desktop.webp", - "realName": "dam-tanah-putih.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/84pnYeV2_9f4xplh9RBXW-desktop.webp", - "category": "image" - }, - { - "id": "cmk3tlrdl000wvn9b67jkppzh", - "name": "5VSeupjyjtam02PNJW3ZG-desktop.webp", - "realName": "umkm.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/5VSeupjyjtam02PNJW3ZG-desktop.webp", - "category": "image" - }, - { - "id": "cmk3tzpd7000zvn9bu519xrjk", - "name": "gjwx1dcHKMJEICbLF6g88-desktop.webp", - "realName": "kuliner.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/gjwx1dcHKMJEICbLF6g88-desktop.webp", - "category": "image" - }, - { - "id": "cmk3u7gsg0012vn9bhqhsw5g6", - "name": "j3q1NLvwPFrxAmgMXBmq2-desktop.webp", - "realName": "ikm.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/j3q1NLvwPFrxAmgMXBmq2-desktop.webp", - "category": "image" - }, - { - "id": "cmk3udr2s0015vn9bqn9hxdxx", - "name": "eZCq49lXnx6zKslb6hLxz-desktop.webp", - "realName": "ikan lele.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/eZCq49lXnx6zKslb6hLxz-desktop.webp", - "category": "image" - }, - { - "id": "cmk4xh3gz0000vnwqjy4zfr3w", - "name": "wkUnTN2pzkEXolbWsgWi7-desktop.webp", - "realName": "perbekel.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/wkUnTN2pzkEXolbWsgWi7-desktop.webp", - "category": "image" - }, - { - "id": "cmk4yswge0001vnwqgfieunnm", - "name": "120DDmtAkWEOlu_z56EVj-desktop.webp", - "realName": "perbekel 1.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/120DDmtAkWEOlu_z56EVj-desktop.webp", - "category": "image" - }, - { - "id": "cmk4yvuv20004vnwqqq8ifxq8", - "name": "bJEAL2K_DcR9AhabklcdP-desktop.webp", - "realName": "perbekel 2.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/bJEAL2K_DcR9AhabklcdP-desktop.webp", - "category": "image" - }, - { - "id": "cmk4ywmiu0007vnwq5ea5jz1z", - "name": "szxGnXEFqa0k0nvZ-ALVG-desktop.webp", - "realName": "Perbekel 3.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/szxGnXEFqa0k0nvZ-ALVG-desktop.webp", - "category": "image" - }, - { - "id": "cmk4yzitx000avnwq7479tvxb", - "name": "ectWSAf6wfzIPzKMf3wzo-desktop.webp", - "realName": "perbekel 4.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ectWSAf6wfzIPzKMf3wzo-desktop.webp", - "category": "image" - }, - { - "id": "cmk4z0scm000dvnwqlntylzyk", - "name": "VwjN6P8HyaKpNngtLCt6z-desktop.webp", - "realName": "perbekel 5.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/VwjN6P8HyaKpNngtLCt6z-desktop.webp", - "category": "image" - }, - { - "id": "cmk4z1vqs000gvnwqj579yvnt", - "name": "f3tdB74WjhVVJXmAE7Sev-desktop.webp", - "realName": "perbekel 6.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/f3tdB74WjhVVJXmAE7Sev-desktop.webp", - "category": "image" - }, - { - "id": "cmk4z2y0r000jvnwq2jgrs565", - "name": "X3FbO9ns3We5GM1uAwds1-desktop.webp", - "realName": "Screenshot 2025-09-19 at 16.45.39.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/X3FbO9ns3We5GM1uAwds1-desktop.webp", - "category": "image" - }, - - { - "id": "cmk4z6epq000mvnwq81dfq29b", - "name": "AO-mB9JXm0ahmNnSAEDJ3-desktop.webp", - "realName": "Screenshot 2025-09-19 at 16.46.51.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/AO-mB9JXm0ahmNnSAEDJ3-desktop.webp", - "category": "image" - }, - { - "id": "cmk4z7e5g000pvnwq7k45e366", - "name": "ropKaJjSbK_XAyxd8mEYt-desktop.webp", - "realName": "Screenshot 2025-09-19 at 16.48.11.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ropKaJjSbK_XAyxd8mEYt-desktop.webp", - "category": "image" - }, - { - "id": "cmkamji130000vntz3loca9q2", - "name": "D4za5fHh_y92Bj9qZkp5j-desktop.webp", - "realName": "prestasi1.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/D4za5fHh_y92Bj9qZkp5j-desktop.webp", - "category": "image" - }, - { - "id": "cmkamk2cf0001vntzjg4rzqep", - "name": "3rshaPxCgk5unArWbKPpk-desktop.webp", - "realName": "prestasi2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/3rshaPxCgk5unArWbKPpk-desktop.webp", - "category": "image" - }, - { - "id": "cmkamkb150002vntzklhz9ryx", - "name": "pxpQFGBkTRpFOwJFTwjbD-desktop.webp", - "realName": "prestasi3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/pxpQFGBkTRpFOwJFTwjbD-desktop.webp", - "category": "image" - }, - { - "id": "cmkamki230003vntzg25voz53", - "name": "_CIAQk1Yem-_6LFjrkmVg-desktop.webp", - "realName": "prestasi4.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/_CIAQk1Yem-_6LFjrkmVg-desktop.webp", - "category": "image" - }, - { - "id": "cmk6bk2va0003vnadn9w0mxc4", - "name": "Wp41ccw3yma9W8i6zBr6E-desktop.webp", - "realName": "berita-sosial-1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Wp41ccw3yma9W8i6zBr6E-desktop.webp", - "category": "image" - }, - { - "id": "cmk6bo3290006vnadzhgalacy", - "name": "IwedNmhjD_wGpY6PvYX7W-desktop.webp", - "realName": "berita-sosial-2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/IwedNmhjD_wGpY6PvYX7W-desktop.webp", - "category": "image" - }, - { - "id": "cmk6bptid0009vnad6my1w4s1", - "name": "EVkMxPdoWyL3y31L7d7x1-desktop.webp", - "realName": "berita-sosial-3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/EVkMxPdoWyL3y31L7d7x1-desktop.webp", - "category": "image" - }, - { - "id": "cmk6c86dc000cvnadlh54q7xr", - "name": "c_5xOKUbMiD8dTAbkAv9a-desktop.webp", - "realName": "pembangunan-1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/c_5xOKUbMiD8dTAbkAv9a-desktop.webp", - "category": "image" - }, - { - "id": "cmk6cbbtw000fvnadk862le38", - "name": "I9CDBqdeDXRbbzbPWhy6h-desktop.webp", - "realName": "pembangunan-2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/I9CDBqdeDXRbbzbPWhy6h-desktop.webp", - "category": "image" - }, - { - "id": "cmk6cdmjp000ivnadeejerm59", - "name": "Gq-gEDaGNb-FkKasVs7i4-desktop.webp", - "realName": "pembangunan-3.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Gq-gEDaGNb-FkKasVs7i4-desktop.webp", - "category": "image" - }, - { - "id": "cmk6crib4000lvnadqtrhnb14", - "name": "TymQ5xDH7vEUOA9BY63hr-desktop.webp", - "realName": "ekonomi-1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/TymQ5xDH7vEUOA9BY63hr-desktop.webp", - "category": "image" - }, - { - "id": "cmk6czfag000ovnad7kjz36lj", - "name": "2nUvEBsMuigIJQWZIdcEJ-desktop.webp", - "realName": "ekonomi-2-.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/2nUvEBsMuigIJQWZIdcEJ-desktop.webp", - "category": "image" - }, - { - "id": "cmk6d3zow000rvnades3btqrh", - "name": "Hokgum3-nI_NWTWJRnWi3-desktop.webp", - "realName": "ekonomi-3.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Hokgum3-nI_NWTWJRnWi3-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hgl8r000uvnadwchcqigp", - "name": "T1fcksUoZSUqNMbzvr9WI-desktop.webp", - "realName": "pemerintahan-1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/T1fcksUoZSUqNMbzvr9WI-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hh34d000xvnadr74cs014", - "name": "-M_tICRVz6ZxOfvkuHQgU-desktop.webp", - "realName": "pemerintahan-2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/-M_tICRVz6ZxOfvkuHQgU-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hhl5p0010vnadx09hrg3n", - "name": "O11hmN9oNwFKs_ACpH9uV-desktop.webp", - "realName": "pemerintahan-3-.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/O11hmN9oNwFKs_ACpH9uV-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hz5640013vnadwdmfzyoa", - "name": "rrgHHUYHDuq3jW94HCRsq-desktop.webp", - "realName": "teknologi-1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/rrgHHUYHDuq3jW94HCRsq-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hzlrg0016vnaduf57rp2i", - "name": "igz0V0MCoLYqAgLIBRZdG-desktop.webp", - "realName": "teknologi-2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/igz0V0MCoLYqAgLIBRZdG-desktop.webp", - "category": "image" - }, - { - "id": "cmk6hzz1i0019vnadwdymqlrf", - "name": "DzVIfpiAP3OcCsZ_VJ02b-desktop.webp", - "realName": "teknologi-3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/DzVIfpiAP3OcCsZ_VJ02b-desktop.webp", - "category": "image" - }, - { - "id": "cmk6i925x001cvnadm3y2m04b", - "name": "xzM77A6bDW2silyp_8W7n-desktop.webp", - "realName": "budaya-1-.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/xzM77A6bDW2silyp_8W7n-desktop.webp", - "category": "image" - }, - { - "id": "cmk6i9cc7001fvnadn9xnl8xq", - "name": "2wivBEDcVNxHGG8HUBsNH-desktop.webp", - "realName": "budaya-2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/2wivBEDcVNxHGG8HUBsNH-desktop.webp", - "category": "image" - }, - { - "id": "cmk6i9qff001ivnadgrrghebr", - "name": "fffAFkeBBjjxHljZIDCZw-desktop.webp", - "realName": "budaya-3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/fffAFkeBBjjxHljZIDCZw-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n68k80005vn6qtdbshoqi", - "name": "wFXYVHKHtU7posfhBKjZt-desktop.webp", - "realName": "data-diri.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/wFXYVHKHtU7posfhBKjZt-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n68vw0006vn6qv65lrdw8", - "name": "kTiZ9uhRUEwu0WeASU00b-desktop.webp", - "realName": "flow-data-diri.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/kTiZ9uhRUEwu0WeASU00b-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n8rwv0007vn6q312rawvt", - "name": "ZkvjJ7Zx8uBy2-d8RWNEt-desktop.webp", - "realName": "yatim.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ZkvjJ7Zx8uBy2-d8RWNEt-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n8s9b0008vn6qwd02eyjf", - "name": "hHfOWKz4USZK-z0nsD7Uz-desktop.webp", - "realName": "flow yatim.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/hHfOWKz4USZK-z0nsD7Uz-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n9ti90009vn6qt48wbklu", - "name": "03WZn5JMKffo62cKzShF4-desktop.webp", - "realName": "organisasi.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/03WZn5JMKffo62cKzShF4-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n9tvx000avn6qwkguha7w", - "name": "dnTcxeYQACzY5yzq-Rjoz-desktop.webp", - "realName": "domisili-organisasi.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/dnTcxeYQACzY5yzq-Rjoz-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nb69n000bvn6qx67n06ee", - "name": "7er4OinxhuKRZUSkKeSYR-desktop.webp", - "realName": "penghasilan-layanan.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/7er4OinxhuKRZUSkKeSYR-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nb6nq000cvn6q75730cr3", - "name": "8ZtJeCnKwMAcEUBU0QvE7-desktop.webp", - "realName": "flow-penghasilan.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/8ZtJeCnKwMAcEUBU0QvE7-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nc438000dvn6q723r7phi", - "name": "Y7IuwpwjT3ZFYWpiXJZYw-desktop.webp", - "realName": "tidak mampu.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Y7IuwpwjT3ZFYWpiXJZYw-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nc4aa000evn6qwl5t53h4", - "name": "Fbi-6gnhokkwux9hvriS--desktop.webp", - "realName": "flow-tidak-mampu.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Fbi-6gnhokkwux9hvriS--desktop.webp", - "category": "image" - }, - { - "id": "cmk6ndw2z000fvn6q3b9wxswd", - "name": "qtdJ39rIbjGTJJQZflrDL-desktop.webp", - "realName": "kelahiran.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/qtdJ39rIbjGTJJQZflrDL-desktop.webp", - "category": "image" - }, - { - "id": "cmk6ndwbf000gvn6qusd4mkhq", - "name": "ldmfJBS2ZBhIda60yU2JW-desktop.webp", - "realName": "flow-kelahiran.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/ldmfJBS2ZBhIda60yU2JW-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nf4pu000hvn6qszs6xyp5", - "name": "CAtRFHiM11gsY4ExcvGgc-desktop.webp", - "realName": "usaha.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/CAtRFHiM11gsY4ExcvGgc-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nf53c000ivn6qawvoxndb", - "name": "MLWp-38kKygXKVekCh0q7-desktop.webp", - "realName": "flow-usaha.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/MLWp-38kKygXKVekCh0q7-desktop.webp", - "category": "image" - }, - { - "id": "cmk6ng6yk000jvn6q0ditzufj", - "name": "C0zE5lneKa888VJDHzgh--desktop.webp", - "realName": "kematian.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/C0zE5lneKa888VJDHzgh--desktop.webp", - "category": "image" - }, - { - "id": "cmk6ng77b000kvn6q51j2s4q7", - "name": "hhDK7OL0wQLik5dsh1a-L-desktop.webp", - "realName": "flow-kematian.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/hhDK7OL0wQLik5dsh1a-L-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nh7ez000lvn6qjfkqeufn", - "name": "sVIfCUGBplNU8h1x99l8z-desktop.webp", - "realName": "tempat-usaha.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/sVIfCUGBplNU8h1x99l8z-desktop.webp", - "category": "image" - }, - { - "id": "cmk6nh7pq000mvn6qor967hjh", - "name": "MM-1CZMai3eXwbVr2HAEv-desktop.webp", - "realName": "flow tempat usaha.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/MM-1CZMai3eXwbVr2HAEv-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n37tp0003vn6qqyvelh5s", - "name": "oNH9VvRPlAmTI_Ndu3slN-desktop.webp", - "realName": "kawin.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/oNH9VvRPlAmTI_Ndu3slN-desktop.webp", - "category": "image" - }, - { - "id": "cmk6n388d0004vn6qby5fkuz8", - "name": "Wze2x68vn-ShZAqgkSCMC-desktop.webp", - "realName": "flow belum kawin.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Wze2x68vn-ShZAqgkSCMC-desktop.webp", - "category": "image" - }, - { - "id": "cmk6mvhwh0001vn6qa6ddzqfm", - "name": "tK9T6BObEQEdYU-5y1xnJ-desktop.webp", - "realName": "kelakuan baik.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/tK9T6BObEQEdYU-5y1xnJ-desktop.webp", - "category": "image" - }, - { - "id": "cmk6mvi8c0002vn6q9vfyv6yt", - "name": "sX9yfcM05OOx2ELhcSNWl-desktop.webp", - "realName": "flow_kelakuan_baik.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/sX9yfcM05OOx2ELhcSNWl-desktop.webp", - "category": "image" - }, - { - "id": "cmkal9d2p0000vnexf8flpunj", - "name": "cte_gy0V8glhDcghMa3-B-desktop.webp", - "realName": "penghargaan1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/cte_gy0V8glhDcghMa3-B-desktop.webp", - "category": "image" - }, - { - "id": "cmkalfbsn0003vnex3bbsx5ja", - "name": "hLoy_DjB_3Yie2vjaXDYz-desktop.webp", - "realName": "penghargaan2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/hLoy_DjB_3Yie2vjaXDYz-desktop.webp", - "category": "image" - }, - { - "id": "cmkalg6fh0006vnexid4z9vlg", - "name": "VxELyZ0ifdHOdRFu7aBSz-desktop.webp", - "realName": "penghargaan3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/VxELyZ0ifdHOdRFu7aBSz-desktop.webp", - "category": "image" - }, - { - "id": "cmkalguac0009vnex5dpixivn", - "name": "xgrBxDdo8g7KA-3zNbRGj-desktop.webp", - "realName": "penghargaan4.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/xgrBxDdo8g7KA-3zNbRGj-desktop.webp", - "category": "image" - }, - { - "id": "cmkanjnfh0004vntz8cdbxa7f", - "name": "TDQReg1lQ73s39crXW0ra-desktop.webp", - "realName": "posyandu1.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/TDQReg1lQ73s39crXW0ra-desktop.webp", - "category": "image" - }, - { - "id": "cmkao2zm90007vntzxqkjy5mt", - "name": "d6hJgycQawWN3VEcHaqtR-desktop.webp", - "realName": "puskesmas.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/d6hJgycQawWN3VEcHaqtR-desktop.webp", - "category": "image" - }, - { - "id": "cmkatoru10000vny38y0wxd6s", - "name": "cg78Sb_QzZFlli9s2FPVc-desktop.webp", - "realName": "puskesmas2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/cg78Sb_QzZFlli9s2FPVc-desktop.webp", - "category": "image" - }, - { - "id": "cmkay1e590010vn6y24pgaa1r", - "name": "hLeF0GRFZqDUngZnDMAAk-desktop.webp", - "realName": "pk1.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/hLeF0GRFZqDUngZnDMAAk-desktop.webp", - "category": "image" - }, - { - "id": "cmkay6hob0011vn6ybjwejcej", - "name": "hyyTFi8EApjzFEZ9EvJgB-desktop.webp", - "realName": "pk2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/hyyTFi8EApjzFEZ9EvJgB-desktop.webp", - "category": "image" - }, - { - "id": "cmkay8vmd0012vn6ylsk2vzfo", - "name": "l4qsUEw2JiclGAkkrXp9g-desktop.webp", - "realName": "pk3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/l4qsUEw2JiclGAkkrXp9g-desktop.webp", - "category": "image" - }, - { - "id": "cmkayd8o90013vn6ye7n8805q", - "name": "Gc79mlIlGuoRQuTqskFj--desktop.webp", - "realName": "pk-4.jpeg", - "path": "uploads/images", + "name": "42RCCpBZla4ZWxXcwx7kG-desktop.webp", + "path": "image/42RCCpBZla4ZWxXcwx7kG-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d05a9e22-feac-4955-b1a2-75faad37f0ac/42RCCpBZla4ZWxXcwx7kG-desktop.webp", "mimeType": "image/webp", "link": "/api/fileStorage/findUnique/Gc79mlIlGuoRQuTqskFj--desktop.webp", "category": "image" + }, { - "id": "cmkayi0x90016vn6ykddxqyq3", - "name": "OsMY3AYPyGC_CoN1xUjOn-desktop.webp", - "realName": "posyandu1.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/OsMY3AYPyGC_CoN1xUjOn-desktop.webp", - "category": "image" + "name": "42RCCpBZla4ZWxXcwx7kG-mobile.webp", + "path": "image/42RCCpBZla4ZWxXcwx7kG-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c91212b5-7408-4ec9-b7c0-6c0fde2a9fc5/42RCCpBZla4ZWxXcwx7kG-mobile.webp" }, { - "id": "cmkaykipf0019vn6yknjno3k1", - "name": "M9QlgVKIEfCdY3g4F_tRZ-desktop.webp", - "realName": "pk6.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/M9QlgVKIEfCdY3g4F_tRZ-desktop.webp", - "category": "image" - }, - { - "id": "cmkayz2h8001cvn6yrb7uptjs", - "name": "Gi8EX3pBmT719AfzXirDS-desktop.webp", - "realName": "pd1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Gi8EX3pBmT719AfzXirDS-desktop.webp", - "category": "image" - }, - { - "id": "cmkawq38m0009vn6yi7evbhap", - "name": "v7Ac2xQvTiJy-HYh1AxF4-desktop.webp", - "realName": "posko-siaga.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/v7Ac2xQvTiJy-HYh1AxF4-desktop.webp", - "category": "image" - }, - { - "id": "cmkawso29000cvn6y879ahra0", - "name": "jYxEXspWH5g6eTTVqK72c-desktop.webp", - "realName": "ambulance.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/jYxEXspWH5g6eTTVqK72c-desktop.webp", - "category": "image" - }, - { - "id": "cmkawu7qj000fvn6yubhimyiv", - "name": "3tNQ9J8I3Ewq5H8CWuqvp-desktop.webp", - "realName": "penanganan darurat.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/3tNQ9J8I3Ewq5H8CWuqvp-desktop.webp", - "category": "image" - }, - { - "id": "cmkb6488i001fvn6ylkddch1j", - "name": "g4ICsRrmOaIqS_yqlQLZK-desktop.webp", - "realName": "puskesmas2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/g4ICsRrmOaIqS_yqlQLZK-desktop.webp", - "category": "image" - }, - { - "id": "cmkb681og001gvn6ykb5uasln", - "name": "1NkzPzQailqE5yNOiUjB9-desktop.webp", - "realName": "puskesmas.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/1NkzPzQailqE5yNOiUjB9-desktop.webp", - "category": "image" - }, - { - "id": "cmkb6brrf0000vn14u8c7wnox", - "name": "NBPAqjPXn7GQmYTDBI5hu-desktop.webp", - "realName": "kd3.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/NBPAqjPXn7GQmYTDBI5hu-desktop.webp", - "category": "image" - }, - { - "id": "cmkb6ehpi0001vn14hjp4tdye", - "name": "EcQIGOF6LW1dIKE53vmba-desktop.webp", - "realName": "kd4.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/EcQIGOF6LW1dIKE53vmba-desktop.webp", - "category": "image" - }, - { - "id": "cmkbynxxo0000vn67wi2nsyl3", - "name": "pps1ZgzJxDb4VZxEvtZeu-desktop.webp", - "realName": "infowp-1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/pps1ZgzJxDb4VZxEvtZeu-desktop.webp", - "category": "image" - }, - { - "id": "cmkbyr3mk0003vn673xrqv8xv", - "name": "JhJigMo269K1TFGzSB1OS-desktop.webp", - "realName": "infowp-2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/JhJigMo269K1TFGzSB1OS-desktop.webp", - "category": "image" - }, - { - "id": "cmkax3o8g000rvn6ygqpmo1nb", - "name": "5giLSHSnWEFoZoMEcjhL7-desktop.webp", - "realName": "diare.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/5giLSHSnWEFoZoMEcjhL7-desktop.webp", - "category": "image" - }, - { - "id": "cmkax5ukz000uvn6yho3aj2nf", - "name": "3faPo-1wjhVDVU6S7S8sS-desktop.webp", - "realName": "tbc.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/3faPo-1wjhVDVU6S7S8sS-desktop.webp", - "category": "image" - }, - { - "id": "cmkax72nw000xvn6ymcuvlzom", - "name": "DyX82oztXbHfu6HEvbrpt-desktop.webp", - "realName": "dbd.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/DyX82oztXbHfu6HEvbrpt-desktop.webp", - "category": "image" - }, - { - "id": "cmkc2tcn30000vnt9esmx8kyb", - "name": "K0wY911212dinYA3AFB_f-desktop.webp", - "realName": "keamananl-1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/K0wY911212dinYA3AFB_f-desktop.webp", - "category": "image" - }, - { - "id": "cmkc2xm1z0003vnt98682dv0a", - "name": "x0_-siY2V8IehBzo4_uph-desktop.webp", - "realName": "keamananl-2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/x0_-siY2V8IehBzo4_uph-desktop.webp", - "category": "image" - }, - { - "id": "cmkc36q2j0006vnt9g87h5it4", - "name": "TXknK9CSRSxwvM2hPW6BO-desktop.webp", - "realName": "pecalang.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/TXknK9CSRSxwvM2hPW6BO-desktop.webp", - "category": "image" - }, - { - "id": "cmkp70z5g0000vnu9b0aieem8", - "name": "vwZsaxcoFWDlxG1PW7FC0-desktop.webp", - "realName": "tips-keamanan-1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/vwZsaxcoFWDlxG1PW7FC0-desktop.webp", - "category": "image" - }, - { - "id": "cmkp71pub0003vnu9ef60huuv", - "name": "dSe0xyvNLkP2t2f6iq-Hk-desktop.webp", - "realName": "tipskaman.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/dSe0xyvNLkP2t2f6iq-Hk-desktop.webp", - "category": "image" - }, - { - "id": "cmkdu8kb20002vn4lihwo4k86", "name": "6DQbAvn0St-xHdPGW3vpY-desktop.webp", - "realName": "Jamban4.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/6DQbAvn0St-xHdPGW3vpY-desktop.webp", - "category": "image" + "path": "image/6DQbAvn0St-xHdPGW3vpY-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/68cc521e-05e5-4258-af8d-c87fb76c927e/6DQbAvn0St-xHdPGW3vpY-desktop.webp" }, { - "id": "cmkew56ls0000vnysrnzr9ttx", - "name": "YdCBnK-bWxlyHjwsk4Qie-desktop.webp", - "realName": "WarungPasar.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/YdCBnK-bWxlyHjwsk4Qie-desktop.webp", - "category": "image" + "name": "6DQbAvn0St-xHdPGW3vpY-mobile.webp", + "path": "image/6DQbAvn0St-xHdPGW3vpY-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/15f7ddd6-448c-4e4a-9b24-0bdc4bce5ce1/6DQbAvn0St-xHdPGW3vpY-mobile.webp" }, { - "id": "cmkewaa2s0001vnysvvs9tu56", - "name": "TWdNTZZbTOhFTNJGGPDyG-desktop.webp", - "realName": "JajananPasar.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/TWdNTZZbTOhFTNJGGPDyG-desktop.webp", - "category": "image" + "name": "buku1 (1).jpeg", + "path": "image/buku1 (1).jpeg", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d72b02a6-91f5-4d64-9729-521b306328d3/buku1%20%281%29.jpeg" }, { - "id": "cmkewcvfq0002vnys6985nm90", - "name": "mtQsaKtQnhxIYVIooCkiQ-desktop.webp", - "realName": "SayurSegar.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/mtQsaKtQnhxIYVIooCkiQ-desktop.webp", - "category": "image" + "name": "buku1.jpeg", + "path": "image/buku1.jpeg", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/912bd7e5-be8a-4c19-8ab8-df6114a38864/buku1.jpeg" }, { - "id": "cmkewf4u90003vnys87en35nj", - "name": "Ez-SkRyf_F-1gksz_amNg-desktop.webp", - "realName": "AyamDaging.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Ez-SkRyf_F-1gksz_amNg-desktop.webp", - "category": "image" + "name": "buku6.jpg", + "path": "image/buku6.jpg", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/ea56bc7c-094b-464e-859a-6c65bf65361d/buku6.jpg" }, { - "id": "cmkksb3jr0005vni4sp3ogr87", - "name": "r_gBF0FuFpFPfSENHc4XI-desktop.webp", - "realName": "desa-digital.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/r_gBF0FuFpFPfSENHc4XI-desktop.webp", - "category": "image" - }, - { - "id": "cmkksoze80008vni4ki2ry81r", - "name": "uE2QwpbcXyBWxVYqCWQQT-desktop.webp", - "realName": "Digital2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/uE2QwpbcXyBWxVYqCWQQT-desktop.webp", - "category": "image" - }, - { - "id": "cmkkx9e38000bvni4azjd3u53", - "name": "SQqSobKRg3ShvgPw_H41h-desktop.webp", - "realName": "pengaduan1.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/SQqSobKRg3ShvgPw_H41h-desktop.webp", - "category": "image" - }, - { - "id": "cmkkxep9l000evni4xkegbk72", - "name": "gyNi4s8TnK2UrViU-gN2C-desktop.webp", - "realName": "pd2.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/gyNi4s8TnK2UrViU-gN2C-desktop.webp", - "category": "image" - }, - { - "id": "cmkky60sq0000vnjjc55k84d2", - "name": "y78xZ2axTOjz87gRKjVAf-desktop.webp", - "realName": "penanganan-sampah-rumah-tangga-di-desa copy.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/y78xZ2axTOjz87gRKjVAf-desktop.webp", - "category": "image" - }, - { - "id": "cmkm0w0my0001vnswthy6ihaw", - "name": "SVeScDA6-OAVvGoAfNC0c-desktop.webp", - "realName": "desadg1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/SVeScDA6-OAVvGoAfNC0c-desktop.webp", - "category": "image" - }, - { - "id": "cmkm0z9hx0004vnswtjd2bk3z", - "name": "kN09yF3sahmy-d5EaeGqA-desktop.webp", - "realName": "desadg1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/kN09yF3sahmy-d5EaeGqA-desktop.webp", - "category": "image" - }, - { - "id": "cmkm1a14d0005vnsww1tsd92o", "name": "c7xWNyoYp8Cak28NG5NoG-desktop.webp", - "realName": "desadg2.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/c7xWNyoYp8Cak28NG5NoG-desktop.webp", - "category": "image" + "path": "image/c7xWNyoYp8Cak28NG5NoG-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d84fb066-4352-44f0-b7bc-5d8c5b8ffb61/c7xWNyoYp8Cak28NG5NoG-desktop.webp" + }, + { + "name": "c7xWNyoYp8Cak28NG5NoG-mobile.webp", + "path": "image/c7xWNyoYp8Cak28NG5NoG-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/9fb1c742-9a80-4788-9c73-9d06108e0051/c7xWNyoYp8Cak28NG5NoG-mobile.webp" + }, + { + "name": "cg78Sb_QzZFlli9s2FPVc-mobile.webp", + "path": "image/cg78Sb_QzZFlli9s2FPVc-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c5a2cd18-806d-4dcb-b5c5-b0c6bcef7f35/cg78Sb_QzZFlli9s2FPVc-mobile.webp" + }, + { + "name": "d3v1AgLoSJhf5xvmmO3oP-mobile.webp", + "path": "image/d3v1AgLoSJhf5xvmmO3oP-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/ae72c51f-9df7-4b07-9fd5-e945c775d9ab/d3v1AgLoSJhf5xvmmO3oP-mobile.webp" + }, + { + "name": "d6hJgycQawWN3VEcHaqtR-desktop.webp", + "path": "image/d6hJgycQawWN3VEcHaqtR-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/4e5b9387-67b5-4c00-8f80-95ec6c54ff4a/d6hJgycQawWN3VEcHaqtR-desktop.webp" + }, + { + "name": "d6hJgycQawWN3VEcHaqtR-mobile.webp", + "path": "image/d6hJgycQawWN3VEcHaqtR-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/011f65c9-4273-43e8-b6d7-ce7a5319ae83/d6hJgycQawWN3VEcHaqtR-mobile.webp" + }, + { + "name": "DyX82oztXbHfu6HEvbrpt-desktop.webp", + "path": "image/DyX82oztXbHfu6HEvbrpt-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/b715dce5-1606-44cf-976f-57d8142e218e/DyX82oztXbHfu6HEvbrpt-desktop.webp" + }, + { + "name": "DyX82oztXbHfu6HEvbrpt-mobile.webp", + "path": "image/DyX82oztXbHfu6HEvbrpt-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d0ff5925-ec84-4100-920c-93e2eb479f13/DyX82oztXbHfu6HEvbrpt-mobile.webp" + }, + { + "name": "EcQIGOF6LW1dIKE53vmba-desktop.webp", + "path": "image/EcQIGOF6LW1dIKE53vmba-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/7a97403e-9d6c-4a00-9c54-d5add0bd5915/EcQIGOF6LW1dIKE53vmba-desktop.webp" + }, + { + "name": "EcQIGOF6LW1dIKE53vmba-mobile.webp", + "path": "image/EcQIGOF6LW1dIKE53vmba-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/7e85b8e8-27f5-46c7-b4fc-590d66eef2ce/EcQIGOF6LW1dIKE53vmba-mobile.webp" + }, + { + "name": "Ez-SkRyf_F-1gksz_amNg-desktop.webp", + "path": "image/Ez-SkRyf_F-1gksz_amNg-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c16de343-1297-4248-b104-83b3e3605f32/Ez-SkRyf_F-1gksz_amNg-desktop.webp" + }, + { + "name": "Ez-SkRyf_F-1gksz_amNg-mobile.webp", + "path": "image/Ez-SkRyf_F-1gksz_amNg-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/ece148ca-8aa1-43ef-a8de-ea0bde0a315a/Ez-SkRyf_F-1gksz_amNg-mobile.webp" + }, + { + "name": "g4ICsRrmOaIqS_yqlQLZK-desktop.webp", + "path": "image/g4ICsRrmOaIqS_yqlQLZK-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/31280b01-6cdb-4d96-9c96-0eecec6a238c/g4ICsRrmOaIqS_yqlQLZK-desktop.webp" + }, + { + "name": "g4ICsRrmOaIqS_yqlQLZK-mobile.webp", + "path": "image/g4ICsRrmOaIqS_yqlQLZK-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/af7f3e11-1f63-4307-88e9-64382a949279/g4ICsRrmOaIqS_yqlQLZK-mobile.webp" + }, + { + "name": "Gc79mlIlGuoRQuTqskFj--desktop.webp", + "path": "image/Gc79mlIlGuoRQuTqskFj--desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/05214122-51bb-4fba-9b7c-f69e072d8a0d/Gc79mlIlGuoRQuTqskFj--desktop.webp" + }, + { + "name": "Gc79mlIlGuoRQuTqskFj--mobile.webp", + "path": "image/Gc79mlIlGuoRQuTqskFj--mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d49ab5d2-7087-4088-8e59-51f116f21e27/Gc79mlIlGuoRQuTqskFj--mobile.webp" + }, + { + "name": "Gi8EX3pBmT719AfzXirDS-desktop.webp", + "path": "image/Gi8EX3pBmT719AfzXirDS-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/4b456bad-228a-4211-a1bb-431dc081ecc7/Gi8EX3pBmT719AfzXirDS-desktop.webp" + }, + { + "name": "Gi8EX3pBmT719AfzXirDS-mobile.webp", + "path": "image/Gi8EX3pBmT719AfzXirDS-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/68308100-d468-4e53-9cc6-3aa12035c8ab/Gi8EX3pBmT719AfzXirDS-mobile.webp" + }, + { + "name": "gyNi4s8TnK2UrViU-gN2C-desktop.webp", + "path": "image/gyNi4s8TnK2UrViU-gN2C-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/539debe4-f3fc-4574-a256-ac8c8dbf5a00/gyNi4s8TnK2UrViU-gN2C-desktop.webp" + }, + { + "name": "gyNi4s8TnK2UrViU-gN2C-mobile.webp", + "path": "image/gyNi4s8TnK2UrViU-gN2C-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/4971a22a-c0dd-4492-bff5-a8aa3e93f27f/gyNi4s8TnK2UrViU-gN2C-mobile.webp" }, { - "id": "cmkm1c8py0008vnsw0unbxkpq", "name": "h_Gd0SoeIJVTi_5TWUO-P-desktop.webp", - "realName": "desadg3.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/h_Gd0SoeIJVTi_5TWUO-P-desktop.webp", - "category": "image" + "path": "image/h_Gd0SoeIJVTi_5TWUO-P-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/8409886e-c01b-421a-ac44-6d3a4bfd0985/h_Gd0SoeIJVTi_5TWUO-P-desktop.webp" }, { - "id": "cmkm1zis2000bvnsw85m6wdlf", - "name": "qJFWokQLCaO60j0XJU_33-desktop.webp", - "realName": "mitrakl1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/qJFWokQLCaO60j0XJU_33-desktop.webp", - "category": "image" + "name": "h_Gd0SoeIJVTi_5TWUO-P-mobile.webp", + "path": "image/h_Gd0SoeIJVTi_5TWUO-P-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/f4a5280d-bd2d-4c5a-8040-183f9e5d951b/h_Gd0SoeIJVTi_5TWUO-P-mobile.webp" }, { - "id": "cmkm2dgif000evnswskk0dfo9", - "name": "nzLJoEAfl7HkpUcYa8Y1E-desktop.webp", - "realName": "mitrak2.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/nzLJoEAfl7HkpUcYa8Y1E-desktop.webp", - "category": "image" + "name": "hLeF0GRFZqDUngZnDMAAk-desktop.webp", + "path": "image/hLeF0GRFZqDUngZnDMAAk-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/6b33097e-8d9d-4864-964b-6dc49b62b4ae/hLeF0GRFZqDUngZnDMAAk-desktop.webp" }, { - "id": "cmkm2fzub000hvnswnvoytlzs", - "name": "JFd5C2FoaZcgDQUmvp-AO-desktop.webp", - "realName": "mitrakl3.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/JFd5C2FoaZcgDQUmvp-AO-desktop.webp", - "category": "image" + "name": "hLeF0GRFZqDUngZnDMAAk-mobile.webp", + "path": "image/hLeF0GRFZqDUngZnDMAAk-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/7dff816b-65bb-429c-b87e-3ff892d547dc/hLeF0GRFZqDUngZnDMAAk-mobile.webp" }, { - "id": "cmkm3b1a2000nvnswb9x48dzk", - "name": "JjUDrfqxuEMYSAza-s7A8-desktop.webp", - "realName": "desa-digital.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/JjUDrfqxuEMYSAza-s7A8-desktop.webp", - "category": "image" + "name": "hsHiD59dZQxr8G2SAfUYp-mobile.webp", + "path": "image/hsHiD59dZQxr8G2SAfUYp-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/55103cd4-6f57-491d-bd41-03c0068974ef/hsHiD59dZQxr8G2SAfUYp-mobile.webp" }, { - "id": "cmkm3bnkt000qvnswzhqa4upf", - "name": "xVrwJgdwtcoABPU6DB__Y-desktop.webp", - "realName": "Digital2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/xVrwJgdwtcoABPU6DB__Y-desktop.webp", - "category": "image" + "name": "hyyTFi8EApjzFEZ9EvJgB-desktop.webp", + "path": "image/hyyTFi8EApjzFEZ9EvJgB-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/0ec4a67e-695e-4524-bf22-f823b80c7e6b/hyyTFi8EApjzFEZ9EvJgB-desktop.webp" }, { - "id": "cmkm3fwg4000rvnsw5d1vbiz0", - "name": "42RCCpBZla4ZWxXcwx7kG-desktop.webp", - "realName": "infotek3-1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/42RCCpBZla4ZWxXcwx7kG-desktop.webp", - "category": "image" + "name": "hyyTFi8EApjzFEZ9EvJgB-mobile.webp", + "path": "image/hyyTFi8EApjzFEZ9EvJgB-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c982541e-f8b2-455a-a3cd-f856cd954bed/hyyTFi8EApjzFEZ9EvJgB-mobile.webp" }, { - "id": "cmkm3hjhz000uvnswwqu6z9f6", - "name": "TrbkwnYM5rKZeHlISHCX4-desktop.webp", - "realName": "infotek4.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/TrbkwnYM5rKZeHlISHCX4-desktop.webp", - "category": "image" + "name": "isTT2LmPbeOWD5wAdqleX-mobile.webp", + "path": "image/isTT2LmPbeOWD5wAdqleX-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/ef6f8237-0803-422a-83af-4daca61c7065/isTT2LmPbeOWD5wAdqleX-mobile.webp" }, { - "id": "cmknb59md0000vnmam828iuzt", - "name": "YgOX5qAP3O1PHG5XmQXkr-desktop.webp", - "realName": "gr-1.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/YgOX5qAP3O1PHG5XmQXkr-desktop.webp", - "category": "image" + "name": "JhJigMo269K1TFGzSB1OS-desktop.webp", + "path": "image/JhJigMo269K1TFGzSB1OS-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/668d2f32-3277-4842-8a01-c3cb5ca0852b/JhJigMo269K1TFGzSB1OS-desktop.webp" }, { - "id": "cmknbp3vd0001vnmarjz542o7", - "name": "qxqSDHe-akIRi1EkQFUbG-desktop.webp", - "realName": "gr-2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/qxqSDHe-akIRi1EkQFUbG-desktop.webp", - "category": "image" + "name": "JhJigMo269K1TFGzSB1OS-mobile.webp", + "path": "image/JhJigMo269K1TFGzSB1OS-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/df8c52a3-189a-48a0-b7e7-98efe2479414/JhJigMo269K1TFGzSB1OS-mobile.webp" }, { - "id": "cmknbrj4r0002vnmantw9rn0l", - "name": "iHTVkQZ1VdkMOXLt5qdAd-desktop.webp", - "realName": "gr-3.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/iHTVkQZ1VdkMOXLt5qdAd-desktop.webp", - "category": "image" + "name": "jYxEXspWH5g6eTTVqK72c-desktop.webp", + "path": "image/jYxEXspWH5g6eTTVqK72c-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/a13572b4-2e22-4d76-8826-64a8e6ae4e13/jYxEXspWH5g6eTTVqK72c-desktop.webp" }, { - "id": "cmkqhbhxi0000vneamj3din9u", - "name": "RnAdv7O0QAFrxkFLAXJSa-desktop.webp", - "realName": "buku1.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/RnAdv7O0QAFrxkFLAXJSa-desktop.webp", - "category": "image" + "name": "jYxEXspWH5g6eTTVqK72c-mobile.webp", + "path": "image/jYxEXspWH5g6eTTVqK72c-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/55f171fa-585f-4a94-bfeb-d2bad2f7ee39/jYxEXspWH5g6eTTVqK72c-mobile.webp" }, { - "id": "cmkqhed8x0003vneakx0c7me2", - "name": "71eZShq4FYAFLxpLfZB0W-desktop.webp", - "realName": "buku2.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/71eZShq4FYAFLxpLfZB0W-desktop.webp", - "category": "image" + "name": "K0wY911212dinYA3AFB_f-desktop.webp", + "path": "image/K0wY911212dinYA3AFB_f-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/31ea22bf-9ce1-4dc6-b901-caaec86c35c4/K0wY911212dinYA3AFB_f-desktop.webp" }, { - "id": "cmkqhg1cb0006vneagsxa6t4t", - "name": "Uxq3GXPqh7HN9fHmRkr3r-desktop.webp", - "realName": "buku3.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Uxq3GXPqh7HN9fHmRkr3r-desktop.webp", - "category": "image" + "name": "K0wY911212dinYA3AFB_f-mobile.webp", + "path": "image/K0wY911212dinYA3AFB_f-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/ea061aa6-7e5e-447c-bec8-be1d927cc578/K0wY911212dinYA3AFB_f-mobile.webp" }, { - "id": "cmkqhl6mv0009vneasgix42ud", - "name": "W5Fc0uRADNkIY3nZicvQA-desktop.webp", - "realName": "buku4.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/W5Fc0uRADNkIY3nZicvQA-desktop.webp", - "category": "image" + "name": "l4qsUEw2JiclGAkkrXp9g-desktop.webp", + "path": "image/l4qsUEw2JiclGAkkrXp9g-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/05088eb1-44bc-44d6-9e67-08dd6bca00ae/l4qsUEw2JiclGAkkrXp9g-desktop.webp" }, { - "id": "cmkqhoa5w000cvneah15n28zq", - "name": "mp77Op-MwtPQZnH3so4JY-desktop.webp", - "realName": "buku5.jpeg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/mp77Op-MwtPQZnH3so4JY-desktop.webp", - "category": "image" + "name": "l4qsUEw2JiclGAkkrXp9g-mobile.webp", + "path": "image/l4qsUEw2JiclGAkkrXp9g-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/cf411a77-b7fc-4ac7-a98d-f9f89bc27e85/l4qsUEw2JiclGAkkrXp9g-mobile.webp" }, { - "id": "cmkqhr9lg000fvneai3q8qw0s", - "name": "V09ZxN1wOwbSFLQiDK0VQ-desktop.webp", - "realName": "buku6.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/V09ZxN1wOwbSFLQiDK0VQ-desktop.webp", - "category": "image" + "name": "M9QlgVKIEfCdY3g4F_tRZ-desktop.webp", + "path": "image/M9QlgVKIEfCdY3g4F_tRZ-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/dfa58064-c17b-453a-b0a1-613109757844/M9QlgVKIEfCdY3g4F_tRZ-desktop.webp" }, { - "id": "cmkqi5knc000ivnea8grp7j06", - "name": "Wqp4AyVkGjqRMED9Q5XAs-desktop.webp", - "realName": "buku7.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/Wqp4AyVkGjqRMED9Q5XAs-desktop.webp", - "category": "image" + "name": "M9QlgVKIEfCdY3g4F_tRZ-mobile.webp", + "path": "image/M9QlgVKIEfCdY3g4F_tRZ-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/4be366ca-1a39-46e9-adf2-d1d28fd83961/M9QlgVKIEfCdY3g4F_tRZ-mobile.webp" }, { - "id": "cmkqi9799000lvneamskmvpq5", - "name": "NH4aLc7cVuutdQBCofTC0-desktop.webp", - "realName": "buku8.webp", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/NH4aLc7cVuutdQBCofTC0-desktop.webp", - "category": "image" + "name": "mtQsaKtQnhxIYVIooCkiQ-desktop.webp", + "path": "image/mtQsaKtQnhxIYVIooCkiQ-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/5015a484-ac9a-485f-9fb0-a29e3824a6ce/mtQsaKtQnhxIYVIooCkiQ-desktop.webp" }, { - "id": "cmkqibjj2000ovnea3zmmvdop", - "name": "MLrsPrD6oiHsrNP4Lc8J7-desktop.webp", - "realName": "buku9.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/MLrsPrD6oiHsrNP4Lc8J7-desktop.webp", - "category": "image" + "name": "mtQsaKtQnhxIYVIooCkiQ-mobile.webp", + "path": "image/mtQsaKtQnhxIYVIooCkiQ-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/10ddd132-5b85-4a8f-b129-56a10540fc8c/mtQsaKtQnhxIYVIooCkiQ-mobile.webp" }, { - "id": "cmkqidn7e000rvnea5rl58f2e", - "name": "iaIeNdhuxqltqKP7aZncQ-desktop.webp", - "realName": "buku10.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/iaIeNdhuxqltqKP7aZncQ-desktop.webp", - "category": "image" + "name": "NBPAqjPXn7GQmYTDBI5hu-desktop.webp", + "path": "image/NBPAqjPXn7GQmYTDBI5hu-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/fd8cfea3-5cf2-489e-9f21-e7985335dc98/NBPAqjPXn7GQmYTDBI5hu-desktop.webp" }, { - "id": "cmkqifdfs000uvneajss8zswp", - "name": "WUDssJ59pTKE_3IuTiZ2s-desktop.webp", - "realName": "buku11.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/WUDssJ59pTKE_3IuTiZ2s-desktop.webp", - "category": "image" + "name": "NBPAqjPXn7GQmYTDBI5hu-mobile.webp", + "path": "image/NBPAqjPXn7GQmYTDBI5hu-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/f5b02049-95db-4e1b-8bfd-b1a4c431ee49/NBPAqjPXn7GQmYTDBI5hu-mobile.webp" }, { - "id": "cmkqik7p5000xvnea6krii3vw", - "name": "RJH_-4_R_nlP7GVEQeD1M-desktop.webp", - "realName": "buku13.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/RJH_-4_R_nlP7GVEQeD1M-desktop.webp", - "category": "image" + "name": "NyPGo-1AtfNm5wkAq7Om6-mobile.webp", + "path": "image/NyPGo-1AtfNm5wkAq7Om6-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/b7361eb8-37e8-4baa-a6d6-01b6131dd788/NyPGo-1AtfNm5wkAq7Om6-mobile.webp" }, { - "id": "cmkqinnih0010vneakpjb9egl", - "name": "9MA-Jx_36uoho2Tg40_G9-desktop.webp", - "realName": "buku14.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/9MA-Jx_36uoho2Tg40_G9-desktop.webp", - "category": "image" + "name": "OsMY3AYPyGC_CoN1xUjOn-desktop.webp", + "path": "image/OsMY3AYPyGC_CoN1xUjOn-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/509a3603-5d11-4857-baa5-d439da43825a/OsMY3AYPyGC_CoN1xUjOn-desktop.webp" }, { - "id": "cmkqiqeb60013vnea2ygrq5rs", - "name": "dkb7ZWFl28TREVcvH8sWd-desktop.webp", - "realName": "buku15.png", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/dkb7ZWFl28TREVcvH8sWd-desktop.webp", - "category": "image" + "name": "OsMY3AYPyGC_CoN1xUjOn-mobile.webp", + "path": "image/OsMY3AYPyGC_CoN1xUjOn-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/cbe9798a-4cf0-45f7-b041-70269490128b/OsMY3AYPyGC_CoN1xUjOn-mobile.webp" }, { - "id": "cmkqiur960016vnea3werdoey", - "name": "nVj3one6CLuWRd04QnsWo-desktop.webp", - "realName": "buku16.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/nVj3one6CLuWRd04QnsWo-desktop.webp", - "category": "image" + "name": "pps1ZgzJxDb4VZxEvtZeu-desktop.webp", + "path": "image/pps1ZgzJxDb4VZxEvtZeu-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/500fa1f3-d412-4f48-bc5f-465b91149c6e/pps1ZgzJxDb4VZxEvtZeu-desktop.webp" }, { - "id": "cmkqix2go0019vnea8coousvn", - "name": "AnB7JO4_6tlPTX3ypOVLi-desktop.webp", - "realName": "buku17.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/AnB7JO4_6tlPTX3ypOVLi-desktop.webp", - "category": "image" + "name": "pps1ZgzJxDb4VZxEvtZeu-mobile.webp", + "path": "image/pps1ZgzJxDb4VZxEvtZeu-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/19c2b1a6-8c9b-4be9-981c-72d7a3ab6e38/pps1ZgzJxDb4VZxEvtZeu-mobile.webp" }, { - "id": "cmkqiytnv001cvnea7o2sv1vt", - "name": "sAyoMERxL6JgFfiO22KPb-desktop.webp", - "realName": "buku18.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/sAyoMERxL6JgFfiO22KPb-desktop.webp", - "category": "image" + "name": "r_gBF0FuFpFPfSENHc4XI-desktop.webp", + "path": "image/r_gBF0FuFpFPfSENHc4XI-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/2e4ab451-df52-4f04-8af0-db2e789e58bb/r_gBF0FuFpFPfSENHc4XI-desktop.webp" }, { - "id": "cmkqj0nn0001fvneaufur3nke", - "name": "WeA-JP2Ks_32fv1k529vj-desktop.webp", - "realName": "buku18.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/WeA-JP2Ks_32fv1k529vj-desktop.webp", - "category": "image" + "name": "r_gBF0FuFpFPfSENHc4XI-mobile.webp", + "path": "image/r_gBF0FuFpFPfSENHc4XI-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/1e2e8884-9da3-4610-9c57-8925740d4128/r_gBF0FuFpFPfSENHc4XI-mobile.webp" }, { - "id": "cmkqj37rg001ivneam29fgayr", - "name": "pxlHu2kDmIprQqC2PuXaL-desktop.webp", - "realName": "buku19.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/pxlHu2kDmIprQqC2PuXaL-desktop.webp", - "category": "image" + "name": "SQqSobKRg3ShvgPw_H41h-desktop.webp", + "path": "image/SQqSobKRg3ShvgPw_H41h-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/4360cb84-f82a-4a68-afd3-65decd912f30/SQqSobKRg3ShvgPw_H41h-desktop.webp" }, { - "id": "cmkqj5ql6001lvnea6p0afr9f", - "name": "G0iELZb2DhQDCCP5OdzJR-desktop.webp", - "realName": "buku20.jpg", - "path": "uploads/images", - "mimeType": "image/webp", - "link": "/api/fileStorage/findUnique/G0iELZb2DhQDCCP5OdzJR-desktop.webp", - "category": "image" + "name": "SQqSobKRg3ShvgPw_H41h-mobile.webp", + "path": "image/SQqSobKRg3ShvgPw_H41h-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c808dff8-2e8a-4358-af03-4a838c9a6d6c/SQqSobKRg3ShvgPw_H41h-mobile.webp" + }, + { + "name": "TDQReg1lQ73s39crXW0ra-desktop.webp", + "path": "image/TDQReg1lQ73s39crXW0ra-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/04d15638-31ed-440f-9fa0-bb30d71bbc59/TDQReg1lQ73s39crXW0ra-desktop.webp" + }, + { + "name": "TDQReg1lQ73s39crXW0ra-mobile.webp", + "path": "image/TDQReg1lQ73s39crXW0ra-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/da174313-329c-4156-88e2-fc929325dfff/TDQReg1lQ73s39crXW0ra-mobile.webp" + }, + { + "name": "TTur8BttDlAS9UgZVe3M8-desktop.webp", + "path": "image/TTur8BttDlAS9UgZVe3M8-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/32fe30ab-0d7b-4ada-8d5d-993baf23545c/TTur8BttDlAS9UgZVe3M8-desktop.webp" + }, + { + "name": "TTur8BttDlAS9UgZVe3M8-mobile.webp", + "path": "image/TTur8BttDlAS9UgZVe3M8-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/85c5ecb0-2fb5-4431-af11-0c851e52de4e/TTur8BttDlAS9UgZVe3M8-mobile.webp" + }, + { + "name": "TWdNTZZbTOhFTNJGGPDyG-desktop.webp", + "path": "image/TWdNTZZbTOhFTNJGGPDyG-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d606d946-fdf9-41b9-b0bd-1421b2ec6843/TWdNTZZbTOhFTNJGGPDyG-desktop.webp" + }, + { + "name": "TWdNTZZbTOhFTNJGGPDyG-mobile.webp", + "path": "image/TWdNTZZbTOhFTNJGGPDyG-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/46859e6a-ebfc-4124-adfe-320953256fe5/TWdNTZZbTOhFTNJGGPDyG-mobile.webp" + }, + { + "name": "TXknK9CSRSxwvM2hPW6BO-desktop.webp", + "path": "image/TXknK9CSRSxwvM2hPW6BO-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/af38b038-0d38-4222-be29-09cb81054ce7/TXknK9CSRSxwvM2hPW6BO-desktop.webp" + }, + { + "name": "TXknK9CSRSxwvM2hPW6BO-mobile.webp", + "path": "image/TXknK9CSRSxwvM2hPW6BO-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/eab1c384-aafa-438f-ac0f-003ddd51c9a5/TXknK9CSRSxwvM2hPW6BO-mobile.webp" + }, + { + "name": "U7rePDZq5E59z-Eo9tLBe-desktop.webp", + "path": "image/U7rePDZq5E59z-Eo9tLBe-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/a2858ed9-8bb6-47cd-9e1b-831928a0389f/U7rePDZq5E59z-Eo9tLBe-desktop.webp" + }, + { + "name": "U7rePDZq5E59z-Eo9tLBe-mobile.webp", + "path": "image/U7rePDZq5E59z-Eo9tLBe-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/1f4a189d-d312-46ef-a68c-c0c7261860d0/U7rePDZq5E59z-Eo9tLBe-mobile.webp" + }, + { + "name": "uDxAalFV0qRv_RrW9flM8-mobile.webp", + "path": "image/uDxAalFV0qRv_RrW9flM8-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/5f006c3c-47f5-4e48-8bdd-7fbe005bf810/uDxAalFV0qRv_RrW9flM8-mobile.webp" + }, + { + "name": "uE2QwpbcXyBWxVYqCWQQT-desktop.webp", + "path": "image/uE2QwpbcXyBWxVYqCWQQT-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/edf73617-214b-44df-960a-dd68f0bad97a/uE2QwpbcXyBWxVYqCWQQT-desktop.webp" + }, + { + "name": "uE2QwpbcXyBWxVYqCWQQT-mobile.webp", + "path": "image/uE2QwpbcXyBWxVYqCWQQT-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/d7f5d738-b18f-44c8-92bb-8e526f47d9ee/uE2QwpbcXyBWxVYqCWQQT-mobile.webp" + }, + { + "name": "v7Ac2xQvTiJy-HYh1AxF4-desktop.webp", + "path": "image/v7Ac2xQvTiJy-HYh1AxF4-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/3e1b8dd9-2bf5-4daf-9dd9-dd687e9b2f2c/v7Ac2xQvTiJy-HYh1AxF4-desktop.webp" + }, + { + "name": "v7Ac2xQvTiJy-HYh1AxF4-mobile.webp", + "path": "image/v7Ac2xQvTiJy-HYh1AxF4-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/44c78026-f802-46f3-8ec2-271f0f001f7a/v7Ac2xQvTiJy-HYh1AxF4-mobile.webp" + }, + { + "name": "wh79hF4HTZMEFtYc-OfZg-mobile.webp", + "path": "image/wh79hF4HTZMEFtYc-OfZg-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/b4b4378e-76ad-4b15-84cf-00178553b3d4/wh79hF4HTZMEFtYc-OfZg-mobile.webp" + }, + { + "name": "x0_-siY2V8IehBzo4_uph-desktop.webp", + "path": "image/x0_-siY2V8IehBzo4_uph-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/7f82bcea-e7c6-4cde-9701-8d3afe49c0f8/x0_-siY2V8IehBzo4_uph-desktop.webp" + }, + { + "name": "x0_-siY2V8IehBzo4_uph-mobile.webp", + "path": "image/x0_-siY2V8IehBzo4_uph-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/c4b23ebc-3915-4102-a25c-4e2f6da0d097/x0_-siY2V8IehBzo4_uph-mobile.webp" + }, + { + "name": "y78xZ2axTOjz87gRKjVAf-desktop.webp", + "path": "image/y78xZ2axTOjz87gRKjVAf-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/180d0c29-c93e-4bbe-b399-7e6a34fbeb49/y78xZ2axTOjz87gRKjVAf-desktop.webp" + }, + { + "name": "y78xZ2axTOjz87gRKjVAf-mobile.webp", + "path": "image/y78xZ2axTOjz87gRKjVAf-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/71b5091a-ebcd-4d4c-9aae-1b7e548051fc/y78xZ2axTOjz87gRKjVAf-mobile.webp" + }, + { + "name": "YdCBnK-bWxlyHjwsk4Qie-desktop.webp", + "path": "image/YdCBnK-bWxlyHjwsk4Qie-desktop.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/bf6f2e11-b328-4da1-bda7-81af2336d03f/YdCBnK-bWxlyHjwsk4Qie-desktop.webp" + }, + { + "name": "YdCBnK-bWxlyHjwsk4Qie-mobile.webp", + "path": "image/YdCBnK-bWxlyHjwsk4Qie-mobile.webp", + "downloadUrl": "https://cld-dkr-makuro-seafile.wibudev.com/seafhttp/files/9d7e5232-3b30-4ead-9482-1fed3a86245a/YdCBnK-bWxlyHjwsk4Qie-mobile.webp" } ] diff --git a/prisma/data/landing-page/prestasi-desa/prestasi-desa.json b/prisma/data/landing-page/prestasi-desa/prestasi-desa.json index ac9d67ad..645964d7 100644 --- a/prisma/data/landing-page/prestasi-desa/prestasi-desa.json +++ b/prisma/data/landing-page/prestasi-desa/prestasi-desa.json @@ -4,27 +4,27 @@ "name": "Desa Darmasaba Raih Juara 1 Lomba Desa Tingkat Provinsi Bali Tahun 2025", "deskripsi": "

Pemerintah Desa Darmasaba meraih prestasi gemilang dengan menyabet Juara 1 Lomba Desa Tingkat Provinsi Bali Tahun 2025 dalam Peringatan Hari Jadi Pemerintah Provinsi Bali ke-67. Inovasi pelayanan publik dan sinergi masyarakat menjadi kunci keberhasilan.

", "kategoriId": "cmdwrp0pr0002vnd35w6nkjh0", - "imageId": "cmkamki230003vntzg25voz53" + "imageName": "_CIAQk1Yem-_6LFjrkmVg-mobile.webp" }, { "id": "cmdwrzs740008vnd329ysez5x", "name": "Desa Darmasaba Raih Juara 1 Lomba Desa Tingkat Kabupaten Badung Tahun 2025", "deskripsi": "

Desa Darmasaba berhasil meraih Juara 1 Lomba Desa Tingkat Kabupaten Badung Tahun 2025 yang diserahkan langsung oleh Bupati Badung dalam rangka memperingati HUT RI ke-80. Prestasi ini menjadi simbol kerja keras dan inovasi desa.

", "kategoriId": "cmdwrp0pr0002vnd35w6nkjh0", - "imageId": "cmkamkb150002vntzklhz9ryx" + "imageName": "pxpQFGBkTRpFOwJFTwjbD-mobile.webp" }, { "id": "cmdwrrxkh0005vnd3p5rxkiev", "name": "TPS3R Pudak Mesari Desa Darmasaba Raih Juara 2 dalam Kompetisi TPS3R Kabupaten Badung", "deskripsi": "

TPS3R Pudak Mesari Desa Darmasaba meraih Juara 2 dalam Kompetisi TPS3R tingkat Kabupaten Badung pada acara HUT Mangupura ke-16 sebagai wujud komitmen pengelolaan sampah berbasis masyarakat.

", "kategoriId": "cmdwrp0pr0002vnd35w6nkjh0", - "imageId": "cmkamk2cf0001vntzjg4rzqep" + "imageName": "3rshaPxCgk5unArWbKPpk-mobile.webp" }, { "id": "cmk3nxfkd0005vn9bcw8d10sh", "name": "Keluarga Sadar Hukum Desa Darmasaba Raih Prestasi Gemilang (Juara 3)", "deskripsi": "

KADARKUM Desa Darmasaba berhasil meraih Juara 3 dalam Lomba Keluarga Sadar Hukum Kabupaten Badung tahun 2024, bukti semangat kolaborasi masyarakat dengan perangkat desa dalam pendidikan hukum.

", "kategoriId": "cmdwrp0pr0002vnd35w6nkjh0", - "imageId": "cmkamji130000vntz3loca9q2" + "imageName": "D4za5fHh_y92Bj9qZkp5j-mobile.webp" } ] \ No newline at end of file diff --git a/prisma/data/landing-page/profile/mediaSosial.json b/prisma/data/landing-page/profile/mediaSosial.json index 3f0ba929..799990bb 100644 --- a/prisma/data/landing-page/profile/mediaSosial.json +++ b/prisma/data/landing-page/profile/mediaSosial.json @@ -3,24 +3,24 @@ "id": "cmds9023u0008vnbe3oxmhwyf", "name": "Desa Darmasaba", "iconUrl": "https://www.youtube.com/channel/UCtPw9WOQO7d2HIKzKgel4Xg", - "imageId": "cmk2cgqgm0003vn96jun52pik" + "imageName": "q1G995W7cLkC_qquLTlKN-mobile.webp" }, { "id": "cmds90oul000bvnbe2bqkptoi", "name": "Pemerintah Desa Darmasaba", "iconUrl": "https://www.facebook.com/DarmasabaDesaku", - "imageId": "cmk2cmr000006vn96qepq6gvl" + "imageName": "I6mlQ4nRmPX26gm79C_rM-mobile.webp" }, { "id": "cmds91i4e000evnbe8gtf1gub", "name": "ddarmasaba", "iconUrl": "https://www.instagram.com/ddarmasaba/", - "imageId": "cmk2cpeba0009vn966jcrpf3u" + "imageName": "WArLC_yvU33MjoqEnQeQ1-mobile.webp" }, { "id": "cmds92de5000hvnbemlu6sq5x", "name": "desa.darmasaba", "iconUrl": "https://www.tiktok.com/@desa.darmasaba?is_from_webapp=1&sender_device=pc", - "imageId": "cmk2crcl1000cvn96j8pmgmo5" + "imageName": "D3RPbNiaNSCjacLjeR_qO-mobile.webp" } ] diff --git a/prisma/data/landing-page/profile/profile.json b/prisma/data/landing-page/profile/profile.json index 1073354f..31cab010 100644 --- a/prisma/data/landing-page/profile/profile.json +++ b/prisma/data/landing-page/profile/profile.json @@ -3,6 +3,6 @@ "id": "edit", "name": "I.B Surya Prabhawa Manuaba, S.H., M.H.", "position": "Perbekel Darmasaba periode 2021-2027", - "imageId": "cmk2a2dl6001nvngck1n0k8qc" + "imageName": "Eqlrr1W-pK8ShMGqgPGL3-mobile.webp" } ] diff --git a/prisma/data/landing-page/profile/programInovasi.json b/prisma/data/landing-page/profile/programInovasi.json index 8cac1dd4..aadd4e79 100644 --- a/prisma/data/landing-page/profile/programInovasi.json +++ b/prisma/data/landing-page/profile/programInovasi.json @@ -4,55 +4,55 @@ "name": "Bares", "description": "

BARES (Darmasaba Recycling Waste Stock/Exchange) adalah Bursa Sampah yang merupakan sebuah sistem inovatif untuk mengelola dan menukar sampah daur ulang menjadi nilai ekonomis melalui TPS3R Pudak Mesari, dengan tujuan memberdayakan masyarakat dan menjaga kebersihan lingkungan, menjadikannya bagian dari upaya lebih besar seperti program desa pintar (smart village) dan pengelolaan sampah terintegrasi.

", "link": "https://darmasaba.desa.id/berita/56722-bares#:~:text=Sampah%20jadi%20uang%20nie%20Semeton,masing%20banjar%20se%2DDesa%20Darmasaba.", - "imageId" : "cmk20mg320000vnevxy0k73fr" + "imageName" : "thpgPSJkBxUIRajZt3AVo-mobile.webp" }, { "id": "cmdr76nqk0008vn5rdddvcxnr", "name": "Bicara Darmasaba", "description": "

Bicara Darmasaba adalah program ruang dialog terbuka yang digagas Pemerintah Desa Darmasaba sebagai forum strategis untuk menggali ide, menyampaikan aspirasi masyarakat, serta merangkai aksi nyata dalam menyelesaikan persoalan desa, seperti pengelolaan sampah. Kegiatan ini diselenggarakan secara berkala dengan pendekatan partisipatif dan ditayangkan secara live streaming agar transparan dan melibatkan banyak pihak, sehingga mendukung tata kelola desa yang responsif terhadap kebutuhan warga.

", "link": "https://badungkab.go.id/kab/berita/67159-bicara-darmasaba-bahas-berbagai-persoalan-warga-didorong-berani-speak-up-sampaikan-aspirasi-dan-cari-solusi-nyata", - "imageId" : "cmk20nqmu0001vnevfte29rk0" + "imageName" : "ubna9N6r7RgVWN5plO5mq-mobile.webp" }, { "id": "cmdr755pf0005vn5rp8tyuubw", "name": "Dmangan", "description": "

Dmangan (Darmasaba Aman Pangan) adalah program inovasi Desa Darmasaba yang fokus pada ketahanan pangan masyarakat desa melalui pengembangan produksi hasil pangan lokal, peningkatan kemandirian pangan, serta pembinaan dan pemberdayaan warga dalam praktik pertanian dan pangan berkelanjutan.

", "link": "https://darmasaba.desa.id/berita/51787-desa-darmasaba-juara-1-lomba-desa-pangan-aman-provinsi-bali-tahun-2023#:~:text=Salah%20satu%20program%20inovasi%20Pemdes%20Darmasaba%20yaitu,Darmasaba%20dan%20seluruh%20stakeholder%20terkait%20yang%20telah", - "imageId" : "cmk20nyen0002vnevd0hfr3u8" + "imageName" : "y4yaE4XdUP1TSUGhWPW9h-mobile.webp" }, { "id": "cmk228ust0009vnev5p8i377o", "name": "Davest", "description": "

DAVEST (Darmasaba Investment) merupakan program inovasi Desa Darmasaba yang bertujuan mempromosikan potensi investasi desa secara terintegrasi melalui media digital dan pendampingan langsung. Program ini menjadi sarana penghubung antara pemerintah desa, pelaku usaha, dan investor dalam rangka mendorong pertumbuhan ekonomi desa yang berkelanjutan.

DAVEST menyajikan informasi potensi unggulan desa seperti sektor UMKM, pariwisata, ekonomi kreatif, serta peluang investasi berbasis sumber daya lokal dengan prinsip transparansi dan kemudahan akses informasi.

Di tahun 2024 ini Davest (Darmasaba Village Festival) akan diadakan lagi, dengan berbagai kegiatan pemerdayaan, edukasi dan hiburan yang tentunya lebih waahhhh dari dua tahun lalu. Untuk memantapkan hal tersebut, Pemdes Darmasaba melakukan rapat koordinasi (rakor) Davest 2024 yang dipimpin langsung oleh Perbekel Darmasaba I. B. Surya Prabhawa Manuaba, S.H.,M.H. pada hari Senin (22/1/2024) bertempat di Ruang Shanti Gosana Kantor Perbekel Darmasaba.


Tujuan Program


Sasaran Program


Bentuk Inovasi


Ruang Lingkup Kegiatan

", "link": "https://darmasaba.desa.id/berita/55862-rakor-davest-2024", - "imageId" : "cmk228urs0007vnevi5b66bqn" + "imageName" : "Z4i2RRnnlHq2iWj94ldyo-mobile.webp" }, { "id": "cmdr7ftob000mvn5rfhgdtg8v", "name": "GM", "description": "

Galah Melah (Gerak dan Langkah Memilah Sampah) adalah program inovasi pengelolaan sampah yang dikembangkan oleh Pemerintah Desa Darmasaba melalui TPS3R Pudak Mesari, dengan fokus pada praktik pemisahan sampah dari sumbernya (di rumah, banjar, maupun fasilitas umum).

", "link": "https://mcinews.id/2025/09/12/serius-tangani-sampah-desa-darmasaba-terapkan-inovasi-dan-osaki-composting-system-di-tps-3r-pudak-mesari-dari-2023", - "imageId" : "cmk20o7mf0003vnevohrksm1d" + "imageName" : "Vr7CoaYDpk2dIkHx9PxRj-mobile.webp" }, { "id": "cmdr7glue000pvn5r6onzslju", "name": "Inovasi Desa Darmasaba", "description": "

Inovasi Desa Darmasaba adalah kumpulan program inovatif yang dikembangkan oleh Pemerintah Desa Darmasaba untuk memperkuat penyelenggaraan pemerintahan desa, pemberdayaan masyarakat, pengelolaan lingkungan, serta peningkatan kualitas sosial-ekonomi dan budaya desa.

", "link": "https://mcinews.id/2025/09/11/inovasi-desa-darmasaba-lanjutkan-perjuangan-ke-tingkat-nasional-dan-diakui-negara-tetangga", - "imageId" : "cmk20of8m0004vnev9ujy5o0l" + "imageName" : "ceoB_sg-HOzljN8j_2nZA-mobile.webp" }, { "id": "cmdr7dlnk000hvn5r9lur3z35", "name": "PDKT", "description": "

PDKT (Perangkat Desa Kuat Teknologi) merupakan program inovasi Desa Darmasaba yang dirancang untuk menguatkan kapasitas dan kompetensi perangkat desa dalam memanfaatkan teknologi informasi dan komunikasi guna mendukung tata kelola pemerintahan desa yang modern, transparan, cepat, dan responsif.

", "link": "https://darmasaba.desa.id/berita/67168-desa-darmasaba-masuk-5-besar-nasional-dalam-ajang-pemerintah-desa-dan-kelurahan-award-2025", - "imageId" : "cmk20omzq0005vnevgi6f4edu" + "imageName" : "vOy5YVUXfHXfiFOHylIN7-mobile.webp" }, { "id": "cmdr7bxtp000evn5rmy85wihx", "name": "Sajjana Dharma Raksaka", "description": "

Sajjana Dharma Raksaka adalah program inovasi Desa Darmasaba yang bertujuan untuk memperkuat akses perlindungan hukum dan pendampingan hukum non-litigasi bagi masyarakat desa. Melalui inovasi ini, desa menyediakan layanan pendampingan, mediasi, dan bantuan dalam menyelesaikan persoalan hukum secara bijaksana, humanis, dan berperspektif keadilan sosial

", "link": "https://ppid.badungkab.go.id/storage/dokumen/5RS9dldGkrgzMQq6bKdZsqsVRHI8gffWv4PGfb3r.pdf", - "imageId" : "cmk20pf3d0006vnev3mkoqpyy" + "imageName" : "gE_qcqIbY0mqI6FV9V4CL-mobile.webp" } ] diff --git a/prisma/data/landing-page/sdgs-desa/sdgs-desa.json b/prisma/data/landing-page/sdgs-desa/sdgs-desa.json index 47ae0139..d8969097 100644 --- a/prisma/data/landing-page/sdgs-desa/sdgs-desa.json +++ b/prisma/data/landing-page/sdgs-desa/sdgs-desa.json @@ -3,109 +3,109 @@ "id": "cmdsjzdl30002vneknuvo4irv", "name": "Desa Tanpa Kemiskinan", "jumlah": "52.62", - "imageId": "cmk3grkby0000vnxwblul7viy" + "imageName": "kxpXwgyx74-HkAGXML7Hv-mobile.webp" }, { "id": "cmdskargd0005vnek0mu2ofk9", "name": "Desa Tanpa Kelaparan", "jumlah": "35.75", - "imageId": "cmk3h87lc0001vnxwxc5sn0xc" + "imageName": "D0DEORcSkSWXEpY29mh_x-mobile.webp" }, { "id": "cmdskbvl0008vnek5dmieatb", "name": "Desa Sehat Dan Sejahtera", "jumlah": "77.37", - "imageId": "cmk3haaaf0002vnxwy5w07z3n" + "imageName": "jrUol97rV5whAUtpljbyF-mobile.webp" }, { "id": "cmdskcx91000bvneko7tuaoqa", "name": "Pendidikan Desa Berkualitas", "jumlah": "34.11", - "imageId": "cmk3hdeeg0003vnxwezx6zu99" + "imageName": "Kh8RTS4ac1bG4ZXy3L2-y-mobile.webp" }, { "id": "cmdskjare000evnek1hglu0x8", "name": "Keterlibatan Perempuan Desa", "jumlah": "45.70", - "imageId": "cmk3hg3n20004vnxwxofi5ylm" + "imageName": "8bAk-cuzJ73W1dgj4lVqM-mobile.webp" }, { "id": "cmdskqcpc0002vnvnqjkqgm92", "name": "Desa Layak Air Bersih Dan Sanitasi", "jumlah": "48.54", - "imageId": "cmk3hjdb10005vnxwjtgd6g9g" + "imageName": "k4zOPRqxi6PS0W_rHgiVp-mobile.webp" }, { "id": "cmdsktl3x0005vnvne15seefw", "name": "Desa Berenergi Bersih Dan Terbarukan", "jumlah": "99.64", - "imageId": "cmk3hlu6l0006vnxw9wtsaq4w" + "imageName": "txtX9hDmrHrRIkmpyQ6rp-mobile.webp" }, { "id": "cmdskuncw0008vnvcsdqoeog", "name": "Pertumbuhan Ekonomi Desa Merata", "jumlah": "40.92", - "imageId": "cmk3hp5ht0007vnxwakvsa7ld" + "imageName": "Yx7ruGLJ_0QtD5RCvYhEC-mobile.webp" }, { "id": "cmdskw83j000bvvn9szqrea6", "name": "Infrastruktur Dan Inovasi Desa Sesuai Kebutuhan", "jumlah": "35.37", - "imageId": "cmk3hrkmp0008vnxwijncfayo" + "imageName": "j1kZLRY4HLFBxdRt24XQw-mobile.webp" }, { "id": "cmdskwrq7000envnvy0c5nbgf", "name": "Desa Tanpa Kesenjangan", "jumlah": "35.47", - "imageId": "cmk3hu2lh0009vnxw82qb8l6h" + "imageName": "Iqx5__9VtAQiScvvGb21S-mobile.webp" }, { "id": "cmdskxivx000hnvnvsx520gv1", "name": "Kawasan Pemukiman Desa Aman Dan Nyaman", "jumlah": "40.35", - "imageId": "cmk3hwtsm000avnxwfug41t9x" + "imageName": "Eelib_Lr7GYv0nPj3XHVo-mobile.webp" }, { "id": "cmdskzg4c000kvnnkiv61gkt", "name": "Konsumsi Dan Produksi Desa Sadar Lingkungan", "jumlah": "16.67", - "imageId": "cmk3i09sa000bvnxw95elyupj" + "imageName": "6MzAfXZyjsSTOkckqYJug-mobile.webp" }, { "id": "cmdsl07lk000nvnnvnrepsdy5m", "name": "Desa Tanggap Perubahan Iklim", "jumlah": "0.00", - "imageId": "cmk3i2q07000cvnxwkjxqld0c" + "imageName": "f05zcftt1hdvkhCeN7wxk-mobile.webp" }, { "id": "cmdsl10rq000qvnvnlch9c1yv", "name": "Desa Peduli Lingkungan Laut", "jumlah": "50.00", - "imageId": "cmk3i53wr000dvnxw074gyuar" + "imageName": "3tuC1Bq5WvH7QEBHQVDaM-mobile.webp" }, { "id": "cmdsl1mc2000tvnvn357n8usi", "name": "Desa Peduli Lingkungan Darat", "jumlah": "0.00", - "imageId": "cmk3i7krz000evnxwe4uturyn" + "imageName": "oTKQeqAydsV5fXelI0S7Y-mobile.webp" }, { "id": "cmdsl2bx3000wvnvntshi4gnj", "name": "Desa Damai Berkeadilan", "jumlah": "78.65", - "imageId": "cmk3ib07w000fvnxwsnb1hga3" + "imageName": "16sdgs.webp" }, { "id": "cmdsl2yz3000zvnvnmf60ok7q", "name": "Kemitraan Untuk Pembangunan Desa", "jumlah": "20.00", - "imageId": "cmk3idx0t000gvnxw16urbiw5" + "imageName": "L8jv3Wvj0GwsQgS7JSJQO-mobile.webp" }, { "id": "cmdsl492h0012vnvnmckm3n2x", "name": "Kelembagaan Desa Dinamis Dan Budaya Desa Adaptif", "jumlah": "47.22", - "imageId": "cmk3ig4ho000hvnxwewlheju3" + "imageName": "18sdgs.webp" } ] diff --git a/prisma/data/ppid/profile-ppid/profilePPid.json b/prisma/data/ppid/profile-ppid/profilePPid.json index b1cdb82b..26fed553 100644 --- a/prisma/data/ppid/profile-ppid/profilePPid.json +++ b/prisma/data/ppid/profile-ppid/profilePPid.json @@ -6,6 +6,6 @@ "riwayat": "", "pengalaman": "", "unggulan": "

Pemberdayaan Ekonomi dan UMKM

", - "imageId" : "cmk3o5wxs0006vn9b1u5kbqyw" + "imageName" : "t9x6bSW8WnbdPS9cx9PLC-mobile.webp" } ] diff --git a/prisma/data/ppid/struktur-ppid/pegawai-PPID.json b/prisma/data/ppid/struktur-ppid/pegawai-PPID.json index 713cb799..8602e313 100644 --- a/prisma/data/ppid/struktur-ppid/pegawai-PPID.json +++ b/prisma/data/ppid/struktur-ppid/pegawai-PPID.json @@ -8,7 +8,8 @@ "telepon": "081234567891", "alamat": "Jl. Raya Desa No. 1", "posisiId": "kepala_desa", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewxfvw000004ibee5013f4", @@ -19,7 +20,8 @@ "telepon": "081234567892", "alamat": "Jl. Raya Desa No. 2", "posisiId": "sekretaris_desa", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewxvqw000104ibgm5l8fzs", @@ -30,7 +32,8 @@ "telepon": "081234567892", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kaur_keuangan", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewy1g9000204ib2n7hbx0i", @@ -41,7 +44,8 @@ "telepon": "081234567892", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kadus_banjar_dinas_menesa", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewybah000304ibgqhn1gm2", @@ -52,7 +56,8 @@ "telepon": "081234567893", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kadus_banjar_dinas_darmasaba", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewygqz000404ib20sv8nvg", @@ -63,7 +68,8 @@ "telepon": "081234567893", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kadus_banjar_dinas_bucu", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewyos1000504ibcu8o2gyk", @@ -74,7 +80,8 @@ "telepon": "081234567893", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kadus_banjar_dinas_gulingan", - "isActive": true + "isActive": true, + "imageName": "" }, { "id": "cmgewyxk7000604ib8djs3i6c", @@ -85,7 +92,8 @@ "telepon": "081234567893", "alamat": "Jl. Raya Desa No. 2", "posisiId": "kadus_banjar_dinas_taman", - "isActive": true + "isActive": true, + "imageName": "" } ] \ No newline at end of file diff --git a/prisma/lib/get_images.ts b/prisma/lib/get_images.ts new file mode 100644 index 00000000..4cc47c54 --- /dev/null +++ b/prisma/lib/get_images.ts @@ -0,0 +1,75 @@ +type DirItem = { + type: "file" | "dir"; + name: string; + path: string; + size?: number; +}; + +const TOKEN = process.env.SEAFILE_TOKEN!; +const REPO_ID = process.env.SEAFILE_REPO_ID!; + +// ⛔ PENTING: RELATIVE PATH (tanpa slash depan) +const DIR_TARGET = "asset-web"; + +const BASE_URL = process.env.SEAFILE_URL; + +const headers = { + Authorization: `Token ${TOKEN}`, +}; + +async function getDirItems(): Promise { + const res = await fetch(`${BASE_URL}/repos/${REPO_ID}/dir/?p=${DIR_TARGET}`, { + headers, + }); + + if (!res.ok) { + throw new Error(`Failed get dir items: ${res.statusText}`); + } + + return res.json(); +} + +async function getDownloadUrl(filePath: string): Promise { + const res = await fetch( + `${BASE_URL}/repos/${REPO_ID}/file/?p=${encodeURIComponent(filePath)}`, + { headers }, + ); + + if (!res.ok) { + throw new Error(`Failed get file url: ${res.statusText}`); + } + + const data = await res.json(); + + return data; +} + +/** + * Ambil semua download URL dari target dir + */ +export async function getAllDownloadUrls() { + const items = await getDirItems(); + + const files = items.filter((item) => item.type === "file"); + + const results = await Promise.all( + files.map(async (file) => { + const filePath = `${DIR_TARGET}/${file.name}`; + const url = await getDownloadUrl(filePath); + return { + name: file.name, + path: filePath, + downloadUrl: url, + }; + }), + ); + + return results; +} + +if (import.meta.main) { + console.log("get data ...") + getAllDownloadUrls().then((res) => { + console.log(res); + }); +} diff --git a/prisma/newseed-asset.ts b/prisma/newseed-asset.ts new file mode 100644 index 00000000..fabdbafc --- /dev/null +++ b/prisma/newseed-asset.ts @@ -0,0 +1,82 @@ +type DirItem = { + type: "file" | "dir"; + name: string; + path: string; + size?: number; +}; + +type FileDownload = { + name: string; + path: string; + link: string; +}; + +const TOKEN = process.env.SEAFILE_TOKEN!; +const REPO_ID = process.env.SEAFILE_REPO_ID!; + +// ⛔ PENTING: RELATIVE PATH (tanpa slash depan) +const DIR_TARGET = "asset-web"; + +const BASE_URL = "https://cld-dkr-makuro-seafile.wibudev.com/api2"; + +const headers = { + Authorization: `Token ${TOKEN}`, +}; + +/** + * Ambil list item di directory + */ +async function getDirItems(): Promise { + const res = await fetch( + `${BASE_URL}/repos/${REPO_ID}/dir/?p=${encodeURIComponent(DIR_TARGET)}`, + { headers }, + ); + + if (!res.ok) { + const body = await res.text(); + throw new Error(`Failed get dir items: ${body}`); + } + + return res.json(); +} + + +/** + * Ambil download URL file + */ +async function getDownloadUrl(filePath: string): Promise { + const res = await fetch( + `${BASE_URL}/repos/${REPO_ID}/file/?p=${encodeURIComponent(filePath)}`, + { headers }, + ); + + if (!res.ok) { + const body = await res.text(); + throw new Error(`Failed get file url: ${body}`); + } + + const data = await res.json(); + return data.url; +} + +/** + * Ambil semua download URL dari folder image + */ +export async function getImageDownloadList(): Promise { + const items = await getDirItems(); + + const files = items.filter((item) => item.type === "file"); + + return Promise.all( + files.map(async (file) => { + const filePath = `${DIR_TARGET}/${file.name}`; // → /image/xxx.webp + + return { + name: file.name, + path: filePath, + link: await getDownloadUrl(filePath), + }; + }), + ); +} + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 8e45d429..40780099 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -569,8 +569,8 @@ model MaskotDesa { model ProfileDesaImage { id String @id @default(cuid()) label String - image FileStorage @relation(fields: [imageId], references: [id]) - imageId String + image FileStorage? @relation(fields: [imageId], references: [id]) + imageId String? MaskotDesa MaskotDesa @relation(fields: [maskotDesaId], references: [id]) maskotDesaId String } diff --git a/prisma/seed.ts b/prisma/seed.ts index 129643d5..c1358afd 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,124 +1,33 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ import prisma from "@/lib/prisma"; -import profilePejabatDesa from "./data/landing-page/profile/profile.json"; -import programInovasi from "./data/landing-page/profile/programInovasi.json"; -import mediaSosial from "./data/landing-page/profile/mediaSosial.json"; -import desaAntiKorupsi from "./data/landing-page/desa-anti-korupsi/desaantiKorpusi.json"; -import kategoriDesaAntiKorupsi from "./data/landing-page/desa-anti-korupsi/kategoriDesaAntiKorupsi.json"; -import sdgsDesa from "./data/landing-page/sdgs-desa/sdgs-desa.json"; -import apbdes from "./data/landing-page/apbdes/apbdes.json"; -import kategoriPrestasiDesa from "./data/landing-page/prestasi-desa/kategori-prestasi.json"; -import prestasiDesa from "./data/landing-page/prestasi-desa/prestasi-desa.json"; -import profilePPID from "./data/ppid/profile-ppid/profilePPid.json"; -import pegawaiPPID from "./data/ppid/struktur-ppid/pegawai-PPID.json"; -import posisiOrganisasiPPID from "./data/ppid/struktur-ppid/posisi-organisasi-PPID.json"; -import visiMisiPPID from "./data/ppid/visi-misi-ppid/visimisiPPID.json"; -import dasarHukumPPID from "./data/ppid/dasar-hukum-ppid/dasarhukumPPID.json"; -import jenisKelamin from "./data/ppid/ikm/jenis-kelamin/jenis-kelamin.json"; -import daftarInformasiPublik from "./data/ppid/daftar-informasi-publik-desa-darmasaba/daftarInformasi.json"; -import pilihanRatingResponden from "./data/ppid/ikm/pilihan-rating-responden/rating-responden.json"; -import umurResponden from "./data/ppid/ikm/umur-responden/umur-responden.json"; -import kategoriPengumuman from "./data/desa/pengumuman/kategori-pengumuman.json"; -import pengumuman from "./data/desa/pengumuman/pengumuman.json"; -import galleryVideo from "./data/desa/gallery/video/video.json"; -import pelayananPerizinanBerusaha from "./data/desa/layanan/pelayananPerizinanBerusaha.json"; -import pelayananSuratKeterangan from "./data/desa/layanan/pelayananSuratKeterangan.json"; -import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSaktiDesa.json"; -import pelayananPendudukNonPermanen from "./data/desa/layanan/pelayanaPendudukNonPermanen.json"; -import penghargaan from "./data/desa/penghargaan/penghargaan.json"; -import lambangDesa from "./data/desa/profile/lambang_desa.json"; -import maskotDesa from "./data/desa/profile/maskot_desa.json"; -import profilPerbekel from "./data/desa/profile/profil_perbekel.json"; -import perbekelDariMasaKeMasa from "./data/desa/profile/profile-perbekel-lalu.json"; -import sejarahDesa from "./data/desa/profile/sejarah_desa.json"; -import visiMisiDesa from "./data/desa/profile/visi_misi_desa.json"; -import detailDataPengangguran from "./data/ekonomi/jumlah-pengangguran/detail-data-pengangguran.json"; -import pegawai from "./data/ekonomi/struktur-organisasi/pegawai-bumdes.json"; -import posisiOrganisasi from "./data/ekonomi/struktur-organisasi/posisi-organisasi-bumdes.json"; -import posyandu from "./data/kesehatan/posyandu/posyandu.json"; -import kontakPuskesmas from "./data/kesehatan/puskesmas/kontak-puskesmas/kontak.json"; -import jamPuskesmas from "./data/kesehatan/puskesmas/jam-puskesmas/jam.json"; -import puskesmas from "./data/kesehatan/puskesmas/puskesmas.json"; -import programKesehatan from "./data/kesehatan/program-kesehatan/program-kesehatan.json"; -import penangananDarurat from "./data/kesehatan/penanganan-darurat/penganan-darurat.json"; -import kontakDarurat from "./data/kesehatan/kontak-darurat/kontak-darurat.json"; -import infoWabahPenyakit from "./data/kesehatan/infowabahpenyakit/infowabahpenyakit.json"; -import keamananLingkungan from "./data/keamanan/keamanan-lingkungan/keamanan-lingkungan.json"; -import kontakDaruratKeamanan from "./data/keamanan/kontak-darurat-keamanan/kontak-darurat-keamanan.json"; -import kontakItem from "./data/keamanan/kontak-darurat-keamanan/kontakItem.json"; -import kontakDaruratToItem from "./data/keamanan/kontak-darurat-keamanan/kontakDaruratToItem.json"; -import pencegahanKriminalitas from "./data/keamanan/pencegahan-kriminalitas/pencegahan-kriminalitas.json"; -import tipsKeamanan from "./data/keamanan/tips-keamanan/tips-keamanan.json"; -import polsekTerdekat from "./data/keamanan/polsek-terdekat/polsek-terdekat.json"; -import layananPolsek from "./data/keamanan/polsek-terdekat/layanan-polsek.json"; -import layananToPolsek from "./data/keamanan/polsek-terdekat/layanan-to-polsek.json"; -import penangananLaporan from "./data/keamanan/laporan-publik/penanganan-laporan.json"; -import laporanPublik from "./data/keamanan/laporan-publik/laporan-publik.json"; -import pasarDesa from "./data/ekonomi/pasar-desa/pasar-desa.json"; -import kategoriProduk from "./data/ekonomi/pasar-desa/kategori-produk.json"; -import kategoriToPasar from "./data/ekonomi/pasar-desa/kategori-to-pasar.json"; -import lowonganKerjaLokal from "./data/ekonomi/lowongan-kerja-lokal/lowongan-kerja-lokal.json"; -import demografiPekerjaan from "./data/ekonomi/demografi-pekerjaan/demografi-pekerjaan.json"; -import sektorUnggulanDesa from "./data/ekonomi/sektor-unggulan/sektor-unggulan.json"; -import programKemiskinan from "./data/ekonomi/program-kemiskinan/program-kemiskinan.json"; -import statistikKemiskinan from "./data/ekonomi/program-kemiskinan/statistik-kemiskinan.json"; -import grafikMenganggurBerdasarkanUsia from "./data/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran-berdasarkan-usia.json"; -import grafikMenganggurBerdasarkanPendidikan from "./data/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran-berdasarkan-pendidikan.json"; -import jumlahPendudukMiskin from "./data/ekonomi/jumlah-penduduk-miskin/jumlah-penduduk-miskin.json"; -import desaDigital from "./data/inovasi/desa-digital/desa-digital.json"; -import jenisLayanan from "./data/inovasi/layanan-online-desa/jenis-layanan.json"; -import jenisPengaduan from "./data/inovasi/layanan-online-desa/jenis-pengaduan.json"; -import administrasiOnline from "./data/inovasi/layanan-online-desa/administrasi-online.json"; -import pengaduanMasyarakat from "./data/inovasi/layanan-online-desa/pengaduan-masyarakat.json"; -import programKreatif from "./data/inovasi/program-kreatif-desa/program-kreatif-desa.json"; -import kolaborasiInovasi from "./data/inovasi/kolaborasi-inovasi/kolaborasi-inovasi.json"; -import mitraKolaborasi from "./data/inovasi/kolaborasi-inovasi/mitra-kolaborasi.json"; -import infoTeknologi from "./data/inovasi/info-teknologi/info-teknologi.json"; -import ajukanIde from "./data/inovasi/ajukan-ide/ajukan-ide.json"; -import pengelolaanSampah from "./data/lingkungan/pengelolaan-sampah/pengelolaan-sampah.json"; -import keteranganBankSampah from "./data/lingkungan/pengelolaan-sampah/keterangan-bank-sampah.json"; -import programPenghijauan from "./data/lingkungan/program-penghijauan/program-penghijauan.json"; -import dataLingkunganDesa from "./data/lingkungan/data-lingkungan-desa/data-lingkungan-desa.json"; -import kategoriGotongRoyong from "./data/lingkungan/gotong-royong/kategori-gotong-royong.json"; -import gotongRoyong from "./data/lingkungan/gotong-royong/gotong-royong.json"; -import berita from "./data/desa/berita/berita.json"; -import kategoriBerita from "./data/desa/berita/kategori-berita.json"; -import contohEdukasiLingkungan from "./data/lingkungan/edukasi-lingkungan/contoh-kegiatan-di-desa-darmasaba.json"; -import materiEdukasiLingkungan from "./data/lingkungan/edukasi-lingkungan/materi-edukasi-yang-diberikan.json"; -import tujuanEdukasiLingkungan from "./data/lingkungan/edukasi-lingkungan/tujuan-edukasi-lingkungan.json"; -import bentukKonservasiBerdasarkanAdat from "./data/lingkungan/konservasi-adat-bali/bentuk-konservasi.json"; -import filosofiTriHita from "./data/lingkungan/konservasi-adat-bali/filosofi-tri-hita.json"; -import nilaiKonservasiAdat from "./data/lingkungan/konservasi-adat-bali/nilai-konservasi-adat.json"; -import jenjangPendidikan from "./data/pendidikan/info-sekolah/jenjang-pendidikan.json"; -import lembagaPendidikan from "./data/pendidikan/info-sekolah/lembaga.json"; -import siswa from "./data/pendidikan/info-sekolah/siswa.json"; -import pengajar from "./data/pendidikan/info-sekolah/pengajar.json"; -import dataPerpustakaan from "./data/pendidikan/perpustakaan-digital/perpustakaan-digital.json"; -import dataPendidikan from "./data/pendidikan/data-pendidikan/data-pendidikan.json" -import caraMemperolehInformasi from "./data/list-caraMemperolehInformasi.json"; -import caraMemperolehSalinanInformasi from "./data/list-caraMemperolehSalinanInformasi.json"; -import jenisInformasiDiminta from "./data/list-jenisInfromasi.json"; -import potensi from "./data/desa/potensi/potensi-desa.json"; -import kategoriPotensi from "./data/desa/potensi/kategori-potensi.json"; -import fasilitasBimbinganBelajarDesa from "./data/pendidikan/bimbingan-belajar-desa/fasilitas-yang-disediakan.json"; -import lokasiJadwalBimbinganBelajarDesa from "./data/pendidikan/bimbingan-belajar-desa/lokasi-dan-jadwal.json"; -import tujuanBimbinganBelajarDesa from "./data/pendidikan/bimbingan-belajar-desa/tujuan-bimbingan-belajar-desa.json"; -import jenisProgramYangDiselenggarakan from "./data/pendidikan/pendidikan-non-formal/jenis-program-yang-diselenggarakan.json"; -import tempatKegiatan from "./data/pendidikan/pendidikan-non-formal/tempat-kegiatan.json"; -import tujuanProgram2 from "./data/pendidikan/pendidikan-non-formal/tujuan-program2.json"; -import programUnggulan from "./data/pendidikan/program-pendidikan-anak/program-unggulan.json"; -import tujuanProgram from "./data/pendidikan/program-pendidikan-anak/tujuan-program.json"; -import kategoriBuku from "./data/pendidikan/perpustakaan-digital/kategori-buku.json"; +import { seedVideo } from "./_seeder_list/desa/gallery/video/seed_video"; +import { seedLayanan } from "./_seeder_list/desa/layanan/seed_layanan"; +import { seedPenghargaan } from "./_seeder_list/desa/penghargaan/penghargaan"; +import { seedPengumuman } from "./_seeder_list/desa/pengumuman/seed_pengumuman"; +import { seedPotensi } from "./_seeder_list/desa/potensi/seed_potensi"; +import { seedProfileDesa } from "./_seeder_list/desa/profile-desa/seed_profile_desa"; +import { seedProfilePerbekel } from "./_seeder_list/desa/profile-desa/seed_profile_perbekel"; +import { seedDesaAntiKorupsi } from "./_seeder_list/landing-page/desa-anti-korupsi/seed_desa_anti_korupsi"; +import { seedPrestasiDesa } from "./_seeder_list/landing-page/prestasi-desa/seed_prestasi_desa"; +import { seedMediaSosial } from "./_seeder_list/landing-page/profil_landing_page/seed_media_sosial"; +import { seedProfileLP } from "./_seeder_list/landing-page/profil_landing_page/seed_profile_lp"; +import { seedProgramInovasi } from "./_seeder_list/landing-page/profil_landing_page/seed_program_inovasi"; +import { seedSDGSDesa } from "./_seeder_list/landing-page/sdgs/seed_sdgs"; +import { seedDaftarInformasiPublikPpid } from "./_seeder_list/ppid/daftar-informasi-publik-ppid/seed_daftar_informasi_publik_ppid"; +import { seedDasarHukumPpid } from "./_seeder_list/ppid/dasar-hukum-ppid/seed_dasar_hukum_ppid"; +import { seedIkmPpid } from "./_seeder_list/ppid/ikm/seed_ikm"; +import { seedPegawaiPpid } from "./_seeder_list/ppid/struktur-ppid/seed_struktur_ppid"; +import { seedVisiMisiPpid } from "./_seeder_list/ppid/visi-misi-ppid/seed_visi_misi_ppid"; +import dataPendidikan from "./data/pendidikan/data-pendidikan/data-pendidikan.json"; import roles from "./data/user/roles.json"; -import fileStorage from "./data/file-storage.json"; -import seedAssets from "./seed_assets"; import users from "./data/user/users.json"; import { safeSeedUnique } from "./safeseedUnique"; -import resolveImageById from "./resolveImageByName"; +import seedAssets from "./seed_assets"; +import { seedBerita } from "./_seeder_list/desa/berita/seed_berita"; +import { seedFoto } from "./_seeder_list/desa/gallery/foto/seed_foto"; (async () => { - // seed assets const totalFiles = await prisma.fileStorage.count(); const hasImageAsset = await prisma.fileStorage.findFirst({ @@ -134,26 +43,6 @@ import resolveImageById from "./resolveImageByName"; } // // =========== FILE STORAGE =========== - console.log("🔄 Seeding file storage..."); - for (const f of fileStorage) { - await safeSeedUnique( - "fileStorage", - { name: f.name }, - { - id: f.id, - name: f.name, - realName: f.realName, - path: f.path, - mimeType: f.mimeType, - link: f.link, - category: f.category, - deletedAt: null, - isActive: true, - }, - ); - } - - console.log("✅ File storage seeded"); console.log("🔄 Seeding roles..."); @@ -227,2796 +116,1813 @@ import resolveImageById from "./resolveImageByName"; console.log("✅ Users seeding completed"); // =========== LANDING PAGE =========== // =========== SUBMENU PROFILE =========== - // =========== PROFILE PEJABAT DESA =========== - // In your seed.ts file, update the PejabatDesa seeding section to: - console.log("🔄 Seeding Pejabat Desa..."); - for (const p of profilePejabatDesa) { - try { - // First, verify the image exists - if (p.imageId) { - const imageExists = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - }); - - if (!imageExists) { - console.warn( - `⚠️ Image not found for PejabatDesa ${p.name}, skipping...`, - ); - continue; - } - } - - await safeSeedUnique( - "pejabatDesa", - { id: p.id }, - { - id: p.id, - name: p.name, - position: p.position, - imageId: p.imageId, - }, - ); - console.log(`✅ Seeded Pejabat Desa -> ${p.name}`); - } catch (error: any) { - console.error(`❌ Failed to seed Pejabat Desa ${p.name}:`, error.message); - } - } - console.log("✅ Pejabat Desa seeding completed"); - - // =========== PROGRAM INOVASI =========== - // Add this section after the other seed operations in seed.ts - console.log("🔄 Seeding Program Inovasi..."); - for (const p of programInovasi) { - const existing = await prisma.programInovasi.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.programInovasi.upsert({ - where: { id: p.id }, - update: { - name: p.name, - description: p.description, - link: p.link, - imageId, - }, - create: { - id: p.id, - name: p.name, - description: p.description, - link: p.link, - imageId, - }, - }); - } - - // =========== MEDIA SOSIAL =========== - console.log("🔄 Seeding Media Sosial..."); - for (const m of mediaSosial) { - const existing = await prisma.mediaSosial.findUnique({ - where: { id: m.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && m.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: m.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${m.imageId} not found for ${m.name}`); - imageId = null; - } - } - - await prisma.mediaSosial.upsert({ - where: { id: m.id }, - update: { - name: m.name, - iconUrl: m.iconUrl, - imageId, - }, - create: { - id: m.id, - name: m.name, - iconUrl: m.iconUrl, - imageId, - }, - }); - } - - console.log("media sosial success ..."); - - // =========== SUBMENU DESA ANTI KORUPSI =========== - // =========== KATEGORI DESA ANTI KORUPSI =========== - for (const k of kategoriDesaAntiKorupsi) { - await prisma.kategoriDesaAntiKorupsi.upsert({ - where: { id: k.id }, - update: { - name: k.name, - }, - create: { - id: k.id, - name: k.name, - }, - }); - } - console.log("kategori desa anti korupsi success ..."); - - // =========== DESA ANTI KORUPSI =========== - for (const p of desaAntiKorupsi) { - await prisma.desaAntiKorupsi.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - kategoriId: p.kategoriId, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - kategoriId: p.kategoriId, - }, - }); - } - console.log("desa anti korupsi success ..."); - - // =========== SDGSDesa =========== - console.log("🔄 Seeding SDGS Desa..."); - for (const l of sdgsDesa) { - const existing = await prisma.sdgsDesa.findUnique({ - where: { id: l.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && l.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: l.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${l.imageId} not found for ${l.name}`); - imageId = null; - } - } - - await prisma.sdgsDesa.upsert({ - where: { id: l.id }, - update: { - name: l.name, - jumlah: l.jumlah, - imageId, - }, - create: { - id: l.id, - name: l.name, - jumlah: l.jumlah, - imageId, - }, - }); - } - console.log("sdgs desa success ..."); - - // =========== APBDes =========== - for (const l of apbdes) { - await prisma.aPBDes.upsert({ - where: { - id: l.id, - }, - update: { - name: l.name, - jumlah: l.jumlah, - }, - create: { - name: l.name, - jumlah: l.jumlah, - }, - }); - } - - console.log("apbdes success ..."); - - // =========== KATEGORI PRESTASI DESA=========== - for (const c of kategoriPrestasiDesa) { - await prisma.kategoriPrestasiDesa.upsert({ - where: { id: c.id }, - update: { - name: c.name, - }, - create: { - id: c.id, - name: c.name, - }, - }); - } - console.log("kategori prestasi desa success ..."); - - // =========== PRESTASI DESA=========== - for (const p of prestasiDesa) { - await prisma.prestasiDesa.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - kategoriId: p.kategoriId, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - kategoriId: p.kategoriId, - }, - }); - } - console.log("prestasi desa success ..."); - - // =========== MENU PPID =========== - // =========== SUBMENU PROFILE PPID =========== - for (const c of profilePPID) { - await prisma.profilePPID.upsert({ - where: { id: c.id }, - update: { - name: c.name, - biodata: c.biodata, - riwayat: c.riwayat, - pengalaman: c.pengalaman, - unggulan: c.unggulan, - // imageId tidak di-update - }, - create: { - id: c.id, - name: c.name, - biodata: c.biodata, - riwayat: c.riwayat, - pengalaman: c.pengalaman, - unggulan: c.unggulan, - // imageId tidak di-create - }, - }); - } - console.log("✅ profilePPID seeded without imageId (editable later via UI)"); - - // =========== SUBMENU STRUKTUR PPID =========== - // =========== POSISI ORGANISASI PPID =========== - - const flattenedPosisi = posisiOrganisasiPPID.flat(); - - // ✅ Urutkan berdasarkan hierarki - const sortedPosisi = flattenedPosisi.sort((a, b) => a.hierarki - b.hierarki); - - for (const p of sortedPosisi) { - console.log(`Seeding: ${p.nama} (id: ${p.id}, parent: ${p.parentId})`); - - if (p.parentId) { - const parentExists = flattenedPosisi.some((pos) => pos.id === p.parentId); - if (!parentExists) { - console.warn( - `⚠️ Parent tidak ditemukan: ${p.parentId} untuk ${p.nama}`, - ); - continue; - } - } - - await prisma.posisiOrganisasiPPID.upsert({ - where: { id: p.id }, - update: p, - create: p, - }); - } - console.log("posisi organisasi berhasil"); - - // =========== PEGAWAI PPID =========== - console.log("🔄 Seeding pegawai PPID..."); - const flattenedPegawai = pegawaiPPID.flat(); - - // Check for duplicate emails - const emails = new Set(); - for (const p of flattenedPegawai) { - if (emails.has(p.email)) { - console.warn(`⚠️ Duplicate email found in pegawaiPPID: ${p.email}`); - } - emails.add(p.email); - } - - for (const p of flattenedPegawai) { - try { - await prisma.pegawaiPPID.upsert({ - where: { id: p.id }, - update: p, - create: p, - }); - console.log(`✅ Seeded pegawai PPID -> ${p.namaLengkap}`); - } catch (error: any) { - if (error.code === "P2002") { - console.warn( - `⚠️ Pegawai PPID with duplicate email (skipping): ${p.email}`, - ); - } else { - console.error( - `❌ Failed to seed pegawai PPID ${p.namaLengkap}:`, - error.message, - ); - } - } - } - console.log("✅ pegawai PPID seeding completed"); - - // =========== SUBMENU VISI MISI PPID =========== - - for (const v of visiMisiPPID) { - await prisma.visiMisiPPID.upsert({ - where: { - id: v.id, - }, - update: { - misi: v.misi, - visi: v.visi, - }, - create: { - id: v.id, - misi: v.misi, - visi: v.visi, - }, - }); - } - console.log("visi misi PPID success ..."); - - // =========== SUBMENU DASAR HUKUM PPID =========== - for (const v of dasarHukumPPID) { - await prisma.dasarHukumPPID.upsert({ - where: { - id: v.id, - }, - update: { - judul: v.judul, - content: v.content, - }, - create: { - id: v.id, - judul: v.judul, - content: v.content, - }, - }); - } - console.log("dasar hukum PPID success ..."); - - // =========== SUBMENU DAFTAR INFORMASI PUBLIK PPID =========== - for (const v of daftarInformasiPublik) { - // Convert string date to Date object - const tanggal = new Date(v.tanggal); - - await prisma.daftarInformasiPublik.upsert({ - where: { - id: v.id, - }, - update: { - jenisInformasi: v.jenisInformasi, - deskripsi: v.deskripsi, - tanggal: tanggal, - }, - create: { - id: v.id, - jenisInformasi: v.jenisInformasi, - deskripsi: v.deskripsi, - tanggal: tanggal, - }, - }); - } - console.log("daftar informasi publik PPID success ..."); - - // =========== SUBMENU PERMOHONAN INFORMASI PUBLIK =========== - - for (const j of jenisInformasiDiminta) { - await prisma.jenisInformasiDiminta.upsert({ - where: { - name: j.name, - }, - update: { - name: j.name, - }, - create: { - name: j.name, - }, - }); - } - console.log("jenis informasi diminta success ..."); - - for (const c of caraMemperolehInformasi) { - await prisma.caraMemperolehInformasi.upsert({ - where: { - name: c.name, - }, - update: { - name: c.name, - }, - create: { - name: c.name, - }, - }); - } - console.log("cara memperoleh informasi success ..."); - - for (const c of caraMemperolehSalinanInformasi) { - await prisma.caraMemperolehSalinanInformasi.upsert({ - where: { - name: c.name, - }, - update: { - name: c.name, - }, - create: { - name: c.name, - }, - }); - } - console.log("cara memperoleh salinan informasi success ..."); - - // =========== SUBMENU INDEKS KEPUASAN MASYARAKAT =========== - for (const j of jenisKelamin) { - await prisma.jenisKelaminResponden.upsert({ - where: { - id: j.id, - }, - update: { - name: j.name, - }, - create: { - id: j.id, - name: j.name, - }, - }); - } - console.log("jenis kelamin responden success ..."); - - for (const r of pilihanRatingResponden) { - await prisma.pilihanRatingResponden.upsert({ - where: { - id: r.id, - }, - update: { - name: r.name, - }, - create: { - id: r.id, - name: r.name, - }, - }); - } - console.log("pilihan rating responden success ..."); - - for (const u of umurResponden) { - await prisma.umurResponden.upsert({ - where: { - id: u.id, - }, - update: { - name: u.name, - }, - create: { - id: u.id, - name: u.name, - }, - }); - } - console.log("umur responden success ..."); - - // =========== MENU DESA =========== - // =========== SUBMENU PROFILE =========== - // =========== SEJARAH DESA =========== - for (const l of sejarahDesa) { - await prisma.sejarahDesa.upsert({ - where: { - id: l.id, - }, - update: { - judul: l.judul, - deskripsi: l.deskripsi, - }, - create: { - id: l.id, - judul: l.judul, - deskripsi: l.deskripsi, - }, - }); - } - - console.log("sejarah desa success ..."); - - // =========== MASKOT DESA =========== - for (const l of maskotDesa) { - await prisma.maskotDesa.upsert({ - where: { - id: l.id, - }, - update: { - judul: l.judul, - deskripsi: l.deskripsi, - }, - create: { - id: l.id, - judul: l.judul, - deskripsi: l.deskripsi, - }, - }); - } - - console.log("maskot desa success ..."); - - // =========== LAMBANG DESA =========== - for (const l of lambangDesa) { - await prisma.lambangDesa.upsert({ - where: { - id: l.id, - }, - update: { - judul: l.judul, - deskripsi: l.deskripsi, - }, - create: { - id: l.id, - judul: l.judul, - deskripsi: l.deskripsi, - }, - }); - } - - console.log("lambang desa success ..."); - - // =========== PROFIL PERBEKEL =========== - console.log("🔄 Seeding Profil Perbekel..."); - for (const c of profilPerbekel) { - const existing = await prisma.profilPerbekel.findUnique({ - where: { id: c.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && c.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: c.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${c.imageId} not found for ${c.biodata}`); - imageId = null; - } - } - - await prisma.profilPerbekel.upsert({ - where: { id: c.id }, - update: { - biodata: c.biodata, - pengalaman: c.pengalaman, - pengalamanOrganisasi: c.pengalamanOrganisasi, - programUnggulan: c.programUnggulan, - imageId, - }, - create: { - id: c.id, - biodata: c.biodata, - pengalaman: c.pengalaman, - pengalamanOrganisasi: c.pengalamanOrganisasi, - programUnggulan: c.programUnggulan, - imageId, - }, - }); - } - - // ============ PERBEKEL DARI MASA KE MAS ============ - console.log("🔄 Seeding Perbekel Dari Masa Ke Masa..."); - for (const c of perbekelDariMasaKeMasa) { - const existing = await prisma.perbekelDariMasaKeMasa.findUnique({ - where: { id: c.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && c.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: c.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${c.imageId} not found for ${c.nama}`); - imageId = null; - } - } - - await prisma.perbekelDariMasaKeMasa.upsert({ - where: { id: c.id }, - update: { - nama: c.nama, - periode: c.periode, - daerah: c.daerah, - imageId, - }, - create: { - id: c.id, - nama: c.nama, - periode: c.periode, - daerah: c.daerah, - imageId, - }, - }); - } - - // =========== VISI MISI DESA =========== - for (const l of visiMisiDesa) { - await prisma.visiMisiDesa.upsert({ - where: { - id: l.id, - }, - update: { - visi: l.visi, - misi: l.misi, - }, - create: { - id: l.id, - visi: l.visi, - misi: l.misi, - }, - }); - } - - console.log("visi misi desa success ..."); - - // =========== SUBMENU POTENSI DESA =========== - console.log("🔄Seeding Kategori Potensi Desa ..."); - for (const c of kategoriPotensi) { - await prisma.kategoriPotensi.upsert({ - where: { - id: c.id, - }, - update: { - nama: c.nama, - }, - create: { - id: c.id, - nama: c.nama, - }, - }); - } - - console.log("kategori Potensi success ..."); - - console.log("🔄 Seeding Potensi Desa..."); - for (const p of potensi) { - const existing = await prisma.potensiDesa.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.potensiDesa.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - deskripsi: p.deskripsi, - content: p.content, - kategoriId: p.kategoriId, - imageId, - }, - create: { - name: p.name, - deskripsi: p.deskripsi, - content: p.content, - kategoriId: p.kategoriId, - imageId, - }, - }); - } - - console.log("potensi success ..."); - - // ================== SUBMENU BERITA ======================== - console.log("🔄 Seeding Kategori Berita..."); - for (const k of kategoriBerita) { - await prisma.kategoriBerita.upsert({ - where: { - name: k.name, // ✅ cocok dengan @unique - }, - update: { - name: k.name, - isActive: true, - }, - create: { - id: k.id, // ✅ id tetap bisa disimpan - name: k.name, - isActive: true, - }, - }); - } - - console.log("kategori berita success ..."); - - console.log("🔄 Seeding Berita..."); - for (const b of berita) { - const existing = await prisma.berita.findUnique({ - where: { id: b.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && b.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: b.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${b.imageId} not found for ${b.judul}`); - imageId = null; - } - } - - await prisma.berita.upsert({ - where: { - id: b.id, - }, - update: { - judul: b.judul, - deskripsi: b.deskripsi, - content: b.content, - kategoriBeritaId: b.kategoriBeritaId, - imageId, - }, - create: { - judul: b.judul, - deskripsi: b.deskripsi, - content: b.content, - kategoriBeritaId: b.kategoriBeritaId, - imageId, - }, - }); - } - console.log("berita success ..."); - - // ================== SUBMENU PENGUMUMAN ======================== - console.log("🔄 Seeding Kategori Pengumuman..."); - for (const c of kategoriPengumuman) { - await safeSeedUnique( - "categoryPengumuman", - { name: c.name }, // ✅ where clause - { - id: c.id, - name: c.name, - }, - ); - } - - console.log("kategori pengumuman success ..."); - - console.log("🔄 Seeding Pengumuman..."); - for (const p of pengumuman) { - await prisma.pengumuman.upsert({ - where: { - id: p.id, - }, - update: { - judul: p.judul, - deskripsi: p.deskripsi, - content: p.content, - categoryPengumumanId: p.categoryPengumumanId, - }, - create: { - judul: p.judul, - deskripsi: p.deskripsi, - content: p.content, - categoryPengumumanId: p.categoryPengumumanId, - }, - }); - } - - console.log("pengumuman success ..."); - - // ================== SUBMENU GALLERY ======================== - console.log("🔄 Seeding Gallery Video..."); - for (const v of galleryVideo) { - await prisma.galleryVideo.upsert({ - where: { - id: v.id, - }, - update: { - name: v.judul, - deskripsi: v.deskripsi, - linkVideo: v.linkVideo, - }, - create: { - name: v.judul, - deskripsi: v.deskripsi, - linkVideo: v.linkVideo, - }, - }); - } - - console.log("gallery video success ..."); - - // =========== LAYANAN DESA =========== - console.log("🔄 Seeding Pelayanan Surat Keterangan..."); - - for (const p of pelayananSuratKeterangan) { - const existing = await prisma.pelayananSuratKeterangan.findUnique({ - where: { id: p.id }, - select: { imageId: true, image2Id: true }, // 📌 tambahkan image2Id - }); - - // 1️⃣ Handle imageId - let imageId = existing?.imageId ?? null; - - if (!imageId && p.image) { - imageId = await resolveImageById(p.image); - - if (imageId) { - console.log(`✅ Image resolved for "${p.name}" → ${p.image}`); - } else { - console.warn(`⚠️ Image not resolved for "${p.name}" → ${p.image}`); - } - } - - // 2️⃣ Handle image2Id - let image2Id = existing?.image2Id ?? null; - - if (!image2Id && p.image2) { - image2Id = await resolveImageById(p.image2); - - if (image2Id) { - console.log(`✅ Image2 resolved for "${p.name}" → ${p.image2}`); - } else { - console.warn(`⚠️ Image2 not resolved for "${p.name}" → ${p.image2}`); - } - } - - // 3️⃣ Upsert dengan kedua image - await prisma.pelayananSuratKeterangan.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - imageId, - image2Id, // 📌 tambahkan ini - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - imageId, - image2Id, // 📌 tambahkan ini - }, - }); - } - console.log("✅ Pelayanan Surat Keterangan success..."); - - for (const p of pelayananTelunjukSaktiDesa) { - await prisma.pelayananTelunjukSaktiDesa.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - link: p.link, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - link: p.link, - }, - }); - } - console.log("pelayanan telunjuk sakti desa success ..."); - - for (const l of pelayananPerizinanBerusaha) { - await prisma.pelayananPerizinanBerusaha.upsert({ - where: { - id: l.id, - }, - update: { - name: l.name, - deskripsi: l.deskripsi, - link: l.link, - }, - create: { - id: l.id, - name: l.name, - deskripsi: l.deskripsi, - link: l.link, - }, - }); - } - - console.log("pelayanan perizinan berusaha success ..."); - - for (const l of pelayananPendudukNonPermanen) { - await prisma.pelayananPendudukNonPermanen.upsert({ - where: { - id: l.id, - }, - update: { - name: l.name, - deskripsi: l.deskripsi, - }, - create: { - id: l.id, - name: l.name, - deskripsi: l.deskripsi, - }, - }); - } - console.log("pelayanan penduduk non permanen success ..."); - - // =========== PENGHARGAAN =========== - console.log("🔄 Seeding Penghargaan..."); - for (const p of penghargaan) { - const existing = await prisma.penghargaan.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.penghargaan.upsert({ - where: { id: p.id }, - update: { - name: p.name, - juara: p.juara, - deskripsi: p.deskripsi, - imageId, - }, - create: { - id: p.id, - name: p.name, - juara: p.juara, - deskripsi: p.deskripsi, - imageId, - }, - }); - } - console.log("penghargaan success ..."); - - const flattenedPosisiBumdes = posisiOrganisasi.flat(); - - // ====================== MENU KESEHATAN ======================== - // ==================== SUBMENU POSYANDU ========================= - console.log("🔄 Seeding Posyandu..."); - for (const p of posyandu) { - const existing = await prisma.posyandu.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.posyandu.upsert({ - where: { id: p.id }, - update: { - name: p.name, - nomor: p.nomor, - deskripsi: p.deskripsi, - jadwalPelayanan: p.jadwalPelayanan, - imageId, - }, - create: { - id: p.id, - name: p.name, - nomor: p.nomor, - deskripsi: p.deskripsi, - jadwalPelayanan: p.jadwalPelayanan, - imageId, - }, - }); - } - console.log("posyandu success ..."); - - // ==================== SUBMENU PUSKESMAS ========================= - console.log("🔄 Seeding Kontak Puskesmas..."); - for (const k of kontakPuskesmas) { - await prisma.kontakPuskesmas.upsert({ - where: { - id: k.id, - }, - update: { - kontakPuskesmas: k.kontakPuskesmas, - email: k.email, - facebook: k.facebook, - kontakUGD: k.kontakUGD, - }, - create: { - id: k.id, - kontakPuskesmas: k.kontakPuskesmas, - email: k.email, - facebook: k.facebook, - kontakUGD: k.kontakUGD, - }, - }); - } - console.log("kontak puskesmas success ..."); - - console.log("🔄 Seeding Jam Puskesmas..."); - for (const k of jamPuskesmas) { - await prisma.jamOperasional.upsert({ - where: { - id: k.id, - }, - update: { - workDays: k.workDays, - weekDays: k.weekDays, - holiday: k.holiday, - }, - create: { - id: k.id, - workDays: k.workDays, - weekDays: k.weekDays, - holiday: k.holiday, - }, - }); - } - console.log("jam puskesmas success ..."); - - console.log("🔄 Seeding Puskesmas..."); - for (const p of puskesmas) { - const existing = await prisma.puskesmas.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.puskesmas.upsert({ - where: { id: p.id }, - update: { - name: p.name, - alamat: p.alamat, - jamId: p.jamId, - imageId, - kontakId: p.kontakId, - }, - create: { - id: p.id, - name: p.name, - alamat: p.alamat, - jamId: p.jamId, - imageId, - kontakId: p.kontakId, - }, - }); - } - console.log("puskesmas success ..."); - - // ==================== SUBMENU PROGRAM KESEHATAN ========================= - console.log("🔄 Seeding Program Kesehatan..."); - for (const p of programKesehatan) { - const existing = await prisma.programKesehatan.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.programKesehatan.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsiSingkat: p.deskripsiSingkat, - deskripsi: p.deskripsi, - imageId, - }, - create: { - id: p.id, - name: p.name, - deskripsiSingkat: p.deskripsiSingkat, - deskripsi: p.deskripsi, - imageId, - }, - }); - } - console.log("program kesehatan success ..."); - - // ==================== SUBMENU PENANGANAN DARURAT ========================= - console.log("🔄 Seeding Penanganan Darurat..."); - for (const p of penangananDarurat) { - const existing = await prisma.penangananDarurat.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.penangananDarurat.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - imageId, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - imageId, - }, - }); - } - console.log("penanganan darurat success ..."); - - // ==================== SUBMENU KONTAK DARURAT ========================= - console.log("🔄 Seeding Kontak Darurat..."); - for (const p of kontakDarurat) { - const existing = await prisma.kontakDarurat.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.kontakDarurat.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsi: p.deskripsi, - whatsapp: p.whatsapp, - imageId, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - whatsapp: p.whatsapp, - imageId, - }, - }); - } - console.log("kontak darurat success ..."); - - // ==================== SUBMENU INFO WABAH PENYAKIT ========================= - console.log("🔄 Seeding Info Wabah Penyakit..."); - for (const p of infoWabahPenyakit) { - const existing = await prisma.infoWabahPenyakit.findUnique({ - where: { id: p.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && p.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: p.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); - imageId = null; - } - } - - await prisma.infoWabahPenyakit.upsert({ - where: { id: p.id }, - update: { - name: p.name, - deskripsiSingkat: p.deskripsiSingkat, - deskripsiLengkap: p.deskripsiLengkap, - imageId, - }, - create: { - id: p.id, - name: p.name, - deskripsiSingkat: p.deskripsiSingkat, - deskripsiLengkap: p.deskripsiLengkap, - imageId, - }, - }); - } - console.log("info wabah penyakit success ..."); - - // ====================== MENU KEAMANAN ======================== - // ==================== SUBMENU KEAMANAN LINGKUNGAN ============ - console.log("🔄 Seeding Keamanan Lingkungan..."); - for (const k of keamananLingkungan) { - const existing = await prisma.keamananLingkungan.findUnique({ - where: { id: k.id }, - select: { imageId: true }, - }); - - let imageId = existing?.imageId; // Pertahankan existing - - // Kalau belum ada imageId, cari berdasarkan name/realName - if (!imageId && k.imageId) { - // ✅ Cari langsung berdasarkan ID yang ada di p.imageId - const fileRecord = await prisma.fileStorage.findUnique({ - where: { id: k.imageId }, - select: { id: true, name: true }, - }); - - if (fileRecord) { - imageId = fileRecord.id; - console.log( - `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, - ); - } else { - console.warn(`⚠️ File with ID ${k.imageId} not found for ${k.name}`); - imageId = null; - } - } - - await prisma.keamananLingkungan.upsert({ - where: { id: k.id }, - update: { - name: k.name, - deskripsi: k.deskripsi, - imageId, - }, - create: { - id: k.id, - name: k.name, - deskripsi: k.deskripsi, - imageId, - }, - }); - } - console.log("info wabah penyakit success ..."); - - // ==================== SUBMENU POLSEK TERDEKAT ================ - console.log("🔄 Seeding Layanan Polsek..."); - for (const k of layananPolsek) { - await prisma.layananPolsek.upsert({ - where: { - id: k.id, - }, - update: { - nama: k.nama, - }, - create: { - id: k.id, - nama: k.nama, - }, - }); - } - - console.log("layanan polsek success ..."); - - console.log("🔄 Seeding Polsek Terdekat..."); - for (const k of polsekTerdekat) { - await prisma.polsekTerdekat.upsert({ - where: { - id: k.id, - }, - update: { - nama: k.nama, - jarakKeDesa: k.jarakKeDesa, - alamat: k.alamat, - nomorTelepon: k.nomorTelepon, - jamOperasional: k.jamOperasional, - embedMapUrl: k.embedMapUrl, - namaTempatMaps: k.namaTempatMaps, - alamatMaps: k.alamatMaps, - linkPetunjukArah: k.linkPetunjukArah, - layananPolsekId: k.layananPolsekId, - }, - create: { - id: k.id, - nama: k.nama, - jarakKeDesa: k.jarakKeDesa, - alamat: k.alamat, - nomorTelepon: k.nomorTelepon, - jamOperasional: k.jamOperasional, - embedMapUrl: k.embedMapUrl, - namaTempatMaps: k.namaTempatMaps, - alamatMaps: k.alamatMaps, - linkPetunjukArah: k.linkPetunjukArah, - layananPolsekId: k.layananPolsekId, - }, - }); - } - - console.log("polsek terdekat success ..."); - - console.log("🔄 Seeding Layanan To Polsek..."); - for (const k of layananToPolsek) { - await prisma.layananToPolsek.upsert({ - where: { - id: k.id, - }, - update: { - layananId: k.layananId, - polsekTerdekatId: k.polsekTerdekatId, - }, - create: { - id: k.id, - layananId: k.layananId, - polsekTerdekatId: k.polsekTerdekatId, - }, - }); - } - - console.log("layanan to polsek success ..."); - - // ==================== SUBMENU KONTAK DARURAT ================= - - console.log("🔄 Seeding Kontak Item..."); - for (const e of kontakItem) { - await prisma.kontakItem.upsert({ - where: { - id: e.id, - }, - update: { - nama: e.nama, - icon: e.icon, - nomorTelepon: e.nomorTelepon, - }, - create: { - id: e.id, // ✅ WAJIB - nama: e.nama, - icon: e.icon, - nomorTelepon: e.nomorTelepon, - }, - }); - } - console.log("✅ Kontak Item seeded successfully"); - - console.log("🔄 Seeding Kontak Darurat Keamanan..."); - for (const d of kontakDaruratKeamanan) { - await prisma.kontakDaruratKeamanan.upsert({ - where: { - id: d.id, - }, - update: { - nama: d.nama, - icon: d.icon, - kategoriId: d.kategoriId, - }, - create: { - id: d.id, - nama: d.nama, - icon: d.icon, - kategoriId: d.kategoriId, - }, - }); - } - - console.log("✅ Kontak Darurat Keamanan seeded successfully"); - - console.log("🔄 Seeding Kontak Darurat To Item..."); - for (const f of kontakDaruratToItem) { - // ✅ Validasi foreign keys - const kontakDaruratExists = await prisma.kontakDaruratKeamanan.findUnique({ - where: { id: f.kontakDaruratId }, - }); - - const kontakItemExists = await prisma.kontakItem.findUnique({ - where: { id: f.kontakItemId }, - }); - - if (!kontakDaruratExists) { - console.warn( - `⚠️ KontakDarurat ${f.kontakDaruratId} not found, skipping...`, - ); - continue; - } - - if (!kontakItemExists) { - console.warn(`⚠️ KontakItem ${f.kontakItemId} not found, skipping...`); - continue; - } - - await prisma.kontakDaruratToItem.upsert({ - where: { id: f.id }, - update: { - kontakDaruratId: f.kontakDaruratId, - kontakItemId: f.kontakItemId, - }, - create: { - id: f.id, - kontakDaruratId: f.kontakDaruratId, - kontakItemId: f.kontakItemId, - }, - }); - } - console.log("✅ Kontak Darurat To Item seeded successfully"); - - // ==================== SUBMENU PENCEGAHAN KRIMINALITAS ======== - console.log("🔄 Seeding Pencegahan Kriminalitas..."); - for (const d of pencegahanKriminalitas) { - await prisma.pencegahanKriminalitas.upsert({ - where: { - id: d.id, - }, - update: { - judul: d.judul, - deskripsi: d.deskripsi, - deskripsiSingkat: d.deskripsiSingkat, - linkVideo: d.linkVideo, - }, - create: { - id: d.id, - judul: d.judul, - deskripsi: d.deskripsi, - deskripsiSingkat: d.deskripsiSingkat, - linkVideo: d.linkVideo, - }, - }); - } - - console.log("✅ Pencegahan Kriminalitas seeded successfully"); - // ==================== SUBMENU LAPORAN PUBLIK ================= - console.log("🔄 Seeding Laporan Publik..."); - for (const l of laporanPublik) { - await prisma.laporanPublik.upsert({ - where: { - id: l.id, - }, - update: { - judul: l.judul, - lokasi: l.lokasi, - tanggalWaktu: l.tanggalWaktu, - kronologi: l.kronologi, - }, - create: { - id: l.id, - judul: l.judul, - lokasi: l.lokasi, - tanggalWaktu: l.tanggalWaktu, - kronologi: l.kronologi, - }, - }); - } - - console.log("laporan publik success ..."); - - console.log("🔄 Seeding Penanganan Laporan..."); - for (const l of penangananLaporan) { - await prisma.penangananLaporanPublik.upsert({ - where: { - id: l.id, - }, - update: { - deskripsi: l.deskripsi, - laporanId: l.laporanId, - }, - create: { - id: l.id, - deskripsi: l.deskripsi, - laporanId: l.laporanId, - }, - }); - } - - console.log("penanganan laporan success ..."); - - // ==================== SUBMENU TIPS KEAMANAN ================== - console.log("🔄 Seeding Tips Keamanan..."); - for (const t of tipsKeamanan) { - await prisma.menuTipsKeamanan.upsert({ - where: { - id: t.id, - }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - imageId: t.imageId, - }, - create: { - judul: t.judul, - deskripsi: t.deskripsi, - imageId: t.imageId, - }, - }); - } - - console.log("✅ Tips Keamanan seeded successfully"); - - // ====================== MENU EKONOMI ======================== - // ==================== SUBMENU PASAR DESA ==================== - console.log("🔄 Seeding Kategori Produk..."); - for (const k of kategoriProduk) { - await prisma.kategoriProduk.upsert({ - where: { - id: k.id, - }, - update: { - nama: k.nama, - }, - create: { - id: k.id, - nama: k.nama, - }, - }); - } - console.log("✅ Kategori Produk seeded successfully"); - - console.log("🔄 Seeding Pasar Desa..."); - for (const p of pasarDesa) { - await prisma.pasarDesa.upsert({ - where: { - id: p.id, - }, - update: { - nama: p.nama, - imageId: p.imageId, - harga: p.harga, - rating: p.rating, - alamatUsaha: p.alamatUsaha, - kontak: p.kontak, - deskripsi: p.deskripsi, - kategoriProdukId: p.kategoriProdukId, - }, - create: { - id: p.id, - nama: p.nama, - imageId: p.imageId, - harga: p.harga, - rating: p.rating, - alamatUsaha: p.alamatUsaha, - kontak: p.kontak, - deskripsi: p.deskripsi, - kategoriProdukId: p.kategoriProdukId, - }, - }); - } - console.log("✅ Pasar Desa seeded successfully"); - - console.log("🔄 Seeding Kategori To Pasar..."); - for (const p of kategoriToPasar) { - await prisma.kategoriToPasar.upsert({ - where: { - id: p.id, - }, - update: { - kategoriId: p.kategoriId, - pasarDesaId: p.pasarDesaId, - }, - create: { - id: p.id, - kategoriId: p.kategoriId, - pasarDesaId: p.pasarDesaId, - }, - }); - } - - // ==================== SUBMENU LOWONGAN KERJA LOKAL ========== - console.log("🔄 Seeding Lowongan Kerja Lokal..."); - for (const k of lowonganKerjaLokal) { - await prisma.lowonganPekerjaan.upsert({ - where: { - id: k.id, - }, - update: { - posisi: k.posisi, - namaPerusahaan: k.namaPerusahaan, - lokasi: k.lokasi, - tipePekerjaan: k.tipePekerjaan, - gaji: k.gaji, - deskripsi: k.deskripsi, - kualifikasi: k.kualifikasi, - notelp: k.notelp, - }, - create: { - id: k.id, - posisi: k.posisi, - namaPerusahaan: k.namaPerusahaan, - lokasi: k.lokasi, - tipePekerjaan: k.tipePekerjaan, - gaji: k.gaji, - deskripsi: k.deskripsi, - kualifikasi: k.kualifikasi, - notelp: k.notelp, - }, - }); - } - console.log("✅ Lowongan Kerja Lokal seeded successfully"); - - // ==================== SUBMENU STRUKTUR ORGANISASI DAN SK PENGURUS BUMDES ========== - const sortedPosisiBumdes = flattenedPosisiBumdes.sort( - (a, b) => a.hierarki - b.hierarki, - ); - - for (const p of sortedPosisiBumdes) { - console.log(`Seeding: ${p.nama} (id: ${p.id}, parent: ${p.parentId})`); - - if (p.parentId) { - const parentExists = flattenedPosisi.some((pos) => pos.id === p.parentId); - if (!parentExists) { - console.warn( - `⚠️ Parent tidak ditemukan: ${p.parentId} untuk ${p.nama}`, - ); - continue; - } - } - - await prisma.posisiOrganisasiBumDes.upsert({ - where: { id: p.id }, - update: p, - create: p, - }); - } - console.log("posisi organisasi berhasil"); - - for (const p of pegawai) { - await prisma.pegawaiBumDes.upsert({ - where: { - id: p.id, - }, - update: { - namaLengkap: p.namaLengkap, - gelarAkademik: p.gelarAkademik, - tanggalMasuk: new Date(p.tanggalMasuk), - email: p.email, - telepon: p.telepon, - alamat: p.alamat, - posisiId: p.posisiId, - isActive: p.isActive, - }, - create: { - id: p.id, - namaLengkap: p.namaLengkap, - gelarAkademik: p.gelarAkademik, - tanggalMasuk: new Date(p.tanggalMasuk), - email: p.email, - telepon: p.telepon, - alamat: p.alamat, - posisiId: p.posisiId, - isActive: p.isActive, - }, - }); - } - console.log("pegawai success ..."); - - // ==================== SUBMENU PENDAPATAN ASLI DESA ========== - - // ==================== SUBMENU JUMLAH PENGANGGURAN ========== - for (const d of detailDataPengangguran) { - await prisma.detailDataPengangguran.upsert({ - where: { - month_year: { month: d.month, year: d.year }, - }, - update: { - totalUnemployment: d.totalUnemployment, - educatedUnemployment: d.educatedUnemployment, - uneducatedUnemployment: d.uneducatedUnemployment, - percentageChange: d.percentageChange, - }, - create: { - month: d.month, - year: d.year, - totalUnemployment: d.totalUnemployment, - educatedUnemployment: d.educatedUnemployment, - uneducatedUnemployment: d.uneducatedUnemployment, - percentageChange: d.percentageChange, - }, - }); - } - console.log("📊 detailDataPengangguran success ..."); - - // ==================== SUBMENU PENDUDUK USIA KERJA ========== - for (const p of grafikMenganggurBerdasarkanUsia) { - await prisma.grafikMenganggurBerdasarkanUsia.upsert({ - where: { - id: p.id, - }, - update: { - usia18_25: p.usia18_25, - usia26_35: p.usia26_35, - usia36_45: p.usia36_45, - usia46_keatas: p.usia46_keatas, - }, - create: { - id: p.id, - usia18_25: p.usia18_25, - usia26_35: p.usia26_35, - usia36_45: p.usia36_45, - usia46_keatas: p.usia46_keatas, - }, - }); - } - console.log("📊 grafikMenganggurBerdasarkanUsia success ..."); - - for (const p of grafikMenganggurBerdasarkanPendidikan) { - await prisma.grafikMenganggurBerdasarkanPendidikan.upsert({ - where: { - id: p.id, - }, - update: { - SD: p.SD, - SMP: p.SMP, - SMA: p.SMA, - D3: p.D3, - S1: p.S1, - }, - create: { - id: p.id, - SD: p.SD, - SMP: p.SMP, - SMA: p.SMA, - D3: p.D3, - S1: p.S1, - }, - }); - } - console.log("📊 grafikMenganggurBerdasarkanUsia success ..."); - - // ==================== SUBMENU PENDUDUK MISKIN ============= - console.log("🔄 Seeding Jumlah Penduduk Miskin..."); - for (const k of jumlahPendudukMiskin) { - await prisma.grafikJumlahPendudukMiskin.upsert({ - where: { - id: k.id, - }, - update: { - year: k.year, - totalPoorPopulation: k.totalPoorPopulation, - }, - create: { - id: k.id, - year: k.year, - totalPoorPopulation: k.totalPoorPopulation, - }, - }); - } - console.log("✅ Jumlah Penduduk Miskin seeded successfully"); - - // ==================== SUBMENU PROGRAM KEMISKINAN ============= - for (const s of statistikKemiskinan) { - await prisma.statistikKemiskinan.upsert({ - where: { tahun: s.tahun }, // ✅ FIX - update: { - jumlah: s.jumlah, - }, - create: { - id: s.id, // id boleh tetap - tahun: s.tahun, - jumlah: s.jumlah, - }, - }); - } - - console.log("📊 Statistik Kemiskinan seeded successfully"); - - console.log("🔄 Seeding Program Kemiskinan..."); - for (const k of programKemiskinan) { - await prisma.programKemiskinan.upsert({ - where: { id: k.id }, - update: { - nama: k.nama, - deskripsi: k.deskripsi, - icon: k.icon, - statistik: { - connect: { - tahun: k.tahun, // 👈 BUKAN ID - }, - }, - }, - create: { - id: k.id, - nama: k.nama, - deskripsi: k.deskripsi, - icon: k.icon, - statistik: { - connect: { - tahun: k.tahun, - }, - }, - }, - }); - } - console.log("✅ Program Kemiskinan seeded successfully"); - - // ==================== SUBMENU SEKTOR UNGGULAN DESA ============= - console.log("🔄 Seeding Sektor Unggulan Desa..."); - for (const k of sektorUnggulanDesa) { - await prisma.sektorUnggulanDesa.upsert({ - where: { - id: k.id, - }, - update: { - name: k.name, - description: k.description, - value: k.value, - }, - create: { - id: k.id, - name: k.name, - description: k.description, - value: k.value, - }, - }); - } - console.log("✅ Sektor Unggulan Desa seeded successfully"); - - // ==================== SUBMENU DEMOGRAFI PEKERJAAN ============= - console.log("🔄 Seeding Demografi Pekerjaan..."); - for (const k of demografiPekerjaan) { - await prisma.dataDemografiPekerjaan.upsert({ - where: { - id: k.id, - }, - update: { - pekerjaan: k.pekerjaan, - lakiLaki: k.lakiLaki, - perempuan: k.perempuan, - }, - create: { - id: k.id, - pekerjaan: k.pekerjaan, - lakiLaki: k.lakiLaki, - perempuan: k.perempuan, - }, - }); - } - console.log("✅ Demografi Pekerjaan seeded successfully"); - - // ====================== MENU INOVASI ========================== - // ====================== SUBMENU AJUKAN IDE INOVATIF =========== - console.log("🔄 Seeding Ajukan Ide Inovatif..."); - for (const d of ajukanIde) { - await prisma.ajukanIdeInovatif.upsert({ - where: { - id: d.id, - }, - update: { - name: d.name, - alamat: d.alamat, - namaIde: d.namaIde, - deskripsi: d.deskripsi, - masalah: d.masalah, - benefit: d.benefit, - }, - create: { - id: d.id, - name: d.name, - alamat: d.alamat, - namaIde: d.namaIde, - deskripsi: d.deskripsi, - masalah: d.masalah, - benefit: d.benefit, - }, - }); - } - console.log("✅ Ajukan Ide Inovatif seeded successfully"); - // ==================== SUBMENU DESA DIGITAL ==================== - console.log("🔄 Seeding Desa Digital..."); - for (const d of desaDigital) { - await prisma.desaDigital.upsert({ - where: { - id: d.id, - }, - update: { - name: d.name, - deskripsi: d.deskripsi, - imageId: d.imageId, - }, - create: { - id: d.id, - name: d.name, - deskripsi: d.deskripsi, - imageId: d.imageId, - }, - }); - } - console.log("✅ Desa Digital seeded successfully"); - - // ==================== SUBMENU LAYANAN ONLINE DESA ========== - console.log("🔄 Seeding Jenis Layanan..."); - for (const j of jenisLayanan) { - await prisma.jenisLayanan.upsert({ - where: { - id: j.id, - }, - update: { - nama: j.nama, - deskripsi: j.deskripsi, - }, - create: { - id: j.id, - nama: j.nama, - deskripsi: j.deskripsi, - }, - }); - } - console.log("✅ Jenis Layanan seeded successfully"); - - console.log("🔄 Seeding Administrasi Online..."); - for (const d of administrasiOnline) { - await prisma.administrasiOnline.upsert({ - where: { - id: d.id, - }, - update: { - name: d.name, - alamat: d.alamat, - nomorTelepon: d.nomorTelepon, - jenisLayananId: d.jenisLayananId, - }, - create: { - id: d.id, - name: d.name, - alamat: d.alamat, - nomorTelepon: d.nomorTelepon, - jenisLayananId: d.jenisLayananId, - }, - }); - } - console.log("✅ Administrasi Online seeded successfully"); - - console.log("🔄 Seeding Jenis Pengaduan Masyarakat..."); - for (const d of jenisPengaduan) { - await prisma.jenisPengaduan.upsert({ - where: { - id: d.id, - }, - update: { - nama: d.nama, - }, - create: { - id: d.id, - nama: d.nama, - }, - }); - } - console.log("✅ Jenis Pengaduan Masyarakat seeded successfully"); - - console.log("🔄 Seeding Pengaduan Masyarakat..."); - for (const d of pengaduanMasyarakat) { - await prisma.pengaduanMasyarakat.upsert({ - where: { - id: d.id, - }, - update: { - name: d.name, - email: d.email, - nik: d.nik, - nomorTelepon: d.nomorTelepon, - judulPengaduan: d.judulPengaduan, - lokasiKejadian: d.lokasiKejadian, - imageId: d.imageId, - deskripsiPengaduan: d.deskripsiPengaduan, - jenisPengaduanId: d.jenisPengaduanId, - }, - create: { - id: d.id, - name: d.name, - email: d.email, - nik: d.nik, - nomorTelepon: d.nomorTelepon, - judulPengaduan: d.judulPengaduan, - lokasiKejadian: d.lokasiKejadian, - imageId: d.imageId, - deskripsiPengaduan: d.deskripsiPengaduan, - jenisPengaduanId: d.jenisPengaduanId, - }, - }); - } - console.log("✅ Pengaduan Masyarakat seeded successfully"); - - // ==================== SUBMENU PROGRAM KREATIF ========== - console.log("🔄 Seeding Program Kreatif..."); - for (const p of programKreatif) { - await prisma.programKreatif.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - deskripsi: p.deskripsi, - icon: p.icon, - slug: p.slug, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - icon: p.icon, - slug: p.slug, - }, - }); - } - console.log("✅ Program Kreatif seeded successfully"); - - // ==================== SUBMENU KOLABORASI INOVASI ========== - console.log("🔄 Seeding Kolaborasi Inovasi..."); - for (const p of kolaborasiInovasi) { - await prisma.kolaborasiInovasi.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - tahun: p.tahun, - slug: p.slug, - deskripsi: p.deskripsi, - kolaborator: p.kolaborator, - }, - create: { - id: p.id, - name: p.name, - tahun: p.tahun, - slug: p.slug, - deskripsi: p.deskripsi, - kolaborator: p.kolaborator, - }, - }); - } - console.log("✅ Kolaborasi Inovasi seeded successfully"); - - console.log("🔄 Seeding Mitra Kolaborasi..."); - for (const p of mitraKolaborasi) { - await prisma.mitraKolaborasi.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - imageId: p.imageId, - }, - create: { - id: p.id, - name: p.name, - imageId: p.imageId, - }, - }); - } - console.log("✅ Mitra Kolaborasi seeded successfully"); - - // ==================== SUBMENU INFO TEKNOLOGI TEPAT GUNA ========== - console.log("🔄 Seeding Info Teknologi..."); - for (const p of infoTeknologi) { - await prisma.infoTekno.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - deskripsi: p.deskripsi, - imageId: p.imageId, - }, - create: { - id: p.id, - name: p.name, - deskripsi: p.deskripsi, - imageId: p.imageId, - }, - }); - } - console.log("✅ Info Teknologi seeded successfully"); - - // ====================== MENU LINGKUNGAN ========================== - // ==================== SUBMENU PENGELOLAAN SAMPAH ========== - console.log("🔄 Seeding Pengelolaan Sampah..."); - for (const p of pengelolaanSampah) { - await prisma.pengelolaanSampah.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - icon: p.icon, - }, - create: { - id: p.id, - name: p.name, - icon: p.icon, - }, - }); - } - console.log("✅ Pengelolaan Sampah seeded successfully"); - - console.log("🔄 Seeding Keterangan Bank Sampah..."); - for (const p of keteranganBankSampah) { - await prisma.keteranganBankSampahTerdekat.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - alamat: p.alamat, - namaTempatMaps: p.namaTempatMaps, - linkPetunjukArah: p.linkPetunjukArah, - lat: p.lat, - lng: p.lng, - }, - create: { - id: p.id, - name: p.name, - alamat: p.alamat, - namaTempatMaps: p.namaTempatMaps, - linkPetunjukArah: p.linkPetunjukArah, - lat: p.lat, - lng: p.lng, - }, - }); - } - console.log("✅ Keterangan Bank Sampah seeded successfully"); - - // ==================== SUBMENU PROGRAM PENGHIJAUAN ========== - console.log("🔄 Seeding Program Penghijauan..."); - for (const p of programPenghijauan) { - await prisma.programPenghijauan.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - judul: p.judul, - deskripsi: p.deskripsi, - icon: p.icon, - }, - create: { - id: p.id, - name: p.name, - judul: p.judul, - deskripsi: p.deskripsi, - icon: p.icon, - }, - }); - } - console.log("✅ Program Penghijauan seeded successfully"); - - // ==================== SUBMENU DATA LINGKUNGAN DESA ========== - console.log("🔄 Seeding Data Lingkungan Desa..."); - for (const p of dataLingkunganDesa) { - await prisma.dataLingkunganDesa.upsert({ - where: { - id: p.id, - }, - update: { - name: p.name, - jumlah: p.jumlah, - deskripsi: p.deskripsi, - icon: p.icon, - }, - create: { - id: p.id, - name: p.name, - jumlah: p.jumlah, - deskripsi: p.deskripsi, - icon: p.icon, - }, - }); - } - console.log("✅ Data Lingkungan Desa seeded successfully"); - - // =========== SUBMENU GOTONG ROYONG =========== - console.log("🔄 Seeding Kategori Gotong Royong..."); - - for (const k of kategoriGotongRoyong) { - await prisma.kategoriKegiatan.upsert({ - where: { - id: k.id, - }, - update: { - nama: k.nama, - }, - create: { - id: k.id, - nama: k.nama, - }, - }); - } - - console.log("✅ Kategori Gotong Royong seeded successfully"); - - console.log("🔄 Seeding Gotong Royong..."); - - for (const k of gotongRoyong) { - await prisma.kegiatanDesa.upsert({ - where: { - id: k.id, - }, - update: { - judul: k.judul, - deskripsiSingkat: k.deskripsiSingkat, - deskripsiLengkap: k.deskripsiLengkap, - tanggal: k.tanggal, - lokasi: k.lokasi, - partisipan: k.partisipan, - imageId: k.imageId, - kategoriKegiatanId: k.kategoriKegiatanId, - }, - create: { - id: k.id, - judul: k.judul, - deskripsiSingkat: k.deskripsiSingkat, - deskripsiLengkap: k.deskripsiLengkap, - tanggal: k.tanggal, - lokasi: k.lokasi, - partisipan: k.partisipan, - imageId: k.imageId, - kategoriKegiatanId: k.kategoriKegiatanId, - }, - }); - } - - console.log("✅ Kategori Gotong Royong seeded successfully"); - - // =========== SUBMENU EDUKASI LINGKUNGAN =========== - - for (const e of tujuanEdukasiLingkungan) { - await prisma.tujuanEdukasiLingkungan.upsert({ - where: { - id: e.id, - }, - update: { - judul: e.judul, - deskripsi: e.deskripsi, - }, - create: { - id: e.id, - judul: e.judul, - deskripsi: e.deskripsi, - }, - }); - } - - console.log("tujuan edukasi lingkungan success ..."); - - for (const m of materiEdukasiLingkungan) { - await prisma.materiEdukasiLingkungan.upsert({ - where: { - id: m.id, - }, - update: { - judul: m.judul, - deskripsi: m.deskripsi, - }, - create: { - id: m.id, - judul: m.judul, - deskripsi: m.deskripsi, - }, - }); - } - - console.log("materi edukasi lingkungan success ..."); - - for (const c of contohEdukasiLingkungan) { - await prisma.contohEdukasiLingkungan.upsert({ - where: { - id: c.id, - }, - update: { - judul: c.judul, - deskripsi: c.deskripsi, - }, - create: { - id: c.id, - judul: c.judul, - deskripsi: c.deskripsi, - }, - }); - } - - console.log("contoh edukasi lingkungan success ..."); - - // =========== SUBMENU KONSERVASI ADAT BALI =========== - - for (const f of filosofiTriHita) { - await prisma.filosofiTriHita.upsert({ - where: { - id: f.id, - }, - update: { - judul: f.judul, - deskripsi: f.deskripsi, - }, - create: { - id: f.id, - judul: f.judul, - deskripsi: f.deskripsi, - }, - }); - } - - console.log("filosofi tri hita success ..."); - - for (const b of bentukKonservasiBerdasarkanAdat) { - await prisma.bentukKonservasiBerdasarkanAdat.upsert({ - where: { - id: b.id, - }, - update: { - judul: b.judul, - deskripsi: b.deskripsi, - }, - create: { - id: b.id, - judul: b.judul, - deskripsi: b.deskripsi, - }, - }); - } - - console.log("bentuk konservasi berdasarkan adat success ..."); - - for (const n of nilaiKonservasiAdat) { - await prisma.nilaiKonservasiAdat.upsert({ - where: { - id: n.id, - }, - update: { - judul: n.judul, - deskripsi: n.deskripsi, - }, - create: { - id: n.id, - judul: n.judul, - deskripsi: n.deskripsi, - }, - }); - } - - console.log("nilai konservasi adat success ..."); - - // ====================== MENU PENDIDIKAN ========================== - // =========== SUBMENU INFO SEKOLAH ===================== - - for (const j of jenjangPendidikan) { - await prisma.jenjangPendidikan.upsert({ - where: { - id: j.id, - }, - update: { - nama: j.nama, - }, - create: { - id: j.id, - nama: j.nama, - }, - }); - } - - console.log("✅ Jenjang Pendidikan seeded successfully"); - - for (const j of lembagaPendidikan) { - await prisma.lembaga.upsert({ - where: { - id: j.id, - }, - update: { - nama: j.nama, - jenjangId: j.jenjangId, - }, - create: { - id: j.id, - nama: j.nama, - jenjangId: j.jenjangId, - }, - }); - } - - console.log("✅ Lembaga Pendidikan seeded successfully"); - - for (const j of siswa) { - await prisma.siswa.upsert({ - where: { - id: j.id, - }, - update: { - nama: j.nama, - lembagaId: j.lembagaId, - }, - create: { - id: j.id, - nama: j.nama, - lembagaId: j.lembagaId, - }, - }); - } - - console.log("✅ siswa seeded successfully"); - - for (const j of pengajar) { - await prisma.pengajar.upsert({ - where: { - id: j.id, - }, - update: { - nama: j.nama, - lembagaId: j.lembagaId, - }, - create: { - id: j.id, - nama: j.nama, - lembagaId: j.lembagaId, - }, - }); - } - - console.log("✅ pengajar seeded successfully"); - - // =========== SUBMENU PROGRAM PENDIDIKAN ANAK ===================== - - for (const t of tujuanProgram) { - await prisma.tujuanProgram.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log("✅ tujuan program seeded (editable later via UI)"); - - for (const t of programUnggulan) { - await prisma.programUnggulan.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log("✅ program unggulan seeded (editable later via UI)"); - - // =========== SUBMENU BIMBINGAN BELAJAR DESA ===================== - - for (const t of tujuanBimbinganBelajarDesa) { - await prisma.tujuanBimbinganBelajarDesa.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ tujuan bimbingan belajar desa seeded (editable later via UI)", - ); - - for (const t of lokasiJadwalBimbinganBelajarDesa) { - await prisma.lokasiJadwalBimbinganBelajarDesa.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ lokasi jadwal bimbingan belajar desa seeded (editable later via UI)", - ); - - for (const t of fasilitasBimbinganBelajarDesa) { - await prisma.fasilitasBimbinganBelajarDesa.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", - ); - - // =========== SUBMENU PENDIDIKAN NON FORMAL ===================== - - for (const t of tujuanProgram2) { - await prisma.tujuanPendidikanNonFormal.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", - ); - - for (const t of tempatKegiatan) { - await prisma.tempatKegiatan.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", - ); - - for (const t of jenisProgramYangDiselenggarakan) { - await prisma.jenisProgramYangDiselenggarakan.upsert({ - where: { id: t.id }, - update: { - judul: t.judul, - deskripsi: t.deskripsi, - }, - create: { - id: t.id, - judul: t.judul, - deskripsi: t.deskripsi, - }, - }); - } - console.log( - "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", - ); - - // =========== SUBMENU PERPUSTAKAAN DIGITAL ===================== - console.log("🔄 Seeding Kategori Buku..."); - for (const k of kategoriBuku) { - await prisma.kategoriBuku.upsert({ - where: { - id: k.id, - }, - update: { - name: k.name, - }, - create: { - id: k.id, - name: k.name, - }, - }); - } - console.log("✅ Kategori Buku seeded successfully"); - - console.log("🔄 Seeding Data perpustakaan..."); - for (const k of dataPerpustakaan) { - await prisma.dataPerpustakaan.upsert({ - where: { - id: k.id, - }, - update: { - judul: k.judul, - deskripsi: k.deskripsi, - kategoriId: k.kategoriId, - imageId: k.imageId, - }, - create: { - id: k.id, - judul: k.judul, - deskripsi: k.deskripsi, - kategoriId: k.kategoriId, - imageId: k.imageId, - }, - }); - } - console.log("✅ Data perpustakaan seeded successfully"); + await seedProgramInovasi(); + await seedProfileLP(); + await seedMediaSosial(); + + // // =========== SUBMENU DESA ANTI KORUPSI =========== + await seedDesaAntiKorupsi(); + + // // =========== SDGSDesa =========== + await seedSDGSDesa(); + + // // =========== APBDes =========== + // for (const l of apbdes) { + // await prisma.aPBDes.upsert({ + // where: { + // id: l.id, + // }, + // update: { + // name: l.name, + // jumlah: l.jumlah, + // }, + // create: { + // name: l.name, + // jumlah: l.jumlah, + // }, + // }); + // } + + // console.log("apbdes success ..."); + + // // =========== PRESTASI DESA=========== + await seedPrestasiDesa(); + + // // =========== MENU PPID =========== + + // // =========== SUBMENU STRUKTUR PPID =========== + await seedPegawaiPpid(); + + // // =========== SUBMENU VISI MISI PPID =========== + await seedVisiMisiPpid(); + + // // =========== SUBMENU DASAR HUKUM PPID =========== + await seedDasarHukumPpid(); + + // // =========== SUBMENU DAFTAR INFORMASI PUBLIK PPID =========== + await seedDaftarInformasiPublikPpid(); + + // // =========== SUBMENU INDEKS KEPUASAN MASYARAKAT =========== + await seedIkmPpid(); + + // // =========== MENU DESA =========== + // // =========== SUBMENU PROFILE =========== + await seedProfileDesa(); + await seedProfilePerbekel(); + + // // =========== SUBMENU POTENSI DESA =========== + await seedPotensi(); + + // // =========== SUBMENU BERITA =========== + await seedBerita(); + + // // ================== SUBMENU PENGUMUMAN ======================== + await seedPengumuman(); + + // // ================== SUBMENU GALLERY ======================== + await seedVideo(); + await seedFoto(); + + // // =========== SUBMENU LAYANAN =========== + await seedLayanan(); + + // // =========== PENGHARGAAN =========== + await seedPenghargaan(); + + // // ====================== MENU KESEHATAN ======================== + // // ==================== SUBMENU POSYANDU ========================= + // console.log("🔄 Seeding Posyandu..."); + // for (const p of posyandu) { + // const existing = await prisma.posyandu.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.posyandu.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // nomor: p.nomor, + // deskripsi: p.deskripsi, + // jadwalPelayanan: p.jadwalPelayanan, + // imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // nomor: p.nomor, + // deskripsi: p.deskripsi, + // jadwalPelayanan: p.jadwalPelayanan, + // imageId, + // }, + // }); + // } + // console.log("posyandu success ..."); + + // // ==================== SUBMENU PUSKESMAS ========================= + // console.log("🔄 Seeding Kontak Puskesmas..."); + // for (const k of kontakPuskesmas) { + // await prisma.kontakPuskesmas.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // kontakPuskesmas: k.kontakPuskesmas, + // email: k.email, + // facebook: k.facebook, + // kontakUGD: k.kontakUGD, + // }, + // create: { + // id: k.id, + // kontakPuskesmas: k.kontakPuskesmas, + // email: k.email, + // facebook: k.facebook, + // kontakUGD: k.kontakUGD, + // }, + // }); + // } + // console.log("kontak puskesmas success ..."); + + // console.log("🔄 Seeding Jam Puskesmas..."); + // for (const k of jamPuskesmas) { + // await prisma.jamOperasional.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // workDays: k.workDays, + // weekDays: k.weekDays, + // holiday: k.holiday, + // }, + // create: { + // id: k.id, + // workDays: k.workDays, + // weekDays: k.weekDays, + // holiday: k.holiday, + // }, + // }); + // } + // console.log("jam puskesmas success ..."); + + // console.log("🔄 Seeding Puskesmas..."); + // for (const p of puskesmas) { + // const existing = await prisma.puskesmas.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.puskesmas.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // alamat: p.alamat, + // jamId: p.jamId, + // imageId, + // kontakId: p.kontakId, + // }, + // create: { + // id: p.id, + // name: p.name, + // alamat: p.alamat, + // jamId: p.jamId, + // imageId, + // kontakId: p.kontakId, + // }, + // }); + // } + // console.log("puskesmas success ..."); + + // // ==================== SUBMENU PROGRAM KESEHATAN ========================= + // console.log("🔄 Seeding Program Kesehatan..."); + // for (const p of programKesehatan) { + // const existing = await prisma.programKesehatan.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.programKesehatan.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // deskripsiSingkat: p.deskripsiSingkat, + // deskripsi: p.deskripsi, + // imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsiSingkat: p.deskripsiSingkat, + // deskripsi: p.deskripsi, + // imageId, + // }, + // }); + // } + // console.log("program kesehatan success ..."); + + // // ==================== SUBMENU PENANGANAN DARURAT ========================= + // console.log("🔄 Seeding Penanganan Darurat..."); + // for (const p of penangananDarurat) { + // const existing = await prisma.penangananDarurat.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.penangananDarurat.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // deskripsi: p.deskripsi, + // imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsi: p.deskripsi, + // imageId, + // }, + // }); + // } + // console.log("penanganan darurat success ..."); + + // // ==================== SUBMENU KONTAK DARURAT ========================= + // console.log("🔄 Seeding Kontak Darurat..."); + // for (const p of kontakDarurat) { + // const existing = await prisma.kontakDarurat.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.kontakDarurat.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // deskripsi: p.deskripsi, + // whatsapp: p.whatsapp, + // imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsi: p.deskripsi, + // whatsapp: p.whatsapp, + // imageId, + // }, + // }); + // } + // console.log("kontak darurat success ..."); + + // // ==================== SUBMENU INFO WABAH PENYAKIT ========================= + // console.log("🔄 Seeding Info Wabah Penyakit..."); + // for (const p of infoWabahPenyakit) { + // const existing = await prisma.infoWabahPenyakit.findUnique({ + // where: { id: p.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && p.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: p.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${p.imageId} not found for ${p.name}`); + // imageId = null; + // } + // } + + // await prisma.infoWabahPenyakit.upsert({ + // where: { id: p.id }, + // update: { + // name: p.name, + // deskripsiSingkat: p.deskripsiSingkat, + // deskripsiLengkap: p.deskripsiLengkap, + // imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsiSingkat: p.deskripsiSingkat, + // deskripsiLengkap: p.deskripsiLengkap, + // imageId, + // }, + // }); + // } + // console.log("info wabah penyakit success ..."); + + // // ====================== MENU KEAMANAN ======================== + // // ==================== SUBMENU KEAMANAN LINGKUNGAN ============ + // console.log("🔄 Seeding Keamanan Lingkungan..."); + // for (const k of keamananLingkungan) { + // const existing = await prisma.keamananLingkungan.findUnique({ + // where: { id: k.id }, + // select: { imageId: true }, + // }); + + // let imageId = existing?.imageId; // Pertahankan existing + + // // Kalau belum ada imageId, cari berdasarkan name/realName + // if (!imageId && k.imageId) { + // // ✅ Cari langsung berdasarkan ID yang ada di p.imageId + // const fileRecord = await prisma.fileStorage.findUnique({ + // where: { id: k.imageId }, + // select: { id: true, name: true }, + // }); + + // if (fileRecord) { + // imageId = fileRecord.id; + // console.log( + // `✅ Found file by ID: ${fileRecord.name} (${fileRecord.id})`, + // ); + // } else { + // console.warn(`⚠️ File with ID ${k.imageId} not found for ${k.name}`); + // imageId = null; + // } + // } + + // await prisma.keamananLingkungan.upsert({ + // where: { id: k.id }, + // update: { + // name: k.name, + // deskripsi: k.deskripsi, + // imageId, + // }, + // create: { + // id: k.id, + // name: k.name, + // deskripsi: k.deskripsi, + // imageId, + // }, + // }); + // } + // console.log("info wabah penyakit success ..."); + + // // ==================== SUBMENU POLSEK TERDEKAT ================ + // console.log("🔄 Seeding Layanan Polsek..."); + // for (const k of layananPolsek) { + // await prisma.layananPolsek.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // nama: k.nama, + // }, + // create: { + // id: k.id, + // nama: k.nama, + // }, + // }); + // } + + // console.log("layanan polsek success ..."); + + // console.log("🔄 Seeding Polsek Terdekat..."); + // for (const k of polsekTerdekat) { + // await prisma.polsekTerdekat.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // nama: k.nama, + // jarakKeDesa: k.jarakKeDesa, + // alamat: k.alamat, + // nomorTelepon: k.nomorTelepon, + // jamOperasional: k.jamOperasional, + // embedMapUrl: k.embedMapUrl, + // namaTempatMaps: k.namaTempatMaps, + // alamatMaps: k.alamatMaps, + // linkPetunjukArah: k.linkPetunjukArah, + // layananPolsekId: k.layananPolsekId, + // }, + // create: { + // id: k.id, + // nama: k.nama, + // jarakKeDesa: k.jarakKeDesa, + // alamat: k.alamat, + // nomorTelepon: k.nomorTelepon, + // jamOperasional: k.jamOperasional, + // embedMapUrl: k.embedMapUrl, + // namaTempatMaps: k.namaTempatMaps, + // alamatMaps: k.alamatMaps, + // linkPetunjukArah: k.linkPetunjukArah, + // layananPolsekId: k.layananPolsekId, + // }, + // }); + // } + + // console.log("polsek terdekat success ..."); + + // console.log("🔄 Seeding Layanan To Polsek..."); + // for (const k of layananToPolsek) { + // await prisma.layananToPolsek.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // layananId: k.layananId, + // polsekTerdekatId: k.polsekTerdekatId, + // }, + // create: { + // id: k.id, + // layananId: k.layananId, + // polsekTerdekatId: k.polsekTerdekatId, + // }, + // }); + // } + + // console.log("layanan to polsek success ..."); + + // // ==================== SUBMENU KONTAK DARURAT ================= + + // console.log("🔄 Seeding Kontak Item..."); + // for (const e of kontakItem) { + // await prisma.kontakItem.upsert({ + // where: { + // id: e.id, + // }, + // update: { + // nama: e.nama, + // icon: e.icon, + // nomorTelepon: e.nomorTelepon, + // }, + // create: { + // id: e.id, // ✅ WAJIB + // nama: e.nama, + // icon: e.icon, + // nomorTelepon: e.nomorTelepon, + // }, + // }); + // } + // console.log("✅ Kontak Item seeded successfully"); + + // console.log("🔄 Seeding Kontak Darurat Keamanan..."); + // for (const d of kontakDaruratKeamanan) { + // await prisma.kontakDaruratKeamanan.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // nama: d.nama, + // icon: d.icon, + // kategoriId: d.kategoriId, + // }, + // create: { + // id: d.id, + // nama: d.nama, + // icon: d.icon, + // kategoriId: d.kategoriId, + // }, + // }); + // } + + // console.log("✅ Kontak Darurat Keamanan seeded successfully"); + + // console.log("🔄 Seeding Kontak Darurat To Item..."); + // for (const f of kontakDaruratToItem) { + // // ✅ Validasi foreign keys + // const kontakDaruratExists = await prisma.kontakDaruratKeamanan.findUnique({ + // where: { id: f.kontakDaruratId }, + // }); + + // const kontakItemExists = await prisma.kontakItem.findUnique({ + // where: { id: f.kontakItemId }, + // }); + + // if (!kontakDaruratExists) { + // console.warn( + // `⚠️ KontakDarurat ${f.kontakDaruratId} not found, skipping...`, + // ); + // continue; + // } + + // if (!kontakItemExists) { + // console.warn(`⚠️ KontakItem ${f.kontakItemId} not found, skipping...`); + // continue; + // } + + // await prisma.kontakDaruratToItem.upsert({ + // where: { id: f.id }, + // update: { + // kontakDaruratId: f.kontakDaruratId, + // kontakItemId: f.kontakItemId, + // }, + // create: { + // id: f.id, + // kontakDaruratId: f.kontakDaruratId, + // kontakItemId: f.kontakItemId, + // }, + // }); + // } + // console.log("✅ Kontak Darurat To Item seeded successfully"); + + // // ==================== SUBMENU PENCEGAHAN KRIMINALITAS ======== + // console.log("🔄 Seeding Pencegahan Kriminalitas..."); + // for (const d of pencegahanKriminalitas) { + // await prisma.pencegahanKriminalitas.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // judul: d.judul, + // deskripsi: d.deskripsi, + // deskripsiSingkat: d.deskripsiSingkat, + // linkVideo: d.linkVideo, + // }, + // create: { + // id: d.id, + // judul: d.judul, + // deskripsi: d.deskripsi, + // deskripsiSingkat: d.deskripsiSingkat, + // linkVideo: d.linkVideo, + // }, + // }); + // } + + // console.log("✅ Pencegahan Kriminalitas seeded successfully"); + // // ==================== SUBMENU LAPORAN PUBLIK ================= + // console.log("🔄 Seeding Laporan Publik..."); + // for (const l of laporanPublik) { + // await prisma.laporanPublik.upsert({ + // where: { + // id: l.id, + // }, + // update: { + // judul: l.judul, + // lokasi: l.lokasi, + // tanggalWaktu: l.tanggalWaktu, + // kronologi: l.kronologi, + // }, + // create: { + // id: l.id, + // judul: l.judul, + // lokasi: l.lokasi, + // tanggalWaktu: l.tanggalWaktu, + // kronologi: l.kronologi, + // }, + // }); + // } + + // console.log("laporan publik success ..."); + + // console.log("🔄 Seeding Penanganan Laporan..."); + // for (const l of penangananLaporan) { + // await prisma.penangananLaporanPublik.upsert({ + // where: { + // id: l.id, + // }, + // update: { + // deskripsi: l.deskripsi, + // laporanId: l.laporanId, + // }, + // create: { + // id: l.id, + // deskripsi: l.deskripsi, + // laporanId: l.laporanId, + // }, + // }); + // } + + // console.log("penanganan laporan success ..."); + + // // ==================== SUBMENU TIPS KEAMANAN ================== + // console.log("🔄 Seeding Tips Keamanan..."); + // for (const t of tipsKeamanan) { + // await prisma.menuTipsKeamanan.upsert({ + // where: { + // id: t.id, + // }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // imageId: t.imageId, + // }, + // create: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // imageId: t.imageId, + // }, + // }); + // } + + // console.log("✅ Tips Keamanan seeded successfully"); + + // // ====================== MENU EKONOMI ======================== + // // ==================== SUBMENU PASAR DESA ==================== + // console.log("🔄 Seeding Kategori Produk..."); + // for (const k of kategoriProduk) { + // await prisma.kategoriProduk.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // nama: k.nama, + // }, + // create: { + // id: k.id, + // nama: k.nama, + // }, + // }); + // } + // console.log("✅ Kategori Produk seeded successfully"); + + // console.log("🔄 Seeding Pasar Desa..."); + // for (const p of pasarDesa) { + // await prisma.pasarDesa.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // nama: p.nama, + // imageId: p.imageId, + // harga: p.harga, + // rating: p.rating, + // alamatUsaha: p.alamatUsaha, + // kontak: p.kontak, + // deskripsi: p.deskripsi, + // kategoriProdukId: p.kategoriProdukId, + // }, + // create: { + // id: p.id, + // nama: p.nama, + // imageId: p.imageId, + // harga: p.harga, + // rating: p.rating, + // alamatUsaha: p.alamatUsaha, + // kontak: p.kontak, + // deskripsi: p.deskripsi, + // kategoriProdukId: p.kategoriProdukId, + // }, + // }); + // } + // console.log("✅ Pasar Desa seeded successfully"); + + // console.log("🔄 Seeding Kategori To Pasar..."); + // for (const p of kategoriToPasar) { + // await prisma.kategoriToPasar.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // kategoriId: p.kategoriId, + // pasarDesaId: p.pasarDesaId, + // }, + // create: { + // id: p.id, + // kategoriId: p.kategoriId, + // pasarDesaId: p.pasarDesaId, + // }, + // }); + // } + + // // ==================== SUBMENU LOWONGAN KERJA LOKAL ========== + // console.log("🔄 Seeding Lowongan Kerja Lokal..."); + // for (const k of lowonganKerjaLokal) { + // await prisma.lowonganPekerjaan.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // posisi: k.posisi, + // namaPerusahaan: k.namaPerusahaan, + // lokasi: k.lokasi, + // tipePekerjaan: k.tipePekerjaan, + // gaji: k.gaji, + // deskripsi: k.deskripsi, + // kualifikasi: k.kualifikasi, + // notelp: k.notelp, + // }, + // create: { + // id: k.id, + // posisi: k.posisi, + // namaPerusahaan: k.namaPerusahaan, + // lokasi: k.lokasi, + // tipePekerjaan: k.tipePekerjaan, + // gaji: k.gaji, + // deskripsi: k.deskripsi, + // kualifikasi: k.kualifikasi, + // notelp: k.notelp, + // }, + // }); + // } + // console.log("✅ Lowongan Kerja Lokal seeded successfully"); + + // // ==================== SUBMENU STRUKTUR ORGANISASI DAN SK PENGURUS BUMDES ========== + // const sortedPosisiBumdes = flattenedPosisiBumdes.sort( + // (a, b) => a.hierarki - b.hierarki, + // ); + + // for (const p of sortedPosisiBumdes) { + // console.log(`Seeding: ${p.nama} (id: ${p.id}, parent: ${p.parentId})`); + + // if (p.parentId) { + // const parentExists = flattenedPosisi.some((pos) => pos.id === p.parentId); + // if (!parentExists) { + // console.warn( + // `⚠️ Parent tidak ditemukan: ${p.parentId} untuk ${p.nama}`, + // ); + // continue; + // } + // } + + // await prisma.posisiOrganisasiBumDes.upsert({ + // where: { id: p.id }, + // update: p, + // create: p, + // }); + // } + // console.log("posisi organisasi berhasil"); + + // for (const p of pegawai) { + // await prisma.pegawaiBumDes.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // namaLengkap: p.namaLengkap, + // gelarAkademik: p.gelarAkademik, + // tanggalMasuk: new Date(p.tanggalMasuk), + // email: p.email, + // telepon: p.telepon, + // alamat: p.alamat, + // posisiId: p.posisiId, + // isActive: p.isActive, + // }, + // create: { + // id: p.id, + // namaLengkap: p.namaLengkap, + // gelarAkademik: p.gelarAkademik, + // tanggalMasuk: new Date(p.tanggalMasuk), + // email: p.email, + // telepon: p.telepon, + // alamat: p.alamat, + // posisiId: p.posisiId, + // isActive: p.isActive, + // }, + // }); + // } + // console.log("pegawai success ..."); + + // // ==================== SUBMENU PENDAPATAN ASLI DESA ========== + + // // ==================== SUBMENU JUMLAH PENGANGGURAN ========== + // for (const d of detailDataPengangguran) { + // await prisma.detailDataPengangguran.upsert({ + // where: { + // month_year: { month: d.month, year: d.year }, + // }, + // update: { + // totalUnemployment: d.totalUnemployment, + // educatedUnemployment: d.educatedUnemployment, + // uneducatedUnemployment: d.uneducatedUnemployment, + // percentageChange: d.percentageChange, + // }, + // create: { + // month: d.month, + // year: d.year, + // totalUnemployment: d.totalUnemployment, + // educatedUnemployment: d.educatedUnemployment, + // uneducatedUnemployment: d.uneducatedUnemployment, + // percentageChange: d.percentageChange, + // }, + // }); + // } + // console.log("📊 detailDataPengangguran success ..."); + + // // ==================== SUBMENU PENDUDUK USIA KERJA ========== + // for (const p of grafikMenganggurBerdasarkanUsia) { + // await prisma.grafikMenganggurBerdasarkanUsia.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // usia18_25: p.usia18_25, + // usia26_35: p.usia26_35, + // usia36_45: p.usia36_45, + // usia46_keatas: p.usia46_keatas, + // }, + // create: { + // id: p.id, + // usia18_25: p.usia18_25, + // usia26_35: p.usia26_35, + // usia36_45: p.usia36_45, + // usia46_keatas: p.usia46_keatas, + // }, + // }); + // } + // console.log("📊 grafikMenganggurBerdasarkanUsia success ..."); + + // for (const p of grafikMenganggurBerdasarkanPendidikan) { + // await prisma.grafikMenganggurBerdasarkanPendidikan.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // SD: p.SD, + // SMP: p.SMP, + // SMA: p.SMA, + // D3: p.D3, + // S1: p.S1, + // }, + // create: { + // id: p.id, + // SD: p.SD, + // SMP: p.SMP, + // SMA: p.SMA, + // D3: p.D3, + // S1: p.S1, + // }, + // }); + // } + // console.log("📊 grafikMenganggurBerdasarkanUsia success ..."); + + // // ==================== SUBMENU PENDUDUK MISKIN ============= + // console.log("🔄 Seeding Jumlah Penduduk Miskin..."); + // for (const k of jumlahPendudukMiskin) { + // await prisma.grafikJumlahPendudukMiskin.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // year: k.year, + // totalPoorPopulation: k.totalPoorPopulation, + // }, + // create: { + // id: k.id, + // year: k.year, + // totalPoorPopulation: k.totalPoorPopulation, + // }, + // }); + // } + // console.log("✅ Jumlah Penduduk Miskin seeded successfully"); + + // // ==================== SUBMENU PROGRAM KEMISKINAN ============= + // for (const s of statistikKemiskinan) { + // await prisma.statistikKemiskinan.upsert({ + // where: { tahun: s.tahun }, // ✅ FIX + // update: { + // jumlah: s.jumlah, + // }, + // create: { + // id: s.id, // id boleh tetap + // tahun: s.tahun, + // jumlah: s.jumlah, + // }, + // }); + // } + + // console.log("📊 Statistik Kemiskinan seeded successfully"); + + // console.log("🔄 Seeding Program Kemiskinan..."); + // for (const k of programKemiskinan) { + // await prisma.programKemiskinan.upsert({ + // where: { id: k.id }, + // update: { + // nama: k.nama, + // deskripsi: k.deskripsi, + // icon: k.icon, + // statistik: { + // connect: { + // tahun: k.tahun, // 👈 BUKAN ID + // }, + // }, + // }, + // create: { + // id: k.id, + // nama: k.nama, + // deskripsi: k.deskripsi, + // icon: k.icon, + // statistik: { + // connect: { + // tahun: k.tahun, + // }, + // }, + // }, + // }); + // } + // console.log("✅ Program Kemiskinan seeded successfully"); + + // // ==================== SUBMENU SEKTOR UNGGULAN DESA ============= + // console.log("🔄 Seeding Sektor Unggulan Desa..."); + // for (const k of sektorUnggulanDesa) { + // await prisma.sektorUnggulanDesa.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // name: k.name, + // description: k.description, + // value: k.value, + // }, + // create: { + // id: k.id, + // name: k.name, + // description: k.description, + // value: k.value, + // }, + // }); + // } + // console.log("✅ Sektor Unggulan Desa seeded successfully"); + + // // ==================== SUBMENU DEMOGRAFI PEKERJAAN ============= + // console.log("🔄 Seeding Demografi Pekerjaan..."); + // for (const k of demografiPekerjaan) { + // await prisma.dataDemografiPekerjaan.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // pekerjaan: k.pekerjaan, + // lakiLaki: k.lakiLaki, + // perempuan: k.perempuan, + // }, + // create: { + // id: k.id, + // pekerjaan: k.pekerjaan, + // lakiLaki: k.lakiLaki, + // perempuan: k.perempuan, + // }, + // }); + // } + // console.log("✅ Demografi Pekerjaan seeded successfully"); + + // // ====================== MENU INOVASI ========================== + // // ====================== SUBMENU AJUKAN IDE INOVATIF =========== + // console.log("🔄 Seeding Ajukan Ide Inovatif..."); + // for (const d of ajukanIde) { + // await prisma.ajukanIdeInovatif.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // name: d.name, + // alamat: d.alamat, + // namaIde: d.namaIde, + // deskripsi: d.deskripsi, + // masalah: d.masalah, + // benefit: d.benefit, + // }, + // create: { + // id: d.id, + // name: d.name, + // alamat: d.alamat, + // namaIde: d.namaIde, + // deskripsi: d.deskripsi, + // masalah: d.masalah, + // benefit: d.benefit, + // }, + // }); + // } + // console.log("✅ Ajukan Ide Inovatif seeded successfully"); + // // ==================== SUBMENU DESA DIGITAL ==================== + // console.log("🔄 Seeding Desa Digital..."); + // for (const d of desaDigital) { + // await prisma.desaDigital.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // name: d.name, + // deskripsi: d.deskripsi, + // imageId: d.imageId, + // }, + // create: { + // id: d.id, + // name: d.name, + // deskripsi: d.deskripsi, + // imageId: d.imageId, + // }, + // }); + // } + // console.log("✅ Desa Digital seeded successfully"); + + // // ==================== SUBMENU LAYANAN ONLINE DESA ========== + // console.log("🔄 Seeding Jenis Layanan..."); + // for (const j of jenisLayanan) { + // await prisma.jenisLayanan.upsert({ + // where: { + // id: j.id, + // }, + // update: { + // nama: j.nama, + // deskripsi: j.deskripsi, + // }, + // create: { + // id: j.id, + // nama: j.nama, + // deskripsi: j.deskripsi, + // }, + // }); + // } + // console.log("✅ Jenis Layanan seeded successfully"); + + // console.log("🔄 Seeding Administrasi Online..."); + // for (const d of administrasiOnline) { + // await prisma.administrasiOnline.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // name: d.name, + // alamat: d.alamat, + // nomorTelepon: d.nomorTelepon, + // jenisLayananId: d.jenisLayananId, + // }, + // create: { + // id: d.id, + // name: d.name, + // alamat: d.alamat, + // nomorTelepon: d.nomorTelepon, + // jenisLayananId: d.jenisLayananId, + // }, + // }); + // } + // console.log("✅ Administrasi Online seeded successfully"); + + // console.log("🔄 Seeding Jenis Pengaduan Masyarakat..."); + // for (const d of jenisPengaduan) { + // await prisma.jenisPengaduan.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // nama: d.nama, + // }, + // create: { + // id: d.id, + // nama: d.nama, + // }, + // }); + // } + // console.log("✅ Jenis Pengaduan Masyarakat seeded successfully"); + + // console.log("🔄 Seeding Pengaduan Masyarakat..."); + // for (const d of pengaduanMasyarakat) { + // await prisma.pengaduanMasyarakat.upsert({ + // where: { + // id: d.id, + // }, + // update: { + // name: d.name, + // email: d.email, + // nik: d.nik, + // nomorTelepon: d.nomorTelepon, + // judulPengaduan: d.judulPengaduan, + // lokasiKejadian: d.lokasiKejadian, + // imageId: d.imageId, + // deskripsiPengaduan: d.deskripsiPengaduan, + // jenisPengaduanId: d.jenisPengaduanId, + // }, + // create: { + // id: d.id, + // name: d.name, + // email: d.email, + // nik: d.nik, + // nomorTelepon: d.nomorTelepon, + // judulPengaduan: d.judulPengaduan, + // lokasiKejadian: d.lokasiKejadian, + // imageId: d.imageId, + // deskripsiPengaduan: d.deskripsiPengaduan, + // jenisPengaduanId: d.jenisPengaduanId, + // }, + // }); + // } + // console.log("✅ Pengaduan Masyarakat seeded successfully"); + + // // ==================== SUBMENU PROGRAM KREATIF ========== + // console.log("🔄 Seeding Program Kreatif..."); + // for (const p of programKreatif) { + // await prisma.programKreatif.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // deskripsi: p.deskripsi, + // icon: p.icon, + // slug: p.slug, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsi: p.deskripsi, + // icon: p.icon, + // slug: p.slug, + // }, + // }); + // } + // console.log("✅ Program Kreatif seeded successfully"); + + // // ==================== SUBMENU KOLABORASI INOVASI ========== + // console.log("🔄 Seeding Kolaborasi Inovasi..."); + // for (const p of kolaborasiInovasi) { + // await prisma.kolaborasiInovasi.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // tahun: p.tahun, + // slug: p.slug, + // deskripsi: p.deskripsi, + // kolaborator: p.kolaborator, + // }, + // create: { + // id: p.id, + // name: p.name, + // tahun: p.tahun, + // slug: p.slug, + // deskripsi: p.deskripsi, + // kolaborator: p.kolaborator, + // }, + // }); + // } + // console.log("✅ Kolaborasi Inovasi seeded successfully"); + + // console.log("🔄 Seeding Mitra Kolaborasi..."); + // for (const p of mitraKolaborasi) { + // await prisma.mitraKolaborasi.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // imageId: p.imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // imageId: p.imageId, + // }, + // }); + // } + // console.log("✅ Mitra Kolaborasi seeded successfully"); + + // // ==================== SUBMENU INFO TEKNOLOGI TEPAT GUNA ========== + // console.log("🔄 Seeding Info Teknologi..."); + // for (const p of infoTeknologi) { + // await prisma.infoTekno.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // deskripsi: p.deskripsi, + // imageId: p.imageId, + // }, + // create: { + // id: p.id, + // name: p.name, + // deskripsi: p.deskripsi, + // imageId: p.imageId, + // }, + // }); + // } + // console.log("✅ Info Teknologi seeded successfully"); + + // // ====================== MENU LINGKUNGAN ========================== + // // ==================== SUBMENU PENGELOLAAN SAMPAH ========== + // console.log("🔄 Seeding Pengelolaan Sampah..."); + // for (const p of pengelolaanSampah) { + // await prisma.pengelolaanSampah.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // icon: p.icon, + // }, + // create: { + // id: p.id, + // name: p.name, + // icon: p.icon, + // }, + // }); + // } + // console.log("✅ Pengelolaan Sampah seeded successfully"); + + // console.log("🔄 Seeding Keterangan Bank Sampah..."); + // for (const p of keteranganBankSampah) { + // await prisma.keteranganBankSampahTerdekat.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // alamat: p.alamat, + // namaTempatMaps: p.namaTempatMaps, + // linkPetunjukArah: p.linkPetunjukArah, + // lat: p.lat, + // lng: p.lng, + // }, + // create: { + // id: p.id, + // name: p.name, + // alamat: p.alamat, + // namaTempatMaps: p.namaTempatMaps, + // linkPetunjukArah: p.linkPetunjukArah, + // lat: p.lat, + // lng: p.lng, + // }, + // }); + // } + // console.log("✅ Keterangan Bank Sampah seeded successfully"); + + // // ==================== SUBMENU PROGRAM PENGHIJAUAN ========== + // console.log("🔄 Seeding Program Penghijauan..."); + // for (const p of programPenghijauan) { + // await prisma.programPenghijauan.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // judul: p.judul, + // deskripsi: p.deskripsi, + // icon: p.icon, + // }, + // create: { + // id: p.id, + // name: p.name, + // judul: p.judul, + // deskripsi: p.deskripsi, + // icon: p.icon, + // }, + // }); + // } + // console.log("✅ Program Penghijauan seeded successfully"); + + // // ==================== SUBMENU DATA LINGKUNGAN DESA ========== + // console.log("🔄 Seeding Data Lingkungan Desa..."); + // for (const p of dataLingkunganDesa) { + // await prisma.dataLingkunganDesa.upsert({ + // where: { + // id: p.id, + // }, + // update: { + // name: p.name, + // jumlah: p.jumlah, + // deskripsi: p.deskripsi, + // icon: p.icon, + // }, + // create: { + // id: p.id, + // name: p.name, + // jumlah: p.jumlah, + // deskripsi: p.deskripsi, + // icon: p.icon, + // }, + // }); + // } + // console.log("✅ Data Lingkungan Desa seeded successfully"); + + // // =========== SUBMENU GOTONG ROYONG =========== + // console.log("🔄 Seeding Kategori Gotong Royong..."); + + // for (const k of kategoriGotongRoyong) { + // await prisma.kategoriKegiatan.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // nama: k.nama, + // }, + // create: { + // id: k.id, + // nama: k.nama, + // }, + // }); + // } + + // console.log("✅ Kategori Gotong Royong seeded successfully"); + + // console.log("🔄 Seeding Gotong Royong..."); + + // for (const k of gotongRoyong) { + // await prisma.kegiatanDesa.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // judul: k.judul, + // deskripsiSingkat: k.deskripsiSingkat, + // deskripsiLengkap: k.deskripsiLengkap, + // tanggal: k.tanggal, + // lokasi: k.lokasi, + // partisipan: k.partisipan, + // imageId: k.imageId, + // kategoriKegiatanId: k.kategoriKegiatanId, + // }, + // create: { + // id: k.id, + // judul: k.judul, + // deskripsiSingkat: k.deskripsiSingkat, + // deskripsiLengkap: k.deskripsiLengkap, + // tanggal: k.tanggal, + // lokasi: k.lokasi, + // partisipan: k.partisipan, + // imageId: k.imageId, + // kategoriKegiatanId: k.kategoriKegiatanId, + // }, + // }); + // } + + // console.log("✅ Kategori Gotong Royong seeded successfully"); + + // // =========== SUBMENU EDUKASI LINGKUNGAN =========== + + // for (const e of tujuanEdukasiLingkungan) { + // await prisma.tujuanEdukasiLingkungan.upsert({ + // where: { + // id: e.id, + // }, + // update: { + // judul: e.judul, + // deskripsi: e.deskripsi, + // }, + // create: { + // id: e.id, + // judul: e.judul, + // deskripsi: e.deskripsi, + // }, + // }); + // } + + // console.log("tujuan edukasi lingkungan success ..."); + + // for (const m of materiEdukasiLingkungan) { + // await prisma.materiEdukasiLingkungan.upsert({ + // where: { + // id: m.id, + // }, + // update: { + // judul: m.judul, + // deskripsi: m.deskripsi, + // }, + // create: { + // id: m.id, + // judul: m.judul, + // deskripsi: m.deskripsi, + // }, + // }); + // } + + // console.log("materi edukasi lingkungan success ..."); + + // for (const c of contohEdukasiLingkungan) { + // await prisma.contohEdukasiLingkungan.upsert({ + // where: { + // id: c.id, + // }, + // update: { + // judul: c.judul, + // deskripsi: c.deskripsi, + // }, + // create: { + // id: c.id, + // judul: c.judul, + // deskripsi: c.deskripsi, + // }, + // }); + // } + + // console.log("contoh edukasi lingkungan success ..."); + + // // =========== SUBMENU KONSERVASI ADAT BALI =========== + + // for (const f of filosofiTriHita) { + // await prisma.filosofiTriHita.upsert({ + // where: { + // id: f.id, + // }, + // update: { + // judul: f.judul, + // deskripsi: f.deskripsi, + // }, + // create: { + // id: f.id, + // judul: f.judul, + // deskripsi: f.deskripsi, + // }, + // }); + // } + + // console.log("filosofi tri hita success ..."); + + // for (const b of bentukKonservasiBerdasarkanAdat) { + // await prisma.bentukKonservasiBerdasarkanAdat.upsert({ + // where: { + // id: b.id, + // }, + // update: { + // judul: b.judul, + // deskripsi: b.deskripsi, + // }, + // create: { + // id: b.id, + // judul: b.judul, + // deskripsi: b.deskripsi, + // }, + // }); + // } + + // console.log("bentuk konservasi berdasarkan adat success ..."); + + // for (const n of nilaiKonservasiAdat) { + // await prisma.nilaiKonservasiAdat.upsert({ + // where: { + // id: n.id, + // }, + // update: { + // judul: n.judul, + // deskripsi: n.deskripsi, + // }, + // create: { + // id: n.id, + // judul: n.judul, + // deskripsi: n.deskripsi, + // }, + // }); + // } + + // console.log("nilai konservasi adat success ..."); + + // // ====================== MENU PENDIDIKAN ========================== + // // =========== SUBMENU INFO SEKOLAH ===================== + + // for (const j of jenjangPendidikan) { + // await prisma.jenjangPendidikan.upsert({ + // where: { + // id: j.id, + // }, + // update: { + // nama: j.nama, + // }, + // create: { + // id: j.id, + // nama: j.nama, + // }, + // }); + // } + + // console.log("✅ Jenjang Pendidikan seeded successfully"); + + // for (const j of lembagaPendidikan) { + // await prisma.lembaga.upsert({ + // where: { + // id: j.id, + // }, + // update: { + // nama: j.nama, + // jenjangId: j.jenjangId, + // }, + // create: { + // id: j.id, + // nama: j.nama, + // jenjangId: j.jenjangId, + // }, + // }); + // } + + // console.log("✅ Lembaga Pendidikan seeded successfully"); + + // for (const j of siswa) { + // await prisma.siswa.upsert({ + // where: { + // id: j.id, + // }, + // update: { + // nama: j.nama, + // lembagaId: j.lembagaId, + // }, + // create: { + // id: j.id, + // nama: j.nama, + // lembagaId: j.lembagaId, + // }, + // }); + // } + + // console.log("✅ siswa seeded successfully"); + + // for (const j of pengajar) { + // await prisma.pengajar.upsert({ + // where: { + // id: j.id, + // }, + // update: { + // nama: j.nama, + // lembagaId: j.lembagaId, + // }, + // create: { + // id: j.id, + // nama: j.nama, + // lembagaId: j.lembagaId, + // }, + // }); + // } + + // console.log("✅ pengajar seeded successfully"); + + // // =========== SUBMENU PROGRAM PENDIDIKAN ANAK ===================== + + // for (const t of tujuanProgram) { + // await prisma.tujuanProgram.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log("✅ tujuan program seeded (editable later via UI)"); + + // for (const t of programUnggulan) { + // await prisma.programUnggulan.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log("✅ program unggulan seeded (editable later via UI)"); + + // // =========== SUBMENU BIMBINGAN BELAJAR DESA ===================== + + // for (const t of tujuanBimbinganBelajarDesa) { + // await prisma.tujuanBimbinganBelajarDesa.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ tujuan bimbingan belajar desa seeded (editable later via UI)", + // ); + + // for (const t of lokasiJadwalBimbinganBelajarDesa) { + // await prisma.lokasiJadwalBimbinganBelajarDesa.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ lokasi jadwal bimbingan belajar desa seeded (editable later via UI)", + // ); + + // for (const t of fasilitasBimbinganBelajarDesa) { + // await prisma.fasilitasBimbinganBelajarDesa.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", + // ); + + // // =========== SUBMENU PENDIDIKAN NON FORMAL ===================== + + // for (const t of tujuanProgram2) { + // await prisma.tujuanPendidikanNonFormal.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", + // ); + + // for (const t of tempatKegiatan) { + // await prisma.tempatKegiatan.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", + // ); + + // for (const t of jenisProgramYangDiselenggarakan) { + // await prisma.jenisProgramYangDiselenggarakan.upsert({ + // where: { id: t.id }, + // update: { + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // create: { + // id: t.id, + // judul: t.judul, + // deskripsi: t.deskripsi, + // }, + // }); + // } + // console.log( + // "✅ fasilitas bimbingan belajar desa seeded (editable later via UI)", + // ); + + // // =========== SUBMENU PERPUSTAKAAN DIGITAL ===================== + // console.log("🔄 Seeding Kategori Buku..."); + // for (const k of kategoriBuku) { + // await prisma.kategoriBuku.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // name: k.name, + // }, + // create: { + // id: k.id, + // name: k.name, + // }, + // }); + // } + // console.log("✅ Kategori Buku seeded successfully"); + + // console.log("🔄 Seeding Data perpustakaan..."); + // for (const k of dataPerpustakaan) { + // await prisma.dataPerpustakaan.upsert({ + // where: { + // id: k.id, + // }, + // update: { + // judul: k.judul, + // deskripsi: k.deskripsi, + // kategoriId: k.kategoriId, + // imageId: k.imageId, + // }, + // create: { + // id: k.id, + // judul: k.judul, + // deskripsi: k.deskripsi, + // kategoriId: k.kategoriId, + // imageId: k.imageId, + // }, + // }); + // } + // console.log("✅ Data perpustakaan seeded successfully"); // =========== SUBMENU DATA PENDIDIKAN ===================== console.log("🔄 Seeding Data pendidikan..."); @@ -3027,17 +1933,16 @@ import resolveImageById from "./resolveImageByName"; }, update: { name: k.name, - jumlah: k.jumlah + jumlah: k.jumlah, }, create: { id: k.id, name: k.name, - jumlah: k.jumlah + jumlah: k.jumlah, }, }); } console.log("✅ Data pendidikan seeded successfully"); - })() .then(() => prisma.$disconnect()) .catch((e) => { diff --git a/prisma/seed_assets.ts b/prisma/seed_assets.ts index 1bc230da..c953b8f5 100644 --- a/prisma/seed_assets.ts +++ b/prisma/seed_assets.ts @@ -1,555 +1,68 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -// /* eslint-disable @typescript-eslint/no-unused-vars */ -// // prisma/seedAssets.ts -// import prisma from "@/lib/prisma"; -// import AdmZip from "adm-zip"; -// import fs from "fs/promises"; -// import path from "path"; -// import sharp from "sharp"; -// import fetchWithRetry from "./data/fetchWithRetry"; - -// const UPLOADS_DIR = path.resolve(process.env.WIBU_UPLOAD_DIR || "uploads"); - -// // --- Helper: deteksi kategori file --- -// function detectCategory(filename: string): "image" | "document" | "other" { -// const ext = path.extname(filename).toLowerCase(); -// if ([".jpg", ".jpeg", ".png", ".webp"].includes(ext)) return "image"; -// if ([".pdf", ".doc", ".docx"].includes(ext)) return "document"; -// return "other"; -// } - -// // --- Helper: recursive walk dir --- -// async function walkDir( -// dir: string, -// fileList: string[] = [], -// ): Promise { -// const entries = await fs.readdir(dir, { withFileTypes: true }); - -// for (const entry of entries) { -// const fullPath = path.join(dir, entry.name); - -// if (entry.isDirectory()) { -// if (entry.name === "__MACOSX") continue; // skip folder sampah -// await walkDir(fullPath, fileList); -// } else { -// if (entry.name.startsWith(".") || entry.name === ".DS_Store") continue; // skip file sampah -// fileList.push(fullPath); -// } -// } - -// return fileList; -// } - -// export default async function seedAssets() { -// console.log("🚀 Seeding assets..."); -// console.log("📁 Upload dir:", UPLOADS_DIR); - -// await fs.mkdir(UPLOADS_DIR, { recursive: true }); - -// // 1. Download zip -// const url = -// "https://cld-dkr-makuro-seafile.wibudev.com/f/03be4043989e4caeb36b/?dl=1"; -// const res = await fetchWithRetry(url, 3, 20000); - -// // Validasi content-type -// const contentType = res.headers.get("content-type"); -// if (!contentType?.includes("zip")) { -// throw new Error(`Invalid content-type (${contentType}). Expected ZIP file`); -// } - -// const buffer = Buffer.from(await res.arrayBuffer()); - -// // Validasi ukuran file -// if (buffer.length < 100) { -// throw new Error("Downloaded ZIP is empty or corrupted"); -// } - -// // Validasi signature ZIP ("PK") -// if (buffer.toString("utf8", 0, 2) !== "PK") { -// throw new Error("Invalid ZIP signature (PK not found)"); -// } - -// // 2. Extract zip ke folder tmp -// const extractDir = path.join(process.cwd(), "tmp_assets"); -// await fs.rm(extractDir, { recursive: true, force: true }); -// await fs.mkdir(extractDir, { recursive: true }); - -// let zip: AdmZip; - -// try { -// zip = new AdmZip(buffer); -// } catch (err) { -// throw new Error("Failed to parse ZIP file (corrupted or invalid)"); -// } - -// try { -// zip.extractAllTo(extractDir, true); -// } catch (err) { -// throw new Error("Failed to extract ZIP contents"); -// } - -// // 3. Cari semua file valid (recursive) -// const files = await walkDir(extractDir); - -// // 4. Loop tiap file & simpan -// for (const filePath of files) { -// const entryName = path.basename(filePath); -// const category = detectCategory(entryName); - -// let finalName = entryName; -// let mimeType = "application/octet-stream"; -// let targetPath = ""; - -// if (category === "image") { -// const fileBaseName = path.parse(entryName).name; -// finalName = `${fileBaseName}.webp`; -// targetPath = path.join(UPLOADS_DIR, "images", finalName); -// await fs.mkdir(path.dirname(targetPath), { recursive: true }); -// await sharp(filePath).webp({ quality: 80 }).toFile(targetPath); -// mimeType = "image/webp"; -// } else if (category === "document") { -// targetPath = path.join(UPLOADS_DIR, "documents", entryName); -// await fs.mkdir(path.dirname(targetPath), { recursive: true }); -// await fs.copyFile(filePath, targetPath); -// mimeType = "application/pdf"; -// } else { -// targetPath = path.join(UPLOADS_DIR, "other", entryName); -// await fs.mkdir(path.dirname(targetPath), { recursive: true }); -// await fs.copyFile(filePath, targetPath); -// } - -// const existing = await prisma.fileStorage.findUnique({ -// where: { name: finalName }, -// }); - -// if (existing) { -// // Restore kalau soft deleted -// await prisma.fileStorage.update({ -// where: { name: finalName }, -// data: { -// path: targetPath, -// realName: entryName, -// mimeType, -// link: `/uploads/${category}/${finalName}`, -// category, -// deletedAt: null, -// isActive: true, -// }, -// }); - -// console.log(`♻️ restored: ${category}/${finalName}`); -// } else { -// await prisma.fileStorage.create({ -// data: { -// name: finalName, -// realName: entryName, -// path: targetPath, -// mimeType, -// link: `/uploads/${category}/${finalName}`, -// category, -// }, -// }); - -// console.log(`📂 created: ${category}/${finalName}`); -// } - -// console.log(`📂 saved: ${category}/${finalName}`); -// } - -// // 6. Cleanup -// await fs.rm(extractDir, { recursive: true, force: true }); - -// console.log("✅ Selesai seed assets!"); -// console.log("DB URL (asset):", process.env.DATABASE_URL); -// } - -// // --- Auto run kalau dipanggil langsung --- -// if (import.meta.main) { -// seedAssets() -// .catch((err) => { -// console.error("❌ Error seeding assets:", err); -// process.exit(1); -// }) -// .finally(async () => { -// await prisma.$disconnect(); -// }); -// } - -// // prisma/seedAssets.ts -// // import prisma from "@/lib/prisma"; -// // import AdmZip from "adm-zip"; -// // import fs from "fs/promises"; -// // import path from "path"; -// // import sharp from "sharp"; -// // import mime from "mime-types"; -// // import fetchWithRetry from "./data/fetchWithRetry"; - -// // /* ========================= -// // * CONFIG -// // * ========================= */ -// // const UPLOADS_DIR = path.resolve( -// // process.env.WIBU_UPLOAD_DIR || "uploads" -// // ); - -// // const TMP_DIR = path.join(process.cwd(), "tmp_assets"); - -// // const CATEGORY_DIR: Record = { -// // image: "images", -// // document: "documents", -// // other: "other", -// // }; - -// // type FileCategory = "image" | "document" | "other"; - -// // /* ========================= -// // * HELPERS -// // * ========================= */ -// // function detectCategory(filename: string): FileCategory { -// // const ext = path.extname(filename).toLowerCase(); -// // if ([".jpg", ".jpeg", ".png", ".webp"].includes(ext)) return "image"; -// // if ([".pdf", ".doc", ".docx", ".txt"].includes(ext)) return "document"; -// // return "other"; -// // } - -// // async function walkDir( -// // dir: string, -// // result: string[] = [] -// // ): Promise { -// // const entries = await fs.readdir(dir, { withFileTypes: true }); - -// // for (const entry of entries) { -// // const fullPath = path.join(dir, entry.name); - -// // if (entry.isDirectory()) { -// // if (entry.name === "__MACOSX") continue; -// // await walkDir(fullPath, result); -// // } else { -// // if (entry.name.startsWith(".") || entry.name === ".DS_Store") continue; -// // result.push(fullPath); -// // } -// // } - -// // return result; -// // } - -// // async function ensureDir(dir: string) { -// // await fs.mkdir(dir, { recursive: true }); -// // } - -// // /* ========================= -// // * FILE PROCESSORS -// // * ========================= */ -// // async function processImage(filePath: string, entryName: string) { -// // const baseName = path.parse(entryName).name; -// // const finalName = `${baseName}.webp`; -// // const targetDir = path.join(UPLOADS_DIR, CATEGORY_DIR.image); -// // const targetPath = path.join(targetDir, finalName); - -// // await ensureDir(targetDir); -// // await sharp(filePath).webp({ quality: 80 }).toFile(targetPath); - -// // return { -// // finalName, -// // targetPath, -// // mimeType: "image/webp", -// // }; -// // } - -// // async function processNonImage( -// // filePath: string, -// // entryName: string, -// // category: FileCategory -// // ) { -// // const targetDir = path.join(UPLOADS_DIR, CATEGORY_DIR[category]); -// // const targetPath = path.join(targetDir, entryName); - -// // await ensureDir(targetDir); -// // await fs.copyFile(filePath, targetPath); - -// // return { -// // finalName: entryName, -// // targetPath, -// // mimeType: mime.lookup(entryName) || "application/octet-stream", -// // }; -// // } - -// // /* ========================= -// // * MAIN -// // * ========================= */ -// // export default async function seedAssets() { -// // console.log("🚀 Seeding assets..."); -// // console.log("📁 Upload dir:", UPLOADS_DIR); - -// // await ensureDir(UPLOADS_DIR); - -// // /* ===== Download ZIP ===== */ -// // const url = -// // "https://cld-dkr-makuro-seafile.wibudev.com/f/e13d5429785640c098ae/?dl=1"; -// // const res = await fetchWithRetry(url, 3, 20000); - -// // if (!res.headers.get("content-type")?.includes("zip")) { -// // throw new Error("Invalid ZIP content-type"); -// // } - -// // const buffer = Buffer.from(await res.arrayBuffer()); -// // if (buffer.length < 100 || buffer.toString("utf8", 0, 2) !== "PK") { -// // throw new Error("Corrupted ZIP file"); -// // } - -// // /* ===== Extract ===== */ -// // await fs.rm(TMP_DIR, { recursive: true, force: true }); -// // await ensureDir(TMP_DIR); - -// // const zip = new AdmZip(buffer); -// // zip.extractAllTo(TMP_DIR, true); - -// // /* ===== Process Files ===== */ -// // const files = await walkDir(TMP_DIR); - -// // for (const filePath of files) { -// // const entryName = path.basename(filePath); -// // const category = detectCategory(entryName); - -// // let result; - -// // if (category === "image") { -// // result = await processImage(filePath, entryName); -// // } else { -// // result = await processNonImage(filePath, entryName, category); -// // } - -// // const { finalName, targetPath, mimeType } = result; - -// // const existing = await prisma.fileStorage.findUnique({ -// // where: { name: finalName }, -// // }); - -// // const data = { -// // name: finalName, -// // realName: entryName, -// // path: targetPath, -// // mimeType, -// // link: `/uploads/${CATEGORY_DIR[category]}/${finalName}`, -// // category, -// // deletedAt: null, -// // isActive: true, -// // }; - -// // if (existing) { -// // await prisma.fileStorage.update({ -// // where: { name: finalName }, -// // data, -// // }); -// // console.log(`♻️ restored: ${category}/${finalName}`); -// // } else { -// // await prisma.fileStorage.create({ data }); -// // console.log(`📂 created: ${category}/${finalName}`); -// // } -// // } - -// // /* ===== Cleanup ===== */ -// // await fs.rm(TMP_DIR, { recursive: true, force: true }); - -// // console.log("✅ Selesai seed assets!"); -// // } - -// // /* ===== Auto Run ===== */ -// // if (import.meta.main) { -// // seedAssets() -// // .catch((err) => { -// // console.error("❌ Error seeding assets:", err); -// // process.exit(1); -// // }) -// // .finally(async () => { -// // await prisma.$disconnect(); -// // }); -// // } - +/* eslint-disable @typescript-eslint/no-explicit-any */ import prisma from "@/lib/prisma"; -import AdmZip from "adm-zip"; -import fs from "fs/promises"; -import path from "path"; -import sharp from "sharp"; -import fetchWithRetry from "./data/fetchWithRetry"; -import { constants } from "fs"; -// ✅ Gunakan env variable dengan fallback -const UPLOADS_DIR = path.join(process.cwd(), process.env.WIBU_UPLOAD_DIR || "uploads"); - - -function detectCategory(filename: string): "image" | "document" | "other" { - const ext = path.extname(filename).toLowerCase(); - if ([".jpg", ".jpeg", ".png", ".webp"].includes(ext)) return "image"; - if ([".pdf", ".doc", ".docx"].includes(ext)) return "document"; - return "other"; -} - -async function walkDir( - dir: string, - fileList: string[] = [], -): Promise { - const entries = await fs.readdir(dir, { withFileTypes: true }); - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - if (entry.name === "__MACOSX") continue; - await walkDir(fullPath, fileList); - } else { - if (entry.name.startsWith(".") || entry.name === ".DS_Store") continue; - fileList.push(fullPath); - } - } - return fileList; -} +import { getAllDownloadUrls } from "./lib/get_images"; export default async function seedAssets() { - console.log("🚀 Seeding assets..."); - console.log("📁 Upload dir:", UPLOADS_DIR); + const images = await getAllDownloadUrls(); - try { - await fs.access(UPLOADS_DIR, fs.constants.W_OK); - } catch (err) { - console.error("❌ Upload directory is not writable:", UPLOADS_DIR); - throw new Error( - `UPLOADS_DIR not writable: ${UPLOADS_DIR}. Check Docker volume or permissions` - ); - } + // for (const img of images) { + // try { + // await prisma.fileStorage.upsert({ + // where: { name: img.name }, + // create: { + // name: img.name, + // category: "image", + // mimeType: "image/webp", + // link: img.downloadUrl, + // path: "images", + // realName: img.name, + // isActive: true, + // }, + // update: { + // link: img.downloadUrl, + // isActive: true, + // }, + // }); - // ✅ Pastikan folder exist - await fs.mkdir(UPLOADS_DIR, { recursive: true }); - try { - await fs.access(UPLOADS_DIR, constants.W_OK); -} catch { - throw new Error( - `UPLOADS_DIR not writable: ${UPLOADS_DIR}. Check Docker volume or permissions` - ); -} - await fs.mkdir(path.join(UPLOADS_DIR, "images"), { recursive: true }); - await fs.mkdir(path.join(UPLOADS_DIR, "documents"), { recursive: true }); - await fs.mkdir(path.join(UPLOADS_DIR, "other"), { recursive: true }); - - const url = - "https://cld-dkr-makuro-seafile.wibudev.com/f/8e9e42e9f3e94c80919e/?dl=1"; - - let buffer: Buffer; - try { - console.log("⬇️ Downloading ZIP from:", url); - const res = await fetchWithRetry(url, 3, 20000); - - const contentType = res.headers.get("content-type"); - if ( - !contentType?.includes("zip") && - !contentType?.includes("octet-stream") - ) { - throw new Error( - `Invalid content-type (${contentType}). Expected ZIP file`, - ); - } - - buffer = Buffer.from(await res.arrayBuffer()); - - if (buffer.length < 100) { - throw new Error("Downloaded ZIP is empty or corrupted"); - } - - if (buffer.toString("utf8", 0, 2) !== "PK") { - throw new Error("Invalid ZIP signature (PK not found)"); - } - - console.log(`✅ Downloaded ${(buffer.length / 1024 / 1024).toFixed(2)} MB`); - } catch (err) { - console.error("❌ Failed to download ZIP:", err); - throw err; - } - - // Extract ZIP - const extractDir = path.join(process.cwd(), "tmp_assets"); - await fs.rm(extractDir, { recursive: true, force: true }); - await fs.mkdir(extractDir, { recursive: true }); - - let zip: AdmZip; - try { - zip = new AdmZip(buffer); - zip.extractAllTo(extractDir, true); - console.log("✅ ZIP extracted successfully"); - } catch (err) { - console.error("❌ Failed to extract ZIP:", err); - throw err; - } - - const files = await walkDir(extractDir); - console.log(`📦 Found ${files.length} files to process`); - - // Process files - for (const filePath of files) { - const entryName = path.basename(filePath); - const category = detectCategory(entryName); - - let finalName = entryName; - let mimeType = "application/octet-stream"; - let targetPath = ""; + // console.log(`✅ ${img.name}`); + // } catch (err: any) { + // console.error(`❌ ${img.name}`, err.code ?? err); + // } + // } + for (const img of images) { try { - if (category === "image") { - const fileBaseName = path.parse(entryName).name; - finalName = `${fileBaseName}.webp`; - targetPath = path.join(UPLOADS_DIR, "images", finalName); - - await fs.mkdir(path.dirname(targetPath), { recursive: true }); - await sharp(filePath).webp({ quality: 80 }).toFile(targetPath); - mimeType = "image/webp"; - } else if (category === "document") { - targetPath = path.join(UPLOADS_DIR, "documents", entryName); - await fs.mkdir(path.dirname(targetPath), { recursive: true }); - await fs.copyFile(filePath, targetPath); - mimeType = "application/pdf"; - } else { - targetPath = path.join(UPLOADS_DIR, "other", entryName); - await fs.mkdir(path.dirname(targetPath), { recursive: true }); - await fs.copyFile(filePath, targetPath); - } - - // ✅ Upsert ke database await prisma.fileStorage.upsert({ - where: { name: finalName }, - update: { - path: path.dirname(targetPath), - realName: entryName, - mimeType, - link: `/api/fileStorage/findUnique/${finalName}`, - category, - deletedAt: null, - isActive: true, + where: { + id: img.name, }, create: { - name: finalName, - realName: entryName, - path: path.dirname(targetPath), - mimeType, - link: `/api/fileStorage/findUnique/${finalName}`, - category, + name: img.name, + category: "image", + mimeType: "image/webp", + link: img.downloadUrl, + path: "images", + realName: img.name, + isActive: true, }, + update: {}, }); - - console.log(`✅ Processed: ${category}/${finalName}`); + console.log(img.name, ": success") } catch (err) { - console.error(`❌ Failed to process ${entryName}`, err); - throw err; // ⛔ penting + console.log("gagal seed assets", JSON.stringify(err)); } } - // Cleanup - await fs.rm(extractDir, { recursive: true, force: true }); - console.log("✅ Asset seeding completed!"); + console.log("🎉 Image seeding completed"); } if (import.meta.main) { seedAssets() - .catch((err) => { - console.error("❌ Error seeding assets:", err); - process.exit(1); + .then(() => { + console.log("seed assets success"); }) - .finally(async () => { - await prisma.$disconnect(); + .catch((err) => { + console.log("gagal seed assets", JSON.stringify(err)); }); } diff --git a/src/app/admin/(dashboard)/_state/desa/profile.ts b/src/app/admin/(dashboard)/_state/desa/profile.ts index b8bb16d8..26ee5240 100644 --- a/src/app/admin/(dashboard)/_state/desa/profile.ts +++ b/src/app/admin/(dashboard)/_state/desa/profile.ts @@ -552,7 +552,7 @@ const maskotDesa = proxy({ deskripsi: profileData.deskripsi || "", images: (profileData.images || []).map((img) => ({ label: img.label, - imageId: img.image.id, + imageId: img?.image?.id || "", })), }; }, diff --git a/src/app/admin/(dashboard)/desa/profil/profil-desa/page.tsx b/src/app/admin/(dashboard)/desa/profil/profil-desa/page.tsx index e40dbcce..5d7a166b 100644 --- a/src/app/admin/(dashboard)/desa/profil/profil-desa/page.tsx +++ b/src/app/admin/(dashboard)/desa/profil/profil-desa/page.tsx @@ -462,7 +462,7 @@ function Page() {
{img.label}
{img.label} ({ - label: img.label, - imageId: img.imageId - })) - } - }, - include: { - images: { - include: { - image: true - } - } - } - }); - - return new Response(JSON.stringify({ - success: true, - message: "Data berhasil diperbarui", - data: updated, - }), { status: 200 }); - } catch (error) { - console.error("Gagal update MaskotDesa:", error); - return new Response(JSON.stringify({ + try { + const id = context.params?.id as string; + const body = (await context.body) as { + judul: string; + deskripsi: string; + images: { label: string; imageId: string }[]; + }; + + if (!id) { + return new Response( + JSON.stringify({ success: false, - message: "Terjadi kesalahan saat update", - }), { status: 500 }); + message: "ID tidak boleh kosong", + }), + { status: 400 }, + ); + } + + const existing = await prisma.maskotDesa.findUnique({ + where: { id }, + include: { images: { include: { image: true } } }, + }); + + if (!existing) { + return new Response( + JSON.stringify({ + success: false, + message: "Data tidak ditemukan", + }), + { status: 404 }, + ); + } + + // Hapus semua gambar lama (dan file-nya jika perlu) + for (const old of existing.images) { + try { + if (old.imageId) { + await prisma.fileStorage.delete({ where: { id: old.imageId } }); + } + // opsional: hapus file dari disk juga kalau kamu simpan file fisik + // await fs.unlink(path.join(old.image.path, old.image.name)); + } catch (error) { + console.warn("Gagal hapus gambar lama:", error); } -} \ No newline at end of file + } + + // Update profile & re-create images + const updated = await prisma.maskotDesa.update({ + where: { id }, + data: { + judul: body.judul, + deskripsi: body.deskripsi, + images: { + deleteMany: {}, + create: body.images.map((img) => ({ + label: img.label, + imageId: img.imageId, + })), + }, + }, + include: { + images: { + include: { + image: true, + }, + }, + }, + }); + + return new Response( + JSON.stringify({ + success: true, + message: "Data berhasil diperbarui", + data: updated, + }), + { status: 200 }, + ); + } catch (error) { + console.error("Gagal update MaskotDesa:", error); + return new Response( + JSON.stringify({ + success: false, + message: "Terjadi kesalahan saat update", + }), + { status: 500 }, + ); + } +} diff --git a/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx b/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx index 50425ff0..8abee1cb 100644 --- a/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx +++ b/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx @@ -61,7 +61,7 @@ function Semua() { {featuredData.judul {img.label} + + + Grafik Pelaksanaan APBDes + + Tidak ada data APBDes tersedia. + + + ); + } + + const items = Array.isArray(apbdesData.items) ? apbdesData.items : []; + + // Show message if no items exist + if (items.length === 0) { + return ( + + + + Grafik Pelaksanaan APBDes Tahun {apbdesData.tahun || 'N/A'} + + Tidak ada rincian anggaran tersedia untuk tahun ini. + + + ); } - 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) { > - Grafik Pelaksanaan APBDes Tahun {apbdesData.tahun} + Grafik Pelaksanaan APBDes Tahun {apbdesData.tahun || 'N/A'} diff --git a/src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx b/src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx index 82a6a499..9b0791f8 100644 --- a/src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx +++ b/src/app/darmasaba/(tambahan)/apbdes/lib/apbDesaTable.tsx @@ -34,7 +34,36 @@ interface APBDesTableProps { } function APBDesTable({ apbdesData }: APBDesTableProps) { + // Handle case where apbdesData is null or undefined + if (!apbdesData) { + return ( + + + Rincian APBDes + + + Tidak ada data APBDes tersedia. + + + ); + } + const items = Array.isArray(apbdesData.items) ? apbdesData.items : []; + + // Show message if no items exist + if (items.length === 0) { + return ( + + + Rincian APBDes Tahun {apbdesData.tahun || 'N/A'} + + + Tidak ada rincian anggaran tersedia untuk tahun ini. + + + ); + } + const sortedItems = [...items].sort((a, b) => a.kode.localeCompare(b.kode)); // Calculate totals @@ -46,7 +75,7 @@ function APBDesTable({ apbdesData }: APBDesTableProps) { return ( - Rincian APBDes Tahun {apbdesData.tahun} + Rincian APBDes Tahun {apbdesData.tahun || 'N/A'} diff --git a/src/app/darmasaba/(tambahan)/apbdes/lib/types.ts b/src/app/darmasaba/(tambahan)/apbdes/lib/types.ts index a52445aa..3c6dde79 100644 --- a/src/app/darmasaba/(tambahan)/apbdes/lib/types.ts +++ b/src/app/darmasaba/(tambahan)/apbdes/lib/types.ts @@ -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 }; } diff --git a/src/app/darmasaba/(tambahan)/apbdes/page.tsx b/src/app/darmasaba/(tambahan)/apbdes/page.tsx index 9e4847e8..8953db53 100644 --- a/src/app/darmasaba/(tambahan)/apbdes/page.tsx +++ b/src/app/darmasaba/(tambahan)/apbdes/page.tsx @@ -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(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 ( diff --git a/src/app/darmasaba/_com/main-page/apbdes/index.tsx b/src/app/darmasaba/_com/main-page/apbdes/index.tsx index 1ff3f25e..0511d69e 100644 --- a/src/app/darmasaba/_com/main-page/apbdes/index.tsx +++ b/src/app/darmasaba/_com/main-page/apbdes/index.tsx @@ -143,29 +143,29 @@ function Apbdes() { )} {/* GRID */} - - {loading ? ( -
- -
- ) : data.length === 0 ? ( -
- - - Belum ada data APBDes yang tersedia - - - Data akan ditampilkan di sini setelah diunggah - - -
- ) : ( - data.map((v, k) => ( + {loading ? ( +
+ +
+ ) : data.length === 0 ? ( +
+ + + Belum ada data APBDes yang tersedia + + + Data akan ditampilkan di sini setelah diunggah + + +
+ ) : ( + + {data.map((v, k) => (
- )) - )} - + ))} + + )}
) } diff --git a/types/env.d.ts b/types/env.d.ts index 2e636b1a..84193e50 100644 --- a/types/env.d.ts +++ b/types/env.d.ts @@ -1,10 +1,15 @@ declare namespace NodeJS { interface ProcessEnv { DATABASE_URL?: string; + SEAFILE_TOKEN?: string; + SEAFILE_REPO_ID?: string; WIBU_UPLOAD_DIR?: string; + WIBU_DOWNLOAD_DIR?: string; + EMAIL_USER?: string; + EMAIL_PASS?: string; NEXT_PUBLIC_BASE_URL?: string; NEXTAUTH_SECRET?: string; NEXTAUTH_URL?: string; - WIBU_DOWNLOAD_DIR?: string; + SEAFILE_URL?: string; } } diff --git a/x.json b/x.json new file mode 100644 index 00000000..d4a9cec1 --- /dev/null +++ b/x.json @@ -0,0 +1,69 @@ +[ + { + "type": "repo", + "id": "8814bfe1-30d5-4e77-ab36-3122fa59a022", + "owner": "0535ccb6211642c0a628f521577863a0@auth.local", + "owner_name": "nico", + "owner_contact_email": "nico@bip.com", + "name": "desa-darmasaba", + "mtime": 1769484147, + "modifier_email": "0535ccb6211642c0a628f521577863a0@auth.local", + "modifier_contact_email": "nico@bip.com", + "modifier_name": "nico", + "mtime_relative": "", + "size": 184351, + "size_formatted": "180.0\u00a0KB", + "encrypted": false, + "permission": "rw", + "virtual": false, + "root": "", + "head_commit_id": "253fd9604e54804a22cbf701bcc551e311e4a428", + "version": 1, + "salt": "" + }, + { + "type": "repo", + "id": "f0e9ee4a-fd13-49a2-81c0-f253951d063a", + "owner": "0535ccb6211642c0a628f521577863a0@auth.local", + "owner_name": "nico", + "owner_contact_email": "nico@bip.com", + "name": "My Library", + "mtime": 1769483609, + "modifier_email": "0535ccb6211642c0a628f521577863a0@auth.local", + "modifier_contact_email": "nico@bip.com", + "modifier_name": "nico", + "mtime_relative": "", + "size": 19392875, + "size_formatted": "18.5\u00a0MB", + "encrypted": false, + "permission": "rw", + "virtual": false, + "root": "", + "head_commit_id": "22374e711577dcfb152fe07921458302feb9970a", + "version": 1, + "salt": "" + }, + { + "type": "grepo", + "id": "9ef9d5e2-6df0-4635-ae1b-53ed52801524", + "name": "RND", + "owner": "Organization", + "mtime": 1768959408, + "mtime_relative": "", + "modifier_email": "dfa07fcb3e27453e969492855a2d6606@auth.local", + "modifier_contact_email": "jun@bip.com", + "modifier_name": "jun", + "size": 1197897275, + "size_formatted": "1.1\u00a0GB", + "encrypted": false, + "permission": "rw", + "share_from": "wibu@bip.com", + "share_from_name": "wibu", + "share_from_contact_email": "wibu@bip.com", + "share_type": "public", + "root": "", + "head_commit_id": "5199e27babe4fd797e64beba62777a1dde58077b", + "version": 1, + "salt": "" + } +] diff --git a/x.sh b/x.sh new file mode 100644 index 00000000..2fd84854 --- /dev/null +++ b/x.sh @@ -0,0 +1,30 @@ + +# ambil token +# curl -X POST https://cld-dkr-makuro-seafile.wibudev.com/api2/auth-token/ \ +# -d "username=nico@bip.com" \ +# -d "password=Production_123" + +# ambil list repo / library + +TOKEN=20a19f4a04032215d50ce53292e6abdd38b9f806 +# curl -X GET \ +# https://cld-dkr-makuro-seafile.wibudev.com/api2/repos/ \ +# -H "Authorization: Token $TOKEN" + +# REPO_NAME=desa-darmasaba +DIR_TARGET=asset-web + +REPO_ID=f0e9ee4a-fd13-49a2-81c0-f253951d063a +curl -X GET \ + "https://cld-dkr-makuro-seafile.wibudev.com/api2/repos/$REPO_ID/dir/?p=$DIR_TARGET" \ + -H "Authorization: Token $TOKEN" + +# curl -X GET \ +# "https://cld-dkr-makuro-seafile.wibudev.com/api2/repos/$REPO_ID/file/?p=$DIR_TARGET/buku6.jpg" \ +# -H "Authorization: Token $TOKEN" + + +# curl -X GET \ +# "https://cld-dkr-makuro-seafile.wibudev.com/api2/repos/$REPO_ID/dir/?p=/" \ +# -H "Authorization: Token $TOKEN" +