fix: pratonton guna koordinat form semasa, No. Sijil ikut toggle
- 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>
This commit is contained in:
@@ -102,8 +102,19 @@ class CertificateTemplateController extends Controller
|
|||||||
$sampleName = $request->input('sample_name', 'NAMA PESERTA CONTOH');
|
$sampleName = $request->input('sample_name', 'NAMA PESERTA CONTOH');
|
||||||
$sampleNo = $request->input('sample_no', 'ECT/2025/0001');
|
$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 {
|
try {
|
||||||
$imageData = $service->generatePreview($template, $sampleName, $sampleNo);
|
$imageData = $service->generatePreview($template, $sampleName, $sampleNo, $liveFields);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return response()->json(['error' => $e->getMessage()], 500);
|
return response()->json(['error' => $e->getMessage()], 500);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
$templatePath = Storage::disk('local')->path($template->image_path);
|
||||||
$image = $this->manager->decodePath($templatePath);
|
$image = $this->manager->decodePath($templatePath);
|
||||||
$config = $template->config_json ?? [];
|
$fields = $overrideFields ?? ($template->config_json['fields'] ?? []);
|
||||||
$fields = $config['fields'] ?? [];
|
|
||||||
|
|
||||||
if (isset($fields['name'])) {
|
if (isset($fields['name'])) {
|
||||||
$this->writeText($image, $sampleName, $fields['name']);
|
$this->writeText($image, $sampleName, $fields['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($fields['certificate_no']) && $sampleNo) {
|
if (isset($fields['certificate_no'])) {
|
||||||
$this->writeText($image, $sampleNo, $fields['certificate_no']);
|
$this->writeText($image, $sampleNo ?: 'ECT/2025/0001', $fields['certificate_no']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image->encode(new JpegEncoder(85))->toString();
|
return $image->encode(new JpegEncoder(85))->toString();
|
||||||
|
|||||||
@@ -368,11 +368,28 @@ function loadPreview() {
|
|||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status"></span> Memuatkan...';
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status"></span> Memuatkan...';
|
||||||
|
|
||||||
const form = new FormData();
|
const fd = new FormData();
|
||||||
form.append('_token', '{{ csrf_token() }}');
|
fd.append('_token', '{{ csrf_token() }}');
|
||||||
form.append('sample_name', name);
|
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 => {
|
.then(r => {
|
||||||
if (!r.ok) return r.json().then(j => { throw new Error(j.error || 'Ralat pelayan (' + r.status + ')'); });
|
if (!r.ok) return r.json().then(j => { throw new Error(j.error || 'Ralat pelayan (' + r.status + ')'); });
|
||||||
return r.blob();
|
return r.blob();
|
||||||
|
|||||||
Reference in New Issue
Block a user