diff --git a/.gitignore b/.gitignore
index 5ef6a520..157b8563 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,10 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+
+# uploads
+/uploads
+
+# cache
+/cache
+
diff --git a/bun.lockb b/bun.lockb
index b9b7c1cd..624c5ecf 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/compressed_pdf.pdf b/compressed_pdf.pdf
deleted file mode 100644
index 4319680e..00000000
Binary files a/compressed_pdf.pdf and /dev/null differ
diff --git a/package.json b/package.json
index b08191ae..5d93f96e 100644
--- a/package.json
+++ b/package.json
@@ -15,13 +15,16 @@
"@elysiajs/swagger": "^1.2.0",
"@mantine/carousel": "^7.16.2",
"@mantine/core": "^7.16.2",
+ "@mantine/dropzone": "^7.17.0",
"@mantine/hooks": "^7.16.2",
+ "@paljs/types": "^8.1.0",
"@prisma/client": "^6.3.1",
"@tabler/icons-react": "^3.30.0",
"@types/bun": "^1.2.2",
"@types/lodash": "^4.17.15",
"add": "^2.0.6",
"animate.css": "^4.1.1",
+ "bun": "^1.2.2",
"elysia": "^1.2.12",
"embla-carousel-autoplay": "^8.5.2",
"embla-carousel-react": "^7.1.0",
@@ -29,11 +32,14 @@
"get-port": "^7.1.0",
"lodash": "^4.17.21",
"motion": "^12.4.1",
+ "nanoid": "^5.1.0",
"next": "15.1.6",
"next-view-transitions": "^0.3.4",
+ "p-limit": "^6.2.0",
"prisma": "^6.3.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
+ "react-simple-toasts": "^6.1.0",
"readdirp": "^4.1.1",
"swr": "^2.3.2",
"valtio": "^2.1.3"
diff --git a/public/assets/images/spash.png b/public/assets/images/spash.png
new file mode 100644
index 00000000..c3cfb585
Binary files /dev/null and b/public/assets/images/spash.png differ
diff --git a/public/no-image.jpg b/public/no-image.jpg
new file mode 100644
index 00000000..8f8d872a
Binary files /dev/null and b/public/no-image.jpg differ
diff --git a/src/app/_com/SpashScreen.tsx b/src/app/_com/SpashScreen.tsx
new file mode 100644
index 00000000..69d22304
--- /dev/null
+++ b/src/app/_com/SpashScreen.tsx
@@ -0,0 +1,41 @@
+"use client";
+
+import colors from "@/con/colors";
+import images from "@/con/images";
+import { Flex, Image, Paper, Stack, Text } from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+
+export default function SpashScreen() {
+ useShallowEffect(() => {
+ const timeout = setTimeout(() => {
+ window.location.href = "/darmasaba";
+ }, 3000);
+ return () => clearTimeout(timeout);
+ }, []);
+ return (
+
+
+
+
+
+ Pemerintah Desa
+
+ DARMASABA
+
+
+
+
+
+ );
+}
diff --git a/src/app/admin/_com/AdminNav.tsx b/src/app/admin/_com/AdminNav.tsx
new file mode 100644
index 00000000..63cd3bf5
--- /dev/null
+++ b/src/app/admin/_com/AdminNav.tsx
@@ -0,0 +1,18 @@
+"use client";
+import { Button, Stack } from "@mantine/core";
+import { Link } from "next-view-transitions";
+
+export default function AdminNav() {
+ return (
+
+
+
+ Images
+
+
+ CSV
+
+
+
+ );
+}
diff --git a/src/app/admin/_com/ListImage.tsx b/src/app/admin/_com/ListImage.tsx
new file mode 100644
index 00000000..e8009b4f
--- /dev/null
+++ b/src/app/admin/_com/ListImage.tsx
@@ -0,0 +1,139 @@
+"use client";
+import stateListImage from "@/state/state-list-image";
+import {
+ ActionIcon,
+ Box,
+ Button,
+ Group,
+ Image,
+ Pagination,
+ Paper,
+ SimpleGrid,
+ Stack,
+ Text,
+ TextInput,
+} from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { IconSearch, IconX } from "@tabler/icons-react";
+import { motion } from "framer-motion";
+import { useState } from "react";
+import toast from "react-simple-toasts";
+import { useSnapshot } from "valtio";
+
+export default function ListImage() {
+ const { list, total } = useSnapshot(stateListImage);
+ const [loading, setLoading] = useState(false);
+
+ useShallowEffect(() => {
+ // get url
+ console.log(window.location.origin);
+ stateListImage.load();
+ }, []);
+
+ let timeOut: NodeJS.Timer;
+ return (
+
+
+ }
+ rightSection={
+ {
+ stateListImage.load();
+ }}
+ >
+
+
+ }
+ placeholder="Cari"
+ onChange={(e) => {
+ if (timeOut) clearTimeout(timeOut);
+ timeOut = setTimeout(() => {
+ stateListImage.load({ search: e.target.value });
+ }, 200);
+ }}
+ />
+
+
+ {list &&
+ list.map((v, k) => {
+ return (
+
+
+ {
+ // copy to clipboard
+ navigator.clipboard.writeText(v.url);
+ toast("Berhasil disalin");
+ }}
+ whileHover={{ scale: 1.05 }}
+ whileTap={{ scale: 0.8 }}
+ >
+
+
+
+
+ {v.name}
+
+
+
+
+ {
+ // copy to clipboard
+ navigator.clipboard.writeText(v.url);
+ toast("Berhasil disalin");
+ }}
+ variant="subtle"
+ size="compact-xs"
+ >
+ Copy
+
+ {
+ stateListImage.del({ name: v.name }).finally(() => {
+ setLoading(false);
+ });
+ }}
+ >
+ delete
+
+
+
+
+
+ );
+ })}
+
+ {total && (
+ {
+ stateListImage.page = e;
+ stateListImage.load();
+ }}
+ />
+ )}
+
+ );
+}
diff --git a/src/app/admin/_com/UploadCsv.tsx b/src/app/admin/_com/UploadCsv.tsx
new file mode 100644
index 00000000..44e53730
--- /dev/null
+++ b/src/app/admin/_com/UploadCsv.tsx
@@ -0,0 +1,49 @@
+"use client";
+import ApiFetch from "@/lib/api-fetch";
+import { Group, Stack, Text } from "@mantine/core";
+import { Dropzone } from "@mantine/dropzone";
+import { useState } from "react";
+import toast from "react-simple-toasts";
+
+export default function UploadCsv() {
+ return (
+
+
+
+ );
+}
+
+function DropUpload() {
+ const [loading, setLoading] = useState(false);
+
+ return (
+
+
+ {
+ if (droppedFiles.length < 0) {
+ return toast("Tidak ada file yang diunggah");
+ }
+
+ setLoading(true);
+ for (const file of droppedFiles) {
+ await ApiFetch.api["upl-csv-single"].post({
+ name: file.name,
+ file,
+ });
+ }
+ setLoading(false);
+ }}
+ >
+
+ Drop Csv here
+
+
+
+
+ );
+}
diff --git a/src/app/admin/_com/UploadImage.tsx b/src/app/admin/_com/UploadImage.tsx
new file mode 100644
index 00000000..6405439d
--- /dev/null
+++ b/src/app/admin/_com/UploadImage.tsx
@@ -0,0 +1,34 @@
+"use client";
+import ApiFetch from "@/lib/api-fetch";
+import stateListImage from "@/state/state-list-image";
+import { Stack, Text } from "@mantine/core";
+import { Dropzone, IMAGE_MIME_TYPE } from "@mantine/dropzone";
+import { useState } from "react";
+
+export default function UploadImage() {
+ const [loading, setLoading] = useState(false);
+ return (
+
+ {
+ setLoading(true);
+ for (const file of droppedFiles) {
+ await ApiFetch.api["upl-img-single"].post({
+ file: file,
+ name: file.name,
+ });
+ }
+
+ setLoading(false);
+ stateListImage.load();
+ }}
+ >
+
+ Drop images here
+
+
+
+ );
+}
diff --git a/src/app/admin/csv/page.tsx b/src/app/admin/csv/page.tsx
new file mode 100644
index 00000000..ffc804b0
--- /dev/null
+++ b/src/app/admin/csv/page.tsx
@@ -0,0 +1,10 @@
+import { Stack } from "@mantine/core";
+import UploadCsv from "../_com/UploadCsv";
+
+export default function Page() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/admin/images/page.tsx b/src/app/admin/images/page.tsx
new file mode 100644
index 00000000..462d9701
--- /dev/null
+++ b/src/app/admin/images/page.tsx
@@ -0,0 +1,12 @@
+import { Stack } from "@mantine/core";
+import ListImage from "../_com/ListImage";
+import UploadImage from "../_com/UploadImage";
+
+export default function Page() {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx
new file mode 100644
index 00000000..b073cdf1
--- /dev/null
+++ b/src/app/admin/layout.tsx
@@ -0,0 +1,11 @@
+import { Stack } from "@mantine/core";
+import AdminNav from "./_com/AdminNav";
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+ );
+}
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
new file mode 100644
index 00000000..bf9b4ecd
--- /dev/null
+++ b/src/app/admin/page.tsx
@@ -0,0 +1,9 @@
+import { Container, Stack } from "@mantine/core";
+
+export default function Page() {
+ return (
+
+ admin
+
+ );
+}
diff --git a/src/app/api/[[...slugs]]/_lib/img-del.ts b/src/app/api/[[...slugs]]/_lib/img-del.ts
new file mode 100644
index 00000000..22b0c7f2
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/img-del.ts
@@ -0,0 +1,20 @@
+import fs from "fs/promises";
+import path from "path";
+
+async function imgDel({
+ name,
+ UPLOAD_DIR_IMAGE,
+}: {
+ name: string;
+ UPLOAD_DIR_IMAGE: string;
+}) {
+ try {
+ await fs.unlink(path.join(UPLOAD_DIR_IMAGE, name));
+ return "ok";
+ } catch (error) {
+ console.log(error);
+ return "error";
+ }
+}
+
+export default imgDel;
diff --git a/src/app/api/[[...slugs]]/_lib/img.ts b/src/app/api/[[...slugs]]/_lib/img.ts
new file mode 100644
index 00000000..4752afbf
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/img.ts
@@ -0,0 +1,61 @@
+import fs from "fs/promises";
+import path from "path";
+import sharp from "sharp";
+
+async function img({
+ name,
+ UPLOAD_DIR_IMAGE,
+ ROOT,
+ size,
+}: {
+ name: string;
+ UPLOAD_DIR_IMAGE: string;
+ ROOT: string;
+ size?: number; // Ukuran opsional (tidak ada default)
+}) {
+ const completeName = path.basename(name); // Nama file lengkap
+ const ext = path.extname(name).toLowerCase(); // Ekstensi file dalam huruf kecil
+ // const fileNameWithoutExt = path.basename(name, ext); // Nama file tanpa ekstensi
+
+ // Default image jika terjadi kesalahan
+ const noImage = path.join(ROOT, "public/no-image.jpg");
+
+ // Validasi ekstensi file
+ if (![".jpg", ".jpeg", ".png"].includes(ext)) {
+ console.warn(`Ekstensi file tidak didukung: ${ext}`);
+ return new Response(await fs.readFile(noImage), {
+ headers: { "Content-Type": "image/jpeg" },
+ });
+ }
+
+ try {
+ // Path ke file asli
+ const filePath = path.join(UPLOAD_DIR_IMAGE, completeName);
+
+ // Periksa apakah file ada
+ await fs.stat(filePath);
+
+ // Metadata gambar asli
+ const metadata = await sharp(filePath).metadata();
+
+ // Proses resize menggunakan sharp
+ const resizedImageBuffer = await sharp(filePath)
+ .resize(size || metadata.width) // Gunakan size jika diberikan, jika tidak gunakan width asli
+ .toBuffer();
+
+ return new Response(resizedImageBuffer, {
+ headers: {
+ "Cache-Control": "public, max-age=3600, stale-while-revalidate=600",
+ "Content-Type": "image/jpeg",
+ },
+ });
+ } catch (error) {
+ console.error(`Gagal memproses file: ${name}`, error);
+ // Jika file tidak ditemukan atau gagal diproses, kembalikan default image
+ return new Response(await fs.readFile(noImage), {
+ headers: { "Content-Type": "image/jpeg" },
+ });
+ }
+}
+
+export default img;
diff --git a/src/app/api/[[...slugs]]/_lib/imgs.ts b/src/app/api/[[...slugs]]/_lib/imgs.ts
new file mode 100644
index 00000000..5b3470f7
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/imgs.ts
@@ -0,0 +1,30 @@
+import fs from "fs/promises";
+
+async function imgs({
+ search = "",
+ page = 1,
+ count = 20,
+ UPLOAD_DIR_IMAGE,
+}: {
+ search?: string;
+ page?: number;
+ count?: number;
+ UPLOAD_DIR_IMAGE: string;
+}) {
+ const files = await fs.readdir(UPLOAD_DIR_IMAGE);
+
+ return files
+ .filter(
+ (file) =>
+ file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".jpeg")
+ )
+ .filter((file) => file.includes(search))
+ .slice((page - 1) * count, page * count)
+ .map((file) => ({
+ name: file,
+ url: `/api/img/${file}`,
+ total: files.length,
+ }));
+}
+
+export default imgs;
diff --git a/src/app/api/[[...slugs]]/_lib/upl-csv-single.ts b/src/app/api/[[...slugs]]/_lib/upl-csv-single.ts
new file mode 100644
index 00000000..c39f9ab2
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/upl-csv-single.ts
@@ -0,0 +1,12 @@
+export async function uplCsvSingle({
+ fileName,
+ file,
+}: {
+ fileName: string;
+ file: File;
+}) {
+ const textFile = await file.text();
+ console.log(fileName, textFile);
+
+ return "ok";
+}
diff --git a/src/app/api/[[...slugs]]/_lib/upl-csv.ts b/src/app/api/[[...slugs]]/_lib/upl-csv.ts
new file mode 100644
index 00000000..c46ee621
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/upl-csv.ts
@@ -0,0 +1,16 @@
+async function uplCsv({ files }: { files: File[] }) {
+ if (!Array.isArray(files) || files.length === 0) {
+ throw new Error("Tidak ada file yang diunggah");
+ }
+
+ for (const file of files) {
+ const textFile = await file.text();
+ const fileName = file.name;
+
+ console.log(textFile, fileName);
+ }
+
+ return "ok";
+}
+
+export default uplCsv;
diff --git a/src/app/api/[[...slugs]]/_lib/upl-img-single.ts b/src/app/api/[[...slugs]]/_lib/upl-img-single.ts
new file mode 100644
index 00000000..a8d7c7a2
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/upl-img-single.ts
@@ -0,0 +1,32 @@
+import { nanoid } from "nanoid";
+import fs from "fs/promises";
+import path from "path";
+import _ from "lodash";
+
+export async function uplImgSingle({
+ fileName,
+ file,
+ UPLOAD_DIR_IMAGE,
+}: {
+ fileName: string;
+ file: File;
+ UPLOAD_DIR_IMAGE: string;
+}) {
+ if (!fileName || typeof fileName !== "string" || fileName.trim() === "") {
+ console.warn(`Nama file tidak valid: ${fileName}`);
+ fileName = nanoid() + ".jpg";
+ }
+ const ext = path.extname(fileName).toLowerCase();
+ const fileNameWithoutExt = path.basename(fileName, ext);
+ const fileNameKebabCase = _.kebabCase(fileNameWithoutExt) + ext;
+
+ try {
+ const buffer = Buffer.from(await file.arrayBuffer());
+ const filePath = path.join(UPLOAD_DIR_IMAGE, fileNameKebabCase);
+ await fs.writeFile(filePath, buffer);
+ return filePath;
+ } catch (error) {
+ console.log(error);
+ return "error";
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/upl-img.ts b/src/app/api/[[...slugs]]/_lib/upl-img.ts
new file mode 100644
index 00000000..9fdf482e
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/upl-img.ts
@@ -0,0 +1,52 @@
+import path from "path";
+import fs from "fs/promises";
+import { nanoid } from "nanoid";
+
+async function uplImg({
+ files,
+ UPLOAD_DIR_IMAGE,
+}: {
+ files: File[];
+ UPLOAD_DIR_IMAGE: string;
+}) {
+ // Validasi input
+ if (!Array.isArray(files) || files.length === 0) {
+ throw new Error("Tidak ada file yang diunggah");
+ }
+
+ for (const file of files) {
+ let fileName = file.name;
+
+ // Validasi nama file
+ if (!fileName || typeof fileName !== "string" || fileName.trim() === "") {
+ console.warn(`Nama file tidak valid: ${fileName}`);
+ fileName = nanoid() + ".jpg";
+ }
+
+ // Sanitasi nama file untuk mencegah path traversal
+ const sanitizedFileName = sanitizeFileName(fileName);
+
+ try {
+ // Konversi file ke buffer
+ const buffer = Buffer.from(await file.arrayBuffer());
+
+ // Tulis file ke direktori uploads
+ const filePath = path.join(UPLOAD_DIR_IMAGE, sanitizedFileName);
+ await fs.writeFile(filePath, buffer);
+
+ console.log(`File berhasil diunggah: ${sanitizedFileName}`);
+ } catch (error) {
+ console.error(`Gagal mengunggah file ${fileName}:`, error);
+ throw new Error(`Gagal mengunggah file: ${fileName}`);
+ }
+ }
+
+ return "ok";
+}
+
+// Fungsi untuk membersihkan nama file dari karakter yang tidak aman
+function sanitizeFileName(fileName: string): string {
+ return fileName.replace(/[^a-zA-Z0-9._\-]/g, "_");
+}
+
+export default uplImg;
diff --git a/src/app/api/[[...slugs]]/route.ts b/src/app/api/[[...slugs]]/route.ts
index c78076ac..a84cb826 100644
--- a/src/app/api/[[...slugs]]/route.ts
+++ b/src/app/api/[[...slugs]]/route.ts
@@ -1,32 +1,171 @@
import prisma from "@/lib/prisma";
import cors, { HTTPMethod } from "@elysiajs/cors";
import swagger from "@elysiajs/swagger";
-import { Elysia } from "elysia";
+import { Elysia, t } from "elysia";
import getPotensi from "./_lib/get-potensi";
+import img from "./_lib/img";
+import fs from "fs/promises";
+import path from "path";
+import uplImg from "./_lib/upl-img";
+import imgs from "./_lib/imgs";
+import uplCsv from "./_lib/upl-csv";
+import imgDel from "./_lib/img-del";
+import { uplImgSingle } from "./_lib/upl-img-single";
+import { uplCsvSingle } from "./_lib/upl-csv-single";
+const ROOT = process.cwd();
+
+if (!process.env.WIBU_UPLOAD_DIR)
+ throw new Error("WIBU_UPLOAD_DIR is not defined");
+
+const UPLOAD_DIR = path.join(ROOT, process.env.WIBU_UPLOAD_DIR);
+const UPLOAD_DIR_IMAGE = path.join(UPLOAD_DIR, "image");
+
+// create uploads dir
+fs.mkdir(UPLOAD_DIR, {
+ recursive: true,
+}).catch(() => {});
+
+// create image uploads dir
+fs.mkdir(UPLOAD_DIR_IMAGE, {
+ recursive: true,
+}).catch(() => {});
const corsConfig = {
- origin: "*",
- methods: ["GET", "POST", "PATCH", "DELETE", "PUT"] as HTTPMethod[],
- allowedHeaders: "*",
- exposedHeaders: "*",
- maxAge: 5,
- credentials: true,
+ origin: "*",
+ methods: ["GET", "POST", "PATCH", "DELETE", "PUT"] as HTTPMethod[],
+ allowedHeaders: "*",
+ exposedHeaders: "*",
+ maxAge: 5,
+ credentials: true,
};
-
async function layanan() {
- const data = await prisma.layanan.findMany();
- return { data };
+ const data = await prisma.layanan.findMany();
+ return { data };
}
const ApiServer = new Elysia()
- .use(swagger({ path: "/api/docs" }))
- .use(cors(corsConfig))
- .group("/api", app => app
- .get("/layanan", layanan)
- .get("/potensi", getPotensi)
- )
-
-
+ .use(swagger({ path: "/api/docs" }))
+ .use(cors(corsConfig))
+ .onError(({ code }) => {
+ if (code === "NOT_FOUND") {
+ return {
+ status: 404,
+ body: "Route not found :(",
+ };
+ }
+ })
+ .group("/api", (app) =>
+ app
+ .get("/layanan", layanan)
+ .get("/potensi", getPotensi)
+ .get(
+ "/img/:name",
+ ({ params, query }) => {
+ return img({
+ name: params.name,
+ UPLOAD_DIR_IMAGE,
+ ROOT,
+ size: query.size,
+ });
+ },
+ {
+ params: t.Object({
+ name: t.String(),
+ }),
+ query: t.Optional(
+ t.Object({
+ size: t.Optional(t.Number()),
+ })
+ ),
+ }
+ )
+ .delete(
+ "/img/:name",
+ ({ params }) => {
+ return imgDel({
+ name: params.name,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ params: t.Object({
+ name: t.String(),
+ }),
+ }
+ )
+ .get(
+ "/imgs",
+ ({ query }) => {
+ return imgs({
+ search: query.search,
+ page: query.page,
+ count: query.count,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ query: t.Optional(
+ t.Object({
+ page: t.Number({ default: 1 }),
+ count: t.Number({ default: 10 }),
+ search: t.String({ default: "" }),
+ })
+ ),
+ }
+ )
+ .post(
+ "/upl-img",
+ ({ body }) => {
+ console.log(body.title);
+ return uplImg({ files: body.files, UPLOAD_DIR_IMAGE });
+ },
+ {
+ body: t.Object({
+ title: t.String(),
+ files: t.Files({ multiple: true }),
+ }),
+ }
+ )
+ .post(
+ "/upl-img-single",
+ ({ body }) => {
+ return uplImgSingle({
+ fileName: body.name,
+ file: body.file,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ body: t.Object({
+ name: t.String(),
+ file: t.File(),
+ }),
+ }
+ )
+ .post(
+ "/upl-csv-single",
+ ({ body }) => {
+ return uplCsvSingle({ fileName: body.name, file: body.file });
+ },
+ {
+ body: t.Object({
+ name: t.String(),
+ file: t.File(),
+ }),
+ }
+ )
+ .post(
+ "/upl-csv",
+ ({ body }) => {
+ return uplCsv({ files: body.files });
+ },
+ {
+ body: t.Object({
+ files: t.Files(),
+ }),
+ }
+ )
+ );
export const GET = ApiServer.handle;
export const POST = ApiServer.handle;
@@ -34,5 +173,4 @@ export const PATCH = ApiServer.handle;
export const DELETE = ApiServer.handle;
export const PUT = ApiServer.handle;
-export type AppServer = typeof ApiServer
-
+export type AppServer = typeof ApiServer;
diff --git a/src/app/(pages)/desa/[sub]/page.tsx b/src/app/darmasaba/(pages)/desa/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/desa/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/desa/[sub]/page.tsx
diff --git a/src/app/(pages)/desa/page.tsx b/src/app/darmasaba/(pages)/desa/page.tsx
similarity index 100%
rename from src/app/(pages)/desa/page.tsx
rename to src/app/darmasaba/(pages)/desa/page.tsx
diff --git a/src/app/(pages)/ekonomi/[sub]/page.tsx b/src/app/darmasaba/(pages)/ekonomi/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/ekonomi/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/ekonomi/[sub]/page.tsx
diff --git a/src/app/(pages)/ekonomi/page.tsx b/src/app/darmasaba/(pages)/ekonomi/page.tsx
similarity index 100%
rename from src/app/(pages)/ekonomi/page.tsx
rename to src/app/darmasaba/(pages)/ekonomi/page.tsx
diff --git a/src/app/(pages)/inovasi/[sub]/page.tsx b/src/app/darmasaba/(pages)/inovasi/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/inovasi/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/inovasi/[sub]/page.tsx
diff --git a/src/app/(pages)/inovasi/page.tsx b/src/app/darmasaba/(pages)/inovasi/page.tsx
similarity index 100%
rename from src/app/(pages)/inovasi/page.tsx
rename to src/app/darmasaba/(pages)/inovasi/page.tsx
diff --git a/src/app/(pages)/keamanan/[sub]/page.tsx b/src/app/darmasaba/(pages)/keamanan/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/keamanan/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/keamanan/[sub]/page.tsx
diff --git a/src/app/(pages)/keamanan/page.tsx b/src/app/darmasaba/(pages)/keamanan/page.tsx
similarity index 100%
rename from src/app/(pages)/keamanan/page.tsx
rename to src/app/darmasaba/(pages)/keamanan/page.tsx
diff --git a/src/app/(pages)/kesehatan/[sub]/page.tsx b/src/app/darmasaba/(pages)/kesehatan/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/kesehatan/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/kesehatan/[sub]/page.tsx
diff --git a/src/app/(pages)/kesehatan/page.tsx b/src/app/darmasaba/(pages)/kesehatan/page.tsx
similarity index 100%
rename from src/app/(pages)/kesehatan/page.tsx
rename to src/app/darmasaba/(pages)/kesehatan/page.tsx
diff --git a/src/app/(pages)/lingkungan/[sub]/page.tsx b/src/app/darmasaba/(pages)/lingkungan/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/lingkungan/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/lingkungan/[sub]/page.tsx
diff --git a/src/app/(pages)/lingkungan/page.tsx b/src/app/darmasaba/(pages)/lingkungan/page.tsx
similarity index 100%
rename from src/app/(pages)/lingkungan/page.tsx
rename to src/app/darmasaba/(pages)/lingkungan/page.tsx
diff --git a/src/app/darmasaba/(pages)/module/[sub]/page.tsx b/src/app/darmasaba/(pages)/module/[sub]/page.tsx
new file mode 100644
index 00000000..951cdbed
--- /dev/null
+++ b/src/app/darmasaba/(pages)/module/[sub]/page.tsx
@@ -0,0 +1,6 @@
+export default async function Page({ params }: { params: Promise<{ sub: string }> }) {
+ const { sub } = await params
+ return
+ {sub}
+
+}
\ No newline at end of file
diff --git a/src/app/module/page.tsx b/src/app/darmasaba/(pages)/module/page.tsx
similarity index 100%
rename from src/app/module/page.tsx
rename to src/app/darmasaba/(pages)/module/page.tsx
diff --git a/src/app/(pages)/pendidikan/[sub]/page.tsx b/src/app/darmasaba/(pages)/pendidikan/[sub]/page.tsx
similarity index 100%
rename from src/app/(pages)/pendidikan/[sub]/page.tsx
rename to src/app/darmasaba/(pages)/pendidikan/[sub]/page.tsx
diff --git a/src/app/(pages)/pendidikan/page.tsx b/src/app/darmasaba/(pages)/pendidikan/page.tsx
similarity index 100%
rename from src/app/(pages)/pendidikan/page.tsx
rename to src/app/darmasaba/(pages)/pendidikan/page.tsx
diff --git a/src/app/(tambahan)/layanan/[sub]/page.tsx b/src/app/darmasaba/(tambahan)/layanan/[sub]/page.tsx
similarity index 100%
rename from src/app/(tambahan)/layanan/[sub]/page.tsx
rename to src/app/darmasaba/(tambahan)/layanan/[sub]/page.tsx
diff --git a/src/app/(tambahan)/layanan/_com/BackButto.tsx b/src/app/darmasaba/(tambahan)/layanan/_com/BackButto.tsx
similarity index 100%
rename from src/app/(tambahan)/layanan/_com/BackButto.tsx
rename to src/app/darmasaba/(tambahan)/layanan/_com/BackButto.tsx
diff --git a/src/app/(tambahan)/layanan/page.tsx b/src/app/darmasaba/(tambahan)/layanan/page.tsx
similarity index 100%
rename from src/app/(tambahan)/layanan/page.tsx
rename to src/app/darmasaba/(tambahan)/layanan/page.tsx
diff --git a/src/app/darmasaba/(tambahan)/penghargaan/page.tsx b/src/app/darmasaba/(tambahan)/penghargaan/page.tsx
new file mode 100644
index 00000000..5d2a6fbe
--- /dev/null
+++ b/src/app/darmasaba/(tambahan)/penghargaan/page.tsx
@@ -0,0 +1,5 @@
+export default function Page() {
+ return
+ penghargaan
+
+}
\ No newline at end of file
diff --git a/src/com/Footer.tsx b/src/app/darmasaba/_com/Footer.tsx
similarity index 100%
rename from src/com/Footer.tsx
rename to src/app/darmasaba/_com/Footer.tsx
diff --git a/src/com/LoadDataFirstClient.tsx b/src/app/darmasaba/_com/LoadDataFirstClient.tsx
similarity index 100%
rename from src/com/LoadDataFirstClient.tsx
rename to src/app/darmasaba/_com/LoadDataFirstClient.tsx
diff --git a/src/com/MainLayout.tsx b/src/app/darmasaba/_com/MainLayout.tsx
similarity index 100%
rename from src/com/MainLayout.tsx
rename to src/app/darmasaba/_com/MainLayout.tsx
diff --git a/src/com/NavBarSearch.tsx b/src/app/darmasaba/_com/NavBarSearch.tsx
similarity index 100%
rename from src/com/NavBarSearch.tsx
rename to src/app/darmasaba/_com/NavBarSearch.tsx
diff --git a/src/com/Navbar.tsx b/src/app/darmasaba/_com/Navbar.tsx
similarity index 96%
rename from src/com/Navbar.tsx
rename to src/app/darmasaba/_com/Navbar.tsx
index 66448e62..3edb7e2a 100644
--- a/src/com/Navbar.tsx
+++ b/src/app/darmasaba/_com/Navbar.tsx
@@ -6,7 +6,7 @@ import { ActionIcon, Box, Burger, Group, Stack, Text } from "@mantine/core";
import { IconHome, IconSquareArrowRight } from "@tabler/icons-react";
import { motion } from 'framer-motion';
import { useSnapshot } from "valtio";
-import { MenuItem } from "../../types/menu-item";
+import { MenuItem } from "../../../../types/menu-item";
import { NavbarMainMenu } from "./NavbarMainMenu";
import { useRouter } from 'next/navigation'
@@ -29,7 +29,7 @@ export function Navbar() {
{
- router.push("/")
+ router.push("/darmasaba")
stateNav.mobileOpen = false
}}>
diff --git a/src/com/NavbarMainMenu.tsx b/src/app/darmasaba/_com/NavbarMainMenu.tsx
similarity index 96%
rename from src/com/NavbarMainMenu.tsx
rename to src/app/darmasaba/_com/NavbarMainMenu.tsx
index 3877118c..3f6a6cd3 100644
--- a/src/com/NavbarMainMenu.tsx
+++ b/src/app/darmasaba/_com/NavbarMainMenu.tsx
@@ -6,7 +6,7 @@ import { ActionIcon, Button, Container, Flex, Image, Stack } from "@mantine/core
import { useHover } from "@mantine/hooks"
import { useTransitionRouter } from 'next-view-transitions'
import { useSnapshot } from "valtio"
-import { MenuItem } from "../../types/menu-item"
+import { MenuItem } from "../../../../types/menu-item"
import { NavbarSearch } from "./NavBarSearch"
import { NavbarSubMenu } from "./NavbarSubMenu"
import { IconSearch } from "@tabler/icons-react"
@@ -26,7 +26,7 @@ export function NavbarMainMenu({ listNavbar }: {
md: "nowrap"
}}>
{
- router.push("/")
+ router.push("/darmasaba")
stateNav.clear()
}} >
diff --git a/src/com/NavbarSubMenu.tsx b/src/app/darmasaba/_com/NavbarSubMenu.tsx
similarity index 96%
rename from src/com/NavbarSubMenu.tsx
rename to src/app/darmasaba/_com/NavbarSubMenu.tsx
index 2bcdbf6c..37dcc180 100644
--- a/src/com/NavbarSubMenu.tsx
+++ b/src/app/darmasaba/_com/NavbarSubMenu.tsx
@@ -4,7 +4,7 @@ import stateNav from "@/state/state-nav";
import { Button, Container, Stack } from "@mantine/core";
import _ from "lodash";
import { motion } from "motion/react";
-import { MenuItem } from "../../types/menu-item";
+import { MenuItem } from "../../../../types/menu-item";
import { useTransitionRouter } from 'next-view-transitions'
export function NavbarSubMenu({ item }: { item: MenuItem[] | null }) {
diff --git a/src/com/main-page/content-4/index.tsx b/src/app/darmasaba/_com/main-page/content-4/index.tsx
similarity index 100%
rename from src/com/main-page/content-4/index.tsx
rename to src/app/darmasaba/_com/main-page/content-4/index.tsx
diff --git a/src/com/main-page/content-5/FlipScroll.tsx b/src/app/darmasaba/_com/main-page/content-5/FlipScroll.tsx
similarity index 100%
rename from src/com/main-page/content-5/FlipScroll.tsx
rename to src/app/darmasaba/_com/main-page/content-5/FlipScroll.tsx
diff --git a/src/com/main-page/content-5/index.tsx b/src/app/darmasaba/_com/main-page/content-5/index.tsx
similarity index 100%
rename from src/com/main-page/content-5/index.tsx
rename to src/app/darmasaba/_com/main-page/content-5/index.tsx
diff --git a/src/com/main-page/content-6/index.tsx b/src/app/darmasaba/_com/main-page/content-6/index.tsx
similarity index 100%
rename from src/com/main-page/content-6/index.tsx
rename to src/app/darmasaba/_com/main-page/content-6/index.tsx
diff --git a/src/com/main-page/content-7/index.tsx b/src/app/darmasaba/_com/main-page/content-7/index.tsx
similarity index 100%
rename from src/com/main-page/content-7/index.tsx
rename to src/app/darmasaba/_com/main-page/content-7/index.tsx
diff --git a/src/com/main-page/content-1/ModuleView.tsx b/src/app/darmasaba/_com/main-page/landing-page/ModuleView.tsx
similarity index 91%
rename from src/com/main-page/content-1/ModuleView.tsx
rename to src/app/darmasaba/_com/main-page/landing-page/ModuleView.tsx
index d227ac10..3595c878 100644
--- a/src/com/main-page/content-1/ModuleView.tsx
+++ b/src/app/darmasaba/_com/main-page/landing-page/ModuleView.tsx
@@ -1,5 +1,4 @@
import images from "@/con/images";
-import stateNav from "@/state/state-nav";
import { Center, Image, Paper, SimpleGrid } from "@mantine/core";
import { motion } from 'framer-motion';
import { useTransitionRouter } from 'next-view-transitions';
@@ -12,8 +11,7 @@ function ModuleItem({ item }: { item: string }) {
return (
{
- stateNav.module = item;
- router.push("/module");
+ router.push(`/module/c`);
}}
p={"md"}
bg={"white"}
diff --git a/src/com/main-page/content-1/SosmedView.tsx b/src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx
similarity index 100%
rename from src/com/main-page/content-1/SosmedView.tsx
rename to src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx
diff --git a/src/com/main-page/content-1/index.tsx b/src/app/darmasaba/_com/main-page/landing-page/index.tsx
similarity index 98%
rename from src/com/main-page/content-1/index.tsx
rename to src/app/darmasaba/_com/main-page/landing-page/index.tsx
index f0684487..875601ba 100644
--- a/src/com/main-page/content-1/index.tsx
+++ b/src/app/darmasaba/_com/main-page/landing-page/index.tsx
@@ -13,7 +13,7 @@ import {
import ModuleView from "./ModuleView";
import SosmedView from "./SosmedView";
-function Content1() {
+function LandingPage() {
return (
+
+
+
+
+
+
+
+ Penghargaan
+
+
+
+ Juara 2 Lomba Video Pendek
+
+
+ Juara 2 Duta Investasi
+
+
+ Juara Favorit Lomba Video Pendek
+
+
+ router.push("/penghargaan")} variant="white" radius={100}>
+ Selanjutnya
+
+
+
+
+
+ );
+}
+
+export default Penghargaan;
\ No newline at end of file
diff --git a/src/app/darmasaba/layout.tsx b/src/app/darmasaba/layout.tsx
new file mode 100644
index 00000000..b1a5dcb4
--- /dev/null
+++ b/src/app/darmasaba/layout.tsx
@@ -0,0 +1,22 @@
+import colors from "@/con/colors";
+import { Box, Space, Stack } from "@mantine/core";
+import Footer from "@/app/darmasaba/_com/Footer";
+import { Navbar } from "@/app/darmasaba/_com/Navbar";
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
+
+ {children}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/app/darmasaba/page.tsx b/src/app/darmasaba/page.tsx
new file mode 100644
index 00000000..00e784ed
--- /dev/null
+++ b/src/app/darmasaba/page.tsx
@@ -0,0 +1,24 @@
+import LandingPage from "@/app/darmasaba/_com/main-page/landing-page";
+import Penghargaan from "@/app/darmasaba/_com/main-page/penghargaan";
+import Content3 from "@/app/darmasaba/_com/main-page/layanan";
+import Content4 from "@/app/darmasaba/_com/main-page/content-4";
+import Content5 from "@/app/darmasaba/_com/main-page/content-5";
+import Content6 from "@/app/darmasaba/_com/main-page/content-6";
+import colors from "@/con/colors";
+// import ApiFetch from "@/lib/api-fetch";
+import { Stack } from "@mantine/core";
+import Content7 from "@/app/darmasaba/_com/main-page/content-7";
+
+export default function Page() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/error.tsx b/src/app/error.tsx
new file mode 100644
index 00000000..c373d1ca
--- /dev/null
+++ b/src/app/error.tsx
@@ -0,0 +1,9 @@
+'use client'
+export default function Error() {
+ return (
+
+
Something went wrong!
+
Sorry, something went wrong.
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index c5005848..6f8c441d 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -2,19 +2,22 @@
// All packages except `@mantine/hooks` require styles imports
import "@mantine/carousel/styles.css";
import "@mantine/core/styles.css";
+import '@mantine/dropzone/styles.css';
import "animate.css";
+import 'react-simple-toasts/dist/style.css';
+import 'react-simple-toasts/dist/theme/dark.css';
import "./globals.css";
-import LoadDataFirstClient from "@/com/LoadDataFirstClient";
+
+
+import LoadDataFirstClient from "@/app/darmasaba/_com/LoadDataFirstClient";
import {
ColorSchemeScript,
MantineProvider,
createTheme,
mantineHtmlProps,
} from "@mantine/core";
-import { MainLayout } from "../com/MainLayout";
import { ViewTransitions } from "next-view-transitions";
-import { WebVitals } from "./_com/WebVitals";
export const metadata = {
title: "desa darmasaba",
@@ -47,10 +50,7 @@ export default function RootLayout({
-
-
- {children}
-
+ {children}
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx
new file mode 100644
index 00000000..466f020e
--- /dev/null
+++ b/src/app/not-found.tsx
@@ -0,0 +1,8 @@
+export default function NotFound() {
+ return (
+
+
Not Found
+
This is the not found page
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/page.tsx b/src/app/page.tsx
index a8bf3681..15be0b6b 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,34 +1,12 @@
-import Content1 from "@/com/main-page/content-1";
-import Content2 from "@/com/main-page/content-2";
-import Content3 from "@/com/main-page/layanan";
-import Content4 from "@/com/main-page/content-4";
-import Content5 from "@/com/main-page/content-5";
-import Content6 from "@/com/main-page/content-6";
import colors from "@/con/colors";
// import ApiFetch from "@/lib/api-fetch";
import { Stack } from "@mantine/core";
-import Content7 from "@/com/main-page/content-7";
+import SpashScreen from "./_com/SpashScreen";
export default function Page() {
return (
-
-
-
-
-
-
-
+
);
}
-
-// async function Content3Loader() {
-// const { data } = await fetch("/api/layanan").then((v) => v.json());
-// return ;
-// }
-
-// async function Content4Loader() {
-// const { data } = await ApiFetch.api.potensi.get();
-// return ;
-// }
diff --git a/src/com/main-page/content-2/index.tsx b/src/com/main-page/content-2/index.tsx
deleted file mode 100644
index 847e3e6e..00000000
--- a/src/com/main-page/content-2/index.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-'use client';
-import { Stack, Box, Container, Button, Text } from "@mantine/core";
-
-function Content2() {
- return (
-
-
-
-
-
-
-
-
- Penghargaan
-
-
-
- Juara 2 Lomba Video Pendek
-
-
- Juara 2 Duta Investasi
-
-
- Juara Favorit Lomba Video Pendek
-
-
-
- Selanjutnya
-
-
-
-
-
- );
- }
-
- export default Content2;
\ No newline at end of file
diff --git a/src/con/navbar-list-menu.ts b/src/con/navbar-list-menu.ts
index 357177e4..2b96af4d 100644
--- a/src/con/navbar-list-menu.ts
+++ b/src/con/navbar-list-menu.ts
@@ -2,37 +2,37 @@ const navbarListMenu = [
{
id: "1",
name: "Desa",
- href: "/desa",
+ href: "/darmasaba/desa",
children: [
{
id: "1.1",
name: "profile",
- href: "/desa/profile"
+ href: "/darmasaba/desa/profile"
},
{
id: "1.2",
name: "potensi",
- href: "/desa/potensi"
+ href: "/darmasaba/desa/potensi"
},
{
id: "1.3",
name: "berita",
- href: "/desa/berita"
+ href: "/darmasaba/desa/berita"
},
{
id: "1.4",
name: "pengumuman",
- href: "/desa/pengumuman"
+ href: "/darmasaba/desa/pengumuman"
},
{
id: "1.5",
name: "galery",
- href: "/desa/galery"
+ href: "/darmasaba/desa/galery"
},
{
id: "1.6",
name: "layanan",
- href: "/desa/layanan"
+ href: "/darmasaba/desa/layanan"
},
]
@@ -40,240 +40,240 @@ const navbarListMenu = [
{
id: "2",
name: "Kesehatan",
- href: "/kesehatan",
+ href: "/darmasaba/kesehatan",
children: [
{
id: "2.1",
name: "Posyandu",
- href: "/kesehatan/posyandu"
+ href: "/darmasaba/kesehatan/posyandu"
},
{
id: "2.2",
name: "Data Kesehatan Warga",
- href: "/kesehatan/data-kesehatan-warga"
+ href: "/darmasaba/kesehatan/data-kesehatan-warga"
},
{
id: "2.3",
name: "Puskesmas",
- href: "/kesehatan/puskesmas"
+ href: "/darmasaba/kesehatan/puskesmas"
},
{
id: "2.4",
name: "Program Kesehatan",
- href: "/kesehatan/program-kesehatan"
+ href: "/darmasaba/kesehatan/program-kesehatan"
},
{
id: "2.5",
name: "Penanganan Darurat",
- href: "/kesehatan/penanganan-darurat"
+ href: "/darmasaba/kesehatan/penanganan-darurat"
},
{
id: "2.6",
name: "Kontak Darurat",
- href: "/kesehatan/kontak-darurat"
+ href: "/darmasaba/kesehatan/kontak-darurat"
},
{
id: "2.7",
name: "Info Wabah/Penyakit",
- href: "/kesehatan/info-wabah-penyakit"
+ href: "/darmasaba/kesehatan/info-wabah-penyakit"
}
]
},
{
id: "3",
name: "Keamanan",
- href: "/keamanan",
+ href: "/darmasaba/keamanan",
children: [
{
id: "3.1",
name: "Keamanan Lingkungan (Pecalang/Patwal)",
- href: "/keamanan/keamanan-lingkungan"
+ href: "/darmasaba/keamanan/keamanan-lingkungan"
},
{
id: "3.2",
name: "Polsek Terdekat",
- href: "/keamanan/polsek-terdekat"
+ href: "/darmasaba/keamanan/polsek-terdekat"
},
{
id: "3.3",
name: "Kontak Darurat",
- href: "/keamanan/kontak-darurat"
+ href: "/darmasaba/keamanan/kontak-darurat"
},
{
id: "3.4",
name: "Pencegahan Kriminalitas",
- href: "/keamanan/pencegahan-kriminalitas"
+ href: "/darmasaba/keamanan/pencegahan-kriminalitas"
},
{
id: "3.5",
name: "Laporan Publik",
- href: "/keamanan/laporan-publik"
+ href: "/darmasaba/keamanan/laporan-publik"
},
{
id: "3.6",
name: "Tips Keamanan",
- href: "/keamanan/tips-keamanan"
+ href: "/darmasaba/keamanan/tips-keamanan"
}
]
},
{
id: "4",
name: "Ekonomi",
- href: "/ekonomi",
+ href: "/darmasaba/ekonomi",
children: [
{
id: "4.1",
name: "Pasar Desa",
- href: "/ekonomi/pasar-desa"
+ href: "/darmasaba/ekonomi/pasar-desa"
},
{
id: "4.2",
name: "Koperasi",
- href: "/ekonomi/koperasi"
+ href: "/darmasaba/ekonomi/koperasi"
},
{
id: "4.3",
name: "UMKM",
- href: "/ekonomi/umkm"
+ href: "/darmasaba/ekonomi/umkm"
},
{
id: "4.4",
name: "Data Ekonomi Desa",
- href: "/ekonomi/data-ekonomi-desa"
+ href: "/darmasaba/ekonomi/data-ekonomi-desa"
},
{
id: "4.5",
name: "Pelatihan Wirausaha",
- href: "/ekonomi/pelatihan-wirausaha"
+ href: "/darmasaba/ekonomi/pelatihan-wirausaha"
},
{
id: "4.6",
name: "Bantuan & Pendanaan",
- href: "/ekonomi/bantuan-pendanaan"
+ href: "/darmasaba/ekonomi/bantuan-pendanaan"
},
{
id: "4.7",
name: "Investasi Desa",
- href: "/ekonomi/investasi-desa"
+ href: "/darmasaba/ekonomi/investasi-desa"
},
{
id: "4.8",
name: "Produk Unggulan",
- href: "/ekonomi/produk-unggulan"
+ href: "/darmasaba/ekonomi/produk-unggulan"
},
{
id: "4.9",
name: "Lowongan Kerja Lokal",
- href: "/ekonomi/lowongan-kerja-lokal"
+ href: "/darmasaba/ekonomi/lowongan-kerja-lokal"
}
]
}, {
id: "5",
name: "Inovasi",
- href: "/inovasi",
+ href: "/darmasaba/inovasi",
children: [
{
id: "5.1",
name: "Desa Digital/Smart Village",
- href: "/inovasi/desa-digital-smart-village"
+ href: "/darmasaba/inovasi/desa-digital-smart-village"
},
{
id: "5.2",
name: "Layanan Online Desa",
- href: "/inovasi/layanan-online-desa"
+ href: "/darmasaba/inovasi/layanan-online-desa"
},
{
id: "5.3",
name: "Program Kreatif Desa",
- href: "/inovasi/program-kreatif-desa"
+ href: "/darmasaba/inovasi/program-kreatif-desa"
},
{
id: "5.4",
name: "Kolaborasi Inovasi",
- href: "/inovasi/kolaborasi-inovasi"
+ href: "/darmasaba/inovasi/kolaborasi-inovasi"
},
{
id: "5.5",
name: "Info Teknologi Tepat Guna",
- href: "/inovasi/info-teknologi-tepat-guna"
+ href: "/darmasaba/inovasi/info-teknologi-tepat-guna"
},
{
id: "5.6",
name: "Ajukan Ide Inovatif",
- href: "/inovasi/ajukan-ide-inovatif"
+ href: "/darmasaba/inovasi/ajukan-ide-inovatif"
}
]
}, {
id: "6",
name: "Lingkungan",
- href: "/lingkungan",
+ href: "/darmasaba/lingkungan",
children: [
{
id: "6.1",
name: "Pengelolaan Sampah (Bank Sampah)",
- href: "/lingkungan/pengelolaan-sampah-bank-sampah"
+ href: "/darmasaba/lingkungan/pengelolaan-sampah-bank-sampah"
},
{
id: "6.2",
name: "Program Penghijauan",
- href: "/lingkungan/program-penghijauan"
+ href: "/darmasaba/lingkungan/program-penghijauan"
},
{
id: "6.3",
name: "Data Lingkungan Desa",
- href: "/lingkungan/data-lingkungan-desa"
+ href: "/darmasaba/lingkungan/data-lingkungan-desa"
},
{
id: "6.4",
name: "Gotong Royong",
- href: "/lingkungan/gotong-royong"
+ href: "/darmasaba/lingkungan/gotong-royong"
},
{
id: "6.5",
name: "Edukasi Lingkungan",
- href: "/lingkungan/edukasi-lingkungan"
+ href: "/darmasaba/lingkungan/edukasi-lingkungan"
},
{
id: "6.6",
name: "Konservasi Adat Bali",
- href: "/lingkungan/konservasi-adat-bali"
+ href: "/darmasaba/lingkungan/konservasi-adat-bali"
}
]
}, {
id: "7",
name: "Pendidikan",
- href: "/pendidikan",
+ href: "/darmasaba/pendidikan",
children: [
{
id: "7.1",
name: "Info Sekolah & PAUD",
- href: "/pendidikan/info-sekolah-paud"
+ href: "/darmasaba/pendidikan/info-sekolah-paud"
},
{
id: "7.2",
name: "Beasiswa Desa",
- href: "/pendidikan/beasiswa-desa"
+ href: "/darmasaba/pendidikan/beasiswa-desa"
},
{
id: "7.3",
name: "Program Pendidikan Anak",
- href: "/pendidikan/program-pendidikan-anak"
+ href: "/darmasaba/pendidikan/program-pendidikan-anak"
},
{
id: "7.4",
name: "Bimbingan Belajar Desa",
- href: "/pendidikan/bimbingan-belajar-desa"
+ href: "/darmasaba/pendidikan/bimbingan-belajar-desa"
},
{
id: "7.5",
name: "Pendidikan Non Formal",
- href: "/pendidikan/pendidikan-non-formal"
+ href: "/darmasaba/pendidikan/pendidikan-non-formal"
},
{
id: "7.6",
name: "Perpustakaan Desa",
- href: "/pendidikan/perpustakaan-desa"
+ href: "/darmasaba/pendidikan/perpustakaan-desa"
}
]
}
diff --git a/src/con/router.ts b/src/con/router.ts
new file mode 100644
index 00000000..0bf41e12
--- /dev/null
+++ b/src/con/router.ts
@@ -0,0 +1,40 @@
+
+
+const pages = {
+ "home": "/",
+ "darmasaba": {
+ "home": "/daramasaba",
+ "desa": "/darmasaba/desa",
+ "ekonomi": "/darmasaba/ekonomi",
+ "keamanan": "/darmasaba/keamanan",
+ "kesehatan": "/darmasaba/kesehatan",
+ "inovasi": "/darmasaba/inovasi",
+ "lingkungan": "/darmasaba/lingkungan",
+ "pendidikan": "/darmasaba/pendidikan",
+ "module": {
+ "daves": "/darmasaba/module/daves",
+ "mangan": "/darmasaba/module/mangan",
+ "bicara-darma": "/darmasaba/module/bicara-darma",
+ "bares": "/darmasaba/module/bares",
+ "sajjana-dharma-raksaka": "/darmasaba/module/sajjana-dharma-raksaka",
+ "pdkt": "/darmasaba/module/pdkt",
+ "gelah-melah": "/darmasaba/module/gelah-melah",
+ "inovasi-desa-darmasaba": "/darmasaba/module/inovasi-desa-darmasaba"
+ }
+ },
+
+
+}
+
+
+const apies = {
+ "/api": "home",
+ "/api/about": "about",
+ "/api/contact": "contact",
+}
+
+const router = {
+ pages,
+ apies
+} as const
+export default router
\ No newline at end of file
diff --git a/src/schema.ts b/src/schema.ts
new file mode 100644
index 00000000..ee73d8e9
--- /dev/null
+++ b/src/schema.ts
@@ -0,0 +1,67 @@
+import { SchemaObject } from '@paljs/types'
+
+export const schema: SchemaObject = {
+ models: [
+ {
+ name: 'Layanan',
+ fields: [
+ {
+ name: 'id',
+ type: 'String',
+ isId: true,
+ unique: false,
+ defaultValue: 'cuid()',
+ list: false,
+ required: true,
+ kind: 'scalar',
+ documentation: '',
+ relationField: false,
+ },
+ {
+ name: 'name',
+ type: 'String',
+ isId: false,
+ unique: true,
+ list: false,
+ required: true,
+ kind: 'scalar',
+ documentation: '',
+ relationField: false,
+ },
+ ],
+ documentation: '',
+ },
+ {
+ name: 'Potensi',
+ fields: [
+ {
+ name: 'id',
+ type: 'String',
+ isId: true,
+ unique: false,
+ defaultValue: 'cuid()',
+ list: false,
+ required: true,
+ kind: 'scalar',
+ documentation: '',
+ relationField: false,
+ },
+ {
+ name: 'name',
+ type: 'String',
+ isId: false,
+ unique: true,
+ list: false,
+ required: true,
+ kind: 'scalar',
+ documentation: '',
+ relationField: false,
+ },
+ ],
+ documentation: '',
+ },
+ ],
+ enums: [],
+ dataSource: { provider: 'postgresql', url: 'env("DATABASE_URL")' },
+ generators: [{ name: 'client', provider: 'prisma-client-js' }],
+}
diff --git a/src/state/state-list-image.ts b/src/state/state-list-image.ts
new file mode 100644
index 00000000..c260e70d
--- /dev/null
+++ b/src/state/state-list-image.ts
@@ -0,0 +1,38 @@
+import ApiFetch from "@/lib/api-fetch";
+import { proxy } from "valtio";
+
+const stateListImage = proxy<{
+ list: { name: string; url: string; total: number }[] | null;
+ page: number;
+ count: number;
+ total: number | undefined;
+ load: (params?: { search?: string }) => Promise;
+ del: ({ name }: { name: string }) => Promise;
+}>({
+ list: null,
+ page: 1,
+ count: 20,
+ total: undefined,
+ async load(params?: { search?: string }) {
+ const { search = "" } = params ?? {};
+ const { data } = await ApiFetch.api.imgs.get({
+ query: {
+ page: this.page,
+ count: this.count,
+ search,
+ },
+ });
+ this.list = data;
+ if (data?.[0]?.total) {
+ this.total = Math.ceil(data[0].total / this.count);
+ } else {
+ this.total = undefined;
+ }
+ },
+ async del({ name }: { name: string }) {
+ await ApiFetch.api.img({ name }).delete();
+ this.load();
+ },
+});
+
+export default stateListImage;
diff --git a/types/bun.ts b/types/bun.ts
index c59578ef..2a8960f2 100644
--- a/types/bun.ts
+++ b/types/bun.ts
@@ -2,5 +2,8 @@ declare module "bun" {
interface Env {
PORT: string;
NEXT_PUBLIC_WIBU_URL: string;
+ DATABASE_URL: string;
+ WIBU_UPLOAD_DIR: string;
+ WIBU_CACHE_DIR: string;
}
}
\ No newline at end of file
diff --git a/unknown/Library/Preferences/nextjs-nodejs/config.json b/unknown/Library/Preferences/nextjs-nodejs/config.json
deleted file mode 100644
index 1b0837d0..00000000
--- a/unknown/Library/Preferences/nextjs-nodejs/config.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "telemetry": {
- "notifiedAt": "1739668984025",
- "anonymousId": "da4db3546c4d6315299db5f269034c4669decd44840966bd3dc435bc184f5d61",
- "salt": "f26f15c27a3239f30152845755757b47"
- }
-}
\ No newline at end of file
diff --git a/xx.ts b/xx.ts
new file mode 100644
index 00000000..7b1dd358
--- /dev/null
+++ b/xx.ts
@@ -0,0 +1,3 @@
+import path from "path";
+
+console.log(path.basename("/apa/kanar.png", ".png"))
\ No newline at end of file