From 49004fb444bd7eb27d5be591197b1afe2c759588 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Wed, 26 Feb 2025 14:49:56 +0800 Subject: [PATCH 1/7] fix pdf to image investasi --- bun.lock | 22 +- ...2026a78b8cb786880c7c733460d7dbe-audit.json | 10 +- ...c6075347623def466341a14f8ba4a12-audit.json | 10 +- package.json | 2 + src/app/api/pdf-to-image/route.ts | 283 ++++++++++++++++++ .../investasi/file-view/dokumen/[id]/page.tsx | 6 +- .../file-view/prospektus/[id]/page.tsx | 7 +- .../_global/lib/api_fetch_global.ts | 55 ++++ .../detail/comp_card_daftar_document.tsx | 7 +- .../detail/comp_card_rekap_document.tsx | 2 +- .../_ui/file_view/ui_file_view_dokumen.tsx | 86 +++++- .../_ui/file_view/ui_file_view_prospektus.tsx | 97 ++++-- .../portofolio/component/button_more_new.tsx | 19 +- src/lib/router_hipmi/router_investasi.ts | 5 +- x-example-show-pdf/index.html | 2 +- 15 files changed, 540 insertions(+), 73 deletions(-) mode change 100755 => 100644 bun.lock create mode 100644 src/app/api/pdf-to-image/route.ts create mode 100644 src/app_modules/_global/lib/api_fetch_global.ts diff --git a/bun.lock b/bun.lock old mode 100755 new mode 100644 index fc8ef387..348ae19e --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,5 @@ { - "lockfileVersion": 0, + "lockfileVersion": 1, "workspaces": { "": { "dependencies": { @@ -58,6 +58,8 @@ "next-dev": "^1.1.9", "next-scroll-loader": "^1.0.9", "p-limit": "^6.2.0", + "pdf-lib": "^1.17.1", + "pdf2pic": "^3.1.3", "pdfjs-dist": "^4.6.82", "postcss": "8.4.27", "prisma": "^6.3.0", @@ -717,6 +719,10 @@ "@oven/bun-windows-x64-baseline": ["@oven/bun-windows-x64-baseline@1.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-bYopMWSCjjjCKjANv7xxAXQoabVUxLZxTw0iC1bGYD9VZGo48nGaJXPn7DsPfeCXGyl+CY3Cy4QIEn+3gNRS2A=="], + "@pdf-lib/standard-fonts": ["@pdf-lib/standard-fonts@1.0.0", "", { "dependencies": { "pako": "^1.0.6" } }, "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA=="], + + "@pdf-lib/upng": ["@pdf-lib/upng@1.0.1", "", { "dependencies": { "pako": "^1.0.10" } }, "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ=="], + "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.3.15", "", { "dependencies": { "asn1js": "^3.0.5", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w=="], "@peculiar/json-schema": ["@peculiar/json-schema@1.1.12", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w=="], @@ -1151,6 +1157,10 @@ "array-includes": ["array-includes@3.1.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ=="], + "array-parallel": ["array-parallel@0.1.3", "", {}, "sha512-TDPTwSWW5E4oiFiKmz6RGJ/a80Y91GuLgUYuLd49+XBS75tYo8PNgaT2K/OxuQYqkoI852MDGBorg9OcUSTQ8w=="], + + "array-series": ["array-series@0.1.5", "", {}, "sha512-L0XlBwfx9QetHOsbLDrE/vh2t018w9462HM3iaFfxRiK83aJjAt/Ja3NMkOW7FICwWTlQBa3ZbL5FKhuQWkDrg=="], + "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="], @@ -1815,6 +1825,8 @@ "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], + "gm": ["gm@1.25.1", "", { "dependencies": { "array-parallel": "~0.1.3", "array-series": "~0.1.5", "cross-spawn": "^7.0.5", "debug": "^3.1.0" } }, "sha512-jgcs2vKir9hFogGhXIfs0ODhJTfIrbECCehg38tqFgHm8zqXx7kAJyCYAFK4jTjx71AxrkFtkJBawbAxYUPX9A=="], + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "gpt-3-encoder": ["gpt-3-encoder@1.1.4", "", {}, "sha512-fSQRePV+HUAhCn7+7HL7lNIXNm6eaFWFbNLOOGtmSJ0qJycyQvj60OvRlH7mee8xAMjBDNRdMXlMwjAbMTDjkg=="], @@ -2457,6 +2469,10 @@ "pbf": ["pbf@3.3.0", "", { "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" }, "bin": { "pbf": "bin/pbf" } }, "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q=="], + "pdf-lib": ["pdf-lib@1.17.1", "", { "dependencies": { "@pdf-lib/standard-fonts": "^1.0.0", "@pdf-lib/upng": "^1.0.1", "pako": "^1.0.11", "tslib": "^1.11.1" } }, "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw=="], + + "pdf2pic": ["pdf2pic@3.1.3", "", { "dependencies": { "gm": "^1.25.0" } }, "sha512-KbW4Qb7iHw2fBRWtA9FTc4pZg9cokiFIzc6cE7dzelTrhXWolfQuG1fYVC0E2BRmK/w7xfBjQ+OEsPZPO3QEew=="], + "pdfjs-dist": ["pdfjs-dist@4.10.38", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.65" } }, "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ=="], "peerjs": ["peerjs@1.5.4", "", { "dependencies": { "@msgpack/msgpack": "^2.8.0", "eventemitter3": "^4.0.7", "peerjs-js-binarypack": "^2.1.0", "webrtc-adapter": "^9.0.0" } }, "sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw=="], @@ -3467,6 +3483,8 @@ "formdata-node/web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], + "gm/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + "has-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], "html-tokenize/readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="], @@ -3555,6 +3573,8 @@ "password-prompt/ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], + "pdf-lib/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], + "peerjs/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], "pkg-dir/find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], diff --git a/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json b/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json index 877fc566..aea69c9f 100644 --- a/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json +++ b/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json @@ -5,11 +5,6 @@ }, "auditLog": "logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json", "files": [ - { - "date": 1739242050497, - "name": "logs/backend/combined-2025-02-11.log", - "hash": "13ef770bd22a1c0c4412156ffbf32e0a38fa2d61caa14054dc71d579374e8f56" - }, { "date": 1739327386336, "name": "logs/backend/combined-2025-02-12.log", @@ -64,6 +59,11 @@ "date": 1740450562875, "name": "logs/backend/combined-2025-02-25.log", "hash": "1ab2165b4d456ebed03006c88d9ce4b4f7be61bd38246e306fecbc73f72f8fdd" + }, + { + "date": 1740536165848, + "name": "logs/backend/combined-2025-02-26.log", + "hash": "428aedb3a3a248ad2c7069fcb8c6e0d669c23eae0dc3db08914886cce8d2cad9" } ], "hashType": "sha256" diff --git a/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json b/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json index b805d8d1..8b75d721 100644 --- a/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json +++ b/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json @@ -5,11 +5,6 @@ }, "auditLog": "logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json", "files": [ - { - "date": 1739242050493, - "name": "logs/backend/error-2025-02-11.log", - "hash": "a346dd5f2327d9f40439c851473199450ec0918d7f0bd4b280343540a0b5ccb0" - }, { "date": 1739327386330, "name": "logs/backend/error-2025-02-12.log", @@ -64,6 +59,11 @@ "date": 1740450562872, "name": "logs/backend/error-2025-02-25.log", "hash": "189996570b83d8dbc20aac1eaf0583edf1472e1d1ac0dc83be0fb9b20a20ee07" + }, + { + "date": 1740536165843, + "name": "logs/backend/error-2025-02-26.log", + "hash": "fc1b904017c0517b4aa4138d2edb5dd58474ef723a17cab177d0605026a23c11" } ], "hashType": "sha256" diff --git a/package.json b/package.json index 5d92a2a6..c6651c3e 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,8 @@ "next-dev": "^1.1.9", "next-scroll-loader": "^1.0.9", "p-limit": "^6.2.0", + "pdf-lib": "^1.17.1", + "pdf2pic": "^3.1.3", "pdfjs-dist": "^4.6.82", "postcss": "8.4.27", "prisma": "^6.3.0", diff --git a/src/app/api/pdf-to-image/route.ts b/src/app/api/pdf-to-image/route.ts new file mode 100644 index 00000000..26274157 --- /dev/null +++ b/src/app/api/pdf-to-image/route.ts @@ -0,0 +1,283 @@ +// // app/api/pdf-to-image/route.ts +import { execSync } from 'child_process'; +import { NextResponse } from 'next/server'; +import { PDFDocument } from 'pdf-lib'; +import { fromBuffer } from 'pdf2pic'; + +// // Tambahkan custom error +// class PDFConversionError extends Error { +// constructor(message: string, public statusCode: number = 500) { +// super(message); +// this.name = 'PDFConversionError'; +// } +// } + +// // Improve fungsi check dependencies +// async function checkDependencies() { +// const dependencies = [ +// { cmd: 'gm version', name: 'GraphicsMagick' }, +// { cmd: 'gs --version', name: 'Ghostscript' } +// ]; + +// for (const dep of dependencies) { +// try { +// execSync(dep.cmd); +// } catch (error) { +// throw new PDFConversionError(`${dep.name} tidak terinstall`, 500); +// } +// } +// } + +// // Tambah konstanta +// const MAX_PDF_SIZE_MB = 50; +// const MAX_IMAGE_DIMENSION = 2000; +// const CONVERSION_TIMEOUT_MS = 30000; +// const MAX_PAGES = 10; // Batasan jumlah halaman +// const DEFAULT_PAGE = 1; + +// // Modifikasi validateParams +// function validateParams(pdfUrl: string | null, pages: number[]) { +// if (!pdfUrl) { +// throw new PDFConversionError('URL parameter wajib diisi', 400); +// } +// if (pages.some(p => p < 1)) { +// throw new PDFConversionError('Nomor halaman tidak valid', 400); +// } +// if (pages.length > MAX_PAGES) { +// throw new PDFConversionError(`Maksimal ${MAX_PAGES} halaman per request`, 400); +// } +// } + +// interface ConversionResult { +// buffer: Buffer; +// text: string; +// density: number; +// width: number; +// height: number; +// } + +// // Fungsi untuk validasi dan fetch PDF +// async function fetchPDF(url: string) { +// const controller = new AbortController(); +// const timeout = setTimeout(() => controller.abort(), 10000); + +// try { +// // Validasi URL +// const validUrl = new URL(url); +// if (!validUrl.protocol.startsWith('http')) { +// throw new PDFConversionError('URL tidak valid', 400); +// } + +// const response = await fetch(url, { +// signal: controller.signal, +// headers: { +// 'Accept': 'application/pdf', +// 'User-Agent': 'Mozilla/5.0 (compatible; PDFConverter/1.0)' +// } +// }); + +// if (!response.ok) { +// throw new PDFConversionError( +// `Gagal mengakses PDF: ${response.status} ${response.statusText}`, +// response.status +// ); +// } + +// const contentType = response.headers.get('content-type'); +// if (!contentType?.includes('pdf')) { +// throw new PDFConversionError('URL bukan file PDF', 400); +// } + +// return response; + +// } catch (error: unknown) { +// if (error instanceof PDFConversionError) throw error; +// if (error instanceof Error && error.name === 'AbortError') { +// throw new PDFConversionError('Timeout saat mengunduh PDF', 504); +// } +// const message = error instanceof Error ? error.message : 'Unknown error'; +// throw new PDFConversionError('Gagal mengunduh PDF: ' + message, 500); +// } finally { +// clearTimeout(timeout); +// } +// } + +// // Tambahkan error SVG template +// const errorImageSvg = ` +// +// +// +// +// +// PDF Conversion Failed +// +// `; + +// // Tambahkan SVG untuk end of page +// const endOfPageSvg = ` +// +// +// +// End of PDF +// +// +// No more pages available +// +// +// `; + +// // Fungsi helper untuk set common headers +// function setCommonHeaders(headers: Headers) { +// headers.set('Access-Control-Allow-Origin', '*'); +// headers.set('Access-Control-Allow-Methods', 'GET, OPTIONS'); +// headers.set('Content-Security-Policy', "default-src 'self'; img-src 'self' data: blob:;"); +// headers.set('X-Content-Type-Options', 'nosniff'); +// } + +// // Fungsi helper untuk return error image +// function returnErrorImage(message: string = 'Conversion failed') { +// const response = new NextResponse(errorImageSvg, { +// headers: { +// 'Content-Type': 'image/svg+xml', +// 'Cache-Control': 'no-store', +// 'X-Error-Message': message +// } +// }); +// setCommonHeaders(response.headers); +// return response; +// } + +// // Fungsi helper untuk return end of page image +// function returnEndOfPageImage() { +// const response = new NextResponse(endOfPageSvg, { +// headers: { +// 'Content-Type': 'image/svg+xml', +// 'Cache-Control': 'public, max-age=31536000', +// 'X-Error-Message': 'End of PDF pages' +// } +// }); +// setCommonHeaders(response.headers); +// return response; +// } + +// // Fungsi untuk get total pages menggunakan pdf-lib +// async function getPDFPageCount(buffer: Buffer): Promise { +// try { +// const pdfDoc = await PDFDocument.load(buffer); +// return pdfDoc.getPageCount(); +// } catch (error) { +// console.error('Error getting PDF page count:', error); +// throw new Error('Failed to get PDF page count'); +// } +// } + +// export async function GET(request: Request) { +// let pdfBuffer: Buffer | null = null; +// const { searchParams } = new URL(request.url); + +// try { +// // Validasi parameter wajib +// const pdfUrl = searchParams.get('url'); +// if (!pdfUrl) { +// return NextResponse.json({ +// error: 'URL parameter wajib diisi' +// }, { status: 400 }); +// } + +// // Decode URL jika perlu +// const decodedUrl = decodeURIComponent(pdfUrl); + +// await checkDependencies(); + +// const getTotalPages = searchParams.get('total') === 'true'; + +// // Single fetch PDF dengan URL yang sudah di-decode +// const pdfResponse = await fetchPDF(decodedUrl); + +// const arrayBuffer = await pdfResponse.arrayBuffer(); +// pdfBuffer = Buffer.from(arrayBuffer); + +// // Get total pages +// if (getTotalPages) { +// try { +// const pageCount = await getPDFPageCount(pdfBuffer); +// return Response.json({ +// totalPages: pageCount, +// message: 'Success get total pages' +// }); +// } catch (error) { +// console.error('PDF parse error:', error); +// return Response.json({ +// error: 'Gagal membaca total halaman PDF', +// totalPages: 0 +// }, { status: 500 }); +// } +// } + +// // Parse page parameter dengan lebih baik +// const pageStr = searchParams.get('page'); +// let pageNum = 1; // Default ke halaman 1 + +// if (pageStr) { +// pageNum = parseInt(pageStr); +// if (isNaN(pageNum) || pageNum < 1) { +// return returnErrorImage('Invalid page number'); +// } + +// // Validasi halaman tidak melebihi total +// const totalPages = await getPDFPageCount(pdfBuffer); +// if (pageNum > totalPages) { +// return returnEndOfPageImage(); +// } +// } + +// const options = { +// density: 300, +// format: "png", +// width: Math.min(1200, MAX_IMAGE_DIMENSION), +// height: Math.min(1700, MAX_IMAGE_DIMENSION), +// preserveAspectRatio: true, +// saveFilename: "", +// savePath: "", +// returnBuffer: true +// }; + +// // Konversi single page +// const convert = fromBuffer(pdfBuffer, options); +// const result = await Promise.race([ +// convert(pageNum, { responseType: "buffer" }), +// new Promise((_, reject) => +// setTimeout(() => reject(new PDFConversionError('Konversi timeout', 504)), +// CONVERSION_TIMEOUT_MS) +// ) +// ]) as ConversionResult; + +// if (!result?.buffer) { +// return returnErrorImage('Konversi gagal: tidak ada output'); +// } + +// // Return image buffer +// const response = new NextResponse(result.buffer, { +// headers: { +// 'Content-Type': 'image/png', +// 'Content-Length': result.buffer.length.toString(), +// 'Cache-Control': 'public, max-age=31536000' +// } +// }); +// setCommonHeaders(response.headers); +// return response; + +// } catch (error) { +// console.error('PDF conversion error:', error); + +// // Return appropriate error response +// const errorMessage = error instanceof Error ? error.message : 'Unknown error'; +// const statusCode = error instanceof PDFConversionError ? error.statusCode : 500; + +// return !searchParams.get('pages') ? +// returnErrorImage(errorMessage) : +// NextResponse.json({ error: errorMessage }, { status: statusCode }); +// } finally { +// pdfBuffer = null; +// } +// } \ No newline at end of file diff --git a/src/app/dev/investasi/file-view/dokumen/[id]/page.tsx b/src/app/dev/investasi/file-view/dokumen/[id]/page.tsx index 446fef71..22aa6e7c 100644 --- a/src/app/dev/investasi/file-view/dokumen/[id]/page.tsx +++ b/src/app/dev/investasi/file-view/dokumen/[id]/page.tsx @@ -1,11 +1,9 @@ import { Investasi_UiFileViewDokumen } from "@/app_modules/investasi/_ui"; -export default async function Page({ params }: { params: { id: string } }) { - const dokumenId = params.id; - +export default async function Page() { return ( <> - + ); } diff --git a/src/app/dev/investasi/file-view/prospektus/[id]/page.tsx b/src/app/dev/investasi/file-view/prospektus/[id]/page.tsx index 25de80fd..dd56c9a0 100644 --- a/src/app/dev/investasi/file-view/prospektus/[id]/page.tsx +++ b/src/app/dev/investasi/file-view/prospektus/[id]/page.tsx @@ -1,12 +1,9 @@ -import { investasi_funGetProspekById } from "@/app_modules/investasi/_fun"; import { Investasi_UiFileView } from "@/app_modules/investasi/_ui"; -export default async function Page({ params }: { params: { id: string } }) { - const pospektusId = params.id; - +export default async function Page() { return ( <> - + ); } diff --git a/src/app_modules/_global/lib/api_fetch_global.ts b/src/app_modules/_global/lib/api_fetch_global.ts new file mode 100644 index 00000000..bea0d5b4 --- /dev/null +++ b/src/app_modules/_global/lib/api_fetch_global.ts @@ -0,0 +1,55 @@ +export { + apiGetPdfToImage, +} + +export interface PageData { + imageUrl: string; + pageNumber: number; +} + +interface PdfResponse { + pages: PageData[]; + totalPages: number; +} +const apiGetPdfToImage = async ({id}: {id: string}) => { + try { + // Fetch token from cookie + // const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + // if (!token) { + // console.error("No token found"); + // return null; + // } + + const token = + "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiY20wdXIxeXh3MDAwMDU2bnNqbHI2MTg3cCIsIm5hbWUiOiJiYWdhcyIsImVtYWlsIjoiYmFnYXNAZ21haWwuY29tIn0sImlhdCI6MTcyNTg3MTAzNiwiZXhwIjo0ODgxNjMxMDM2fQ.wFQLcrJj66wFeqIMYk2esMx3ULaHK6RFxkiToaLCuko"; + + + // Anda bisa menggunakan prospektusId di URL jika diperlukan + const pdfUrl = `https://wibu-storage.wibudev.com/api/pdf-to-image?url=https://wibu-storage.wibudev.com/api/files/${id}`; + + const response = await fetch(pdfUrl, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Error get admin contact:", + errorData?.message || "Unknown error" + ); + + return null; + } + + const jsonData: PdfResponse = await response.json(); + return jsonData; + } catch (error) { + console.error("Error get admin contact:", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/investasi/_component/detail/comp_card_daftar_document.tsx b/src/app_modules/investasi/_component/detail/comp_card_daftar_document.tsx index 5e9d6b15..bcb30abf 100644 --- a/src/app_modules/investasi/_component/detail/comp_card_daftar_document.tsx +++ b/src/app_modules/investasi/_component/detail/comp_card_daftar_document.tsx @@ -22,10 +22,9 @@ export function Investasi_ComponentCardDaftarDocument({ justify="center" h={"100%"} onClick={() => { - router.push( - NEW_RouterInvestasi.file_prospektus({ id: data.fileId }), - { scroll: false } - ); + router.push(NEW_RouterInvestasi.file_dokumen({ id: data.fileId }), { + scroll: false, + }); setVisible(true); }} > diff --git a/src/app_modules/investasi/_component/detail/comp_card_rekap_document.tsx b/src/app_modules/investasi/_component/detail/comp_card_rekap_document.tsx index b2727e20..9bfa2458 100644 --- a/src/app_modules/investasi/_component/detail/comp_card_rekap_document.tsx +++ b/src/app_modules/investasi/_component/detail/comp_card_rekap_document.tsx @@ -97,7 +97,7 @@ export function Investasi_ComponentCardRekapDocument({ span={"auto"} onClick={() => { router.push( - NEW_RouterInvestasi.file_prospektus({ id: data.fileId }), + NEW_RouterInvestasi.file_dokumen({ id: data.fileId }), { scroll: false } ); setVisible(true); diff --git a/src/app_modules/investasi/_ui/file_view/ui_file_view_dokumen.tsx b/src/app_modules/investasi/_ui/file_view/ui_file_view_dokumen.tsx index c29c745b..df3c745d 100644 --- a/src/app_modules/investasi/_ui/file_view/ui_file_view_dokumen.tsx +++ b/src/app_modules/investasi/_ui/file_view/ui_file_view_dokumen.tsx @@ -3,27 +3,85 @@ import { APIs } from "@/lib"; import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate"; import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"; -import { Box } from "@mantine/core"; +import { Box, Stack } from "@mantine/core"; import { IconX } from "@tabler/icons-react"; import dynamic from "next/dynamic"; -const PdfToImage = dynamic( - () => - import("../../_view/file_view/view_file_viewer").then((mod) => mod.default), - { ssr: false } -); +import { apiGetPdfToImage, PageData } from "@/app_modules/_global/lib/api_fetch_global"; +import { useParams } from "next/navigation"; +import { useState, useRef, useEffect } from "react"; +import PdfToImage from "../../_view/file_view/view_file_viewer"; +import Image from "next/image"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; + + +export function Investasi_UiFileViewDokumen() { + const param = useParams<{ id: string }>(); + const dokumenId = param.id; + + const [pdfPages, setPdfPages] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const pdfsRef = useRef(null); + + useEffect(() => { + const fetchPdfData = async () => { + try { + setLoading(true); + const response = await apiGetPdfToImage({ id: dokumenId }); + + if (response) { + setPdfPages(response.pages as any); + setLoading(false); + } + } catch (err) { + console.error("Error fetching PDF:", err); + setError( + err instanceof Error ? err.message : "Unknown error occurred" + ); + setLoading(false); + } + }; + + fetchPdfData(); + }, [dokumenId]); + -export function Investasi_UiFileViewDokumen({ - dokumenId, -}: { - dokumenId: string; -}) { return ( <> } />} + header={} />} > - - + + {loading ? ( + + ) : error ? ( + + + + + ) : ( +
+ {pdfPages?.map((page, index) => ( + {`Page + ))} +
+ )}
diff --git a/src/app_modules/investasi/_ui/file_view/ui_file_view_prospektus.tsx b/src/app_modules/investasi/_ui/file_view/ui_file_view_prospektus.tsx index adb3cae5..8c822a7b 100644 --- a/src/app_modules/investasi/_ui/file_view/ui_file_view_prospektus.tsx +++ b/src/app_modules/investasi/_ui/file_view/ui_file_view_prospektus.tsx @@ -1,33 +1,90 @@ "use client"; -import { APIs } from "@/lib"; -import { RouterInvestasi_OLD } from "@/lib/router_hipmi/router_investasi"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; +import { + apiGetPdfToImage, + PageData, +} from "@/app_modules/_global/lib/api_fetch_global"; import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate"; import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"; -import { Box } from "@mantine/core"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { Box, Stack } from "@mantine/core"; import { IconX } from "@tabler/icons-react"; -import dynamic from "next/dynamic"; -const PdfToImage = dynamic( - () => - import("../../_view/file_view/view_file_viewer").then((mod) => mod.default), - { ssr: false } -); +import Image from "next/image"; +import { useParams } from "next/navigation"; +import { useEffect, useRef, useState } from "react"; + +export function Investasi_UiFileViewProspektus() { + const param = useParams<{ id: string }>(); + const prospektusId = param.id; + + const [pdfPages, setPdfPages] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const pdfsRef = useRef(null); + + useEffect(() => { + const fetchPdfData = async () => { + try { + setLoading(true); + const response = await apiGetPdfToImage({ id: prospektusId }); + + console.log("res:", response) + + if (response) { + setPdfPages(response.pages as any); + setLoading(false); + } + } catch (err) { + console.error("Error fetching PDF:", err); + setError(err instanceof Error ? err.message : "Unknown error occurred"); + setLoading(false); + } + }; + + fetchPdfData(); + }, [prospektusId]); -export function Investasi_UiFileViewProspektus({ - pospektusId, -}: { - pospektusId: string; -}) { return ( <> } />} - > - - } /> + } + > + + {loading ? ( + + ) : error ? ( + + + + + ) : ( +
+ {pdfPages?.map((page, index) => ( + {`Page + ))} +
+ )}
diff --git a/src/app_modules/katalog/portofolio/component/button_more_new.tsx b/src/app_modules/katalog/portofolio/component/button_more_new.tsx index 33b325bc..dd641880 100644 --- a/src/app_modules/katalog/portofolio/component/button_more_new.tsx +++ b/src/app_modules/katalog/portofolio/component/button_more_new.tsx @@ -118,18 +118,13 @@ export default function ComponentPortofolio_ButtonMoreNew({ return ( <> - { - userLoginId === authorId && ( - setOpenDrawer(true)}> - - - ) - // : ( - // - // - // - // ) - } + {userLoginId === authorId ? ( + setOpenDrawer(true)}> + + + ) : ( + + )} `/dev/investasi/main/portofolio/${id}`, + portofolio: ({ id }: { id: "1" | "2" | "3" | "4" }) => + `/dev/investasi/main/portofolio/${id}`, // portofolio: ({ id }: { id?: string }) => `/dev/investasi/main/portofolio/${id}`, // TRANSAKSI @@ -24,6 +25,8 @@ export const NEW_RouterInvestasi = { // FILE VIEW file_prospektus: ({ id }: { id: string }) => `/dev/investasi/file-view/prospektus/${id}`, + file_dokumen: ({ id }: { id: string }) => + `/dev/investasi/file-view/dokumen/${id}`, OLD_file_view_prospektus: "/dev/investasi/file-view/prospektus/", OLD_file_view_dokumen: "/dev/investasi/file-view/dokumen/", diff --git a/x-example-show-pdf/index.html b/x-example-show-pdf/index.html index 23e750a9..3aeee7f1 100644 --- a/x-example-show-pdf/index.html +++ b/x-example-show-pdf/index.html @@ -20,7 +20,7 @@ const token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiY20wdXIxeXh3MDAwMDU2bnNqbHI2MTg3cCIsIm5hbWUiOiJiYWdhcyIsImVtYWlsIjoiYmFnYXNAZ21haWwuY29tIn0sImlhdCI6MTcyNTg3MTAzNiwiZXhwIjo0ODgxNjMxMDM2fQ.wFQLcrJj66wFeqIMYk2esMx3ULaHK6RFxkiToaLCuko"; const res = await fetch( - "https://wibu-storage.wibudev.com/api/pdf-to-image?url=https://wibu-storage.wibudev.com/api/files/cm5jgzg7d001dxpugxseb2ua0", + "https://wibu-storage.wibudev.com/api/pdf-to-image?url=https://wibu-storage.wibudev.com/api/files/cm7liew81000t3y8ax1v6yo02", { method: "GET", headers: { From f0a5b2df8bd817da81da66ad61a8067c9e1b0ea0 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Wed, 26 Feb 2025 14:50:04 +0800 Subject: [PATCH 2/7] chore(release): 1.2.64 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3791091..76edd004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. +## [1.2.64](https://github.com/bipproduction/hipmi/compare/v1.2.63...v1.2.64) (2025-02-26) + ## [1.2.63](https://github.com/bipproduction/hipmi/compare/v1.2.62...v1.2.63) (2025-02-26) ## [1.2.62](https://github.com/bipproduction/hipmi/compare/v1.2.61...v1.2.62) (2025-02-25) diff --git a/package.json b/package.json index c6651c3e..eda61859 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hipmi", - "version": "1.2.63", + "version": "1.2.64", "private": true, "type": "module", "prisma": { From bc9b68f5201ab5b15a9b8c834e7cf92a3586ecf9 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Thu, 27 Feb 2025 03:47:14 +0800 Subject: [PATCH 3/7] fix investasi: - beranda progress - admin publish and reject button --- ...2026a78b8cb786880c7c733460d7dbe-audit.json | 10 +- ...c6075347623def466341a14f8ba4a12-audit.json | 10 +- .../admin/investasi/konfirmasi/[id]/page.tsx | 7 +- src/app/dev/investasi/main/page.tsx | 3 - src/app/zCoba/pdf/_view.tsx | 46 ++++ src/app/zCoba/pdf/page.tsx | 13 + .../_global/lib/api_fetch_global.ts | 7 +- .../investasi/_component/ui_detail_file.tsx | 5 +- .../admin/investasi/detail/detail_review.tsx | 179 +++++++------- src/app_modules/crowd/main/view.tsx | 8 +- .../_component/main/com_card_beranda_new.tsx | 224 ++++++++++-------- .../_ui/file_view/ui_file_view_dokumen.tsx | 124 +++++++--- .../_ui/file_view/ui_file_view_prospektus.tsx | 57 ++++- .../investasi/_view/main/view_beranda_new.tsx | 9 +- 14 files changed, 443 insertions(+), 259 deletions(-) create mode 100644 src/app/zCoba/pdf/_view.tsx create mode 100644 src/app/zCoba/pdf/page.tsx diff --git a/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json b/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json index aea69c9f..b3f493a3 100644 --- a/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json +++ b/logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json @@ -5,11 +5,6 @@ }, "auditLog": "logs/backend/.31d2357fa2026a78b8cb786880c7c733460d7dbe-audit.json", "files": [ - { - "date": 1739327386336, - "name": "logs/backend/combined-2025-02-12.log", - "hash": "e37b3d0427223c278c22797248e12d501c266188b48b4edee0591037415ce990" - }, { "date": 1739413125862, "name": "logs/backend/combined-2025-02-13.log", @@ -64,6 +59,11 @@ "date": 1740536165848, "name": "logs/backend/combined-2025-02-26.log", "hash": "428aedb3a3a248ad2c7069fcb8c6e0d669c23eae0dc3db08914886cce8d2cad9" + }, + { + "date": 1740595120097, + "name": "logs/backend/combined-2025-02-27.log", + "hash": "f6884fe9b12faf0557662daa93ae1d32d64bb6b12714c8be494ce9396a55ae18" } ], "hashType": "sha256" diff --git a/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json b/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json index 8b75d721..98e1702e 100644 --- a/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json +++ b/logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json @@ -5,11 +5,6 @@ }, "auditLog": "logs/backend/.5d9a990e0c6075347623def466341a14f8ba4a12-audit.json", "files": [ - { - "date": 1739327386330, - "name": "logs/backend/error-2025-02-12.log", - "hash": "0d834a4ac0d78d547969ae0e55bc53a760b5a11942ed2efb7a08b50b2a16e7ee" - }, { "date": 1739413125859, "name": "logs/backend/error-2025-02-13.log", @@ -64,6 +59,11 @@ "date": 1740536165843, "name": "logs/backend/error-2025-02-26.log", "hash": "fc1b904017c0517b4aa4138d2edb5dd58474ef723a17cab177d0605026a23c11" + }, + { + "date": 1740595120075, + "name": "logs/backend/error-2025-02-27.log", + "hash": "50f75c53936bf2ca5beb3f48fb5de09dde49fea0792fc3532055fab75aae408f" } ], "hashType": "sha256" diff --git a/src/app/dev/admin/investasi/konfirmasi/[id]/page.tsx b/src/app/dev/admin/investasi/konfirmasi/[id]/page.tsx index 533187e5..b31fb4a0 100644 --- a/src/app/dev/admin/investasi/konfirmasi/[id]/page.tsx +++ b/src/app/dev/admin/investasi/konfirmasi/[id]/page.tsx @@ -1,14 +1,9 @@ import { Admin_KonfirmasiInvestasi } from "@/app_modules/admin/investasi"; -import { adminInvestasi_getOneById } from "@/app_modules/admin/investasi/fun"; export default async function Page() { - // const investasiId = params.id; - // const dataInvestasi = await adminInvestasi_getOneById({investasiId}); - // console.log(dataUser) - return ( <> - + ); } diff --git a/src/app/dev/investasi/main/page.tsx b/src/app/dev/investasi/main/page.tsx index 7951c323..e168b7bb 100644 --- a/src/app/dev/investasi/main/page.tsx +++ b/src/app/dev/investasi/main/page.tsx @@ -1,11 +1,8 @@ import { Investasi_ViewBerandaNew } from "@/app_modules/investasi/_ui"; export default async function Page() { - // const allData = await investasi_funGetAllPublish({ page: 1 }); - return ( <> - {/* */} ); diff --git a/src/app/zCoba/pdf/_view.tsx b/src/app/zCoba/pdf/_view.tsx new file mode 100644 index 00000000..fc7378ef --- /dev/null +++ b/src/app/zCoba/pdf/_view.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { Button } from "@mantine/core"; + +interface DownloadButtonProps { + fileUrl: string; + fileName: string; +} + +export default function Coba() { + const fileUrl = + "https://wibu-storage.wibudev.com/api/pdf-to-image?url=https://wibu-storage.wibudev.com/api/files/cm7liew81000t3y8ax1v6yo02"; + const fileName = "example.pdf"; // Nama file yang akan diunduh + + return ( +
+

Download File Example

+ +
+ ); +} + +export function DownloadButton({ fileUrl, fileName }: DownloadButtonProps) { + const handleDownloadFromAPI = async () => { + try { + const response = await fetch("https://wibu-storage.wibudev.com/api/files/cm7liew81000t3y8ax1v6yo02") + const blob = await response.blob(); // Konversi respons ke Blob + const url = window.URL.createObjectURL(blob); // Buat URL untuk Blob + const link = document.createElement("a"); + link.href = url; + link.download = "generated-file.pdf"; // Nama file yang akan diunduh + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); // Bersihkan URL + } catch (error) { + console.error("Error downloading file:", error); + } + }; + + return ( + + ); +} diff --git a/src/app/zCoba/pdf/page.tsx b/src/app/zCoba/pdf/page.tsx new file mode 100644 index 00000000..a645fa5d --- /dev/null +++ b/src/app/zCoba/pdf/page.tsx @@ -0,0 +1,13 @@ +import Coba from "./_view"; + + + +async function Page() { + return ( + <> + + + ); +} + +export default Page; diff --git a/src/app_modules/_global/lib/api_fetch_global.ts b/src/app_modules/_global/lib/api_fetch_global.ts index bea0d5b4..c07ee4a6 100644 --- a/src/app_modules/_global/lib/api_fetch_global.ts +++ b/src/app_modules/_global/lib/api_fetch_global.ts @@ -1,6 +1,4 @@ -export { - apiGetPdfToImage, -} +export { apiGetPdfToImage }; export interface PageData { imageUrl: string; @@ -11,7 +9,7 @@ interface PdfResponse { pages: PageData[]; totalPages: number; } -const apiGetPdfToImage = async ({id}: {id: string}) => { +const apiGetPdfToImage = async ({ id }: { id: string }) => { try { // Fetch token from cookie // const { token } = await fetch("/api/get-cookie").then((res) => res.json()); @@ -22,7 +20,6 @@ const apiGetPdfToImage = async ({id}: {id: string}) => { const token = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7ImlkIjoiY20wdXIxeXh3MDAwMDU2bnNqbHI2MTg3cCIsIm5hbWUiOiJiYWdhcyIsImVtYWlsIjoiYmFnYXNAZ21haWwuY29tIn0sImlhdCI6MTcyNTg3MTAzNiwiZXhwIjo0ODgxNjMxMDM2fQ.wFQLcrJj66wFeqIMYk2esMx3ULaHK6RFxkiToaLCuko"; - // Anda bisa menggunakan prospektusId di URL jika diperlukan const pdfUrl = `https://wibu-storage.wibudev.com/api/pdf-to-image?url=https://wibu-storage.wibudev.com/api/files/${id}`; diff --git a/src/app_modules/admin/investasi/_component/ui_detail_file.tsx b/src/app_modules/admin/investasi/_component/ui_detail_file.tsx index f0780e28..b9727556 100644 --- a/src/app_modules/admin/investasi/_component/ui_detail_file.tsx +++ b/src/app_modules/admin/investasi/_component/ui_detail_file.tsx @@ -11,6 +11,7 @@ import { Group, Button, Text, + Box, } from "@mantine/core"; import { IconFileTypePdf } from "@tabler/icons-react"; import _ from "lodash"; @@ -73,7 +74,7 @@ export function ComponentAdminInvestasi_UIDetailFile({ - ) : ( listDokumen.map((e: MODEL_INVESTASI_DOKUMEN) => ( - + {e.title} @@ -84,7 +85,7 @@ export function ComponentAdminInvestasi_UIDetailFile({ - + )) )} diff --git a/src/app_modules/admin/investasi/detail/detail_review.tsx b/src/app_modules/admin/investasi/detail/detail_review.tsx index df0992c3..e73ac196 100644 --- a/src/app_modules/admin/investasi/detail/detail_review.tsx +++ b/src/app_modules/admin/investasi/detail/detail_review.tsx @@ -1,10 +1,10 @@ "use client"; -import { IRealtimeData } from "@/lib/global_state"; import { MainColor } from "@/app_modules/_global/color"; import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface"; -import getOneInvestasiById from "@/app_modules/investasi/fun/get_one_investasi_by_id"; -import { Button, Group, SimpleGrid, Stack, Loader } from "@mantine/core"; +import { IRealtimeData } from "@/lib/global_state"; +import { clientLogger } from "@/util/clientLogger"; +import { Button, Group, SimpleGrid, Stack } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import _ from "lodash"; import { useParams, useRouter } from "next/navigation"; @@ -20,12 +20,11 @@ import adminNotifikasi_funCreateToUser from "../../notifikasi/fun/create/fun_cre import { ComponentAdminInvestasi_DetailDataAuthor } from "../_component/detail_data_author"; import { ComponentAdminInvestasi_DetailData } from "../_component/detail_data_investasi"; import { ComponentAdminInvestasi_DetailGambar } from "../_component/detail_gambar_investasi"; +import SkeletonAdminInvestasi from "../_component/skeleton_admin_investasi"; import { ComponentAdminInvestasi_UIDetailFile } from "../_component/ui_detail_file"; +import { apiGetAdminInvestasiById } from "../_lib/api_fetch_admin_investasi"; import { adminInvestasi_funEditStatusPublishById } from "../fun/edit/fun_status_publish_by_id"; import Admin_funRejectInvestasi from "../fun/fun_reject_investasi"; -import { clientLogger } from "@/util/clientLogger"; -import { apiGetAdminInvestasiById } from "../_lib/api_fetch_admin_investasi"; -import SkeletonAdminInvestasi from "../_component/skeleton_admin_investasi"; export default function AdminInvestasi_DetailReview() { const params = useParams<{ id: string }>(); @@ -45,19 +44,19 @@ export default function AdminInvestasi_DetailReview() { }, []); const loadInitialData = async () => { - try { - const response = await apiGetAdminInvestasiById({ - id: params.id, - }) + try { + const response = await apiGetAdminInvestasiById({ + id: params.id, + }); - if (response?.success && response?.data) { - setData(response.data); + if (response?.success && response?.data) { + setData(response.data); + } + } catch (error) { + clientLogger.error("Invalid data format recieved:", error); + setData(null); } - } catch (error) { - clientLogger.error("Invalid data format recieved:", error); - setData(null); - } -} + }; async function cekStatusPublish() { if (data?.MasterStatusInvestasi.id === "3") setPublish(false); @@ -72,98 +71,106 @@ export default function AdminInvestasi_DetailReview() { if (_.isEmpty(body.catatan)) return ComponentAdminGlobal_NotifikasiPeringatan("Lengkapi alasan"); - const res = await Admin_funRejectInvestasi(body); - if (res.status === 200) { + try { setIsLoadingReject(true); + const res = await Admin_funRejectInvestasi(body); + if (res.status === 200) { + const dataNotifikasi: IRealtimeData = { + appId: res.data?.id as string, + userId: res.data?.authorId as string, + pesan: res.data?.title as string, + status: res.data?.MasterStatusInvestasi?.name as any, + kategoriApp: "INVESTASI", + title: "Investasi anda di tolak !", + }; - const dataNotifikasi: IRealtimeData = { - appId: res.data?.id as string, - userId: res.data?.authorId as string, - pesan: res.data?.title as string, - status: res.data?.MasterStatusInvestasi?.name as any, - kategoriApp: "INVESTASI", - title: "Investasi anda di tolak !", - }; - - const notif = await adminNotifikasi_funCreateToUser({ - data: dataNotifikasi as any, - }); - - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, + const notif = await adminNotifikasi_funCreateToUser({ + data: dataNotifikasi as any, }); + + if (notif.status === 201) { + WibuRealtime.setData({ + type: "notification", + pushNotificationTo: "USER", + dataMessage: dataNotifikasi, + }); + } + + ComponentAdminGlobal_NotifikasiBerhasil(res.message); + router.back(); + setOpenModalReject(false); + setIsLoadingReject(false); + } else { + ComponentAdminGlobal_NotifikasiGagal(res.message); + setOpenModalReject(false); + setIsLoadingReject(false); } - - // const loadData = await getOneInvestasiById(data?.id); - // setData(loadData as any); - - ComponentAdminGlobal_NotifikasiBerhasil(res.message); - router.back(); + } catch (error) { + console.log(error); setOpenModalReject(false); setIsLoadingReject(false); - } else { - ComponentAdminGlobal_NotifikasiGagal(res.message); - setOpenModalReject(false); } } async function onPublish() { - const res = await adminInvestasi_funEditStatusPublishById({ - investasiId: data?.id as any, - statusId: "1", - progesInvestasiId: "1", - }); - if (res.status === 200) { + try { setIsLoadingPublish(true); - const dataNotifikasi: IRealtimeData = { - appId: res.data?.id as string, - userId: res.data?.authorId as any, - pesan: res.data?.title as any, - status: res.data?.MasterStatusInvestasi?.name as any, - kategoriApp: "INVESTASI", - title: "Investasi publish", - }; - - const notif = await adminNotifikasi_funCreateToUser({ - data: dataNotifikasi as any, + const res = await adminInvestasi_funEditStatusPublishById({ + investasiId: data?.id as any, + statusId: "1", + progesInvestasiId: "1", }); + if (res.status === 200) { + const dataNotifikasi: IRealtimeData = { + appId: res.data?.id as string, + userId: res.data?.authorId as any, + pesan: res.data?.title as any, + status: res.data?.MasterStatusInvestasi?.name as any, + kategoriApp: "INVESTASI", + title: "Investasi publish", + }; - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, + const notif = await adminNotifikasi_funCreateToUser({ + data: dataNotifikasi as any, }); - WibuRealtime.setData({ - type: "trigger", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, - }); + if (notif.status === 201) { + WibuRealtime.setData({ + type: "notification", + pushNotificationTo: "USER", + dataMessage: dataNotifikasi, + }); - const loadData = await getOneInvestasiById(data?.id as any); - setData(loadData as any); + WibuRealtime.setData({ + type: "trigger", + pushNotificationTo: "USER", + dataMessage: dataNotifikasi, + }); - ComponentAdminGlobal_NotifikasiBerhasil("Proyek Investasi Di Publish"); + ComponentAdminGlobal_NotifikasiBerhasil( + "Proyek Investasi Di Publish" + ); + setOpenModalPublish(false); + setIsLoadingPublish(false); + router.back(); + // router.push(RouterAdminInvestasi_OLD.table_status_review); + } + } else { + ComponentAdminGlobal_NotifikasiGagal(res.message); setOpenModalPublish(false); setIsLoadingPublish(false); - router.back(); - // router.push(RouterAdminInvestasi_OLD.table_status_review); } - } else { - ComponentAdminGlobal_NotifikasiGagal(res.message); + } catch (error) { + console.log(error); setOpenModalPublish(false); + setIsLoadingPublish(false); } } if (!data) { - return + return ; } - return ( <> @@ -173,8 +180,6 @@ export default function AdminInvestasi_DetailReview() { {data?.masterStatusInvestasiId === "2" ? ( - )} - - - - - {/* Upload File */} - - - - {!filePdf ? ( - - Upload File Prospektus - - ) : ( - - - - - {filePdf.name} - - - -
- -
-
-
- )} -
- - - { - try { - const buffer = URL.createObjectURL( - new Blob([new Uint8Array(await files.arrayBuffer())]) - ); - setFPdf(buffer); - setFilePdf(files); - } catch (error) { - console.log(error); - } - }} - > - {(props) => ( - - )} - - -
- - - { - setValue({ - ...value, - title: val.target.value, - }); - }} - /> - - Rp.} - min={0} - withAsterisk - label="Dana Dibutuhkan" - placeholder="0" - value={target} - onChange={(val) => { - // console.log(typeof val) - const match = val.currentTarget.value - .replace(/\./g, "") - .match(/^[0-9]+$/); - - if (val.currentTarget.value === "") return setTarget(0 + ""); - if (!match?.[0]) return null; - - const nilai = val.currentTarget.value.replace(/\./g, ""); - const targetNilai = Intl.NumberFormat("id-ID").format(+nilai); - - onTotalLembar({ - target: +nilai, - harga: +value.hargaLembar, - }); - - setTarget(targetNilai); - setValue({ - ...value, - targetDana: +nilai, - }); - }} - /> - - Rp.} - min={0} - withAsterisk - label="Harga Per Lembar" - placeholder="0" - value={harga} - onChange={(val) => { - try { - // console.log(typeof +val.currentTarget.value); - - const match = val.currentTarget.value - .replace(/\./g, "") - .match(/^[0-9]+$/); - - if (val.currentTarget.value === "") return setHarga(0 + ""); - - if (!match?.[0]) return null; - - const nilai = val.currentTarget.value.replace(/\./g, ""); - const targetNilai = Intl.NumberFormat("id-ID").format(+nilai); - - onTotalLembar({ - harga: +nilai, - target: +value.targetDana, - }); - - setHarga(targetNilai); - setValue({ - ...value, - hargaLembar: +nilai, - }); - } catch (error) { - console.log(error); - } - }} - /> - - - - - % - - } - withAsterisk - type="number" - label={"Rasio Keuntungan / ROI %"} - placeholder="Masukan rasio keuntungan" - onChange={(val) => { - setValue({ - ...value, - roi: _.toNumber(val.target.value), - }); - }} - /> - - ({ value: e.id, label: e.name }))} - onChange={(val) => { - setValue({ - ...(value as any), - periodeDevidenId: val, - }); - }} - /> - -