feat: input field saiz font No IC dalam konfigurasi template
- 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>
This commit is contained in:
@@ -55,6 +55,7 @@ class CertificateTemplateController extends Controller
|
|||||||
'fields.*.x' => 'required|integer|min:0',
|
'fields.*.x' => 'required|integer|min:0',
|
||||||
'fields.*.y' => 'required|integer|min:0',
|
'fields.*.y' => 'required|integer|min:0',
|
||||||
'fields.*.font_size' => 'required|integer|min:8|max:200',
|
'fields.*.font_size' => 'required|integer|min:8|max:200',
|
||||||
|
'fields.*.ic_font_size' => 'nullable|integer|min:8|max:200',
|
||||||
'fields.*.font_color' => 'required|string|max:20',
|
'fields.*.font_color' => 'required|string|max:20',
|
||||||
'fields.*.align' => 'required|in:left,center,right',
|
'fields.*.align' => 'required|in:left,center,right',
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -90,13 +90,14 @@ class CertificateService
|
|||||||
return $image->encode(new JpegEncoder(85))->toString();
|
return $image->encode(new JpegEncoder(85))->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tulis IC di bawah nama — auto-posisi, font 50% nama
|
// Tulis IC di bawah nama — auto-posisi Y, saiz font dari config atau fallback 70%
|
||||||
private function writeIcBelow(\Intervention\Image\Interfaces\ImageInterface $image, string $ic, array $nameCfg): void
|
private function writeIcBelow(\Intervention\Image\Interfaces\ImageInterface $image, string $ic, array $nameCfg): void
|
||||||
{
|
{
|
||||||
$nameFontSize = (int) ($nameCfg['font_size'] ?? 48);
|
$nameFontSize = (int) ($nameCfg['font_size'] ?? 48);
|
||||||
$icFontSize = (int) round($nameFontSize * 0.5);
|
$icFontSize = isset($nameCfg['ic_font_size']) && (int) $nameCfg['ic_font_size'] > 0
|
||||||
|
? (int) $nameCfg['ic_font_size']
|
||||||
|
: (int) round($nameFontSize * 0.7);
|
||||||
|
|
||||||
// Y offset: line height nama (1.4×) + sedikit jarak
|
|
||||||
$icY = (int) ($nameCfg['y'] ?? 0) + (int) round($nameFontSize * 1.5);
|
$icY = (int) ($nameCfg['y'] ?? 0) + (int) round($nameFontSize * 1.5);
|
||||||
|
|
||||||
$this->writeText($image, $ic, array_merge($nameCfg, [
|
$this->writeText($image, $ic, array_merge($nameCfg, [
|
||||||
|
|||||||
@@ -175,6 +175,12 @@
|
|||||||
class="form-control form-control-color form-control-sm"
|
class="form-control form-control-color form-control-sm"
|
||||||
value="{{ $fields['name']['font_color'] ?? '#1a3a6b' }}">
|
value="{{ $fields['name']['font_color'] ?? '#1a3a6b' }}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<label class="form-label small">Saiz Font No IC</label>
|
||||||
|
<input type="number" name="fields[name][ic_font_size]"
|
||||||
|
class="form-control form-control-sm" min="8" max="200"
|
||||||
|
value="{{ $fields['name']['ic_font_size'] ?? (int) round(($fields['name']['font_size'] ?? 52) * 0.7) }}">
|
||||||
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label class="form-label small">Align</label>
|
<label class="form-label small">Align</label>
|
||||||
<select name="fields[name][align]" class="form-select form-select-sm">
|
<select name="fields[name][align]" class="form-select form-select-sm">
|
||||||
@@ -374,11 +380,12 @@ function loadPreview() {
|
|||||||
|
|
||||||
// Hantar nilai form semasa — preview guna koordinat terkini walaupun belum simpan
|
// Hantar nilai form semasa — preview guna koordinat terkini walaupun belum simpan
|
||||||
const read = (sel) => document.querySelector(sel)?.value ?? '';
|
const read = (sel) => document.querySelector(sel)?.value ?? '';
|
||||||
fd.append('fields[name][x]', read('[name="fields[name][x]"]'));
|
fd.append('fields[name][x]', read('[name="fields[name][x]"]'));
|
||||||
fd.append('fields[name][y]', read('[name="fields[name][y]"]'));
|
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_size]', read('[name="fields[name][font_size]"]'));
|
||||||
fd.append('fields[name][font_color]', read('[name="fields[name][font_color]"]'));
|
fd.append('fields[name][font_color]', read('[name="fields[name][font_color]"]'));
|
||||||
fd.append('fields[name][align]', read('[name="fields[name][align]"]'));
|
fd.append('fields[name][ic_font_size]', read('[name="fields[name][ic_font_size]"]'));
|
||||||
|
fd.append('fields[name][align]', read('[name="fields[name][align]"]'));
|
||||||
|
|
||||||
// Sertakan No. Sijil hanya jika toggle aktif
|
// Sertakan No. Sijil hanya jika toggle aktif
|
||||||
if (document.getElementById('showCertNo')?.checked) {
|
if (document.getElementById('showCertNo')?.checked) {
|
||||||
|
|||||||
Reference in New Issue
Block a user