Add Layanan Polsek submenu polsek terdekat

Seeder menu keamanan -> menu ekonomi submenu : demografi pekerjaan, junlah pengangguran, lowongan kerja lokal, pasar desa, program kemiskinan, sektor unggulan, struktur organisasi
This commit is contained in:
2026-01-17 10:32:48 +08:00
parent 184854d273
commit 17b20e0d40
67 changed files with 3238 additions and 1079 deletions

View File

@@ -13,6 +13,7 @@ const templatePasarDesaForm = z.object({
rating: z.number().min(1, "Rating minimal 1"),
kategoriId: z.array(z.string()).min(1, "Minimal pilih satu kategori"),
kontak: z.string().min(1, "Kontak wajib diisi"),
deskripsi: z.string().min(1, "Deskripsi wajib diisi"),
});
const defaultPasarDesaForm = {
@@ -23,6 +24,7 @@ const defaultPasarDesaForm = {
rating: 0,
kategoriId: [] as string[],
kontak: "",
deskripsi: ""
};
const pasarDesa = proxy({
@@ -191,6 +193,7 @@ const pasarDesa = proxy({
rating: data.rating,
kategoriId: data.kategoriId,
kontak: data.kontak,
deskripsi: data.deskripsi
};
return data;
} else {
@@ -229,6 +232,7 @@ const pasarDesa = proxy({
rating: this.form.rating,
kategoriId: this.form.kategoriId,
kontak: this.form.kontak,
deskripsi: this.form.deskripsi
}),
});
if (!response.ok) {

View File

@@ -15,7 +15,7 @@ const templateForm = z.object({
namaTempatMaps: z.string().min(1, "Nama Tempat Maps minimal 1 karakter"),
alamatMaps: z.string().min(1, "Alamat Maps minimal 1 karakter"),
linkPetunjukArah: z.string().min(1, "Link Petunjuk Arah minimal 1 karakter"),
layananPolsekId: z.string().min(1, "Layanan Polsek Id minimal 1 karakter"),
layananPolsekId: z.array(z.string()).min(1, "Pilih minimal 1 layanan polsek"),
});
const defaultForm = {
@@ -28,7 +28,7 @@ const defaultForm = {
namaTempatMaps: "",
alamatMaps: "",
linkPetunjukArah: "",
layananPolsekId: "",
layananPolsekId: [] as string[],
};
const polsekTerdekatState = proxy({
@@ -66,6 +66,11 @@ const polsekTerdekatState = proxy({
| Prisma.PolsekTerdekatGetPayload<{
include: {
layananPolsek: true;
LayananToPolsek: {
include: {
layanan: true;
}
}
};
}>[]
| null,
@@ -104,7 +109,14 @@ const polsekTerdekatState = proxy({
},
findUnique: {
data: null as Prisma.PolsekTerdekatGetPayload<{
include: { layananPolsek: true };
include: {
layananPolsek: true;
LayananToPolsek: {
include: {
layanan: true;
}
}
};
}> | null,
async load(id: string) {
try {
@@ -117,7 +129,7 @@ const polsekTerdekatState = proxy({
polsekTerdekatState.findUnique.data = null;
}
} catch (error) {
console.error("Error fetching data:", error);
console.error("Gagal fetch detail polsek terdekat:", error);
polsekTerdekatState.findUnique.data = null;
}
},
@@ -273,10 +285,13 @@ const polsekTerdekatState = proxy({
};
}> | null,
loading: false,
load: async () => { // Changed to arrow function
load: async () => {
// Changed to arrow function
polsekTerdekatState.findFirst.loading = true;
try {
const res = await ApiFetch.api.keamanan.polsekterdekat["find-first"].get();
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 {
@@ -287,8 +302,284 @@ const polsekTerdekatState = proxy({
} finally {
polsekTerdekatState.findFirst.loading = false;
}
}
}
},
},
});
export default polsekTerdekatState;
const templateFormLayananPolsek = z.object({
nama: z.string().min(1, "Nama harus diisi"),
});
const defaultFormLayananPolsek = {
nama: "",
};
const layananPolsek = proxy({
create: {
form: { ...defaultFormLayananPolsek },
loading: false,
async create() {
const cek = templateFormLayananPolsek.safeParse(
layananPolsek.create.form
);
if (!cek.success) {
const err = `[${cek.error.issues
.map((v) => `${v.path.join(".")}`)
.join("\n")}] required`;
return toast.error(err);
}
try {
layananPolsek.create.loading = true;
const res = await ApiFetch.api.keamanan["layananpolsek"][
"create"
].post(layananPolsek.create.form);
if (res.status === 200) {
layananPolsek.findManyAll.load();
return toast.success("Data Kategori Berita Berhasil Dibuat");
}
console.log(res);
return toast.error("failed create");
} catch (error) {
console.log(error);
return toast.error("failed create");
} finally {
layananPolsek.create.loading = false;
}
},
},
findMany: {
data: null as
| Prisma.LayananPolsekGetPayload<{
omit: {
isActive: true;
};
}>[]
| null,
page: 1,
totalPages: 1,
loading: false,
search: "",
load: async (page = 1, limit = 10, search = "") => {
layananPolsek.findMany.loading = true; // ✅ Akses langsung via nama path
layananPolsek.findMany.page = page;
layananPolsek.findMany.search = search;
try {
const query: any = { page, limit };
if (search) query.search = search;
const res = await ApiFetch.api.keamanan["layananpolsek"]["findMany"].get({ query });
if (res.status === 200 && res.data?.success) {
layananPolsek.findMany.data = res.data.data ?? [];
layananPolsek.findMany.totalPages = res.data.totalPages ?? 1;
} else {
layananPolsek.findMany.data = [];
layananPolsek.findMany.totalPages = 1;
}
} catch (err) {
console.error("Gagal fetch layanan polsek paginated:", err);
layananPolsek.findMany.data = [];
layananPolsek.findMany.totalPages = 1;
} finally {
layananPolsek.findMany.loading = false;
}
},
},
findManyAll: {
data: [] as Prisma.LayananPolsekGetPayload<{ omit: { isActive: true } }>[],
loading: false,
async load() {
this.loading = true;
try {
const res = await ApiFetch.api.keamanan["layananpolsek"][
"findManyAll"
].get();
if (res.status === 200 && res.data?.success) {
this.data = (res.data.data ?? []).map((item: any) => ({
id: String(item.id),
nama: String(item.nama || ""),
createdAt: item.createdAt ? new Date(item.createdAt) : new Date(),
updatedAt: item.updatedAt ? new Date(item.updatedAt) : new Date(),
deletedAt: item.deletedAt ? new Date(item.deletedAt) : null,
}));
} else {
this.data = [];
}
} catch (error) {
console.error("Gagal fetch layanan polsek:", error);
this.data = [];
} finally {
this.loading = false;
}
},
},
findUnique: {
data: null as Prisma.LayananPolsekGetPayload<{
omit: {
isActive: true;
};
}> | null,
loading: false,
async load(id: string) {
try {
const res = await fetch(`/api/keamanan/layananpolsek/${id}`);
if (res.ok) {
const data = await res.json();
layananPolsek.findUnique.data = data.data ?? null;
} else {
console.error("Failed to fetch data", res.status, res.statusText);
layananPolsek.findUnique.data = null;
}
} catch (error) {
console.error("Error fetching data:", error);
layananPolsek.findUnique.data = null;
}
},
},
delete: {
loading: false,
async delete(id: string) {
if (!id) return toast.warn("ID tidak valid");
try {
layananPolsek.delete.loading = true;
const response = await fetch(`/api/keamanan/layananpolsek/del/${id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
});
const result = await response.json();
if (response.ok && result?.success) {
toast.success(
result.message || "Data layanan polsek berhasil dihapus"
);
await layananPolsek.findManyAll.load(); // refresh list
} else {
toast.error(result?.message || "Gagal menghapus Data layanan polsek");
}
} catch (error) {
console.error("Gagal delete:", error);
toast.error("Terjadi kesalahan saat menghapus Data layanan polsek");
} finally {
layananPolsek.delete.loading = false;
}
},
},
update: {
id: "",
form: { ...defaultFormLayananPolsek },
loading: false,
async load(id: string) {
if (!id) {
toast.warn("ID tidak valid");
return null;
}
try {
const response = await fetch(`/api/keamanan/layananpolsek/${id}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
if (result?.success) {
const data = result.data;
this.id = data.id;
this.form = {
nama: data.nama,
};
return data; // Return the loaded data
} else {
throw new Error(result?.message || "Gagal memuat data");
}
} catch (error) {
console.error("Error loading layanan polsek:", error);
toast.error(
error instanceof Error ? error.message : "Gagal memuat data"
);
return null;
}
},
async update() {
const cek = templateFormLayananPolsek.safeParse(
layananPolsek.update.form
);
if (!cek.success) {
const err = `[${cek.error.issues
.map((v) => `${v.path.join(".")}`)
.join("\n")}] required`;
toast.error(err);
return false;
}
try {
layananPolsek.update.loading = true;
const response = await fetch(
`/api/keamanan/layananpolsek/${this.id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
nama: this.form.nama,
}),
}
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.message || `HTTP error! status: ${response.status}`
);
}
const result = await response.json();
if (result.success) {
toast.success("Berhasil update data layanan polsek");
await layananPolsek.findManyAll.load(); // refresh list
return true;
} else {
throw new Error(result.message || "Gagal update data layanan polsek");
}
} catch (error) {
console.error("Error updating data layanan polsek:", error);
toast.error(
error instanceof Error
? error.message
: "Terjadi kesalahan saat update data layanan polsek"
);
return false;
} finally {
layananPolsek.update.loading = false;
}
},
reset() {
layananPolsek.update.id = "";
layananPolsek.update.form = { ...defaultFormLayananPolsek };
},
},
});
const statePolsekTerdekat = proxy({
polsekTerdekatState,
layananPolsek,
});
export default statePolsekTerdekat;