From d597bf45fb2c5133efa2b2d6830a86f25273354e Mon Sep 17 00:00:00 2001 From: Saufi Date: Mon, 18 May 2026 21:46:21 +0800 Subject: [PATCH] fix: pratonton guna koordinat form semasa, No. Sijil ikut toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .../Admin/CertificateTemplateController.php | 13 +++++++++- app/Services/CertificateService.php | 9 +++---- .../admin/programs/template/show.blade.php | 25 ++++++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Admin/CertificateTemplateController.php b/app/Http/Controllers/Admin/CertificateTemplateController.php index d730f47..8e78c00 100644 --- a/app/Http/Controllers/Admin/CertificateTemplateController.php +++ b/app/Http/Controllers/Admin/CertificateTemplateController.php @@ -102,8 +102,19 @@ class CertificateTemplateController extends Controller $sampleName = $request->input('sample_name', 'NAMA PESERTA CONTOH'); $sampleNo = $request->input('sample_no', 'ECT/2025/0001'); + // Bina override dari nilai form semasa (belum disimpan) + // Gabung dengan config tersimpan supaya font_file & valign kekal + $liveFields = null; + if ($request->has('fields') && is_array($request->input('fields'))) { + $saved = $template->config_json['fields'] ?? []; + $liveFields = []; + foreach ($request->input('fields') as $key => $cfg) { + $liveFields[$key] = array_merge($saved[$key] ?? [], array_filter($cfg, fn($v) => $v !== null && $v !== '')); + } + } + try { - $imageData = $service->generatePreview($template, $sampleName, $sampleNo); + $imageData = $service->generatePreview($template, $sampleName, $sampleNo, $liveFields); } catch (\Throwable $e) { return response()->json(['error' => $e->getMessage()], 500); } diff --git a/app/Services/CertificateService.php b/app/Services/CertificateService.php index af5af60..35037cb 100644 --- a/app/Services/CertificateService.php +++ b/app/Services/CertificateService.php @@ -71,19 +71,18 @@ class CertificateService } } - public function generatePreview(CertificateTemplate $template, string $sampleName, string $sampleNo = ''): string + public function generatePreview(CertificateTemplate $template, string $sampleName, string $sampleNo = '', ?array $overrideFields = null): string { $templatePath = Storage::disk('local')->path($template->image_path); $image = $this->manager->decodePath($templatePath); - $config = $template->config_json ?? []; - $fields = $config['fields'] ?? []; + $fields = $overrideFields ?? ($template->config_json['fields'] ?? []); if (isset($fields['name'])) { $this->writeText($image, $sampleName, $fields['name']); } - if (isset($fields['certificate_no']) && $sampleNo) { - $this->writeText($image, $sampleNo, $fields['certificate_no']); + if (isset($fields['certificate_no'])) { + $this->writeText($image, $sampleNo ?: 'ECT/2025/0001', $fields['certificate_no']); } return $image->encode(new JpegEncoder(85))->toString(); diff --git a/resources/views/admin/programs/template/show.blade.php b/resources/views/admin/programs/template/show.blade.php index c86ad57..79fe93b 100644 --- a/resources/views/admin/programs/template/show.blade.php +++ b/resources/views/admin/programs/template/show.blade.php @@ -368,11 +368,28 @@ function loadPreview() { btn.disabled = true; btn.innerHTML = ' Memuatkan...'; - const form = new FormData(); - form.append('_token', '{{ csrf_token() }}'); - form.append('sample_name', name); + const fd = new FormData(); + fd.append('_token', '{{ csrf_token() }}'); + fd.append('sample_name', name); - fetch(url, { method: 'POST', body: form }) + // Hantar nilai form semasa — preview guna koordinat terkini walaupun belum simpan + const read = (sel) => document.querySelector(sel)?.value ?? ''; + fd.append('fields[name][x]', read('[name="fields[name][x]"]')); + fd.append('fields[name][y]', read('[name="fields[name][y]"]')); + fd.append('fields[name][font_size]', read('[name="fields[name][font_size]"]')); + fd.append('fields[name][font_color]', read('[name="fields[name][font_color]"]')); + fd.append('fields[name][align]', read('[name="fields[name][align]"]')); + + // Sertakan No. Sijil hanya jika toggle aktif + if (document.getElementById('showCertNo')?.checked) { + fd.append('fields[certificate_no][x]', read('[name="fields[certificate_no][x]"]')); + fd.append('fields[certificate_no][y]', read('[name="fields[certificate_no][y]"]')); + fd.append('fields[certificate_no][font_size]', read('[name="fields[certificate_no][font_size]"]')); + fd.append('fields[certificate_no][font_color]', read('[name="fields[certificate_no][font_color]"]')); + fd.append('fields[certificate_no][align]', read('[name="fields[certificate_no][align]"]')); + } + + fetch(url, { method: 'POST', body: fd }) .then(r => { if (!r.ok) return r.json().then(j => { throw new Error(j.error || 'Ralat pelayan (' + r.status + ')'); }); return r.blob();