DONE: fix error where image not showing on digital card, generate letter not working on prod

This commit is contained in:
ISMAIL MASSERAN
2026-07-06 13:24:15 +08:00
parent d06c4701a4
commit 1f62c9dd25
7 changed files with 81 additions and 18 deletions
+3 -3
View File
@@ -18,8 +18,8 @@
## Present to Boss (2/7/2026)
[x] discuss logo baru MyKOPKB
[x] layout footer untuk surat rasmi
[ ] maklumat pekerjaan kena buat dropdown untuk nama majikan
[ ] tambah minima untuk borang permohonan (tukar jadi caruman saham potongan bulanan)
[x] maklumat pekerjaan kena buat dropdown untuk nama majikan
[x] tambah minima untuk borang permohonan (tukar jadi caruman saham potongan bulanan)
[x] tukar waris ke penama
[x] ic dan surat pengesahan majikkan perlu mandatori
[ ] semakan lembaga tukar jadi maklumat keputusan
@@ -27,5 +27,5 @@
[x] surat attach dekat email selepas bos
[ ] pembayaran pertama tukar jadi one-off
[ ] syer maksima silap tukar jadi rm50.00
[ ] letak sign digital
[x] letak sign digital
[x] running no anggota dalam surat dan masa.
+4 -3
View File
@@ -67,11 +67,12 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
# Browsershot (PDF generation via headless Chrome + Puppeteer in be/)
# Required in Docker/Sail. After first sail up: sail npm install && sail npx puppeteer browsers install chrome-headless-shell
# Local/Sail: sail npm install && sail npx puppeteer browsers install chrome-headless-shell
# Production Docker image bundles Node + Puppeteer; keep NO_SANDBOX enabled in containers.
BROWSERSHOT_NO_SANDBOX=true
# BROWSERSHOT_NODE_BINARY=
# BROWSERSHOT_NODE_BINARY=/usr/local/bin/node
# BROWSERSHOT_NPM_BINARY=
# BROWSERSHOT_NODE_MODULE_PATH=
# BROWSERSHOT_NODE_MODULE_PATH=/var/www
# BROWSERSHOT_CHROME_PATH=
# BROWSERSHOT_TIMEOUT=60
+2 -1
View File
@@ -105,4 +105,5 @@ API_VALID_KEYS=86f58825e5c1e0872d8786092d47e3bd,6461fc5390660c55dc47bdfcd85ed9ae
API_LOG_KEY_USAGE=true
PUBLIC_PROFILE_TOKEN_TTL_DAYS=7
FRONTEND_URL=https://mykopkb.koppkb.com
FRONTEND_URL=https://mykopkb.koppkb.com
BROWSERSHOT_NO_SANDBOX=true
+1 -1
View File
@@ -124,6 +124,6 @@ return [
|
*/
'logo_path' => public_path('images/logo/logo.svg'),
'logo_path' => public_path('images/logo/logo.png'),
];
+54 -1
View File
@@ -46,6 +46,19 @@ COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
RUN composer install --no-dev --optimize-autoloader --no-interaction --no-progress --prefer-dist --no-scripts \
&& rm -rf bootstrap/cache/services.php bootstrap/cache/packages.php
# Stage 1b: Node + Puppeteer for Browsershot PDF generation
FROM node:22-bookworm-slim AS node-deps
WORKDIR /var/www
COPY be/package.json be/package-lock.json ./
RUN npm ci --omit=dev
ENV PUPPETEER_CACHE_DIR=/var/www/.cache/puppeteer
RUN npx puppeteer browsers install chrome-headless-shell
# Stage 2: Unified production image with PHP-FPM + Nginx
FROM php:8.4-fpm AS base
@@ -79,6 +92,37 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& docker-php-ext-enable redis \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Chromium runtime libraries for Puppeteer (Browsershot PDF generation)
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libglib2.0-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
libxrender1 \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Download and install php-fpm health check script
RUN curl -o /usr/local/bin/php-fpm-healthcheck \
https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \
@@ -120,11 +164,20 @@ RUN echo '[www]' > /usr/local/etc/php-fpm.d/zzz-status.conf && \
# Copy the application code and dependencies from the build stage first
COPY --from=builder /var/www /var/www
# Node runtime + Puppeteer for Browsershot (letter PDF generation)
COPY --from=node-deps /usr/local/bin/node /usr/local/bin/node
COPY --from=node-deps /var/www/node_modules /var/www/node_modules
COPY --from=node-deps /var/www/.cache/puppeteer /var/www/.cache/puppeteer
ENV PUPPETEER_CACHE_DIR=/var/www/.cache/puppeteer \
BROWSERSHOT_NO_SANDBOX=true \
BROWSERSHOT_NODE_BINARY=/usr/local/bin/node
# Set working directory
WORKDIR /var/www
# Ensure correct permissions
RUN chown -R www-data:www-data /var/www
RUN chown -R www-data:www-data /var/www /var/www/.cache/puppeteer
# Create Nginx log directory
RUN mkdir -p /var/log/nginx && chown -R www-data:www-data /var/log/nginx
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

@@ -14,14 +14,22 @@ export function buildCardDownloadFileName(
export function toProxiedStorageUrl(url: string | null | undefined): string | null | undefined {
if (!url) return url
try {
const parsed = new URL(url, window.location.origin)
if (parsed.pathname.startsWith('/storage/')) {
return `${parsed.pathname}${parsed.search}`
}
} catch {
// Keep original URL when parsing fails.
}
const apiBase = import.meta.env.VITE_API_BASE_URL?.replace(/\/$/, '')
return url
try {
const parsed = new URL(url, apiBase || window.location.origin)
if (!parsed.pathname.startsWith('/storage/')) {
return url
}
// Production serves the SPA from a different host than Laravel storage files.
if (apiBase) {
return `${apiBase}${parsed.pathname}${parsed.search}`
}
// Dev fallback: Vite proxies /storage to the API.
return `${parsed.pathname}${parsed.search}`
} catch {
return url
}
}