Compare commits
6 Commits
nico/18-au
...
nico/20-au
| Author | SHA1 | Date | |
|---|---|---|---|
| b580978f8e | |||
| 1c01397c0d | |||
| 90a6605efd | |||
| c22d865283 | |||
| 49067f0218 | |||
| d79425d529 |
@@ -223,7 +223,7 @@ model KategoriPrestasiDesa {
|
|||||||
model Responden {
|
model Responden {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String @unique
|
name String @unique
|
||||||
tanggal DateTime // misal: 2025-05-01
|
tanggal String // misal: 2025-05-01
|
||||||
jenisKelamin JenisKelaminResponden @relation(fields: [jenisKelaminId], references: [id])
|
jenisKelamin JenisKelaminResponden @relation(fields: [jenisKelaminId], references: [id])
|
||||||
jenisKelaminId String
|
jenisKelaminId String
|
||||||
rating PilihanRatingResponden @relation(fields: [ratingId], references: [id])
|
rating PilihanRatingResponden @relation(fields: [ratingId], references: [id])
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@@ -61,13 +62,39 @@ const lowonganKerjaState = proxy({
|
|||||||
findMany: {
|
findMany: {
|
||||||
data: null as
|
data: null as
|
||||||
| Prisma.LowonganPekerjaanGetPayload<{
|
| Prisma.LowonganPekerjaanGetPayload<{
|
||||||
omit: { isActive: true };
|
omit: {
|
||||||
|
isActive: true;
|
||||||
|
};
|
||||||
}>[]
|
}>[]
|
||||||
| null,
|
| null,
|
||||||
async load() {
|
page: 1,
|
||||||
const res = await ApiFetch.api.ekonomi.lowongankerja["find-many"].get();
|
totalPages: 1,
|
||||||
if (res.status === 200) {
|
loading: false,
|
||||||
lowonganKerjaState.findMany.data = res.data?.data ?? [];
|
search: "",
|
||||||
|
load: async (page = 1, limit = 10, search = "") => {
|
||||||
|
lowonganKerjaState.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
|
lowonganKerjaState.findMany.page = page;
|
||||||
|
lowonganKerjaState.findMany.search = search;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.ekonomi.lowongankerja["find-many"].get({ query });
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
lowonganKerjaState.findMany.data = res.data.data ?? [];
|
||||||
|
lowonganKerjaState.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
lowonganKerjaState.findMany.data = [];
|
||||||
|
lowonganKerjaState.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch lowongan kerja paginated:", err);
|
||||||
|
lowonganKerjaState.findMany.data = [];
|
||||||
|
lowonganKerjaState.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
lowonganKerjaState.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@@ -53,22 +54,47 @@ const pasarDesa = proxy({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
findMany: {
|
findMany: {
|
||||||
data: null as Array<
|
data: null as
|
||||||
Prisma.PasarDesaGetPayload<{
|
| Prisma.PasarDesaGetPayload<{
|
||||||
include: {
|
include: {
|
||||||
image: true;
|
image: true;
|
||||||
KategoriToPasar: {
|
KategoriToPasar: {
|
||||||
include: {
|
include: {
|
||||||
kategori: true;
|
kategori: true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
}>[]
|
||||||
}>
|
| null,
|
||||||
> | null,
|
page: 1,
|
||||||
async load() {
|
totalPages: 1,
|
||||||
const res = await ApiFetch.api.ekonomi.pasardesa["find-many"].get();
|
loading: false,
|
||||||
if (res.status === 200) {
|
search: "",
|
||||||
pasarDesa.findMany.data = res.data?.data ?? [];
|
load: async (page = 1, limit = 10, search = "", categoryId?: string) => {
|
||||||
|
pasarDesa.findMany.loading = true;
|
||||||
|
pasarDesa.findMany.page = page;
|
||||||
|
pasarDesa.findMany.search = search;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
if (categoryId) query.categoryId = categoryId;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.ekonomi.pasardesa["find-many"].get({ query });
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
pasarDesa.findMany.data = res.data.data ?? [];
|
||||||
|
pasarDesa.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
pasarDesa.findMany.data = [];
|
||||||
|
pasarDesa.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch keamanan lingkungan paginated:", err);
|
||||||
|
pasarDesa.findMany.data = [];
|
||||||
|
pasarDesa.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
pasarDesa.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -272,14 +298,41 @@ const kategoriProduk = proxy({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
findMany: {
|
findMany: {
|
||||||
data: null as Array<{
|
data: null as
|
||||||
id: string;
|
| Prisma.KategoriProdukGetPayload<{
|
||||||
nama: string;
|
omit: {
|
||||||
}> | null,
|
isActive: true;
|
||||||
async load() {
|
};
|
||||||
const res = await ApiFetch.api.ekonomi.kategoriproduk["find-many"].get();
|
}>[]
|
||||||
if (res.status === 200) {
|
| null,
|
||||||
kategoriProduk.findMany.data = res.data?.data ?? [];
|
page: 1,
|
||||||
|
totalPages: 1,
|
||||||
|
loading: false,
|
||||||
|
search2: "",
|
||||||
|
load: async (page = 1, limit = 10, search2 = "") => {
|
||||||
|
kategoriProduk.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
|
kategoriProduk.findMany.page = page;
|
||||||
|
kategoriProduk.findMany.search2 = search2;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search2) query.search2 = search2;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.ekonomi.kategoriproduk["find-many"].get({ query });
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
kategoriProduk.findMany.data = res.data.data ?? [];
|
||||||
|
kategoriProduk.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
kategoriProduk.findMany.data = [];
|
||||||
|
kategoriProduk.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch kategori produk paginated:", err);
|
||||||
|
kategoriProduk.findMany.data = [];
|
||||||
|
kategoriProduk.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
kategoriProduk.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@@ -53,15 +54,39 @@ const keamananLingkunganState = proxy({
|
|||||||
findMany: {
|
findMany: {
|
||||||
data: null as
|
data: null as
|
||||||
| Prisma.KeamananLingkunganGetPayload<{
|
| Prisma.KeamananLingkunganGetPayload<{
|
||||||
include: { image: true };
|
include: {
|
||||||
|
image: true;
|
||||||
|
};
|
||||||
}>[]
|
}>[]
|
||||||
| null,
|
| null,
|
||||||
async load() {
|
page: 1,
|
||||||
const res = await ApiFetch.api.keamanan.keamananlingkungan[
|
totalPages: 1,
|
||||||
"find-many"
|
loading: false,
|
||||||
].get();
|
search: "",
|
||||||
if (res.status === 200) {
|
load: async (page = 1, limit = 10, search = "") => {
|
||||||
keamananLingkunganState.findMany.data = res.data?.data ?? [];
|
keamananLingkunganState.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
|
keamananLingkunganState.findMany.page = page;
|
||||||
|
keamananLingkunganState.findMany.search = search;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.keamanan.keamananlingkungan["find-many"].get({ query });
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
keamananLingkunganState.findMany.data = res.data.data ?? [];
|
||||||
|
keamananLingkunganState.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
keamananLingkunganState.findMany.data = [];
|
||||||
|
keamananLingkunganState.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch keamanan lingkungan paginated:", err);
|
||||||
|
keamananLingkunganState.findMany.data = [];
|
||||||
|
keamananLingkunganState.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
keamananLingkunganState.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@@ -63,13 +64,41 @@ const polsekTerdekatState = proxy({
|
|||||||
findMany: {
|
findMany: {
|
||||||
data: null as
|
data: null as
|
||||||
| Prisma.PolsekTerdekatGetPayload<{
|
| Prisma.PolsekTerdekatGetPayload<{
|
||||||
include: { layananPolsek: true };
|
include: {
|
||||||
|
layananPolsek: true;
|
||||||
|
};
|
||||||
}>[]
|
}>[]
|
||||||
| null,
|
| null,
|
||||||
async load() {
|
page: 1,
|
||||||
const res = await ApiFetch.api.keamanan.polsekterdekat["find-many"].get();
|
totalPages: 1,
|
||||||
if (res.status === 200) {
|
loading: false,
|
||||||
polsekTerdekatState.findMany.data = res.data?.data ?? [];
|
search: "",
|
||||||
|
load: async (page = 1, limit = 10, search = "") => {
|
||||||
|
polsekTerdekatState.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
|
polsekTerdekatState.findMany.page = page;
|
||||||
|
polsekTerdekatState.findMany.search = search;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.keamanan.polsekterdekat["find-many"].get(
|
||||||
|
{ query }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
polsekTerdekatState.findMany.data = res.data.data ?? [];
|
||||||
|
polsekTerdekatState.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
polsekTerdekatState.findMany.data = [];
|
||||||
|
polsekTerdekatState.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch polsek terdekat paginated:", err);
|
||||||
|
polsekTerdekatState.findMany.data = [];
|
||||||
|
polsekTerdekatState.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
polsekTerdekatState.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -237,6 +266,29 @@ const polsekTerdekatState = proxy({
|
|||||||
polsekTerdekatState.edit.form = { ...defaultForm };
|
polsekTerdekatState.edit.form = { ...defaultForm };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
findFirst: {
|
||||||
|
data: null as Prisma.PolsekTerdekatGetPayload<{
|
||||||
|
include: {
|
||||||
|
layananPolsek: true;
|
||||||
|
};
|
||||||
|
}> | null,
|
||||||
|
loading: false,
|
||||||
|
load: async () => { // Changed to arrow function
|
||||||
|
polsekTerdekatState.findFirst.loading = true;
|
||||||
|
try {
|
||||||
|
const res = await ApiFetch.api.keamanan.polsekterdekat["find-first"].get();
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
polsekTerdekatState.findFirst.data = res.data.data || null;
|
||||||
|
} else {
|
||||||
|
polsekTerdekatState.findFirst.data = null;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch polsek terdekat terbaru:", err);
|
||||||
|
} finally {
|
||||||
|
polsekTerdekatState.findFirst.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default polsekTerdekatState;
|
export default polsekTerdekatState;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ApiFetch from "@/lib/api-fetch";
|
import ApiFetch from "@/lib/api-fetch";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@@ -53,15 +54,39 @@ const tipsKeamananState = proxy({
|
|||||||
findMany: {
|
findMany: {
|
||||||
data: null as
|
data: null as
|
||||||
| Prisma.MenuTipsKeamananGetPayload<{
|
| Prisma.MenuTipsKeamananGetPayload<{
|
||||||
include: { image: true };
|
include: {
|
||||||
|
image: true;
|
||||||
|
};
|
||||||
}>[]
|
}>[]
|
||||||
| null,
|
| null,
|
||||||
async load() {
|
page: 1,
|
||||||
const res = await ApiFetch.api.keamanan.menutipskeamanan[
|
totalPages: 1,
|
||||||
"find-many"
|
loading: false,
|
||||||
].get();
|
search: "",
|
||||||
if (res.status === 200) {
|
load: async (page = 1, limit = 10, search = "") => {
|
||||||
tipsKeamananState.findMany.data = res.data?.data ?? [];
|
tipsKeamananState.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
|
tipsKeamananState.findMany.page = page;
|
||||||
|
tipsKeamananState.findMany.search = search;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.keamanan.menutipskeamanan["find-many"].get({ query });
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data?.success) {
|
||||||
|
tipsKeamananState.findMany.data = res.data.data ?? [];
|
||||||
|
tipsKeamananState.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
|
} else {
|
||||||
|
tipsKeamananState.findMany.data = [];
|
||||||
|
tipsKeamananState.findMany.totalPages = 1;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Gagal fetch menu tips keamanan paginated:", err);
|
||||||
|
tipsKeamananState.findMany.data = [];
|
||||||
|
tipsKeamananState.findMany.totalPages = 1;
|
||||||
|
} finally {
|
||||||
|
tipsKeamananState.findMany.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -181,7 +181,13 @@ const responden = proxy({
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(this.form),
|
body: JSON.stringify({
|
||||||
|
name: this.form.name,
|
||||||
|
tanggal: this.form.tanggal,
|
||||||
|
jenisKelaminId: this.form.jenisKelaminId,
|
||||||
|
ratingId: this.form.ratingId,
|
||||||
|
kelompokUmurId: this.form.kelompokUmurId,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (!response.ok || !result?.success) {
|
if (!response.ok || !result?.success) {
|
||||||
|
|||||||
@@ -49,35 +49,38 @@ const daftarInformasiPublik = proxy({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
findMany: {
|
findMany: {
|
||||||
data: null as any[] | null,
|
data: null as
|
||||||
|
| Prisma.DaftarInformasiPublikGetPayload<{
|
||||||
|
omit: {
|
||||||
|
isActive: true;
|
||||||
|
};
|
||||||
|
}>[]
|
||||||
|
| null,
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 1,
|
totalPages: 1,
|
||||||
total: 0,
|
|
||||||
loading: false,
|
loading: false,
|
||||||
load: async (page = 1, limit = 10) => { // Change to arrow function
|
search: "",
|
||||||
daftarInformasiPublik.findMany.loading = true; // Use the full path to access the property
|
load: async (page = 1, limit = 10, search = "") => {
|
||||||
|
daftarInformasiPublik.findMany.loading = true; // ✅ Akses langsung via nama path
|
||||||
daftarInformasiPublik.findMany.page = page;
|
daftarInformasiPublik.findMany.page = page;
|
||||||
try {
|
daftarInformasiPublik.findMany.search = search;
|
||||||
const res = await ApiFetch.api.ppid.daftarinformasipublik[
|
|
||||||
"find-many"
|
|
||||||
].get({
|
|
||||||
query: { page, limit },
|
|
||||||
});
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query: any = { page, limit };
|
||||||
|
if (search) query.search = search;
|
||||||
|
|
||||||
|
const res = await ApiFetch.api.ppid.daftarinformasipublik["find-many"].get({ query });
|
||||||
|
|
||||||
if (res.status === 200 && res.data?.success) {
|
if (res.status === 200 && res.data?.success) {
|
||||||
daftarInformasiPublik.findMany.data = res.data.data || [];
|
daftarInformasiPublik.findMany.data = res.data.data ?? [];
|
||||||
daftarInformasiPublik.findMany.total = res.data.total || 0;
|
daftarInformasiPublik.findMany.totalPages = res.data.totalPages ?? 1;
|
||||||
daftarInformasiPublik.findMany.totalPages = res.data.totalPages || 1;
|
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to load daftar informasi publik:", res.data?.message);
|
|
||||||
daftarInformasiPublik.findMany.data = [];
|
daftarInformasiPublik.findMany.data = [];
|
||||||
daftarInformasiPublik.findMany.total = 0;
|
|
||||||
daftarInformasiPublik.findMany.totalPages = 1;
|
daftarInformasiPublik.findMany.totalPages = 1;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error("Error loading daftar informasi publik:", error);
|
console.error("Gagal fetch daftar informasi publik paginated:", err);
|
||||||
daftarInformasiPublik.findMany.data = [];
|
daftarInformasiPublik.findMany.data = [];
|
||||||
daftarInformasiPublik.findMany.total = 0;
|
|
||||||
daftarInformasiPublik.findMany.totalPages = 1;
|
daftarInformasiPublik.findMany.totalPages = 1;
|
||||||
} finally {
|
} finally {
|
||||||
daftarInformasiPublik.findMany.loading = false;
|
daftarInformasiPublik.findMany.loading = false;
|
||||||
|
|||||||
@@ -55,17 +55,17 @@ function EditLowonganKerja() {
|
|||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
try {
|
try {
|
||||||
lowonganKerjaState.update.form = {
|
// Set the ID for the update
|
||||||
...lowonganKerjaState.update.form,
|
lowonganState.update.id = params?.id as string;
|
||||||
posisi: formData.posisi,
|
|
||||||
namaPerusahaan: formData.namaPerusahaan,
|
// Update the form state
|
||||||
lokasi: formData.lokasi,
|
lowonganState.update.form = {
|
||||||
tipePekerjaan: formData.tipePekerjaan,
|
...lowonganState.update.form,
|
||||||
gaji: formData.gaji,
|
...formData
|
||||||
deskripsi: formData.deskripsi,
|
};
|
||||||
kualifikasi: formData.kualifikasi,
|
|
||||||
}
|
// Call the update function
|
||||||
await lowonganState.update.update()
|
await lowonganState.update.update();
|
||||||
toast.success("Lowongan kerja berhasil diperbarui!");
|
toast.success("Lowongan kerja berhasil diperbarui!");
|
||||||
router.push("/admin/ekonomi/lowongan-kerja-lokal");
|
router.push("/admin/ekonomi/lowongan-kerja-lokal");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -88,7 +88,7 @@ function EditLowonganKerja() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
value={formData.posisi}
|
value={formData.posisi}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.posisi = val.target.value;
|
setFormData(prev => ({ ...prev, posisi: val.target.value }));
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Posisi</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Posisi</Text>}
|
||||||
placeholder='Masukkan posisi'
|
placeholder='Masukkan posisi'
|
||||||
@@ -96,7 +96,7 @@ function EditLowonganKerja() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
value={formData.namaPerusahaan}
|
value={formData.namaPerusahaan}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.namaPerusahaan = val.target.value;
|
setFormData(prev => ({ ...prev, namaPerusahaan: val.target.value }));
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Nama Perusahaan</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Nama Perusahaan</Text>}
|
||||||
placeholder='Masukkan nama perusahaan'
|
placeholder='Masukkan nama perusahaan'
|
||||||
@@ -104,7 +104,7 @@ function EditLowonganKerja() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
value={formData.lokasi}
|
value={formData.lokasi}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.lokasi = val.target.value;
|
setFormData(prev => ({ ...prev, lokasi: val.target.value }));
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Lokasi</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Lokasi</Text>}
|
||||||
placeholder='Masukkan lokasi'
|
placeholder='Masukkan lokasi'
|
||||||
@@ -112,7 +112,7 @@ function EditLowonganKerja() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
value={formData.tipePekerjaan}
|
value={formData.tipePekerjaan}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.tipePekerjaan = val.target.value;
|
setFormData(prev => ({ ...prev, tipePekerjaan: val.target.value }));
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Tipe Pekerjaan</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Tipe Pekerjaan</Text>}
|
||||||
placeholder='Masukkan tipe pekerjaan'
|
placeholder='Masukkan tipe pekerjaan'
|
||||||
@@ -120,7 +120,7 @@ function EditLowonganKerja() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
value={formData.gaji}
|
value={formData.gaji}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.gaji = val.target.value;
|
setFormData(prev => ({ ...prev, gaji: val.target.value }));
|
||||||
}}
|
}}
|
||||||
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
label={<Text fw={"bold"} fz={"sm"}>Gaji selama 1 bulan</Text>}
|
||||||
placeholder='Masukkan gaji'
|
placeholder='Masukkan gaji'
|
||||||
@@ -130,7 +130,7 @@ function EditLowonganKerja() {
|
|||||||
<EditEditor
|
<EditEditor
|
||||||
value={formData.deskripsi}
|
value={formData.deskripsi}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.deskripsi = val;
|
setFormData(prev => ({ ...prev, deskripsi: val }));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -139,7 +139,7 @@ function EditLowonganKerja() {
|
|||||||
<EditEditor
|
<EditEditor
|
||||||
value={formData.kualifikasi}
|
value={formData.kualifikasi}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
formData.kualifikasi = val;
|
setFormData(prev => ({ ...prev, kualifikasi: val }));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import HeaderSearch from '../../_com/header';
|
import HeaderSearch from '../../_com/header';
|
||||||
import JudulList from '../../_com/judulList';
|
import JudulList from '../../_com/judulList';
|
||||||
@@ -30,20 +30,21 @@ function ListLowonganKerjaLokal({ search }: { search: string }) {
|
|||||||
const lowonganState = useProxy(lowonganKerjaState)
|
const lowonganState = useProxy(lowonganKerjaState)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = lowonganState.findMany
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
lowonganState.findMany.load();
|
load(page, 10, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
|
|
||||||
const filteredData = (lowonganState.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.posisi.toLowerCase().includes(keyword) ||
|
|
||||||
item.namaPerusahaan.toLowerCase().includes(keyword) ||
|
|
||||||
item.lokasi.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!lowonganState.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -60,18 +61,24 @@ function ListLowonganKerjaLokal({ search }: { search: string }) {
|
|||||||
<Table striped withTableBorder withRowBorders>
|
<Table striped withTableBorder withRowBorders>
|
||||||
<TableThead>
|
<TableThead>
|
||||||
<TableTr>
|
<TableTr>
|
||||||
<TableTh>Bekerja Sebagai</TableTh>
|
<TableTh>Pekerjaan</TableTh>
|
||||||
<TableTh>Nama Usaha</TableTh>
|
<TableTh>Nama Perusahaan</TableTh>
|
||||||
<TableTh>Alamat Usaha</TableTh>
|
<TableTh>Lokasi</TableTh>
|
||||||
<TableTh>Detail</TableTh>
|
<TableTh>Detail</TableTh>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>{item.posisi}</TableTd>
|
<TableTd>
|
||||||
<TableTd>{item.namaPerusahaan}</TableTd>
|
<Text fz={"md"}>{item.posisi}</Text>
|
||||||
<TableTd>{item.lokasi}</TableTd>
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Text fz={"md"}>{item.namaPerusahaan}</Text>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Text fz={"md"}>{item.lokasi}</Text>
|
||||||
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Button onClick={() => router.push(`/admin/ekonomi/lowongan-kerja-lokal/${item.id}`)}>
|
<Button onClick={() => router.push(`/admin/ekonomi/lowongan-kerja-lokal/${item.id}`)}>
|
||||||
<IconDeviceImac size={20} />
|
<IconDeviceImac size={20} />
|
||||||
@@ -82,6 +89,14 @@ function ListLowonganKerjaLokal({ search }: { search: string }) {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconEdit, IconSearch, IconX } from '@tabler/icons-react';
|
import { IconEdit, IconSearch, IconX } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@@ -13,31 +13,39 @@ import pasarDesaState from '../../../_state/ekonomi/pasar-desa/pasar-desa';
|
|||||||
|
|
||||||
|
|
||||||
function PasarDesa() {
|
function PasarDesa() {
|
||||||
const [search, setSearch] = useState("")
|
const [search2, setSearch2] = useState("")
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<HeaderSearch
|
<HeaderSearch
|
||||||
title='Kategori Produk'
|
title='Kategori Produk'
|
||||||
placeholder='pencarian'
|
placeholder='pencarian'
|
||||||
searchIcon={<IconSearch size={20} />}
|
searchIcon={<IconSearch size={20} />}
|
||||||
value={search}
|
value={search2}
|
||||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
onChange={(e) => setSearch2(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
<ListPasarDesa search={search} />
|
<ListPasarDesa search2={search2} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ListPasarDesa({ search }: { search: string }) {
|
function ListPasarDesa({ search2 }: { search2: string }) {
|
||||||
const statePasar = useProxy(pasarDesaState.kategoriProduk)
|
const statePasar = useProxy(pasarDesaState.kategoriProduk)
|
||||||
const [modalHapus, setModalHapus] = useState(false)
|
const [modalHapus, setModalHapus] = useState(false)
|
||||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||||
// const params = useParams()
|
// const params = useParams()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = statePasar.findMany
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
statePasar.findMany.load()
|
load(page, 10, search2)
|
||||||
}, [])
|
}, [page, search2])
|
||||||
|
|
||||||
const handleHapus = () => {
|
const handleHapus = () => {
|
||||||
if (selectedId) {
|
if (selectedId) {
|
||||||
@@ -47,14 +55,9 @@ function ListPasarDesa({ search }: { search: string }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredData = (statePasar.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.nama.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!statePasar.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -99,6 +102,14 @@ function ListPasarDesa({ search }: { search: string }) {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my={"md"}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
{/* Modal Konfirmasi Hapus */}
|
{/* Modal Konfirmasi Hapus */}
|
||||||
<ModalKonfirmasiHapus
|
<ModalKonfirmasiHapus
|
||||||
opened={modalHapus}
|
opened={modalHapus}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@@ -30,21 +30,21 @@ function ListPasarDesa({ search }: { search: string }) {
|
|||||||
const statePasar = useProxy(pasarDesaState.pasarDesa)
|
const statePasar = useProxy(pasarDesaState.pasarDesa)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = statePasar.findMany
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
statePasar.findMany.load()
|
load(page, 10, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
|
|
||||||
const filteredData = (statePasar.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.nama.toLowerCase().includes(keyword) ||
|
|
||||||
item.harga.toString().toLowerCase().includes(keyword) ||
|
|
||||||
item.rating.toString().toLowerCase().includes(keyword) ||
|
|
||||||
item.alamatUsaha.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!statePasar.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -86,6 +86,14 @@ function ListPasarDesa({ search }: { search: string }) {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my={"md"}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ function DetailKeamananLingkungan() {
|
|||||||
{keamananState.findUnique.data ? (
|
{keamananState.findUnique.data ? (
|
||||||
<Paper key={keamananState.findUnique.data.id} bg={colors['BG-trans']} p={'md'}>
|
<Paper key={keamananState.findUnique.data.id} bg={colors['BG-trans']} p={'md'}>
|
||||||
<Stack gap={"xs"}>
|
<Stack gap={"xs"}>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"} fz={"lg"}>Gambar</Text>
|
||||||
|
<Image w={{ base: 150, md: 490}} src={keamananState.findUnique.data?.image?.link} alt="gambar" />
|
||||||
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={"bold"} fz={"lg"}>Judul Keamanan Lingkungan</Text>
|
<Text fw={"bold"} fz={"lg"}>Judul Keamanan Lingkungan</Text>
|
||||||
<Text fz={"lg"}>{keamananState.findUnique.data?.name}</Text>
|
<Text fz={"lg"}>{keamananState.findUnique.data?.name}</Text>
|
||||||
@@ -62,10 +66,6 @@ function DetailKeamananLingkungan() {
|
|||||||
<Text fw={"bold"} fz={"lg"}>Deskripsi</Text>
|
<Text fw={"bold"} fz={"lg"}>Deskripsi</Text>
|
||||||
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: keamananState.findUnique.data?.deskripsi }} />
|
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: keamananState.findUnique.data?.deskripsi }} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
|
||||||
<Text fw={"bold"} fz={"lg"}>Gambar</Text>
|
|
||||||
<Image w={{ base: 150, md: 150, lg: 150 }} src={keamananState.findUnique.data?.image?.link} alt="gambar" />
|
|
||||||
</Box>
|
|
||||||
<Flex gap={"xs"} mt={10}>
|
<Flex gap={"xs"} mt={10}>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import HeaderSearch from '../../_com/header';
|
import HeaderSearch from '../../_com/header';
|
||||||
import JudulList from '../../_com/judulList';
|
import JudulList from '../../_com/judulList';
|
||||||
@@ -30,19 +30,21 @@ function ListKeamananLingkungan({ search }: { search: string }) {
|
|||||||
const keamananState = useProxy(keamananLingkunganState)
|
const keamananState = useProxy(keamananLingkunganState)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = keamananState.findMany;
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
keamananState.findMany.load()
|
load(page, 10, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
|
|
||||||
const filteredData = (keamananState.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.name.toLowerCase().includes(keyword) ||
|
|
||||||
item.deskripsi.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!keamananState.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -67,9 +69,15 @@ function ListKeamananLingkungan({ search }: { search: string }) {
|
|||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>{item.name}</TableTd>
|
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Text fz={"md"} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
<Box w={180}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1}>{item.name}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Box w={250}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
||||||
|
</Box>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Button onClick={() => router.push(`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${item.id}`)}>
|
<Button onClick={() => router.push(`/admin/keamanan/keamanan-lingkungan-pecalang-patwal/${item.id}`)}>
|
||||||
@@ -81,6 +89,14 @@ function ListKeamananLingkungan({ search }: { search: string }) {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my={"md"}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@@ -21,7 +21,7 @@ function PolsekTerdekat() {
|
|||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
<ListPolsekTerdekat search={search}/>
|
<ListPolsekTerdekat search={search} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -30,20 +30,21 @@ function ListPolsekTerdekat({ search }: { search: string }) {
|
|||||||
const polsekState = useProxy(polsekTerdekat)
|
const polsekState = useProxy(polsekTerdekat)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = polsekState.findMany;
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
polsekState.findMany.load()
|
load(page, 10, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
|
|
||||||
const filteredData = (polsekState.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.nama.toLowerCase().includes(keyword) ||
|
|
||||||
item.jarakKeDesa.toLowerCase().includes(keyword) ||
|
|
||||||
item.alamat.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!polsekState.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -64,24 +65,44 @@ function ListPolsekTerdekat({ search }: { search: string }) {
|
|||||||
<TableTh>Jarak Polsek</TableTh>
|
<TableTh>Jarak Polsek</TableTh>
|
||||||
<TableTh>Alamat</TableTh>
|
<TableTh>Alamat</TableTh>
|
||||||
<TableTh>Detail</TableTh>
|
<TableTh>Detail</TableTh>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
</TableThead>
|
</TableThead>
|
||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>{item.nama}</TableTd>
|
<TableTd>
|
||||||
<TableTd>{item.jarakKeDesa}</TableTd>
|
<Box w={180}>
|
||||||
<TableTd>{item.alamat}</TableTd>
|
<Text fz='md' truncate={"end"} lineClamp={1}>{item.nama}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Box w={180}>
|
||||||
|
<Text fz='md' truncate={"end"} lineClamp={1}>{item.jarakKeDesa}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Box w={250}>
|
||||||
|
<Text fz='md' truncate={"end"} lineClamp={1}>{item.alamat}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Button onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${item.id}`)}>
|
<Button onClick={() => router.push(`/admin/keamanan/polsek-terdekat/${item.id}`)}>
|
||||||
<IconDeviceImac size={20} />
|
<IconDeviceImac size={20} />
|
||||||
</Button>
|
</Button>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
</TableTr>
|
</TableTr>
|
||||||
))}
|
))}
|
||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||||
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
|
||||||
import HeaderSearch from '../../_com/header';
|
import HeaderSearch from '../../_com/header';
|
||||||
import JudulList from '../../_com/judulList';
|
import JudulList from '../../_com/judulList';
|
||||||
@@ -30,19 +30,21 @@ function ListTipsKeamanan({ search }: { search: string }) {
|
|||||||
const stateKeamanan = useProxy(tipsKeamananState)
|
const stateKeamanan = useProxy(tipsKeamananState)
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = stateKeamanan.findMany
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
stateKeamanan.findMany.load()
|
load(page, 10, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
|
|
||||||
const filteredData = (stateKeamanan.findMany.data || []).filter(item => {
|
const filteredData = data || []
|
||||||
const keyword = search.toLowerCase();
|
|
||||||
return (
|
|
||||||
item.judul.toLowerCase().includes(keyword) ||
|
|
||||||
item.deskripsi.toLowerCase().includes(keyword)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!stateKeamanan.findMany.data) {
|
if (loading || !data) {
|
||||||
return (
|
return (
|
||||||
<Stack py={10}>
|
<Stack py={10}>
|
||||||
<Skeleton h={500} />
|
<Skeleton h={500} />
|
||||||
@@ -67,9 +69,15 @@ function ListTipsKeamanan({ search }: { search: string }) {
|
|||||||
<TableTbody>
|
<TableTbody>
|
||||||
{filteredData.map((item) => (
|
{filteredData.map((item) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd>{item.judul}</TableTd>
|
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Text fz={"xs"} dangerouslySetInnerHTML={{__html: item.deskripsi}} />
|
<Box w={150}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1}>{item.judul}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Box w={250}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1} dangerouslySetInnerHTML={{__html: item.deskripsi}} />
|
||||||
|
</Box>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<Button onClick={() => router.push(`/admin/keamanan/tips-keamanan/${item.id}`)}>
|
<Button onClick={() => router.push(`/admin/keamanan/tips-keamanan/${item.id}`)}>
|
||||||
@@ -81,6 +89,14 @@ function ListTipsKeamanan({ search }: { search: string }) {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,8 +106,16 @@ function ListDaftarInformasi({ search }: { search: string }) {
|
|||||||
{filteredData.map((item, index) => (
|
{filteredData.map((item, index) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd style={{ textAlign: 'center' }}>{index + 1}</TableTd>
|
<TableTd style={{ textAlign: 'center' }}>{index + 1}</TableTd>
|
||||||
<TableTd style={{ wordWrap: 'break-word' }}>{item.jenisInformasi}</TableTd>
|
<TableTd style={{ wordWrap: 'break-word' }}>
|
||||||
<TableTd style={{ wordWrap: 'break-word' }} dangerouslySetInnerHTML={{ __html: item.deskripsi }}></TableTd>
|
<Box w={200}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1}>{item.jenisInformasi}</Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd style={{ wordWrap: 'break-word' }}>
|
||||||
|
<Box w={200}>
|
||||||
|
<Text fz={"md"} truncate={"end"} lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }}></Text>
|
||||||
|
</Box>
|
||||||
|
</TableTd>
|
||||||
<TableTd style={{ textAlign: 'center' }}>
|
<TableTd style={{ textAlign: 'center' }}>
|
||||||
<Button bg={"green"} onClick={() => router.push(`/admin/ppid/daftar-informasi-publik-desa-darmasaba/${item.id}`)}>
|
<Button bg={"green"} onClick={() => router.push(`/admin/ppid/daftar-informasi-publik-desa-darmasaba/${item.id}`)}>
|
||||||
<IconDeviceImacCog size={25} />
|
<IconDeviceImacCog size={25} />
|
||||||
|
|||||||
@@ -41,15 +41,11 @@ function EditResponden() {
|
|||||||
try {
|
try {
|
||||||
const data = await state.update.load(id);
|
const data = await state.update.load(id);
|
||||||
if (data) {
|
if (data) {
|
||||||
const formattedDate = data.tanggal && !isNaN(new Date(data.tanggal).getTime())
|
|
||||||
? new Date(data.tanggal).toISOString().split('T')[0]
|
|
||||||
: '';
|
|
||||||
// ⬇️ FIX PENTING: tambahkan ini
|
|
||||||
state.update.id = id;
|
state.update.id = id;
|
||||||
|
|
||||||
state.update.form = {
|
state.update.form = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
tanggal: formattedDate,
|
tanggal: data.tanggal,
|
||||||
jenisKelaminId: data.jenisKelaminId,
|
jenisKelaminId: data.jenisKelaminId,
|
||||||
ratingId: data.ratingId,
|
ratingId: data.ratingId,
|
||||||
kelompokUmurId: data.kelompokUmurId,
|
kelompokUmurId: data.kelompokUmurId,
|
||||||
@@ -76,6 +72,7 @@ function EditResponden() {
|
|||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
state.update.id = id;
|
state.update.id = id;
|
||||||
|
state.update.form = { ...formData }; // <-- sinkronisasi manual
|
||||||
await state.update.submit();
|
await state.update.submit();
|
||||||
router.push('/admin/ppid/ikm-desa-darmasaba/responden')
|
router.push('/admin/ppid/ikm-desa-darmasaba/responden')
|
||||||
}
|
}
|
||||||
@@ -103,12 +100,15 @@ function EditResponden() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
label="Tanggal"
|
||||||
type="date"
|
type="date"
|
||||||
value={formData.tanggal}
|
placeholder='Pilih tanggal'
|
||||||
|
value={formData.tanggal ? new Date(formData.tanggal).toISOString().split('T')[0] : ''}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
const selectedDate = e.currentTarget.value;
|
||||||
setFormData({
|
setFormData({
|
||||||
...formData,
|
...formData,
|
||||||
tanggal: e.currentTarget.value, // ✅ sudah format YYYY-MM-DD
|
tanggal: selectedDate,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,21 +1,55 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function lowonganKerjaFindMany() {
|
async function lowonganKerjaFindMany(context: Context) {
|
||||||
try {
|
// Ambil parameter dari query
|
||||||
const data = await prisma.lowonganPekerjaan.findMany({
|
const page = Number(context.query.page) || 1;
|
||||||
where: { isActive: true },
|
const limit = Number(context.query.limit) || 10;
|
||||||
});
|
const search = (context.query.search as string) || '';
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
return {
|
// Buat where clause
|
||||||
success: true,
|
const where: any = { isActive: true };
|
||||||
message: "Success fetch lowongan kerja",
|
|
||||||
data,
|
// Tambahkan pencarian (jika ada)
|
||||||
};
|
if (search) {
|
||||||
} catch (e) {
|
where.OR = [
|
||||||
console.error("Find many error:", e);
|
{ posisi: { contains: search, mode: 'insensitive' } },
|
||||||
return {
|
{ namaPerusahaan: { contains: search, mode: 'insensitive' } },
|
||||||
success: false,
|
{ lokasi: { contains: search, mode: 'insensitive' } },
|
||||||
message: "Failed fetch lowongan kerja",
|
];
|
||||||
};
|
}
|
||||||
}
|
|
||||||
}
|
try {
|
||||||
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.lowonganPekerjaan.findMany({
|
||||||
|
where,
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.lowonganPekerjaan.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil lowongan kerja dengan pagination",
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data lowongan kerja",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default lowonganKerjaFindMany;
|
||||||
@@ -1,26 +1,84 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function pasarDesaFindMany() {
|
async function pasarDesaFindMany(context: Context) {
|
||||||
const data = await prisma.pasarDesa.findMany({
|
// Ambil parameter dari query
|
||||||
where: {
|
const page = Number(context.query.page) || 1;
|
||||||
isActive: true, // Opsional filter
|
const limit = Number(context.query.limit) || 10;
|
||||||
},
|
const search = (context.query.search as string) || '';
|
||||||
orderBy: {
|
const categoryId = context.query.categoryId as string | undefined;
|
||||||
createdAt: "desc",
|
const skip = (page - 1) * limit;
|
||||||
},
|
|
||||||
include: {
|
// Buat where clause
|
||||||
image: true,
|
const where: any = { isActive: true };
|
||||||
KategoriToPasar: {
|
|
||||||
|
// Tambahkan filter kategori (jika ada)
|
||||||
|
if (categoryId) {
|
||||||
|
where.KategoriToPasar = {
|
||||||
|
some: {
|
||||||
|
kategoriId: categoryId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan pencarian (jika ada)
|
||||||
|
if (search) {
|
||||||
|
where.AND = where.AND || [];
|
||||||
|
where.AND.push({
|
||||||
|
OR: [
|
||||||
|
{ nama: { contains: search, mode: 'insensitive' } },
|
||||||
|
{ alamatUsaha: { contains: search, mode: 'insensitive' } },
|
||||||
|
{
|
||||||
|
KategoriToPasar: {
|
||||||
|
some: {
|
||||||
|
kategori: {
|
||||||
|
nama: { contains: search, mode: 'insensitive' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.pasarDesa.findMany({
|
||||||
|
where,
|
||||||
include: {
|
include: {
|
||||||
kategori: true,
|
image: true,
|
||||||
|
KategoriToPasar: {
|
||||||
|
include: {
|
||||||
|
kategori: true
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
skip,
|
||||||
},
|
take: limit,
|
||||||
});
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.pasarDesa.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil mengambil semua data pasar desa",
|
message: "Berhasil ambil pasar desa dengan pagination",
|
||||||
data,
|
data,
|
||||||
};
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data pasar desa",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default pasarDesaFindMany;
|
||||||
@@ -1,15 +1,60 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function kategoriProdukFindMany() {
|
async function kategoriProdukFindMany(context: Context) {
|
||||||
const data = await prisma.kategoriProduk.findMany();
|
// Ambil parameter dari query
|
||||||
return {
|
const page = Number(context.query.page) || 1;
|
||||||
success: true,
|
const limit = Number(context.query.limit) || 10;
|
||||||
data: data.map((item: any) => {
|
const search2 = (context.query.search as string) || '';
|
||||||
return {
|
const skip = (page - 1) * limit;
|
||||||
id: item.id,
|
|
||||||
nama: item.nama,
|
// Buat where clause
|
||||||
}
|
const where: any = { isActive: true };
|
||||||
}),
|
|
||||||
|
// Tambahkan pencarian (jika ada)
|
||||||
|
if (search2) {
|
||||||
|
where.OR = [
|
||||||
|
{ nama: { contains: search2, mode: 'insensitive' } },
|
||||||
|
{KategoriToPasar : {
|
||||||
|
some: {
|
||||||
|
kategori: {
|
||||||
|
nama: { contains: search2, mode: 'insensitive' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.kategoriProduk.findMany({
|
||||||
|
where,
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.kategoriProduk.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil kategori produk dengan pagination",
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
};
|
};
|
||||||
}
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data kategori produk",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default kategoriProdukFindMany;
|
||||||
@@ -1,24 +1,57 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function keamananLingkunganFindMany() {
|
async function keamananLingkunganFindMany(context: Context) {
|
||||||
try {
|
// Ambil parameter dari query
|
||||||
const data = await prisma.keamananLingkungan.findMany({
|
const page = Number(context.query.page) || 1;
|
||||||
where: { isActive: true },
|
const limit = Number(context.query.limit) || 10;
|
||||||
include: {
|
const search = (context.query.search as string) || '';
|
||||||
image: true,
|
const skip = (page - 1) * limit;
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
// Buat where clause
|
||||||
success: true,
|
const where: any = { isActive: true };
|
||||||
message: "Success fetch keamanan lingkungan",
|
|
||||||
data,
|
// Tambahkan pencarian (jika ada)
|
||||||
};
|
if (search) {
|
||||||
} catch (e) {
|
where.OR = [
|
||||||
console.error("Find many error:", e);
|
{ name: { contains: search, mode: 'insensitive' } },
|
||||||
return {
|
{ deskripsi: { contains: search, mode: 'insensitive' } },
|
||||||
success: false,
|
];
|
||||||
message: "Failed fetch keamanan lingkungan",
|
}
|
||||||
};
|
|
||||||
}
|
try {
|
||||||
}
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.keamananLingkungan.findMany({
|
||||||
|
where,
|
||||||
|
include: {
|
||||||
|
image: true,
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.keamananLingkungan.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil keamanan lingkungan dengan pagination",
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data keamanan lingkungan",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default keamananLingkunganFindMany;
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// find-first.ts
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
async function polsekTerdekatFindFirst() {
|
||||||
|
const where: any = { isActive: true };
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.polsekTerdekat.findFirst({
|
||||||
|
where,
|
||||||
|
include: {
|
||||||
|
layananPolsek: true,
|
||||||
|
},
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil polsek terdekat terbaru",
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findFirst:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal ambil polsek terdekat terbaru",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default polsekTerdekatFindFirst;
|
||||||
@@ -1,24 +1,57 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function polsekTerdekatFindMany() {
|
async function polsekTerdekatFindMany(context: Context) {
|
||||||
try {
|
// Ambil parameter dari query
|
||||||
const data = await prisma.polsekTerdekat.findMany({
|
const page = Number(context.query.page) || 1;
|
||||||
where: { isActive: true },
|
const limit = Number(context.query.limit) || 10;
|
||||||
include: {
|
const search = (context.query.search as string) || '';
|
||||||
layananPolsek: true,
|
const skip = (page - 1) * limit;
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
// Buat where clause
|
||||||
success: true,
|
const where: any = { isActive: true };
|
||||||
message: "Success fetch polsek terdekat",
|
|
||||||
data,
|
// Tambahkan pencarian (jika ada)
|
||||||
};
|
if (search) {
|
||||||
} catch (e) {
|
where.OR = [
|
||||||
console.error("Find many error:", e);
|
{ nama: { contains: search, mode: 'insensitive' } },
|
||||||
return {
|
{ alamat: { contains: search, mode: 'insensitive' } },
|
||||||
success: false,
|
];
|
||||||
message: "Failed fetch polsek terdekat",
|
}
|
||||||
};
|
|
||||||
}
|
try {
|
||||||
}
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.polsekTerdekat.findMany({
|
||||||
|
where,
|
||||||
|
include: {
|
||||||
|
layananPolsek: true,
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.polsekTerdekat.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil polsek terdekat dengan pagination",
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data polsek terdekat",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default polsekTerdekatFindMany;
|
||||||
@@ -4,6 +4,7 @@ import polsekTerdekatDelete from "./del";
|
|||||||
import polsekTerdekatFindMany from "./findMany";
|
import polsekTerdekatFindMany from "./findMany";
|
||||||
import polsekTerdekatFindUnique from "./findUnique";
|
import polsekTerdekatFindUnique from "./findUnique";
|
||||||
import polsekTerdekatUpdate from "./updt";
|
import polsekTerdekatUpdate from "./updt";
|
||||||
|
import polsekTerdekatFindFirst from "./findFirst";
|
||||||
|
|
||||||
|
|
||||||
const PolsekTerdekat = new Elysia({ prefix: "/polsekterdekat", tags: ["Keamanan/Polsek Terdekat"] })
|
const PolsekTerdekat = new Elysia({ prefix: "/polsekterdekat", tags: ["Keamanan/Polsek Terdekat"] })
|
||||||
@@ -12,6 +13,7 @@ const PolsekTerdekat = new Elysia({ prefix: "/polsekterdekat", tags: ["Keamanan/
|
|||||||
const response = await polsekTerdekatFindUnique(new Request(context.request));
|
const response = await polsekTerdekatFindUnique(new Request(context.request));
|
||||||
return response;
|
return response;
|
||||||
})
|
})
|
||||||
|
.get("/find-first", polsekTerdekatFindFirst)
|
||||||
.post("/create", polsekTerdekatCreate, {
|
.post("/create", polsekTerdekatCreate, {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
nama: t.String(),
|
nama: t.String(),
|
||||||
|
|||||||
@@ -1,24 +1,57 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
export default async function menuTipsKeamananFindMany() {
|
async function tipsKeamananFindMany(context: Context) {
|
||||||
try {
|
// Ambil parameter dari query
|
||||||
const data = await prisma.menuTipsKeamanan.findMany({
|
const page = Number(context.query.page) || 1;
|
||||||
where: { isActive: true },
|
const limit = Number(context.query.limit) || 10;
|
||||||
include: {
|
const search = (context.query.search as string) || '';
|
||||||
image: true,
|
const skip = (page - 1) * limit;
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
// Buat where clause
|
||||||
success: true,
|
const where: any = { isActive: true };
|
||||||
message: "Success fetch menu tips keamanan",
|
|
||||||
data,
|
// Tambahkan pencarian (jika ada)
|
||||||
};
|
if (search) {
|
||||||
} catch (e) {
|
where.OR = [
|
||||||
console.error("Find many error:", e);
|
{ judul: { contains: search, mode: 'insensitive' } },
|
||||||
return {
|
{ deskripsi: { contains: search, mode: 'insensitive' } },
|
||||||
success: false,
|
];
|
||||||
message: "Failed fetch menu tips keamanan",
|
}
|
||||||
};
|
|
||||||
}
|
try {
|
||||||
}
|
// Ambil data dan total count secara paralel
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
prisma.menuTipsKeamanan.findMany({
|
||||||
|
where,
|
||||||
|
include: {
|
||||||
|
image: true,
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
}),
|
||||||
|
prisma.menuTipsKeamanan.count({ where }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil ambil menu tips keamanan dengan pagination",
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error di findMany paginated:", e);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengambil data tips keamanan",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default tipsKeamananFindMany;
|
||||||
@@ -15,16 +15,12 @@ export default async function respondenCreate(context: Context) {
|
|||||||
try {
|
try {
|
||||||
// Convert the date string to a Date object
|
// Convert the date string to a Date object
|
||||||
const tanggal = new Date(body.tanggal);
|
const tanggal = new Date(body.tanggal);
|
||||||
|
|
||||||
// Validate the date
|
|
||||||
if (isNaN(tanggal.getTime())) {
|
|
||||||
throw new Error('Tanggal tidak valid');
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await prisma.responden.create({
|
const result = await prisma.responden.create({
|
||||||
data: {
|
data: {
|
||||||
name: body.name,
|
name: body.name,
|
||||||
tanggal: tanggal, // Use the Date object
|
tanggal: tanggal.toISOString(), // Use the Date object
|
||||||
jenisKelaminId: body.jenisKelaminId,
|
jenisKelaminId: body.jenisKelaminId,
|
||||||
ratingId: body.ratingId,
|
ratingId: body.ratingId,
|
||||||
kelompokUmurId: body.kelompokUmurId,
|
kelompokUmurId: body.kelompokUmurId,
|
||||||
|
|||||||
@@ -2,35 +2,40 @@ import prisma from "@/lib/prisma";
|
|||||||
import { Context } from "elysia";
|
import { Context } from "elysia";
|
||||||
|
|
||||||
type FormUpdate = {
|
type FormUpdate = {
|
||||||
name: string;
|
name: string;
|
||||||
tanggal: string;
|
tanggal: string;
|
||||||
jenisKelaminId: string;
|
jenisKelaminId: string;
|
||||||
ratingId: string;
|
ratingId: string;
|
||||||
kelompokUmurId: string;
|
kelompokUmurId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default async function respondenUpdate(context: Context) {
|
export default async function respondenUpdate(context: Context) {
|
||||||
const body = (await context.body) as FormUpdate;
|
const body = (await context.body) as FormUpdate;
|
||||||
const id = context.params.id as string;
|
const id = context.params.id as string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await prisma.responden.update({
|
const result = await prisma.responden.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: {
|
data: {
|
||||||
name: body.name,
|
name: body.name,
|
||||||
tanggal: body.tanggal,
|
tanggal: new Date(body.tanggal).toISOString(),
|
||||||
jenisKelaminId: body.jenisKelaminId,
|
jenisKelaminId: body.jenisKelaminId,
|
||||||
ratingId: body.ratingId,
|
ratingId: body.ratingId,
|
||||||
kelompokUmurId: body.kelompokUmurId,
|
kelompokUmurId: body.kelompokUmurId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil mengupdate responden",
|
message: "Berhasil mengupdate responden",
|
||||||
data: result,
|
data: result,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating responden:", error);
|
console.error("Error updating responden:", error);
|
||||||
throw new Error("Gagal mengupdate responden: " + (error as Error).message);
|
// Instead of throwing an error, return a proper JSON response
|
||||||
}
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mengupdate responden: " + (error as Error).message,
|
||||||
|
data: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,54 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
// /api/berita/findManyPaginated.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { Context } from "elysia";
|
import { Context } from "elysia";
|
||||||
|
|
||||||
// Di findMany.ts
|
async function daftarInformasiPublikFindMany(context: Context) {
|
||||||
export default async function daftarInformasiPublikFindMany(context: Context) {
|
// Ambil parameter dari query
|
||||||
const page = Number(context.query.page) || 1;
|
const page = Number(context.query.page) || 1;
|
||||||
const limit = Number(context.query.limit) || 10;
|
const limit = Number(context.query.limit) || 10;
|
||||||
|
const search = (context.query.search as string) || '';
|
||||||
const skip = (page - 1) * limit;
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Buat where clause
|
||||||
|
const where: any = { isActive: true };
|
||||||
|
|
||||||
|
// Tambahkan pencarian (jika ada)
|
||||||
|
if (search) {
|
||||||
|
where.OR = [
|
||||||
|
{ jenisInformasi: { contains: search, mode: 'insensitive' } },
|
||||||
|
{ deskripsi: { contains: search, mode: 'insensitive' } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Ambil data dan total count secara paralel
|
||||||
const [data, total] = await Promise.all([
|
const [data, total] = await Promise.all([
|
||||||
prisma.daftarInformasiPublik.findMany({
|
prisma.daftarInformasiPublik.findMany({
|
||||||
where: { isActive: true },
|
where,
|
||||||
skip,
|
skip,
|
||||||
take: limit,
|
take: limit,
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
}),
|
}),
|
||||||
prisma.daftarInformasiPublik.count({
|
prisma.daftarInformasiPublik.count({ where }),
|
||||||
where: { isActive: true }
|
|
||||||
})
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const totalPages = Math.ceil(total / limit);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Success fetch daftar informasi publik with pagination",
|
message: "Berhasil ambil daftar informasi publik dengan pagination",
|
||||||
data,
|
data,
|
||||||
page,
|
page,
|
||||||
totalPages,
|
limit,
|
||||||
total,
|
total,
|
||||||
|
totalPages: Math.ceil(total / limit),
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Find many paginated error:", e);
|
console.error("Error di findMany paginated:", e);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "Failed fetch daftar informasi publik with pagination",
|
message: "Gagal mengambil data daftar informasi publik",
|
||||||
data: [],
|
|
||||||
page: 1,
|
|
||||||
totalPages: 1,
|
|
||||||
total: 0,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default daftarInformasiPublikFindMany;
|
||||||
@@ -1,64 +1,52 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
import lowonganKerjaState from '@/app/admin/(dashboard)/_state/ekonomi/lowongan-kerja';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Box, Text, TextInput, Group, SimpleGrid, Paper, Flex, Button } from '@mantine/core';
|
import { Box, Button, Center, Flex, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
import React from 'react';
|
import { useDebouncedValue } from '@mantine/hooks';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
|
||||||
import { IconBriefcase, IconClock, IconMapPin, IconSearch } from '@tabler/icons-react';
|
import { IconBriefcase, IconClock, IconMapPin, IconSearch } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
const data = [
|
const formatCurrency = (value: string | number) => {
|
||||||
{
|
// Convert to string if it's a number
|
||||||
id: 1,
|
const numStr = typeof value === 'number' ? value.toString() : value;
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
// Remove all non-digit characters
|
||||||
alamat: 'Desa Munggu , Badung',
|
const digitsOnly = numStr.replace(/\D/g, '');
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
// Format with thousand separators
|
||||||
|
const formatted = digitsOnly.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||||
|
|
||||||
|
return `Rp.${formatted}`;
|
||||||
|
};
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
|
||||||
alamat: 'Desa Munggu , Badung',
|
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
|
||||||
alamat: 'Desa Munggu , Badung',
|
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
|
||||||
alamat: 'Desa Munggu , Badung',
|
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
|
||||||
alamat: 'Desa Munggu , Badung',
|
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
kerja: 'Kasir',
|
|
||||||
tempat: 'Toko Sumber Rejeki',
|
|
||||||
alamat: 'Desa Munggu , Badung',
|
|
||||||
gaji: 'Rp. 2.500.000 / bulan'
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const state = useProxy(lowonganKerjaState)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const [search, setSearch] = useState('')
|
||||||
|
const [debouncedSearch] = useDebouncedValue(search, 500); // 500ms delay
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = state.findMany
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
load(page, 6, debouncedSearch)
|
||||||
|
}, [page, debouncedSearch, load])
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Stack py={10}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
@@ -74,6 +62,8 @@ function Page() {
|
|||||||
w={{ base: 500, md: 700 }}
|
w={{ base: 500, md: 700 }}
|
||||||
placeholder='Cari Pekerjaan'
|
placeholder='Cari Pekerjaan'
|
||||||
leftSection={<IconSearch size={20} />}
|
leftSection={<IconSearch size={20} />}
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -93,15 +83,15 @@ function Page() {
|
|||||||
<Flex gap={'xl'} align={'center'}>
|
<Flex gap={'xl'} align={'center'}>
|
||||||
<IconBriefcase color={colors['blue-button']} size={50} />
|
<IconBriefcase color={colors['blue-button']} size={50} />
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={'bold'} fz={'h4'} c={colors['blue-button']}>{v.kerja}</Text>
|
<Text fw={'bold'} fz={'h4'} c={colors['blue-button']}>{v.posisi}</Text>
|
||||||
<Text fz={'h4'}>{v.tempat}</Text>
|
<Text fz={'h4'}>{v.namaPerusahaan}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Flex gap={'xl'} align={'center'}>
|
<Flex gap={'xl'} align={'center'}>
|
||||||
<IconMapPin color={colors['blue-button']} size={50} />
|
<IconMapPin color={colors['blue-button']} size={50} />
|
||||||
<Text fz={'h4'}>{v.alamat}</Text>
|
<Text fz={'h4'}>{v.lokasi}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
@@ -109,7 +99,7 @@ function Page() {
|
|||||||
<IconClock color={colors['blue-button']} size={50} />
|
<IconClock color={colors['blue-button']} size={50} />
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={'bold'} fz={'h4'} c={colors['blue-button']}>Full Time</Text>
|
<Text fw={'bold'} fz={'h4'} c={colors['blue-button']}>Full Time</Text>
|
||||||
<Text fz={'h4'}>{v.gaji}</Text>
|
<Text fz={'h4'}>{formatCurrency(v.gaji)}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -119,6 +109,14 @@ function Page() {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box >
|
</Box >
|
||||||
</Stack >
|
</Stack >
|
||||||
|
|||||||
@@ -1,90 +1,76 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
import pasarDesaState from '@/app/admin/(dashboard)/_state/ekonomi/pasar-desa/pasar-desa';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Combobox, Flex, Image, InputBase, InputPlaceholder, Paper, SimpleGrid, Stack, Text, TextInput, useCombobox } from '@mantine/core';
|
import { Box, Center, Flex, Grid, GridCol, Image, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconMapPinFilled, IconSearch, IconShoppingCartFilled, IconStarFilled } from '@tabler/icons-react';
|
import { IconMapPinFilled, IconSearch, IconShoppingCartFilled, IconStarFilled } from '@tabler/icons-react';
|
||||||
import { motion } from 'motion/react';
|
import { motion } from 'motion/react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
const groceries = [
|
|
||||||
'Makanan',
|
|
||||||
'Minuman',
|
|
||||||
'Pakaian',
|
|
||||||
'Alat Dapur',
|
|
||||||
'Alat Mandi',
|
|
||||||
'Furniture',
|
|
||||||
];
|
|
||||||
|
|
||||||
const dataBarang = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
image: '/api/img/semat.png',
|
|
||||||
judul: 'Semat Bambu / Semat Banten',
|
|
||||||
harga: 'Rp. 3000 / pcs',
|
|
||||||
bintang: '4.9',
|
|
||||||
alamat: 'Jl. Kecubung no.6'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
image: '/api/img/kerupuk.png',
|
|
||||||
judul: 'Kerupuk Babi',
|
|
||||||
harga: 'Rp. 12000 / pcs',
|
|
||||||
bintang: '4.9',
|
|
||||||
alamat: 'Jl. Kenari no.7'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
image: '/api/img/beras.png',
|
|
||||||
judul: 'beras Merah Organik',
|
|
||||||
harga: 'Rp. 40000 / 1 kg',
|
|
||||||
bintang: '4.9',
|
|
||||||
alamat: 'Jl. Mawar no.8'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
image: '/api/img/genteng.png',
|
|
||||||
judul: 'Genteng',
|
|
||||||
harga: 'Rp. 3600 / pcs',
|
|
||||||
bintang: '4.9',
|
|
||||||
alamat: 'Jl. Kecubung no.16'
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
|
||||||
function Page() {
|
function Page() {
|
||||||
const [search, setSearch] = useState('');
|
|
||||||
const combobox = useCombobox({
|
|
||||||
onDropdownClose: () => {
|
|
||||||
combobox.resetSelectedOption();
|
|
||||||
combobox.focusTarget();
|
|
||||||
setSearch('');
|
|
||||||
},
|
|
||||||
|
|
||||||
onDropdownOpen: () => {
|
|
||||||
combobox.focusSearchInput();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [value, setValue] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const options = groceries
|
|
||||||
.filter((item) => item.toLowerCase().includes(search.toLowerCase().trim()))
|
|
||||||
.map((item) => (
|
|
||||||
<Combobox.Option value={item} key={item}>
|
|
||||||
{item}
|
|
||||||
</Combobox.Option>
|
|
||||||
));
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const state = useProxy(pasarDesaState.pasarDesa)
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
loading,
|
||||||
|
totalPages,
|
||||||
|
load,
|
||||||
|
} = state.findMany
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
pasarDesaState.kategoriProduk.findMany.load()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Filter data based on selected category
|
||||||
|
const filteredData = selectedCategory
|
||||||
|
? data?.filter(item =>
|
||||||
|
item.KategoriToPasar?.some(kategori => kategori.kategoriId === selectedCategory)
|
||||||
|
)
|
||||||
|
: data;
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
load(page, 4, search, selectedCategory || undefined)
|
||||||
|
}, [page, search, selectedCategory])
|
||||||
|
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Stack py={10}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||||
Pasar Desa
|
<GridCol span={{ base: 12, md: 9 }}>
|
||||||
</Text>
|
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||||
<Text px={{ base: 20, md: 150 }} ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
Pasar Desa
|
||||||
|
</Text>
|
||||||
|
</GridCol>
|
||||||
|
<GridCol span={{ base: 12, md: 3 }}>
|
||||||
|
<TextInput
|
||||||
|
radius={"lg"}
|
||||||
|
placeholder='Cari Produk'
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w={{ base: "50%", md: "100%" }}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
|
<Text px={{ base: 'md', md: 100 }} ta={"justify"} fz={{ base: "h4", md: "h3" }} >
|
||||||
Pasar Desa Online merupakan Media Promosi yang bertujuan untuk membantu warga desa dalam memasarkan dan memperkenalkan produknya kepada masyarakat.
|
Pasar Desa Online merupakan Media Promosi yang bertujuan untuk membantu warga desa dalam memasarkan dan memperkenalkan produknya kepada masyarakat.
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -98,48 +84,23 @@ function Page() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box>
|
<Box>
|
||||||
<Combobox
|
<Select
|
||||||
store={combobox}
|
placeholder="Pilih Kategori"
|
||||||
withinPortal={false}
|
data={pasarDesaState.kategoriProduk.findMany.data?.map((v) => ({
|
||||||
onOptionSubmit={(val) => {
|
value: v.id,
|
||||||
setValue(val);
|
label: v.nama
|
||||||
combobox.closeDropdown();
|
})) || []}
|
||||||
}}
|
value={selectedCategory}
|
||||||
>
|
onChange={setSelectedCategory}
|
||||||
<Combobox.Target>
|
clearable
|
||||||
<InputBase
|
searchable
|
||||||
component="button"
|
nothingFoundMessage="Tidak ada kategori ditemukan"
|
||||||
type="button"
|
style={{ width: '100%' }}
|
||||||
pointer
|
|
||||||
rightSection={<Combobox.Chevron />}
|
|
||||||
onClick={() => combobox.toggleDropdown()}
|
|
||||||
rightSectionPointerEvents="none"
|
|
||||||
>
|
|
||||||
{value || <InputPlaceholder>Kategori</InputPlaceholder>}
|
|
||||||
</InputBase>
|
|
||||||
</Combobox.Target>
|
|
||||||
|
|
||||||
<Combobox.Dropdown>
|
|
||||||
<Combobox.Search
|
|
||||||
value={search}
|
|
||||||
onChange={(event) => setSearch(event.currentTarget.value)}
|
|
||||||
placeholder="Search groceries"
|
|
||||||
/>
|
|
||||||
<Combobox.Options>
|
|
||||||
{options.length > 0 ? options : <Combobox.Empty>Nothing found</Combobox.Empty>}
|
|
||||||
</Combobox.Options>
|
|
||||||
</Combobox.Dropdown>
|
|
||||||
</Combobox>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<TextInput
|
|
||||||
placeholder='Cari Produk'
|
|
||||||
leftSection={<IconSearch size={20} />}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
<SimpleGrid cols={{ base: 1, md: 4 }}>
|
<SimpleGrid cols={{ base: 1, md: 4 }}>
|
||||||
{dataBarang.map((v, k) => {
|
{filteredData?.map((v, k) => {
|
||||||
return (
|
return (
|
||||||
<Stack key={k}>
|
<Stack key={k}>
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -148,18 +109,25 @@ function Page() {
|
|||||||
whileTap={{ scale: 0.8 }}
|
whileTap={{ scale: 0.8 }}
|
||||||
>
|
>
|
||||||
<Paper p={'lg'}>
|
<Paper p={'lg'}>
|
||||||
<Image radius={'lg'} src={v.image} alt='' />
|
<Image
|
||||||
<Text py={10} fw={'bold'} fz={'lg'}>{v.judul}</Text>
|
radius={'lg'}
|
||||||
<Text fz={'md'}>{v.harga}</Text>
|
src={v.image?.link || '/placeholder-product.jpg'}
|
||||||
|
alt={v.nama}
|
||||||
|
h={200}
|
||||||
|
w='100%'
|
||||||
|
style={{ objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
<Text py={10} fw={'bold'} fz={'lg'}>{v.nama}</Text>
|
||||||
|
<Text fz={'md'}>Rp {v.harga.toLocaleString('id-ID')}</Text>
|
||||||
<Flex py={10} gap={'md'}>
|
<Flex py={10} gap={'md'}>
|
||||||
<IconStarFilled size={20} color='#EBCB09' />
|
<IconStarFilled size={20} color='#EBCB09' />
|
||||||
<Text fz={'sm'} ml={2}>{v.bintang}</Text>
|
<Text fz={'sm'} ml={2}>{v.rating}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex justify={'space-between'} align={'center'}>
|
<Flex justify={'space-between'} align={'center'}>
|
||||||
<Box>
|
<Box>
|
||||||
<Flex gap={'md'} align={'center'}>
|
<Flex gap={'md'} align={'center'}>
|
||||||
<IconMapPinFilled size={20} color='red' />
|
<IconMapPinFilled size={20} color='red' />
|
||||||
<Text fz={'sm'} ml={2}>{v.alamat}</Text>
|
<Text fz={'sm'} ml={2}>{v.alamatUsaha}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
<IconShoppingCartFilled size={20} color={colors['blue-button']} />
|
<IconShoppingCartFilled size={20} color={colors['blue-button']} />
|
||||||
@@ -170,6 +138,14 @@ function Page() {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)} // ini penting!
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,67 +1,61 @@
|
|||||||
|
'use client'
|
||||||
|
import keamananLingkunganState from '@/app/admin/(dashboard)/_state/keamanan/keamanan-lingkungan';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Center, Image, List, ListItem, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
|
import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { IconSearch } from '@tabler/icons-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
const data1 = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
judul: 'Peran Pecalang dalam Keamanan Desa',
|
|
||||||
image: '/api/img/pecalang.png',
|
|
||||||
pengertian: 'Pecalang adalah petugas keamanan adat di Bali yang memiliki peran penting dalam menjaga ketertiban dan budaya lokal. Tugas mereka meliputi:',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Mengamankan upacara adat dan kegiatan keagamaan.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Mengatur lalu lintas saat ada perayaan atau kegiatan besar.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Berpatroli untuk mencegah gangguan keamanan di lingkungan desa.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Berkoordinasi dengan aparat desa dan kepolisian dalam penanganan situasi darurat.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
judul: 'Patwal (Patroli Pengawal) Desa',
|
|
||||||
image: '/api/img/patwal-1.png',
|
|
||||||
pengertian: 'Selain Pecalang, Desa Darmasaba juga memiliki Patwal yang bertugas menjaga keamanan sehari-hari. Peran mereka antara lain:',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Berpatroli secara rutin untuk memastikan lingkungan tetap aman.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Menjaga ketertiban lalu lintas di area desa.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Melakukan tindakan preventif terhadap potensi gangguan keamanan.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Siap siaga dalam keadaan darurat untuk membantu warga.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
judul: 'Layanan Keamanan yang Tersedia',
|
|
||||||
image: '/api/img/pospecalang.png',
|
|
||||||
pengertian: 'Jika terjadi keadaan darurat atau membutuhkan bantuan keamanan, warga dapat menghubungi:',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Pos Pecalang Desa: [Masukkan Nomor Kontak].</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Patwal Desa Darmasaba: [Masukkan Nomor Kontak].</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Polsek Terdekat: 110 (Layanan Kepolisian).</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
judul: 'Program Keamanan Desa',
|
|
||||||
image: '/api/img/rond.png',
|
|
||||||
pengertian: 'Untuk meningkatkan keamanan, Desa Darmasaba menjalankan berbagai program, seperti:',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Ronda Malam Warga: Kegiatan jaga malam secara bergilir oleh warga bersama Pecalang dan Patwal.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}>Sosialisasi Keamanan: Edukasi bagi warga tentang cara menjaga keamanan lingkungan.</ListItem>
|
|
||||||
<ListItem fz={{ base: 'h4', md: 'lg' }}> Pengawasan Kamera CCTV: Memantau titik- titik strategis untuk mencegah tindak kejahatan.</ListItem>
|
|
||||||
</List>
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const state = useProxy(keamananLingkunganState)
|
||||||
|
const [search, setSearch] = useState('')
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = state.findMany;
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
load(page, 3, search)
|
||||||
|
}, [page, search])
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Box py={10}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||||
Keamanan Lingkungan (Pecalang / Patwal)
|
<GridCol span={{ base: 12, md: 9 }}>
|
||||||
</Text>
|
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||||
<Text px={{ base: 20, md: 150 }} ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
Keamanan Lingkungan (Pecalang / Patwal)
|
||||||
|
</Text>
|
||||||
|
</GridCol>
|
||||||
|
<GridCol span={{ base: 12, md: 3 }}>
|
||||||
|
<TextInput
|
||||||
|
radius={"lg"}
|
||||||
|
placeholder='Cari Puskesmas'
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w={{ base: "50%", md: "100%" }}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
|
<Text px={{ base: 'md', md: 100 }} ta={"justify"} fz={{ base: "h4", md: "h3" }} >
|
||||||
Keamanan dan ketertiban lingkungan di Desa Darmasaba dijaga melalui peran aktif Pecalang dan Patwal (Patroli Pengawal). Mereka bertugas memastikan desa tetap aman, tertib, dan kondusif bagi seluruh warga.
|
Keamanan dan ketertiban lingkungan di Desa Darmasaba dijaga melalui peran aktif Pecalang dan Patwal (Patroli Pengawal). Mereka bertugas memastikan desa tetap aman, tertib, dan kondusif bagi seluruh warga.
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -73,24 +67,19 @@ function Page() {
|
|||||||
base: 1,
|
base: 1,
|
||||||
md: 3,
|
md: 3,
|
||||||
}}>
|
}}>
|
||||||
{data1.map((v, k) => {
|
{data.map((v, k) => {
|
||||||
return (
|
return (
|
||||||
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
||||||
<Stack gap={'xs'}>
|
<Stack gap={'xs'}>
|
||||||
<Center px={10} py={20}>
|
<Center px={10} py={20}>
|
||||||
<Image src={v.image} alt='' />
|
<Image src={v.image?.link} alt='' />
|
||||||
</Center>
|
</Center>
|
||||||
<Box px={'lg'}>
|
<Box px={'lg'}>
|
||||||
<Box pb={20}>
|
<Box pb={20}>
|
||||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||||
{v.judul}
|
{v.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Text pb={10} fz={"h4"} ta={'justify'}>
|
<Text pb={10} fz={"h4"} ta={'justify'} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||||
{v.pengertian}
|
|
||||||
</Text>
|
|
||||||
<Box px={10}>
|
|
||||||
{v.deskripsi}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -99,7 +88,15 @@ function Page() {
|
|||||||
})}
|
})}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)} // ini penting!
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
|
'use client'
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import polsekTerdekatState from '@/app/admin/(dashboard)/_state/keamanan/polsek-terdekat';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Badge, Box, Button, Flex, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
|
import { Badge, Box, Button, Center, Flex, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
import { IconArrowDown, IconClock, IconNavigation, IconPhone, IconPin, IconSearch } from '@tabler/icons-react';
|
import { IconArrowDown, IconClock, IconNavigation, IconPhone, IconPin } from '@tabler/icons-react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const state = useProxy(polsekTerdekatState.findFirst);
|
||||||
|
const router = useRouter()
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!data && !loading) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
}, [data, loading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
@@ -17,7 +37,6 @@ function Page() {
|
|||||||
<Text pb={15} fz={'h4'} >
|
<Text pb={15} fz={'h4'} >
|
||||||
Desa Darmasaba, Kecamatan Abiansemal, Kabupaten Badung
|
Desa Darmasaba, Kecamatan Abiansemal, Kabupaten Badung
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput radius={10} leftSection={<IconSearch size={20} />} placeholder='Cari Kantor Polisi' />
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
<Stack gap={'lg'}>
|
<Stack gap={'lg'}>
|
||||||
@@ -30,59 +49,56 @@ function Page() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Content Sebelah Kiri */}
|
{/* Content Sebelah Kiri */}
|
||||||
<Box>
|
{loading ? (
|
||||||
<Text c={colors["blue-button"]} fw={'bold'} fz={'h2'}>Polsek Abiansemal</Text>
|
<Center><Skeleton h={400} /></Center>
|
||||||
<Text c={colors["blue-button"]} fz={'sm'}>2,5 Km dari Desa Darmasaba</Text>
|
) : data ? (
|
||||||
<Flex py={10} gap={9} align={'center'}>
|
<>
|
||||||
<IconPin size={25} color={colors["blue-button"]} />
|
<Box>
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>Jl. Gandamayu 1 Blahkiuh</Text>
|
<Text c={colors["blue-button"]} fw={'bold'} fz={'h2'}>{data.nama}</Text>
|
||||||
</Flex>
|
<Text c={colors["blue-button"]} fz={'sm'}>{data.jarakKeDesa}</Text>
|
||||||
<Flex gap={9} align={'center'}>
|
<Flex py={10} gap={9} align={'center'}>
|
||||||
<IconPhone size={25} color={colors["blue-button"]} />
|
<IconPin size={25} color={colors["blue-button"]} />
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>08xxxxxxxx</Text>
|
<Text c={colors["blue-button"]} fz={'lg'}>{data.alamat}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex py={10} gap={9} align={'center'}>
|
<Flex gap={9} align={'center'}>
|
||||||
<IconClock size={25} color={colors["blue-button"]} />
|
<IconPhone size={25} color={colors["blue-button"]} />
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>24 Jam</Text>
|
<Text c={colors["blue-button"]} fz={'lg'}>{data.nomorTelepon}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box>
|
<Flex py={10} gap={9} align={'center'}>
|
||||||
<Text c={colors["blue-button"]} fw={'bold'} fz={'h2'}>Layanan Yang Tersedia :</Text>
|
<IconClock size={25} color={colors["blue-button"]} />
|
||||||
<SimpleGrid
|
<Text c={colors["blue-button"]} fz={'lg'}>{data.jamOperasional}</Text>
|
||||||
py={10}
|
</Flex>
|
||||||
cols={{
|
|
||||||
base: 1,
|
|
||||||
md: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>Laporan Kehilangan</Text>
|
<Text c={colors["blue-button"]} fw={'bold'} fz={'h2'}>Layanan Yang Tersedia :</Text>
|
||||||
|
<SimpleGrid
|
||||||
|
py={10}
|
||||||
|
cols={{
|
||||||
|
base: 1,
|
||||||
|
md: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
<Text c={colors["blue-button"]} fz={'lg'}>{data.layananPolsek.nama}</Text>
|
||||||
|
</Box>
|
||||||
|
</SimpleGrid>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>Laporan Kriminal</Text>
|
<Button bg={colors["blue-button"]} onClick={() => router.push(`/darmasaba/keamanan/polsek-terdekat/semua-polsek`)} rightSection={<IconArrowDown size={20} />}>Lihat Kantor Polisi Lainnya</Button>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
</Box>
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>Pelayanan SKCK</Text>
|
<Box pos={'relative'}>
|
||||||
|
<Box style={{ position: 'absolute', top: 0, right: 0 }}>
|
||||||
|
<Badge size='lg' c={'#287407'} bg={'#A8EDC4'}>Buka</Badge>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box pt={40}>
|
||||||
<Text c={colors["blue-button"]} fz={'lg'}>Pengaduan Masyarakat</Text>
|
<iframe style={{ border: 2, width: "100%" }} src={data.embedMapUrl} width="550" height="300" ></iframe>
|
||||||
</Box>
|
</Box>
|
||||||
</SimpleGrid>
|
<Box pt={20}>
|
||||||
</Box>
|
<Button onClick={() => router.push(data.linkPetunjukArah)} fullWidth bg={colors["blue-button"]} radius={10} leftSection={<IconNavigation size={20} />}>Petunjuk Arah</Button>
|
||||||
<Box>
|
</Box>
|
||||||
<Button bg={colors["blue-button"]} rightSection={<IconArrowDown size={20}/>}>Lihat Kantor Polisi Lainnya</Button>
|
</Box>
|
||||||
</Box>
|
</>
|
||||||
</Box>
|
) : null}
|
||||||
<Box pos={'relative'}>
|
|
||||||
<Box style={{ position: 'absolute', top: 0, right: 0 }}>
|
|
||||||
<Badge size='lg' c={'#287407'} bg={'#A8EDC4'}>Buka</Badge>
|
|
||||||
</Box>
|
|
||||||
<Box pt={40}>
|
|
||||||
<iframe style={{ border: 2, width: "100%" }} src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3945.7949871034166!2d115.20778387533218!3d-8.519275686287415!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x2dd23ceb4f6e5363%3A0xa353662f070f47d8!2sAbian%20Semal%20Police%20Station!5e0!3m2!1sid!2sid!4v1742789148825!5m2!1sid!2sid" width="550" height="300" ></iframe>
|
|
||||||
</Box>
|
|
||||||
<Box pt={20}>
|
|
||||||
<Button fullWidth bg={colors["blue-button"]} radius={10} leftSection={<IconNavigation size={20}/>}>Petunjuk Arah</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
'use client'
|
||||||
|
import polsekTerdekatState from '@/app/admin/(dashboard)/_state/keamanan/polsek-terdekat';
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
import { Box, Button, Center, Grid, GridCol, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { IconNavigation, IconSearch } from '@tabler/icons-react';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import BackButton from '../../../desa/layanan/_com/BackButto';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
function Page() {
|
||||||
|
const state = useProxy(polsekTerdekatState);
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = state.findMany;
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
load(page, 3, search)
|
||||||
|
}, [page, search])
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Box py={10}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
|
<BackButton />
|
||||||
|
</Box>
|
||||||
|
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||||
|
<GridCol span={{ base: 12, md: 9 }}>
|
||||||
|
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||||
|
Semua Polsek Terdekat
|
||||||
|
</Text>
|
||||||
|
</GridCol>
|
||||||
|
<GridCol span={{ base: 12, md: 3 }}>
|
||||||
|
<TextInput
|
||||||
|
radius={"lg"}
|
||||||
|
placeholder='Cari Polsek'
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w={{ base: "50%", md: "100%" }}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
|
<SimpleGrid
|
||||||
|
cols={{
|
||||||
|
base: 1,
|
||||||
|
md: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{data.map((v, k) => {
|
||||||
|
return (
|
||||||
|
<Paper p={"xl"} bg={colors['white-trans-1']} key={k}>
|
||||||
|
<Stack gap={"xs"}>
|
||||||
|
<Text fw={"bold"} fz={"h3"}>{v.nama}</Text>
|
||||||
|
<Text>Alamat: {v.alamat}</Text>
|
||||||
|
<Text>Jarak: {v.jarakKeDesa}</Text>
|
||||||
|
<Text>Telepon: {v.nomorTelepon}</Text>
|
||||||
|
<Text>Jam Operasional: {v.jamOperasional}</Text>
|
||||||
|
<Box pt={20}>
|
||||||
|
<iframe style={{ border: 2, width: "100%" }} src={v.embedMapUrl} width="550" height="300" ></iframe>
|
||||||
|
</Box>
|
||||||
|
<Box pt={20}>
|
||||||
|
<Button onClick={() => router.push(v.linkPetunjukArah)} fullWidth bg={colors["blue-button"]} radius={10} leftSection={<IconNavigation size={20} />}>Petunjuk Arah</Button>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</SimpleGrid>
|
||||||
|
</Box>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)} // ini penting!
|
||||||
|
total={totalPages}
|
||||||
|
mt="md"
|
||||||
|
mb="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Page;
|
||||||
@@ -1,83 +1,62 @@
|
|||||||
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Center, Image, List, ListItem, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
|
import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import tipsKeamananState from '@/app/admin/(dashboard)/_state/keamanan/tips-keamanan';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { IconSearch } from '@tabler/icons-react';
|
||||||
|
|
||||||
const data1 = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
judul: 'Keamanan Rumah',
|
|
||||||
image: '/api/img/kemanan.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Pastikan pintu dan jendela selalu terkunci saat meninggalkan rumah.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Pasang lampu penerangan di halaman dan area sekitar rumah untuk mencegah tindak kejahatan.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Jangan mudah memberikan akses masuk ke orang yang tidak dikenal.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
judul: 'Keamanan di Jalan',
|
|
||||||
image: '/api/img/keamananjalan.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Hindari berjalan sendirian di tempat sepi, terutama pada malam hari.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Simpan barang berharga di tempat yang aman saat bepergian.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Gunakan jalur yang ramai dan terang saat pulang malam.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
judul: 'Keamanan Kendaraan',
|
|
||||||
image: '/api/img/keamanankendaraan.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Gunakan kunci ganda saat memarkir kendaraan, terutama di tempat umum.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Parkir di tempat yang terang dan mudah diawasi.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Jangan meninggalkan barang berharga di dalam kendaraan.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
judul: 'Keamanan Sosial',
|
|
||||||
image: '/api/img/mencurigakan.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Laporkan kejadian mencurigakan kepada Pecalang atau perangkat desa.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Jangan mudah percaya terhadap informasi yang belum jelas sumbernya.</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Ikuti program sosialisasi keamanan yang diadakan oleh desa.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
judul: 'Sistem Laporan Kejadian',
|
|
||||||
image: '/api/img/securitydigital.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem>Jangan mudah membagikan informasi pribadi di media sosial.</ListItem>
|
|
||||||
<ListItem>Waspada terhadap penipuan online dan telepon yang mengatasnamakan instansi resmi.</ListItem>
|
|
||||||
<ListItem>Gunakan kata sandi yang kuat untuk akun digital dan ganti secara berkala.</ListItem>
|
|
||||||
</List>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
judul: 'Nomor Darurat yang Bisa Dihubungi',
|
|
||||||
image: '/api/img/kontakpecalang.png',
|
|
||||||
deskripsi: <List>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Pecalang: 08125651052</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Ambulans: 08125651052</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Pemadam Kebakaran: 113</ListItem>
|
|
||||||
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Polisi: 110</ListItem>
|
|
||||||
</List>
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const state = useProxy(tipsKeamananState)
|
||||||
|
const [search, setSearch] = useState('')
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = state.findMany;
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
load(page, 3, search)
|
||||||
|
}, [page, search])
|
||||||
|
|
||||||
|
if (loading || !data) {
|
||||||
|
return (
|
||||||
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
|
<Skeleton h={500} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||||
Tips Keamanan
|
<GridCol span={{ base: 12, md: 9 }}>
|
||||||
</Text>
|
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||||
<Text px={{ base: 20, md: 150 }} ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
Tips Keamanan
|
||||||
Desa Darmasaba berkomitmen untuk menjaga keamanan dan kenyamanan seluruh warganya. Berikut beberapa tips yang dapat membantu meningkatkan keamanan di lingkungan desa.
|
</Text>
|
||||||
|
</GridCol>
|
||||||
|
<GridCol span={{ base: 12, md: 3 }}>
|
||||||
|
<TextInput
|
||||||
|
radius={"lg"}
|
||||||
|
placeholder='Cari Tips'
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w={{ base: "50%", md: "100%" }}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
|
<Text px={{ base: 'md', md: 100 }} ta={"justify"} fz={{ base: "h4", md: "h3" }} >
|
||||||
|
Keamanan dan ketertiban lingkungan di Desa Darmasaba dijaga melalui peran aktif Pecalang dan Patwal (Patroli Pengawal). Mereka bertugas memastikan desa tetap aman, tertib, dan kondusif bagi seluruh warga.
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
@@ -88,21 +67,21 @@ function Page() {
|
|||||||
base: 1,
|
base: 1,
|
||||||
md: 3,
|
md: 3,
|
||||||
}}>
|
}}>
|
||||||
{data1.map((v, k) => {
|
{data.map((v, k) => {
|
||||||
return (
|
return (
|
||||||
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
||||||
<Stack gap={'xs'}>
|
<Stack gap={'xs'}>
|
||||||
<Center p={10}>
|
<Center p={10}>
|
||||||
<Image src={v.image} radius={10}
|
<Image src={v.image?.link} radius={10}
|
||||||
alt='' />
|
alt='' />
|
||||||
</Center>
|
</Center>
|
||||||
<Box px={'xl'}>
|
<Box px={'xl'}>
|
||||||
<Box pb={20}>
|
<Box pb={20}>
|
||||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||||
{v.judul}
|
{v.judul}
|
||||||
</Text>
|
</Text>
|
||||||
<Box pr={10}>
|
<Box>
|
||||||
{v.deskripsi}
|
<Text pb={10} fz={"md"} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -113,6 +92,14 @@ function Page() {
|
|||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)} // ini penting!
|
||||||
|
total={totalPages}
|
||||||
|
my="md"
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import daftarInformasiPublik from '@/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
|
import daftarInformasiPublik from '@/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Center, Image, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput } from '@mantine/core';
|
import { Box, Center, Image, Pagination, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput } from '@mantine/core';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
import { IconSearch } from '@tabler/icons-react';
|
import { IconSearch } from '@tabler/icons-react';
|
||||||
|
import { useState } from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
const listData = useProxy(daftarInformasiPublik)
|
const listData = useProxy(daftarInformasiPublik)
|
||||||
|
const [search, setSearch] = useState('')
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
page,
|
||||||
|
totalPages,
|
||||||
|
loading,
|
||||||
|
load,
|
||||||
|
} = listData.findMany
|
||||||
|
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
listData.findMany.load()
|
load(page, 5, search)
|
||||||
}, [])
|
}, [page, search])
|
||||||
if (!listData.findMany.data) return <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
|
||||||
|
if (loading || !data) return <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<Skeleton h={40} />
|
<Skeleton h={40} />
|
||||||
</Box>
|
</Box>
|
||||||
@@ -40,6 +54,9 @@ function Page() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder='Cari Informasi...'
|
placeholder='Cari Informasi...'
|
||||||
leftSection={<IconSearch size={20} />}
|
leftSection={<IconSearch size={20} />}
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
style={{ marginBottom: 16 }}
|
||||||
/>
|
/>
|
||||||
<Table withRowBorders withColumnBorders withTableBorder>
|
<Table withRowBorders withColumnBorders withTableBorder>
|
||||||
<TableThead bg={colors['blue-button']}>
|
<TableThead bg={colors['blue-button']}>
|
||||||
@@ -54,8 +71,17 @@ function Page() {
|
|||||||
{listData.findMany.data?.map((item, index) => (
|
{listData.findMany.data?.map((item, index) => (
|
||||||
<TableTr key={item.id}>
|
<TableTr key={item.id}>
|
||||||
<TableTd ta={'center'}>{index + 1}</TableTd>
|
<TableTd ta={'center'}>{index + 1}</TableTd>
|
||||||
<TableTd>{item.jenisInformasi}</TableTd>
|
<TableTd>
|
||||||
<TableTd dangerouslySetInnerHTML={{ __html: item.deskripsi }}></TableTd>
|
<Text fz={'md'}>
|
||||||
|
{item.jenisInformasi}
|
||||||
|
</Text>
|
||||||
|
</TableTd>
|
||||||
|
<TableTd>
|
||||||
|
<Text
|
||||||
|
fz={'md'}
|
||||||
|
dangerouslySetInnerHTML={{ __html: item.deskripsi }}
|
||||||
|
/>
|
||||||
|
</TableTd>
|
||||||
<TableTd style={{ width: '20%', textAlign: 'center' }}>{item.tanggal
|
<TableTd style={{ width: '20%', textAlign: 'center' }}>{item.tanggal
|
||||||
? new Date(item.tanggal).toLocaleDateString('id-ID')
|
? new Date(item.tanggal).toLocaleDateString('id-ID')
|
||||||
: '-'}</TableTd>
|
: '-'}</TableTd>
|
||||||
@@ -64,6 +90,14 @@ function Page() {
|
|||||||
</TableTbody>
|
</TableTbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<Center>
|
||||||
|
<Pagination
|
||||||
|
value={page}
|
||||||
|
onChange={(newPage) => load(newPage)}
|
||||||
|
total={totalPages}
|
||||||
|
my={"md"}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
<Text pt={20} fz={'h4'} fw={"bold"}>Kontak PPID</Text>
|
<Text pt={20} fz={'h4'} fw={"bold"}>Kontak PPID</Text>
|
||||||
<Text fz={'sm'}>Email: ppid@desadarmasaba.id | WhatsApp: 081-xxx-xxx-xxx</Text>
|
<Text fz={'sm'}>Email: ppid@desadarmasaba.id | WhatsApp: 081-xxx-xxx-xxx</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>HIPMI Feature Checklist</title>
|
<title>Desa Darmasaba Feature Checklist</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
@@ -267,284 +267,262 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Indeks Kepuasan Masayarakat (IKM) (Landing Page - PPID) -->
|
<!-- SubMenu Indeks Kepuasan Masayarakat (IKM) (Landing Page - PPID) -->
|
||||||
<h4>Indeks Kepuasan Masayarakat (IKM) (Landing Page - PPID)</h4>
|
<h4>Indeks Kepuasan Masayarakat (IKM) (Landing Page - PPID)</h4>
|
||||||
<!-- List Responden -->
|
<!-- List Responden -->
|
||||||
<h4>List Desa Anti Korupsi</h4>
|
<h4>List Responden</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="19" /> <label for="19">Search sudah berfungsi</label>
|
<input type="checkbox" id="33" />
|
||||||
</li>
|
<label for="33">Search sudah berfungsi</label>
|
||||||
<li>
|
</li>
|
||||||
<input type="checkbox" id="20" /> <label for="20">Data tampil di halaman list</label>
|
<li>
|
||||||
|
<input type="checkbox" id="34" />
|
||||||
|
<label for="34">Data tampil di halaman list</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="35" />
|
||||||
|
<label for="35">Create list responden</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="36" />
|
||||||
|
<label for="36">Detail mau tampil datanya</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="37" />
|
||||||
|
<label for="37">Hapus list responden bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="38" />
|
||||||
|
<label for="38">Edit / Update list responden bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="39" />
|
||||||
|
<label for="39">Pagination bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="21" />
|
<input type="checkbox" id="40" />
|
||||||
<label for="21">Create list desa anti korupsi</label>
|
<label for="40">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="22" />
|
|
||||||
<label for="22">Detail mau tampil datanya</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="23" />
|
|
||||||
<label for="23">Hapus list desa anti korupsi bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="24" />
|
|
||||||
<label for="24">Edit / Update list desa anti korupsi bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h4>List Responden</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="33" />
|
|
||||||
<label for="33">Search sudah berfungsi</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="34" />
|
|
||||||
<label for="34">Data tampil di halaman list</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="35" />
|
|
||||||
<label for="35">Create list responden</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="36" />
|
|
||||||
<label for="36">Detail mau tampil datanya</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="37" />
|
|
||||||
<label for="37">Hapus list responden bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="38" />
|
|
||||||
<label for="38">Edit / Update list responden bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="39" />
|
|
||||||
<label for="39">Pagination bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="40" />
|
|
||||||
<label for="40">Sinkronisasi ke UI</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- SubMenu SDGs Desa -->
|
</ul>
|
||||||
<h4>SDGs Desa</h4>
|
|
||||||
<!-- List SDGs Desa -->
|
<!-- SubMenu SDGs Desa -->
|
||||||
<h4>List SDGs Desa</h4>
|
<h4>SDGs Desa</h4>
|
||||||
|
<!-- List SDGs Desa -->
|
||||||
|
<h4>List SDGs Desa</h4>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="41" />
|
||||||
|
<label for="41">Search sudah berfungsi</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="42" />
|
||||||
|
<label for="42">Data tampil di halaman list</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="43" />
|
||||||
|
<label for="43">Create list SDGs Desa</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="44" />
|
||||||
|
<label for="44">Detail mau tampil datanya</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="45" />
|
||||||
|
<label for="45">Hapus list SDGs Desa bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="46" />
|
||||||
|
<label for="46">Edit / Update list SDGs Desa bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="47" />
|
||||||
|
<label for="47">Pagination bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="48" />
|
||||||
|
<label for="48">Sinkronisasi ke UI</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- SubMenu APBDes -->
|
||||||
|
<h4>APBDes</h4>
|
||||||
|
<!-- List APBDes -->
|
||||||
|
<h4>List APBDes</h4>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="49" />
|
||||||
|
<label for="49">Search sudah berfungsi</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="50" />
|
||||||
|
<label for="50">Data tampil di halaman list</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="51" />
|
||||||
|
<label for="51">Create list APBDes</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="52" />
|
||||||
|
<label for="52">Detail mau tampil datanya</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="53" />
|
||||||
|
<label for="53">Hapus list APBDes bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="54" />
|
||||||
|
<label for="54">Edit / Update list APBDes bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="55" />
|
||||||
|
<label for="55">Pagination bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="56" />
|
||||||
|
<label for="56">Sinkronisasi ke UI</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- SubMenu Prestasi Desa -->
|
||||||
|
<h4>Prestasi Desa</h4>
|
||||||
|
<!-- List Prestasi Desa -->
|
||||||
|
<h4>List Prestasi Desa</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="41" />
|
<input type="checkbox" id="57" />
|
||||||
<label for="41">Search sudah berfungsi</label>
|
<label for="57">Search sudah berfungsi</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="42" />
|
<input type="checkbox" id="58" />
|
||||||
<label for="42">Data tampil di halaman list</label>
|
<label for="58">Data tampil di halaman list</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="43" />
|
<input type="checkbox" id="59" />
|
||||||
<label for="43">Create list SDGs Desa</label>
|
<label for="59">Create list Prestasi Desa</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="44" />
|
<input type="checkbox" id="60" />
|
||||||
<label for="44">Detail mau tampil datanya</label>
|
<label for="60">Detail mau tampil datanya</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="45" />
|
<input type="checkbox" id="61" />
|
||||||
<label for="45">Hapus list SDGs Desa bekerja</label>
|
<label for="61">Hapus list Prestasi Desa bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="46" />
|
<input type="checkbox" id="62" />
|
||||||
<label for="46">Edit / Update list SDGs Desa bekerja</label>
|
<label for="62">Edit / Update list Prestasi Desa bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="47" />
|
<input type="checkbox" id="63" />
|
||||||
<label for="47">Pagination bekerja</label>
|
<label for="63">Pagination bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="48" />
|
<input type="checkbox" id="64" />
|
||||||
<label for="48">Sinkronisasi ke UI</label>
|
<label for="64">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu APBDes -->
|
<!-- Menu PPID -->
|
||||||
<h4>APBDes</h4>
|
<h3>Menu PPID</h3>
|
||||||
<!-- List APBDes -->
|
|
||||||
<h4>List APBDes</h4>
|
<!-- SubMenu Profile PPID -->
|
||||||
<ul>
|
<h4>Profile PPID</h4>
|
||||||
<li>
|
<ul>
|
||||||
<input type="checkbox" id="49" />
|
<li>
|
||||||
<label for="49">Search sudah berfungsi</label>
|
<input type="checkbox" id="65" />
|
||||||
</li>
|
<label for="65">Data tampil di halaman</label>
|
||||||
<li>
|
</li>
|
||||||
<input type="checkbox" id="50" />
|
<li>
|
||||||
<label for="50">Data tampil di halaman list</label>
|
<input type="checkbox" id="66" />
|
||||||
</li>
|
<label for="66">Edit / Update Profile PPID</label>
|
||||||
<li>
|
</li>
|
||||||
<input type="checkbox" id="51" />
|
<li>
|
||||||
<label for="51">Create list APBDes</label>
|
<input type="checkbox" id="67" />
|
||||||
</li>
|
<label for="67">Sinkronisasi ke UI</label>
|
||||||
<li>
|
</li>
|
||||||
<input type="checkbox" id="52" />
|
</ul>
|
||||||
<label for="52">Detail mau tampil datanya</label>
|
|
||||||
</li>
|
<!-- SubMenu Struktur PPID -->
|
||||||
<li>
|
<h4>Struktur PPID</h4>
|
||||||
<input type="checkbox" id="53" />
|
<h4>Pegawai</h4>
|
||||||
<label for="53">Hapus list APBDes bekerja</label>
|
<ul>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<input type="checkbox" id="68" />
|
||||||
<input type="checkbox" id="54" />
|
<label for="68">Search sudah berfungsi</label>
|
||||||
<label for="54">Edit / Update list APBDes bekerja</label>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<input type="checkbox" id="69" />
|
||||||
<input type="checkbox" id="55" />
|
<label for="69">Data tampil di halaman list</label>
|
||||||
<label for="55">Pagination bekerja</label>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<input type="checkbox" id="70" />
|
||||||
<input type="checkbox" id="56" />
|
<label for="70">Create list Pegawai</label>
|
||||||
<label for="56">Sinkronisasi ke UI</label>
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="71" />
|
||||||
|
<label for="71">Detail mau tampil datanya</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="72" />
|
||||||
|
<label for="72">Hapus list Pegawai bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="73" />
|
||||||
|
<label for="73">Edit / Update list Pegawai bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="74" />
|
||||||
|
<label for="74">Pagination bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="75" />
|
||||||
|
<label for="75">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Prestasi Desa -->
|
|
||||||
<h4>Prestasi Desa</h4>
|
|
||||||
<!-- List Prestasi Desa -->
|
|
||||||
<h4>List Prestasi Desa</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="57" />
|
|
||||||
<label for="57">Search sudah berfungsi</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="58" />
|
|
||||||
<label for="58">Data tampil di halaman list</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="59" />
|
|
||||||
<label for="59">Create list Prestasi Desa</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="60" />
|
|
||||||
<label for="60">Detail mau tampil datanya</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="61" />
|
|
||||||
<label for="61">Hapus list Prestasi Desa bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="62" />
|
|
||||||
<label for="62">Edit / Update list Prestasi Desa bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="63" />
|
|
||||||
<label for="63">Pagination bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="64" />
|
|
||||||
<label for="64">Sinkronisasi ke UI</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Menu PPID -->
|
|
||||||
<h3>Menu PPID</h3>
|
|
||||||
<!-- SubMenu Profile PPID -->
|
|
||||||
<h4>Profile PPID</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="65" />
|
|
||||||
<label for="65">Data tampil di halaman</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="66" />
|
|
||||||
<label for="66">Edit / Update Profile PPID</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="67" />
|
|
||||||
<label for="67">Sinkronisasi ke UI</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- SubMenu Struktur PPID -->
|
|
||||||
<h4>Struktur PPID</h4>
|
|
||||||
<h4>Pegawai</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="68" />
|
|
||||||
<label for="68">Search sudah berfungsi</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="69" />
|
|
||||||
<label for="69">Data tampil di halaman list</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="70" />
|
|
||||||
<label for="70">Create list Pegawai</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="71" />
|
|
||||||
<label for="71">Detail mau tampil datanya</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="72" />
|
|
||||||
<label for="72">Hapus list Pegawai bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="73" />
|
|
||||||
<label for="73">Edit / Update list Pegawai bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="74" />
|
|
||||||
<label for="74">Pagination bekerja</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="75" />
|
|
||||||
<label for="75">Sinkronisasi ke UI</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h4>Posisi Organisasi PPID</h4>
|
<h4>Posisi Organisasi PPID</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="76" />
|
<input type="checkbox" id="76" />
|
||||||
<label for="76">Search sudah berfungsi</label>
|
<label for="76">Search sudah berfungsi</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="77" />
|
<input type="checkbox" id="77" />
|
||||||
<label for="77">Data tampil di halaman list</label>
|
<label for="77">Data tampil di halaman list</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="78" />
|
<input type="checkbox" id="78" />
|
||||||
<label for="78">Create list Posisi Organisasi PPID</label>
|
<label for="78">Create list Posisi Organisasi PPID</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="79" />
|
<input type="checkbox" id="79" />
|
||||||
<label for="79">Detail mau tampil datanya</label>
|
<label for="79">Detail mau tampil datanya</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="80" />
|
<input type="checkbox" id="80" />
|
||||||
<label for="80">Hapus list Posisi Organisasi PPID bekerja</label>
|
<label for="80">Hapus list Posisi Organisasi PPID bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="81" />
|
<input type="checkbox" id="81" />
|
||||||
<label for="81">Edit / Update list Posisi Organisasi PPID bekerja</label>
|
<label for="81">Edit / Update list Posisi Organisasi PPID bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="82" />
|
<input type="checkbox" id="82" />
|
||||||
<label for="82">Pagination bekerja</label>
|
<label for="82">Pagination bekerja</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="83" />
|
<input type="checkbox" id="83" />
|
||||||
<label for="83">Sinkronisasi ke UI</label>
|
<label for="83">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Visi Misi PPID -->
|
<!-- SubMenu Visi Misi PPID -->
|
||||||
<h4>Visi Misi PPID</h4>
|
<h4>Visi Misi PPID</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="84" />
|
<input type="checkbox" id="84" />
|
||||||
<label for="84">Data tampil di halaman</label>
|
<label for="84">Data tampil di halaman</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -558,27 +536,27 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Dasar Hukum PPID -->
|
<!-- SubMenu Dasar Hukum PPID -->
|
||||||
<h4>Dasar Hukum PPID</h4>
|
<h4>Dasar Hukum PPID</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="87" />
|
<input type="checkbox" id="87" />
|
||||||
<label for="87">Data tampil di halaman</label>
|
<label for="87">Data tampil di halaman</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="88" />
|
<input type="checkbox" id="88" />
|
||||||
<label for="88">Edit / Update Dasar Hukum PPID</label>
|
<label for="88">Edit / Update Dasar Hukum PPID</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="89" />
|
<input type="checkbox" id="89" />
|
||||||
<label for="89">Sinkronisasi ke UI</label>
|
<label for="89">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Permohonan Informasi Publik -->
|
<!-- SubMenu Permohonan Informasi Publik -->
|
||||||
<h4>Permohonan Informasi Publik</h4>
|
<h4>Permohonan Informasi Publik</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="90" />
|
<input type="checkbox" id="90" />
|
||||||
<label for="90">Data tampil di halaman</label>
|
<label for="90">Data tampil di halaman</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -591,22 +569,65 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SubMenu Permohonan Keberatan Informasi Publik -->
|
<!-- SubMenu Permohonan Keberatan Informasi Publik -->
|
||||||
<h4>Permohonan Keberatan Informasi Publik</h4>
|
<h4>Permohonan Keberatan Informasi Publik</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="93" />
|
<input type="checkbox" id="93" />
|
||||||
<label for="93">Data tampil di halaman</label>
|
<label for="93">Data tampil di halaman</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="94" />
|
<input type="checkbox" id="94" />
|
||||||
<label for="94">Create Permohonan Keberatan Informasi Publik</label>
|
<label for="94">Create Permohonan Keberatan Informasi Publik</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="95" />
|
<input type="checkbox" id="95" />
|
||||||
<label for="95">Sinkronisasi ke UI</label>
|
<label for="95">Sinkronisasi ke UI</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- SubMenu Daftar Informasi Publik -->
|
||||||
|
<h4>Daftar Informasi Publik</h4>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="96" />
|
||||||
|
<label for="96">Search sudah berfungsi</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="97" />
|
||||||
|
<label for="97">Data tampil di halaman list</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="98" />
|
||||||
|
<label for="98">Create list daftar informasi publik</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="99" />
|
||||||
|
<label for="99">Detail mau tampil datanya</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="100" />
|
||||||
|
<label for="100">Hapus list daftar informasi publik bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="101" />
|
||||||
|
<label for="101">Edit / Update list daftar informasi publik bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="102" />
|
||||||
|
<label for="102">Pagination bekerja</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="103" />
|
||||||
|
<label for="103">Sinkronisasi ke UI</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user