- Tambah fields[name][ic_font_size] dalam form — baris: Warna | Saiz Font No IC | Align
- Default: 70% daripada saiz font nama (sebelum ini hardcode 50%)
- loadPreview() hantar ic_font_size terkini ke endpoint pratonton
- writeIcBelow() baca ic_font_size dari config, fallback 70% jika tiada
- Validasi updateConfig: ic_font_size nullable|integer|min:8|max:200
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- loadPreview() hantar semua nilai field (X, Y, font_size, color, align) ke endpoint
- certificate_no disertakan hanya jika toggle showCertNo aktif
- testGenerate() bina liveFields dari request, gabung dengan config tersimpan
(supaya font_file & valign kekal dari config asal)
- generatePreview() terima overrideFields optional — preview sentiasa refresh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Panduan Template di bahagian atas, boleh lipat/kembang
- Template Aktif (kiri) bersebelahan Konfigurasi Teks (kanan) — col-lg-6
- Auto-detect portrait/landscape dari naturalWidth/naturalHeight imej
- Portrait: max-height 520px | Landscape: max-height 340px
- Badge orientasi (hijau=Landscape, biru=Portrait) dalam header kad
- Laras tinggi juga untuk pratonton upload form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Tab QR: Storage::disk('public')->url() — selaras dengan fix QrCodeService
- Tab Template: guna route preview (controller baca dari private disk)
Storage::url() tanpa disk pada private storage tidak boleh diakses terus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Storage::put() guna default disk (local/private) menyebabkan fail disimpan
di storage/app/private/public/qrcodes/ tapi URL /storage/qrcodes/... cari
fail di storage/app/public/qrcodes/ melalui symlink — lokasi berbeza.
- QrCodeService: guna disk('public'), path ringkas 'qrcodes/{token}.png'
- View: Storage::disk('public')->url() untuk URL yang betul
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>