Compare commits
1 Commits
nico/5-feb
...
nico/test-
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c59d7b4fb |
@@ -47,7 +47,9 @@
|
||||
{
|
||||
"id" : "cmdxy754q000svniiiz8oqyo0",
|
||||
"name" : "Surat Keterangan Belum Kawin",
|
||||
"deskripsi" : "<p>Persyaratan Dokumen :</p><ul><li><p>Pengantar Kelian Banjar Dinas di Wilayah Masing - masing</p></li><li><p>Fotocopy KTP atau Kartu Keluarga</p></li><li><p>Khusus bagi yang berstatus duda atau janda melampirkan fotocopy akta cerai atau dokumen pendukung lainnya</p></li></ul><p>Alur Pelayanan :</p>"
|
||||
"deskripsi" : "<p>Persyaratan Dokumen :</p><ul><li><p>Pengantar Kelian Banjar Dinas di Wilayah Masing - masing</p></li><li><p>Fotocopy KTP atau Kartu Keluarga</p></li><li><p>Khusus bagi yang berstatus duda atau janda melampirkan fotocopy akta cerai atau dokumen pendukung lainnya</p></li></ul><p>Alur Pelayanan :</p>",
|
||||
"imageId" : "cmeilibnt000007i66s5f73ss",
|
||||
"image2Id" : "cmeilvjmp000007kz9kll5bd2"
|
||||
},
|
||||
{
|
||||
"id" : "cmdxy8pi2000wvnii48fc1sxd",
|
||||
|
||||
29
prisma/data/file-storage.json
Normal file
29
prisma/data/file-storage.json
Normal file
@@ -0,0 +1,29 @@
|
||||
[
|
||||
{
|
||||
"id": "cmeijzdwk000207lb2u4u96wn",
|
||||
"name": "foto_kades",
|
||||
"realName": "kades.jpg",
|
||||
"path": "uploads/images/kades.jpg",
|
||||
"mimeType": "image/jpeg",
|
||||
"link": "https://drive.google.com/file/d/18C_kzKfEWvsGepAHASb2FIwXyyrzMdu2",
|
||||
"category": "image"
|
||||
},
|
||||
{
|
||||
"id": "cmeilibnt000007i66s5f73ss",
|
||||
"name": "surat-keterangan-belum-kawin",
|
||||
"realName": "surat-keterangan-belum-kawin.jpg",
|
||||
"path": "uploads/images/surat-keterangan-belum-kawin.jpg",
|
||||
"mimeType": "image/jpeg",
|
||||
"link": "https://drive.google.com/file/d/1S6p1gSlgf5fRt6f3UOtB7r3MIHQ4-BlU",
|
||||
"category": "image"
|
||||
},
|
||||
{
|
||||
"id": "cmeilvjmp000007kz9kll5bd2",
|
||||
"name": "skema-surat-keterangan-belum-kawin",
|
||||
"realName": "skema-surat-keterangan-belum-kawin.jpg",
|
||||
"path": "uploads/images/skema-surat-keterangan-belum-kawin.jpg",
|
||||
"mimeType": "image/jpeg",
|
||||
"link": "https://drive.google.com/file/d/1vTXobCipplsNj21BefDuEDTHsb-CbyAz",
|
||||
"category": "image"
|
||||
}
|
||||
]
|
||||
@@ -5,6 +5,7 @@
|
||||
"biodata": "<p>I.B Surya Prabhawa Manuaba, S.H., M.H., adalah Perbekel Darmasaba periode 2021-2027, seorang advokat, pendiri Mantra Legal Consultants & Advocates, serta aktif di bidang musik dan akademis. Dia menempuh pendidikan hukum di Universitas Udayana dan Universitas Mahasaraswati Denpasar, serta memiliki pengalaman luas di berbagai organisasi dan kepemimpinan.</p>",
|
||||
"riwayat": "<ul> <li>2021 - 2027: Perbekel Desa Darmasaba</li> <li>2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates</li> <li>2020 - Sekarang: Founder Ugawa Record Music Studio</li> <li>2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar</li> </ul>",
|
||||
"pengalaman": "<ul> <li>1996 – 1997: Ketua OSIS SMP Negeri 1 Abiansemal</li><li>1999 – 2000: Ketua OSIS SMA Negeri 1 Mengwi</li> <li>2008 – 2009: Ketua BEM Universitas Mahasaraswati Denpasar</li> <li>2008 – 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba</li> <li>2020 – Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar</li> <li>2021 – Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung</li> <li>2023 – 2028: Komite Tetap Advokasi – Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung</li> </ul>",
|
||||
"unggulan": "<h3>Pemberdayaan Ekonomi dan UMKM</h3> <ul> <li>Pelatihan dan pendampingan UMKM lokal</li> <li>Program bantuan modal usaha bagi pelaku usaha kecil</li><li>Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal</li></ul>"
|
||||
"unggulan": "<h3>Pemberdayaan Ekonomi dan UMKM</h3> <ul> <li>Pelatihan dan pendampingan UMKM lokal</li> <li>Program bantuan modal usaha bagi pelaku usaha kecil</li><li>Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal</li></ul>",
|
||||
"imageId": "cmeijzdwk000207lb2u4u96wn"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import profilePejabatDesa from "./data/landing-page/profile/profile.json";
|
||||
import penghargaan from "./data/landing-page/penghargaan/penghargaan.json";
|
||||
import programInovasi from "./data/landing-page/profile/programInovasi.json";
|
||||
@@ -50,6 +52,32 @@ import pegawaiPPID from "./data/ppid/struktur-ppid/pegawai-PPID.json";
|
||||
import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSaktiDesa.json";
|
||||
|
||||
(async () => {
|
||||
//seed file storage
|
||||
const filePath = path.join(__dirname, "data/file-storage.json");
|
||||
const rawData = await fs.readFile(filePath, "utf-8");
|
||||
const files = JSON.parse(rawData);
|
||||
|
||||
console.log(`Seeding ${files.length} file(s) into FileStorage...`);
|
||||
|
||||
for (const file of files) {
|
||||
await prisma.fileStorage.upsert({
|
||||
where: { name: file.name },
|
||||
update: {},
|
||||
create: {
|
||||
id: file.id,
|
||||
name: file.name,
|
||||
realName: file.realName,
|
||||
path: file.path,
|
||||
link: file.link,
|
||||
category: file.category,
|
||||
mimeType: file.mimeType,
|
||||
isActive: file.isActive ?? true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log("✅ Seeding selesai!");
|
||||
|
||||
// =========== LANDING PAGE ===========
|
||||
// =========== PROFILE ===========
|
||||
for (const p of profilePejabatDesa) {
|
||||
@@ -127,16 +155,26 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
||||
|
||||
// =========== LAYANAN DESA ===========
|
||||
for (const p of pelayananSuratKeterangan) {
|
||||
// Skip if required image references don't exist
|
||||
if (!p.imageId || !p.image2Id) {
|
||||
console.warn(`Skipping ${p.name} due to missing image references`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await prisma.pelayananSuratKeterangan.upsert({
|
||||
where: { id: p.id },
|
||||
update: {
|
||||
name: p.name,
|
||||
deskripsi: p.deskripsi,
|
||||
imageId: p.imageId,
|
||||
image2Id: p.image2Id,
|
||||
},
|
||||
create: {
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
deskripsi: p.deskripsi,
|
||||
imageId: p.imageId,
|
||||
image2Id: p.image2Id,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -495,7 +533,7 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
||||
riwayat: c.riwayat,
|
||||
pengalaman: c.pengalaman,
|
||||
unggulan: c.unggulan,
|
||||
// imageId tidak di-update
|
||||
imageId: c.imageId,
|
||||
},
|
||||
create: {
|
||||
id: c.id,
|
||||
@@ -504,7 +542,7 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
||||
riwayat: c.riwayat,
|
||||
pengalaman: c.pengalaman,
|
||||
unggulan: c.unggulan,
|
||||
// imageId tidak di-create
|
||||
imageId: c.imageId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ function DetailSuratKeterangan() {
|
||||
suratKeteranganState.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
|
||||
console.log("Ini datanya",suratKeteranganState.findUnique.data)
|
||||
|
||||
const handleHapus = () => {
|
||||
if (selectedId) {
|
||||
suratKeteranganState.delete.byId(selectedId)
|
||||
|
||||
@@ -63,8 +63,8 @@ function CreateSuratKeterangan() {
|
||||
|
||||
// Create the record
|
||||
await stateSurat.create.create();
|
||||
|
||||
// Reset form dan redirect
|
||||
|
||||
// If we get here without errors, the create was successful
|
||||
resetForm();
|
||||
toast.success("Data surat keterangan berhasil ditambahkan");
|
||||
router.push("/admin/desa/layanan/pelayanan_surat_keterangan");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// create.ts
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Context } from "elysia";
|
||||
import fs from "fs/promises";
|
||||
@@ -5,47 +6,155 @@ import path from "path";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
|
||||
|
||||
const fileStorageCreate = async (context: Context) => {
|
||||
const body = (await context.body) as {
|
||||
name: string;
|
||||
file: File;
|
||||
file?: File;
|
||||
googleDriveLink?: string;
|
||||
};
|
||||
|
||||
const file = body.file;
|
||||
const googleDriveLink = body.googleDriveLink?.trim();
|
||||
const name = body.name;
|
||||
|
||||
if (!file) return { status: 400, body: "No file uploaded" };
|
||||
if (!name) return { status: 400, body: "No name provided" };
|
||||
if (!UPLOAD_DIR) return { status: 500, body: "UPLOAD_DIR is not defined" };
|
||||
if (!BASE_URL) return { status: 500, body: "NEXT_PUBLIC_BASE_URL is not defined" };
|
||||
|
||||
// Tentukan kategori berdasarkan mimeType
|
||||
const isImage = file.type.startsWith("image/");
|
||||
const category = isImage ? "image" : "document";
|
||||
let category = "document";
|
||||
let mimeType = "application/octet-stream";
|
||||
let link = "";
|
||||
|
||||
const pathName = category === "image" ? "images" : "documents";
|
||||
const rootPath = path.join(UPLOAD_DIR, pathName);
|
||||
await fs.mkdir(rootPath, { recursive: true });
|
||||
// 📁 1. Upload File Lokal
|
||||
if (file) {
|
||||
const isImage = file.type.startsWith("image/");
|
||||
category = isImage ? "image" : "document";
|
||||
const pathName = category === "image" ? "images" : "documents";
|
||||
const rootPath = path.join(UPLOAD_DIR, pathName);
|
||||
await fs.mkdir(rootPath, { recursive: true });
|
||||
|
||||
const ext = file.name.split(".").pop();
|
||||
const newName = nanoid() + "." + ext;
|
||||
const parts = file.name.split(".");
|
||||
const ext = parts.length > 1 ? parts.pop() : "bin";
|
||||
const newName = nanoid() + "." + ext;
|
||||
|
||||
const data = await prisma.fileStorage.create({
|
||||
data: {
|
||||
name: newName,
|
||||
realName: file.name,
|
||||
path: rootPath,
|
||||
mimeType: file.type,
|
||||
category,
|
||||
link: `/api/fileStorage/findUnique/${newName}`,
|
||||
},
|
||||
});
|
||||
mimeType = file.type;
|
||||
link = `${BASE_URL}/uploads/${pathName}/${newName}`;
|
||||
|
||||
await fs.writeFile(
|
||||
path.join(rootPath, newName),
|
||||
Buffer.from(await file.arrayBuffer())
|
||||
);
|
||||
const data = await prisma.fileStorage.create({
|
||||
data: {
|
||||
name: newName,
|
||||
realName: file.name,
|
||||
path: rootPath,
|
||||
mimeType,
|
||||
category,
|
||||
link,
|
||||
},
|
||||
});
|
||||
|
||||
return { data };
|
||||
await fs.writeFile(
|
||||
path.join(rootPath, newName),
|
||||
Buffer.from(await file.arrayBuffer())
|
||||
);
|
||||
|
||||
return { data };
|
||||
}
|
||||
|
||||
// 🌐 2. Upload dari Google Drive
|
||||
if (googleDriveLink) {
|
||||
// Ekstrak ID dari link Google Drive
|
||||
const idMatch = googleDriveLink.match(/[-\w]{25,}/);
|
||||
if (!idMatch) {
|
||||
return { status: 400, body: "Invalid Google Drive link" };
|
||||
}
|
||||
|
||||
const fileId = idMatch[0];
|
||||
const embedLink = `https://drive.google.com/uc?export=view&id=${fileId}`;
|
||||
|
||||
// Validasi: cek apakah file bisa diakses
|
||||
try {
|
||||
const res = await fetch(embedLink);
|
||||
if (!res.ok) {
|
||||
return { status: 400, body: "Google Drive file not accessible (403/404)" };
|
||||
}
|
||||
} catch (error) {
|
||||
return { status: 400, body: "Failed to access Google Drive file", error };
|
||||
}
|
||||
|
||||
// Simpan ke database
|
||||
const data = await prisma.fileStorage.create({
|
||||
data: {
|
||||
name: `gdrive-${fileId}`,
|
||||
realName: name,
|
||||
path: "",
|
||||
mimeType: "image/jpeg", // default untuk embed
|
||||
category: "image",
|
||||
link: embedLink,
|
||||
},
|
||||
});
|
||||
|
||||
return { data };
|
||||
}
|
||||
|
||||
// ❌ Tidak ada file atau link
|
||||
return { status: 400, body: "Either 'file' or 'googleDriveLink' must be provided" };
|
||||
};
|
||||
|
||||
export default fileStorageCreate;
|
||||
|
||||
|
||||
|
||||
|
||||
// //kodingan sebelumnya:
|
||||
// import prisma from "@/lib/prisma";
|
||||
// import { Context } from "elysia";
|
||||
// import fs from "fs/promises";
|
||||
// import path from "path";
|
||||
// import { nanoid } from "nanoid";
|
||||
|
||||
// const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
|
||||
|
||||
// const fileStorageCreate = async (context: Context) => {
|
||||
// const body = (await context.body) as {
|
||||
// name: string;
|
||||
// file: File;
|
||||
// };
|
||||
// const file = body.file;
|
||||
// const name = body.name;
|
||||
|
||||
// if (!file) return { status: 400, body: "No file uploaded" };
|
||||
// if (!name) return { status: 400, body: "No name provided" };
|
||||
// if (!UPLOAD_DIR) return { status: 500, body: "UPLOAD_DIR is not defined" };
|
||||
|
||||
// // Tentukan kategori berdasarkan mimeType
|
||||
// const isImage = file.type.startsWith("image/");
|
||||
// const category = isImage ? "image" : "document";
|
||||
|
||||
// const pathName = category === "image" ? "images" : "documents";
|
||||
// const rootPath = path.join(UPLOAD_DIR, pathName);
|
||||
// await fs.mkdir(rootPath, { recursive: true });
|
||||
|
||||
// const ext = file.name.split(".").pop();
|
||||
// const newName = nanoid() + "." + ext;
|
||||
|
||||
// const data = await prisma.fileStorage.create({
|
||||
// data: {
|
||||
// name: newName,
|
||||
// realName: file.name,
|
||||
// path: rootPath,
|
||||
// mimeType: file.type,
|
||||
// category,
|
||||
// link: `/api/fileStorage/findUnique/${newName}`,
|
||||
// },
|
||||
// });
|
||||
|
||||
// await fs.writeFile(
|
||||
// path.join(rootPath, newName),
|
||||
// Buffer.from(await file.arrayBuffer())
|
||||
// );
|
||||
|
||||
// return { data };
|
||||
// };
|
||||
|
||||
// export default fileStorageCreate;
|
||||
Reference in New Issue
Block a user