Test foto gdrive
This commit is contained in:
@@ -47,7 +47,9 @@
|
|||||||
{
|
{
|
||||||
"id" : "cmdxy754q000svniiiz8oqyo0",
|
"id" : "cmdxy754q000svniiiz8oqyo0",
|
||||||
"name" : "Surat Keterangan Belum Kawin",
|
"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",
|
"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>",
|
"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>",
|
"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>",
|
"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 prisma from "@/lib/prisma";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import path from "path";
|
||||||
import profilePejabatDesa from "./data/landing-page/profile/profile.json";
|
import profilePejabatDesa from "./data/landing-page/profile/profile.json";
|
||||||
import penghargaan from "./data/landing-page/penghargaan/penghargaan.json";
|
import penghargaan from "./data/landing-page/penghargaan/penghargaan.json";
|
||||||
import programInovasi from "./data/landing-page/profile/programInovasi.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";
|
import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSaktiDesa.json";
|
||||||
|
|
||||||
(async () => {
|
(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 ===========
|
// =========== LANDING PAGE ===========
|
||||||
// =========== PROFILE ===========
|
// =========== PROFILE ===========
|
||||||
for (const p of profilePejabatDesa) {
|
for (const p of profilePejabatDesa) {
|
||||||
@@ -127,16 +155,26 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
|||||||
|
|
||||||
// =========== LAYANAN DESA ===========
|
// =========== LAYANAN DESA ===========
|
||||||
for (const p of pelayananSuratKeterangan) {
|
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({
|
await prisma.pelayananSuratKeterangan.upsert({
|
||||||
where: { id: p.id },
|
where: { id: p.id },
|
||||||
update: {
|
update: {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
deskripsi: p.deskripsi,
|
deskripsi: p.deskripsi,
|
||||||
|
imageId: p.imageId,
|
||||||
|
image2Id: p.image2Id,
|
||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
id: p.id,
|
id: p.id,
|
||||||
name: p.name,
|
name: p.name,
|
||||||
deskripsi: p.deskripsi,
|
deskripsi: p.deskripsi,
|
||||||
|
imageId: p.imageId,
|
||||||
|
image2Id: p.image2Id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -495,7 +533,7 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
|||||||
riwayat: c.riwayat,
|
riwayat: c.riwayat,
|
||||||
pengalaman: c.pengalaman,
|
pengalaman: c.pengalaman,
|
||||||
unggulan: c.unggulan,
|
unggulan: c.unggulan,
|
||||||
// imageId tidak di-update
|
imageId: c.imageId,
|
||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
id: c.id,
|
id: c.id,
|
||||||
@@ -504,7 +542,7 @@ import pelayananTelunjukSaktiDesa from "./data/desa/layanan/pelayananTelunjukSak
|
|||||||
riwayat: c.riwayat,
|
riwayat: c.riwayat,
|
||||||
pengalaman: c.pengalaman,
|
pengalaman: c.pengalaman,
|
||||||
unggulan: c.unggulan,
|
unggulan: c.unggulan,
|
||||||
// imageId tidak di-create
|
imageId: c.imageId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ function DetailSuratKeterangan() {
|
|||||||
suratKeteranganState.findUnique.load(params?.id as string)
|
suratKeteranganState.findUnique.load(params?.id as string)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
console.log("Ini datanya",suratKeteranganState.findUnique.data)
|
||||||
|
|
||||||
const handleHapus = () => {
|
const handleHapus = () => {
|
||||||
if (selectedId) {
|
if (selectedId) {
|
||||||
suratKeteranganState.delete.byId(selectedId)
|
suratKeteranganState.delete.byId(selectedId)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function CreateSuratKeterangan() {
|
|||||||
// Create the record
|
// Create the record
|
||||||
await stateSurat.create.create();
|
await stateSurat.create.create();
|
||||||
|
|
||||||
// Reset form dan redirect
|
// If we get here without errors, the create was successful
|
||||||
resetForm();
|
resetForm();
|
||||||
toast.success("Data surat keterangan berhasil ditambahkan");
|
toast.success("Data surat keterangan berhasil ditambahkan");
|
||||||
router.push("/admin/desa/layanan/pelayanan_surat_keterangan");
|
router.push("/admin/desa/layanan/pelayanan_surat_keterangan");
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// create.ts
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { Context } from "elysia";
|
import { Context } from "elysia";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
@@ -5,38 +6,50 @@ import path from "path";
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
|
const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
|
||||||
|
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
|
||||||
|
|
||||||
const fileStorageCreate = async (context: Context) => {
|
const fileStorageCreate = async (context: Context) => {
|
||||||
const body = (await context.body) as {
|
const body = (await context.body) as {
|
||||||
name: string;
|
name: string;
|
||||||
file: File;
|
file?: File;
|
||||||
|
googleDriveLink?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const file = body.file;
|
const file = body.file;
|
||||||
|
const googleDriveLink = body.googleDriveLink?.trim();
|
||||||
const name = body.name;
|
const name = body.name;
|
||||||
|
|
||||||
if (!file) return { status: 400, body: "No file uploaded" };
|
|
||||||
if (!name) return { status: 400, body: "No name provided" };
|
if (!name) return { status: 400, body: "No name provided" };
|
||||||
if (!UPLOAD_DIR) return { status: 500, body: "UPLOAD_DIR is not defined" };
|
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
|
let category = "document";
|
||||||
|
let mimeType = "application/octet-stream";
|
||||||
|
let link = "";
|
||||||
|
|
||||||
|
// 📁 1. Upload File Lokal
|
||||||
|
if (file) {
|
||||||
const isImage = file.type.startsWith("image/");
|
const isImage = file.type.startsWith("image/");
|
||||||
const category = isImage ? "image" : "document";
|
category = isImage ? "image" : "document";
|
||||||
|
|
||||||
const pathName = category === "image" ? "images" : "documents";
|
const pathName = category === "image" ? "images" : "documents";
|
||||||
const rootPath = path.join(UPLOAD_DIR, pathName);
|
const rootPath = path.join(UPLOAD_DIR, pathName);
|
||||||
await fs.mkdir(rootPath, { recursive: true });
|
await fs.mkdir(rootPath, { recursive: true });
|
||||||
|
|
||||||
const ext = file.name.split(".").pop();
|
const parts = file.name.split(".");
|
||||||
|
const ext = parts.length > 1 ? parts.pop() : "bin";
|
||||||
const newName = nanoid() + "." + ext;
|
const newName = nanoid() + "." + ext;
|
||||||
|
|
||||||
|
mimeType = file.type;
|
||||||
|
link = `${BASE_URL}/uploads/${pathName}/${newName}`;
|
||||||
|
|
||||||
const data = await prisma.fileStorage.create({
|
const data = await prisma.fileStorage.create({
|
||||||
data: {
|
data: {
|
||||||
name: newName,
|
name: newName,
|
||||||
realName: file.name,
|
realName: file.name,
|
||||||
path: rootPath,
|
path: rootPath,
|
||||||
mimeType: file.type,
|
mimeType,
|
||||||
category,
|
category,
|
||||||
link: `/api/fileStorage/findUnique/${newName}`,
|
link,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,6 +59,102 @@ const fileStorageCreate = async (context: Context) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return { data };
|
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;
|
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