348 lines
12 KiB
PHP
348 lines
12 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||
<title>{{ get_phrase('Download Certificate') }}</title>
|
||
<link rel="shortcut icon" href="{{ asset(get_frontend_settings('favicon')) }}" />
|
||
<script src="{{ asset('assets/frontend/default/js/jquery-3.7.1.min.js') }}"></script>
|
||
<script src="{{ asset('assets/global/html2canvas/html2canvas.min.js') }}"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<style>
|
||
html, body{
|
||
overflow-x: hidden;
|
||
}
|
||
body {
|
||
position: relative;
|
||
}
|
||
|
||
.remove-item,
|
||
.ui-resizable-handle {
|
||
display: none !important;
|
||
}
|
||
|
||
.certificate-layout-module {
|
||
left: unset !important;
|
||
top: unset !important;
|
||
margin-left: auto !important;
|
||
margin-right: auto !important;
|
||
}
|
||
|
||
svg {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.certificate-page {
|
||
width: 1123px;
|
||
height: 794px;
|
||
}
|
||
|
||
.download-wrapper {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 20px;
|
||
display: flex;
|
||
gap: 15px;
|
||
z-index: 100;
|
||
}
|
||
|
||
.download-btn {
|
||
padding: 12px 24px;
|
||
border-radius: 8px;
|
||
color: #ffffff;
|
||
background: linear-gradient(135deg, #3d9bff 0%, #0066cc 100%);
|
||
border: none;
|
||
font-weight: 600;
|
||
font-size: 16px;
|
||
text-decoration: none;
|
||
box-shadow: 0 4px 12px rgba(61, 155, 255, 0.3);
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
display: inline-block;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
min-width: 160px;
|
||
}
|
||
|
||
.download-btn.secondary {
|
||
background: linear-gradient(135deg, #6c757d 0%, #495057 100%);
|
||
box-shadow: 0 4px 12px rgba(108, 117, 125, 0.3);
|
||
}
|
||
|
||
.download-btn.secondary:hover {
|
||
background: linear-gradient(135deg, #5a6268 0%, #3d4349 100%);
|
||
box-shadow: 0 6px 16px rgba(108, 117, 125, 0.4);
|
||
}
|
||
|
||
.download-btn:hover {
|
||
background: linear-gradient(135deg, #2d8bef 0%, #0055b3 100%);
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 16px rgba(61, 155, 255, 0.4);
|
||
}
|
||
|
||
.download-btn:active {
|
||
transform: translateY(0);
|
||
box-shadow: 0 2px 8px rgba(61, 155, 255, 0.3);
|
||
}
|
||
|
||
.download-btn:focus {
|
||
outline: 2px solid rgba(61, 155, 255, 0.5);
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
/* Responsive untuk mobile */
|
||
@media (max-width: 768px) {
|
||
.download-btn {
|
||
bottom: 16px;
|
||
right: 16px;
|
||
padding: 10px 20px;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.absolute-view{
|
||
background-color: #e6e6e6;
|
||
position: fixed;
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
overflow-y: auto;
|
||
z-index: 50;
|
||
width: 100%;
|
||
}
|
||
|
||
.certificate_builder_view{
|
||
width: 60%;
|
||
height: auto;
|
||
min-width: 350px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
padding-top: 60px;
|
||
}
|
||
</style>
|
||
|
||
@php
|
||
$bulan_indonesia = [
|
||
1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April',
|
||
5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Agustus',
|
||
9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'
|
||
];
|
||
|
||
$completion_date = $certificate->created_at;
|
||
$timestamp = strtotime($completion_date);
|
||
$hari = date('j', $timestamp);
|
||
$bulan_angka = (int)date('n', $timestamp);
|
||
$tahun = date('Y', $timestamp);
|
||
|
||
$course_completion_date = $hari . ' ' . $bulan_indonesia[$bulan_angka] . ' ' . $tahun;
|
||
$course_duration = $certificate->course->total_duration();
|
||
$student_name = $certificate->user->name;
|
||
$course_title = $certificate->course->title;
|
||
$number_of_lesson = $certificate->course->lessons->count();
|
||
$qr_code = $qrcode;
|
||
$certificate_id = $certificate->identifier;
|
||
$certificate_download_date = date('d M Y');
|
||
$course_level = ucfirst($certificate->course->level);
|
||
$course_language = ucfirst($certificate->course->language);
|
||
|
||
$instructor_name = '';
|
||
foreach ($certificate->course->instructors() as $instructor) {
|
||
$instructor_name .= '<p>' . $instructor->name . '</p>';
|
||
}
|
||
|
||
// --- PERBAIKAN DI SINI (Hapus tanda = yang nyasar) ---
|
||
|
||
$sections = $certificate->course->sections()->orderBy('sort', 'asc')->get();
|
||
|
||
// --- PERBAIKAN NAMA VARIABEL ---
|
||
// Ubah $section_list menjadi $section_list_html agar sesuai dengan pemanggilan di bawah
|
||
$section_list_html = '<ol style="list-style-type: decimal; padding-left: 20px;">';
|
||
foreach ($sections as $section) {
|
||
$section_list_html .= '<li style="margin-bottom: 5px;">' . $section->title . '</li>';
|
||
}
|
||
$section_list_html .= '</ol>';
|
||
|
||
|
||
$certificate_builder_content = get_settings('certificate_builder_content');
|
||
|
||
// Replacements Array (Agar lebih rapi dan bisa dipakai ulang)
|
||
$replacements = [
|
||
'{course_duration}' => $course_duration,
|
||
'{instructor_name}' => $instructor_name,
|
||
'{student_name}' => $student_name,
|
||
'{course_title}' => $course_title,
|
||
'{number_of_lesson}' => $number_of_lesson,
|
||
'{qr_code}' => $qr_code,
|
||
'{course_completion_date}' => $course_completion_date,
|
||
'{certificate_id}' => $certificate_id,
|
||
'{certificate_download_date}' => $certificate_download_date,
|
||
'{course_level}' => $course_level,
|
||
'{course_language}' => $course_language,
|
||
];
|
||
|
||
// Proses Halaman 1
|
||
foreach ($replacements as $key => $value) {
|
||
$certificate_builder_content = str_replace($key, $value, $certificate_builder_content);
|
||
}
|
||
|
||
// Update Image Src Halaman 1
|
||
$newSrc = get_image(get_settings('certificate_template'));
|
||
$certificate_builder_content = preg_replace('/(<img[^>]*class=["\']certificate-template["\'][^>]*src=["\'])([^"\']*)(["\'])/i', '${1}' . $newSrc . '${3}', $certificate_builder_content);
|
||
|
||
|
||
// --- PEMROSESAN HALAMAN TAMBAHAN (DETAILS) ---
|
||
$certificate_builder_content_details = get_settings('certificate_builder_content_details');
|
||
|
||
// Proses Halaman 2
|
||
foreach ($replacements as $key => $value) {
|
||
$certificate_builder_content_details = str_replace($key, $value, $certificate_builder_content_details);
|
||
}
|
||
|
||
// Masukkan Section List (Pastikan variabelnya $section_list_html)
|
||
$certificate_builder_content_details = str_replace('{section_list}', $section_list_html, $certificate_builder_content_details);
|
||
|
||
// Update Image Src Halaman 2
|
||
$newSrcDetails = get_image(get_settings('certificate_template_details'));
|
||
$certificate_builder_content_details = preg_replace('/(<img[^>]*class=["\']certificate-template-details["\'][^>]*src=["\'])([^"\']*)(["\'])/i', '${1}' . $newSrcDetails . '${3}', $certificate_builder_content_details);
|
||
@endphp
|
||
|
||
|
||
{{-- Capture Certificate Wrapper --}}
|
||
<div class="captureCertificate" id="captureCertificate">
|
||
|
||
{{-- Halaman 1 --}}
|
||
<div class="certificate-page page-1">
|
||
{!! $certificate_builder_content !!}
|
||
</div>
|
||
|
||
{{-- Halaman 2 (Baru) --}}
|
||
{{-- Style margin-top hanya visual di web, tidak mempengaruhi PDF split --}}
|
||
<div class="certificate-page page-2" style="margin-top: 50px;">
|
||
{!! $certificate_builder_content_details !!}
|
||
</div>
|
||
|
||
</div>
|
||
{{-- Capture Certificate End --}}
|
||
|
||
|
||
{{-- Preview Certificate --}}
|
||
<div class="absolute-view">
|
||
<div class="certificate_builder_view" id="certificate_builder_view">
|
||
{{-- Tampilkan kedua halaman di preview juga --}}
|
||
<div class="certificate-page">
|
||
{!! $certificate_builder_content !!}
|
||
</div>
|
||
<div class="certificate-page" style="margin-top: 20px;">
|
||
{!! $certificate_builder_content_details !!}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="download-wrapper">
|
||
<!-- <a class="download-btn secondary" href="#"
|
||
onclick="setTimeout(() => renderCanvasToImage(), 500); return false;">
|
||
{{ get_phrase('Download Image') }}
|
||
</a> -->
|
||
|
||
<a class="download-btn" href="#"
|
||
onclick="renderCanvasToPDF(); return false;">
|
||
{{ get_phrase('Download Sertificate') }}
|
||
</a>
|
||
</div>
|
||
|
||
<script>
|
||
"use strict";
|
||
|
||
$(function() {
|
||
// Skrip zoom diperbaiki agar berlaku untuk semua halaman sertifikat
|
||
var certificate_builder_view_width = $('.certificate_builder_view').width();
|
||
|
||
// Ambil modul layout pertama untuk perhitungan rasio
|
||
var certificate_layout_module = $('.certificate_builder_view .certificate-layout-module').first().width();
|
||
|
||
if(certificate_layout_module > 0) {
|
||
var zoomScaleValue = ((certificate_builder_view_width / certificate_layout_module) * 100) - 8;
|
||
// Terapkan zoom ke SEMUA layout module
|
||
$('.certificate_builder_view .certificate-layout-module').css('zoom', zoomScaleValue + '%');
|
||
}
|
||
});
|
||
|
||
// Fungsi Gambar (Download PNG) - Hanya mengambil halaman pertama atau gabungan (opsional)
|
||
// Disarankan default mengambil halaman utama saja untuk PNG, atau biarkan custom
|
||
function renderCanvasToImage() {
|
||
// Mengambil elemen halaman pertama saja untuk PNG thumbnail
|
||
var elementToCapture = document.querySelector("#captureCertificate .page-1");
|
||
var certificate_width = $(elementToCapture).width();
|
||
|
||
html2canvas(elementToCapture, {
|
||
allowTaint: true,
|
||
useCORS: true,
|
||
width: certificate_width,
|
||
scale: 3
|
||
}).then(canvas => {
|
||
// Logic download existing
|
||
var link = document.createElement('a');
|
||
link.download = 'certificate.png';
|
||
link.href = canvas.toDataURL("image/png");
|
||
link.click();
|
||
});
|
||
}
|
||
|
||
async function renderCanvasToPDF() {
|
||
const pages = document.querySelectorAll("#captureCertificate .certificate-page");
|
||
if (pages.length === 0) return;
|
||
|
||
const pdf = new window.jspdf.jsPDF({
|
||
orientation: 'landscape',
|
||
unit: 'mm',
|
||
format: 'a4'
|
||
});
|
||
|
||
const pageWidth = pdf.internal.pageSize.getWidth(); // 297 mm
|
||
const pageHeight = pdf.internal.pageSize.getHeight(); // 210 mm
|
||
|
||
for (let i = 0; i < pages.length; i++) {
|
||
const pageElement = pages[i];
|
||
|
||
const canvas = await html2canvas(pageElement, {
|
||
allowTaint: true,
|
||
useCORS: true,
|
||
scale: 2, // cukup tajam, jangan kebesaran
|
||
backgroundColor: '#ffffff'
|
||
});
|
||
|
||
const imgData = canvas.toDataURL("image/png");
|
||
|
||
if (i > 0) pdf.addPage();
|
||
|
||
// 🔥 FULL PAGE – TANPA WHITESPACE
|
||
pdf.addImage(
|
||
imgData,
|
||
'PNG',
|
||
0,
|
||
0,
|
||
pageWidth,
|
||
pageHeight,
|
||
undefined,
|
||
'FAST'
|
||
);
|
||
}
|
||
|
||
const courseTitle = {!! json_encode($course_title) !!};
|
||
const fileName = `Grownesesa Certificate - ${courseTitle}.pdf`;
|
||
pdf.save(fileName);
|
||
}
|
||
|
||
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|