Fix Compres Gambar && seed gambar profile - landing page

This commit is contained in:
2025-09-12 11:55:40 +08:00
parent 6a7bd386ae
commit a5d841bb6b
65 changed files with 386 additions and 156 deletions

View File

@@ -3,6 +3,8 @@ import { Context } from "elysia";
import fs from "fs/promises";
import path from "path";
import { nanoid } from "nanoid";
import sharp from "sharp";
import zlib from "zlib";
const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
@@ -11,6 +13,7 @@ const fileStorageCreate = async (context: Context) => {
name: string;
file: File;
};
const file = body.file;
const name = body.name;
@@ -18,7 +21,6 @@ const fileStorageCreate = async (context: Context) => {
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";
@@ -26,25 +28,54 @@ const fileStorageCreate = async (context: Context) => {
const rootPath = path.join(UPLOAD_DIR, pathName);
await fs.mkdir(rootPath, { recursive: true });
const ext = file.name.split(".").pop();
const newName = nanoid() + "." + ext;
// Convert File ke Buffer
const buffer = Buffer.from(await file.arrayBuffer());
let finalName = nanoid();
let finalMimeType = file.type;
if (isImage) {
// Simpan sebagai WebP untuk kompresi maksimal
const mobileBuffer = await sharp(buffer)
.resize({ width: 720 })
.webp({ quality: 80 })
.toBuffer();
const desktopBuffer = await sharp(buffer)
.resize({ width: 1920, withoutEnlargement: true })
.webp({ quality: 80 })
.toBuffer();
const mobileName = `${finalName}-mobile.webp`;
const desktopName = `${finalName}-desktop.webp`;
await fs.writeFile(path.join(rootPath, mobileName), mobileBuffer);
await fs.writeFile(path.join(rootPath, desktopName), desktopBuffer);
// Simpan metadata untuk versi desktop sebagai default
finalName = desktopName;
finalMimeType = "image/webp";
} else {
// Kompres dokumen (opsional pakai gzip)
const gzBuffer = zlib.gzipSync(buffer);
const docName = `${finalName}.gz`;
await fs.writeFile(path.join(rootPath, docName), gzBuffer);
finalName = docName;
finalMimeType = "application/gzip";
}
const data = await prisma.fileStorage.create({
data: {
name: newName,
name: finalName,
realName: file.name,
path: rootPath,
mimeType: file.type,
mimeType: finalMimeType,
category,
link: `/api/fileStorage/findUnique/${newName}`,
link: `/api/fileStorage/findUnique/${finalName}`,
},
});
await fs.writeFile(
path.join(rootPath, newName),
Buffer.from(await file.arrayBuffer())
);
return { data };
};

View File

@@ -11,7 +11,7 @@ export default async function sdgsDesaCreate(context: Context) {
const body = context.body as FormCreate;
try {
const result = await prisma.sDGSDesa.create({
const result = await prisma.sdgsDesa.create({
data: {
name: body.name,
jumlah: body.jumlah,

View File

@@ -9,7 +9,7 @@ export default async function sdgsDesaDelete(context: Context) {
throw new Error("ID tidak ditemukan dalam parameter");
}
const deleted = await prisma.sDGSDesa.delete({
const deleted = await prisma.sdgsDesa.delete({
where: { id },
});

View File

@@ -21,7 +21,7 @@ async function sdgsDesaFindMany(context: Context) {
try {
const [data, total] = await Promise.all([
prisma.sDGSDesa.findMany({
prisma.sdgsDesa.findMany({
where,
include: {
image: true,
@@ -30,7 +30,7 @@ async function sdgsDesaFindMany(context: Context) {
take: limit,
orderBy: { jumlah: "desc" }, // opsional, kalau mau urut berdasarkan waktu
}),
prisma.sDGSDesa.count({
prisma.sdgsDesa.count({
where,
}),
]);

View File

@@ -9,7 +9,7 @@ export default async function sdgsDesaFindUnique(context: Context) {
throw new Error("ID tidak ditemukan dalam parameter");
}
const data = await prisma.sDGSDesa.findUnique({
const data = await prisma.sdgsDesa.findUnique({
where: { id },
include: {
image: true,

View File

@@ -21,7 +21,7 @@ export default async function sdgsDesaUpdate(context: Context) {
}
try {
const updated = await prisma.sDGSDesa.update({
const updated = await prisma.sdgsDesa.update({
where: { id },
data: {
name: body.name,