668 lines
32 KiB
PHP
668 lines
32 KiB
PHP
@extends('layouts.site')
|
||
|
||
@section('content')
|
||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700;800;900&family=Inter:wght@300;400;500;600;700&family=Playfair+Display:ital,wght@0,500;0,700;1,400&display=swap" rel="stylesheet">
|
||
|
||
@if($application->status === 'accepted')
|
||
<div class="bg-slate-100 py-12 no-print">
|
||
<div class="container max-w-6xl mx-auto px-4">
|
||
<!-- Verification Banner (e-Devlet Style) -->
|
||
<div class="bg-emerald-50 border-l-4 border-emerald-500 p-4 rounded-xl shadow-sm mb-6 flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
||
<div class="flex items-center gap-3 flex-1 min-w-0">
|
||
<div class="w-10 h-10 rounded-full bg-emerald-500 text-white flex items-center justify-center flex-shrink-0 shadow-md shadow-emerald-500/10">
|
||
<i class="uil uil-shield-check text-xl"></i>
|
||
</div>
|
||
<div class="text-sm leading-normal">
|
||
<span class="font-bold text-slate-800">Güvenli Belge Doğrulama:</span>
|
||
<span class="text-slate-600 ml-1">Bu staj sertifikası ve transkripti, Trunçgil Teknopark sistemi üzerinden dijital olarak imzalanıp onaylanmıştır.</span>
|
||
</div>
|
||
</div>
|
||
<div class="flex-shrink-0">
|
||
<!-- PDF Download Button -->
|
||
<button onclick="downloadPDF()" id="pdf-btn" class="px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white text-sm font-bold rounded-lg transition-all shadow-sm flex items-center gap-1.5 whitespace-nowrap">
|
||
<i class="uil uil-file-download text-base" id="pdf-icon"></i>
|
||
<span class="spinner-border spinner-border-sm hidden animate-spin w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full" id="pdf-spinner" role="status"></span>
|
||
<span id="pdf-btn-text">PDF İndir</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Printable Area -->
|
||
<div class="print-container bg-slate-100 py-6 min-h-screen">
|
||
<div class="container max-w-6xl mx-auto px-4 pb-20 space-y-12">
|
||
|
||
<!-- ================= PAGE 1: CERTIFICATE (LANDSCAPE A4) ================= -->
|
||
<div class="certificate-container-wrapper overflow-hidden w-full flex justify-center items-start">
|
||
<div id="certificate-node" class="certificate-page bg-white rounded-[2rem] shadow-2xl p-12 relative overflow-hidden page-break mx-auto">
|
||
|
||
<!-- Watermark Logo -->
|
||
<div class="absolute inset-0 flex items-center justify-center pointer-events-none z-0 opacity-[0.05]">
|
||
<img src="{{ asset('logos/truncgil-dikey.svg') }}" class="w-[300px] h-[300px] object-contain">
|
||
</div>
|
||
|
||
<!-- Thin Minimal Orange/Slate Inner Border -->
|
||
|
||
<div class="relative z-10 flex flex-col justify-between h-full min-h-[580px] md:min-h-[540px]">
|
||
|
||
<!-- Logo & Header -->
|
||
<div class="relative flex justify-between items-center w-full min-h-[64px]">
|
||
<div class="w-1/3"></div>
|
||
<div class="w-1/3 flex justify-center">
|
||
<img src="{{ asset('logos/truncgil-yatay.svg') }}" alt="Trunçgil Teknoloji" class="h-16 md:h-20 object-contain">
|
||
</div>
|
||
<div class="w-1/3 text-right">
|
||
<span class="text-[10px] font-bold text-slate-400 tracking-widest block">VERİFİKASYON NO</span>
|
||
<span class="text-xs font-mono font-bold text-slate-800">{{ $application->certificate_code }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main Content -->
|
||
<div class="text-center my-auto px-4">
|
||
<h1 class="font-cinzel text-3xl md:text-5xl text-slate-900 mt-8 mb-2" style="font-weight: 900; letter-spacing: 0.04em;">STAJ BİTİRME<br>SERTİFİKASI</h1>
|
||
|
||
<p class="text-slate-400 text-xs md:text-sm tracking-wider mb-0">SAYIN</p>
|
||
<h2 class="font-cinzel text-2xl md:text-4xl font-extrabold text-slate-900 tracking-wide mb-6 mt-0">{{ $application->name }}</h2>
|
||
|
||
<div class="max-w-3xl mx-auto text-slate-700 leading-relaxed text-sm md:text-base space-y-4">
|
||
<p>
|
||
<strong>{{ \Carbon\Carbon::parse($application->internship_start_date)->format('d.m.Y') }}</strong> -
|
||
<strong>{{ \Carbon\Carbon::parse($application->internship_end_date)->format('d.m.Y') }}</strong> tarihleri arasında,
|
||
<strong>Trunçgil Teknoloji</strong> bünyesinde gerçekleştirdiği uzaktan staj programını başarıyla tamamlayarak bu belgeyi almaya hak kazanmıştır.
|
||
</p>
|
||
<p class="text-xs md:text-sm text-slate-500 max-w-2xl mx-auto italic font-serif">
|
||
Gösterdiği üstün gayret, sorumluluk bilinci, teknik beceriler ve ekip çalışmasına sağladığı değerli katkılardan dolayı teşekkür eder, profesyonel kariyerinde başarılar dileriz.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Footer Section (Signatures & Verification QR) -->
|
||
<div class="grid grid-cols-3 items-end pt-6 border-t border-slate-100/50">
|
||
<!-- Left: QR Code -->
|
||
<div class="flex items-center gap-4">
|
||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data={{ urlencode(route('internship.verify', $application->certificate_code)) }}" alt="QR Code" class="w-28 h-28 border border-slate-200 p-1 rounded-xl bg-white shadow-sm">
|
||
<div class="text-left hidden sm:block">
|
||
<span class="text-[8px] font-bold text-slate-400 tracking-wider block">DİJİTAL DOĞRULAMA</span>
|
||
<span class="text-[9px] text-slate-500 block">Karekod okutularak belgenin güncelliği doğrulanabilir.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Middle: Date -->
|
||
<div class="text-center">
|
||
<span class="text-[9px] text-slate-600 block tracking-wider text-glow-white font-semibold">DÜZENLENME TARİHİ</span>
|
||
<span class="text-xs font-bold text-slate-800 text-glow-white">{{ \Carbon\Carbon::parse($application->internship_end_date)->format('d.m.Y') }}</span>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ================= PAGE 2: TRANSCRIPT (PORTRAIT A4) ================= -->
|
||
<div class="transcript-container-wrapper overflow-hidden w-full flex justify-center items-start">
|
||
<div id="transcript-node" class="transcript-page bg-white rounded-[2rem] shadow-2xl p-6 md:p-8 relative overflow-hidden mx-auto">
|
||
|
||
<!-- Thin border decor for transcript -->
|
||
<div class="absolute inset-4 border border-slate-100 rounded-[1.5rem] pointer-events-none"></div>
|
||
|
||
<div class="relative z-10 flex flex-col justify-between h-full text-slate-700">
|
||
<div>
|
||
<!-- Header -->
|
||
<div class="flex justify-between items-center pb-2 border-b border-slate-100 mb-3">
|
||
<div>
|
||
<h2 class="font-serif font-bold text-slate-900 transcript-header-title">STAJ AKADEMİK TRANSKRİPTİ</h2>
|
||
<p class="text-slate-400 tracking-wider mt-0.5 transcript-header-subtitle">VE PERFORMANS DEĞERLENDİRME RAPORU</p>
|
||
</div>
|
||
<img src="{{ asset('logos/truncgil-yatay.svg') }}" alt="Trunçgil Logo" class="h-6 object-contain">
|
||
</div>
|
||
|
||
<!-- Student Info block -->
|
||
<div class="bg-slate-50 rounded-xl p-2.5 border border-slate-100 mb-3">
|
||
<h3 class="font-bold text-slate-400 tracking-widest mb-1.5 student-info-title">ÖĞRENCİ / STAJYER BİLGİLERİ</h3>
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-y-1 gap-x-8 student-info-grid">
|
||
<div class="flex justify-between border-b border-slate-200/50 pb-1">
|
||
<span class="text-slate-500">Adı Soyadı:</span>
|
||
<strong class="text-slate-800">{{ $application->name }}</strong>
|
||
</div>
|
||
<div class="flex justify-between border-b border-slate-200/50 pb-1">
|
||
<span class="text-slate-500">E-Posta Adresi:</span>
|
||
<strong class="text-slate-800">{{ $application->email }}</strong>
|
||
</div>
|
||
<div class="flex justify-between border-b border-slate-200/50 pb-1">
|
||
<span class="text-slate-500">Staj Dönemi:</span>
|
||
<strong class="text-slate-800">{{ \Carbon\Carbon::parse($application->internship_start_date)->format('d.m.Y') }} - {{ \Carbon\Carbon::parse($application->internship_end_date)->format('d.m.Y') }}</strong>
|
||
</div>
|
||
<div class="flex justify-between border-b border-slate-200/50 pb-1">
|
||
<span class="text-slate-500">Toplam Staj Süresi:</span>
|
||
<strong class="text-slate-800">{{ $application->internship_total_days }} İş Günü</strong>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Dynamic Markdown Content (Transcript and marks) -->
|
||
<div class="prose max-w-none text-slate-700 leading-relaxed mb-3">
|
||
{!! new \Illuminate\Support\HtmlString(\Illuminate\Support\Str::markdown($application->transcript_markdown ?? '')) !!}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Footer with verification details -->
|
||
<div class="w-full flex justify-between items-center pt-2 border-t border-slate-100 gap-4 mt-auto">
|
||
<div class="flex items-center gap-3">
|
||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=120x120&data={{ urlencode(route('internship.verify', $application->certificate_code)) }}" alt="QR Code" class="w-14 h-14 border border-slate-200 p-0.5 rounded-lg bg-white">
|
||
<div>
|
||
<span class="font-bold text-slate-400 tracking-wider block verify-code-label">GÜVENLİ DOĞRULAMA KODU</span>
|
||
<span class="font-mono font-bold text-slate-800 block verify-code">{{ $application->certificate_code }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-right text-slate-400 footer-address">
|
||
Trunçgil Teknoloji San. ve Tic. Ltd. Şti.<br>
|
||
Gaziantep Üniversitesi Teknopark No: 4A
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ================= PAGE 3: STAJ DEFTERİ (PORTRAIT A4) ================= -->
|
||
@if($application->notebook_approved || $application->notebook_supervisor_signed || $application->notebook_unit_signed)
|
||
<div class="notebook-container-wrapper overflow-hidden w-full flex justify-center items-start mt-8">
|
||
<div id="notebook-node" class="transcript-page bg-white rounded-[2rem] shadow-2xl p-6 md:p-8 relative overflow-hidden mx-auto">
|
||
|
||
<!-- Thin border decor for notebook -->
|
||
<div class="absolute inset-4 border border-slate-100 rounded-[1.5rem] pointer-events-none"></div>
|
||
|
||
<div class="relative z-10 flex flex-col justify-between h-full text-slate-700">
|
||
<div>
|
||
<!-- Header -->
|
||
<div class="flex justify-between items-center pb-2 border-b border-slate-100 mb-3">
|
||
<div>
|
||
<h2 class="font-serif font-bold text-slate-900 transcript-header-title">ONAYLI STAJ DEFTERİ RAPORU</h2>
|
||
<p class="text-slate-400 tracking-wider mt-0.5 transcript-header-subtitle">DİJİTAL İMZALI VE ONAYLI STAJ RAPORLARI</p>
|
||
</div>
|
||
<img src="{{ asset('logos/truncgil-yatay.svg') }}" alt="Trunçgil Logo" class="h-6 object-contain">
|
||
</div>
|
||
|
||
<!-- Signatures Information -->
|
||
<div class="bg-emerald-50 border border-emerald-200 rounded-xl p-3 mb-4 flex justify-between items-center">
|
||
<div>
|
||
<span class="text-xs font-extrabold text-emerald-800 uppercase block tracking-wider">Dijital İmza Durumu</span>
|
||
<span class="text-[10px] text-emerald-600 font-semibold block mt-0.5">Bu staj defteri yetkililer tarafından elektronik olarak imzalanmıştır.</span>
|
||
</div>
|
||
<div class="flex gap-2">
|
||
@if($application->notebook_supervisor_signed)
|
||
<span class="inline-flex px-2 py-1 rounded bg-emerald-100 text-emerald-800 text-[8px] font-extrabold uppercase border border-emerald-200">
|
||
Sorumlu: {{ $application->notebook_supervisor_name ?: 'Alperen Trunç' }}
|
||
</span>
|
||
@endif
|
||
@if($application->notebook_unit_signed)
|
||
<span class="inline-flex px-2 py-1 rounded bg-emerald-100 text-emerald-800 text-[8px] font-extrabold uppercase border border-emerald-200">
|
||
Yetkili: {{ $application->notebook_unit_name ?: 'Birim Yetkilisi' }}
|
||
</span>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Notebook Days content overview -->
|
||
<div class="overflow-y-auto max-h-[700px] pr-2 no-scrollbar space-y-4">
|
||
@foreach($days as $day)
|
||
@php
|
||
$entry = $savedEntries->get($day['day_number']);
|
||
@endphp
|
||
@if($entry && trim($entry->content))
|
||
<div class="p-3 bg-slate-50 border border-slate-100 rounded-xl">
|
||
<div class="flex justify-between items-center pb-1.5 border-b border-slate-200/50 mb-1.5">
|
||
<span class="text-xs font-extrabold text-slate-800">{{ $day['day_number'] }}. Gün Raporu</span>
|
||
<span class="text-[10px] text-slate-400 font-bold">{{ $day['formatted_date'] }}</span>
|
||
</div>
|
||
<p class="text-xs text-slate-600 whitespace-pre-wrap leading-relaxed" style="font-size: 11px;">{{ $entry->content }}</p>
|
||
</div>
|
||
@endif
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Footer -->
|
||
<div class="w-full flex justify-between items-center pt-2 border-t border-slate-100 gap-4 mt-auto">
|
||
<div class="flex items-center gap-3">
|
||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=120x120&data={{ urlencode(route('internship.verify', $application->certificate_code)) }}" alt="QR Code" class="w-14 h-14 border border-slate-200 p-0.5 rounded-lg bg-white">
|
||
<div>
|
||
<span class="font-bold text-slate-400 tracking-wider block verify-code-label">GÜVENLİ DOĞRULAMA KODU</span>
|
||
<span class="font-mono font-bold text-slate-800 block verify-code">{{ $application->certificate_code }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-right text-slate-400 footer-address">
|
||
Trunçgil Teknoloji San. ve Tic. Ltd. Şti.<br>
|
||
Gaziantep Üniversitesi Teknopark No: 4A
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
</div>
|
||
</div>
|
||
@else
|
||
<div class="min-h-screen bg-slate-100 flex items-center justify-center p-6 no-print">
|
||
<div class="bg-white rounded-3xl p-8 max-w-md w-full shadow-2xl border border-slate-100 text-center">
|
||
<div class="w-16 h-16 rounded-full bg-red-50 text-[#e31e24] flex items-center justify-center text-3xl mx-auto mb-4">
|
||
<i class="uil uil-exclamation-triangle"></i>
|
||
</div>
|
||
<h1 class="text-xl font-bold text-slate-800">Doğrulanamayan Belge</h1>
|
||
<p class="text-xs text-slate-500 mt-2 leading-relaxed">Görüntülemeye çalıştığınız staj kaydı henüz onaylanmamıştır veya aktif değildir. Detaylı bilgi için kurum yetkilileri ile iletişime geçebilirsiniz.</p>
|
||
<a href="/" class="mt-6 inline-flex px-5 py-2.5 bg-slate-800 hover:bg-slate-900 text-white font-bold rounded-xl text-xs transition-all shadow-md">Anasayfaya Dön</a>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@push('styles')
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||
<style>
|
||
:root {
|
||
/* Global scale factor for transcript page fonts. Adjust this easily (e.g. 1.0, 1.10, 1.20) */
|
||
--transcript-font-scale: 1.30;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', sans-serif;
|
||
}
|
||
.font-serif {
|
||
font-family: 'Cinzel', 'Playfair Display', Georgia, serif;
|
||
}
|
||
.font-cinzel {
|
||
font-family: 'Cinzel', serif !important;
|
||
}
|
||
|
||
.text-glow-white {
|
||
text-shadow: 0 0 10px #ffffff, 0 0 6px #ffffff, 0 0 3px #ffffff;
|
||
}
|
||
|
||
/* Transcript typography helpers scaled globally */
|
||
.transcript-header-title {
|
||
font-size: calc(0.875rem * var(--transcript-font-scale)) !important;
|
||
}
|
||
.transcript-header-subtitle {
|
||
font-size: calc(7px * var(--transcript-font-scale)) !important;
|
||
}
|
||
.student-info-title {
|
||
font-size: calc(7.5px * var(--transcript-font-scale)) !important;
|
||
}
|
||
.student-info-grid {
|
||
font-size: calc(8.5px * var(--transcript-font-scale)) !important;
|
||
}
|
||
.verify-code-label {
|
||
font-size: calc(6.5px * var(--transcript-font-scale)) !important;
|
||
}
|
||
.verify-code {
|
||
font-size: calc(9px * var(--transcript-font-scale)) !important;
|
||
}
|
||
.footer-address {
|
||
font-size: calc(7.5px * var(--transcript-font-scale)) !important;
|
||
}
|
||
|
||
/* Screen display aspect styling */
|
||
.certificate-page {
|
||
width: 1122px;
|
||
min-height: 794px;
|
||
box-sizing: border-box;
|
||
background-image: url('{{ asset("assets/img/cert_bg_futuristic.png") }}');
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
background-color: #ffffff;
|
||
}
|
||
.transcript-page {
|
||
width: 794px;
|
||
height: 1122px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* Elegant Markdown Table Styling inside prose (Reduced font sizes & paddings) */
|
||
.prose table {
|
||
width: 100%;
|
||
margin-top: 0.35rem !important;
|
||
margin-bottom: 0.35rem !important;
|
||
border-collapse: collapse;
|
||
text-align: left;
|
||
}
|
||
.prose th {
|
||
font-weight: 700;
|
||
padding: 0.2rem 0.35rem !important;
|
||
background-color: #f8fafc;
|
||
border-bottom: 2px solid #e2e8f0;
|
||
color: #1e293b;
|
||
font-size: calc(0.45rem * var(--transcript-font-scale)) !important;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.prose td {
|
||
padding: 0.2rem 0.35rem !important;
|
||
border-bottom: 1px solid #e2e8f0;
|
||
color: #334155;
|
||
font-size: calc(0.45rem * var(--transcript-font-scale)) !important;
|
||
line-height: 1.2 !important;
|
||
}
|
||
.prose tr:hover {
|
||
background-color: #f8fafc;
|
||
}
|
||
.prose h3 {
|
||
font-family: 'Cinzel', serif;
|
||
color: #0f172a;
|
||
margin-top: 0.5rem !important;
|
||
margin-bottom: 0.25rem !important;
|
||
border-bottom: 1px solid #e2e8f0;
|
||
padding-bottom: 0.15rem;
|
||
font-weight: 700;
|
||
font-size: calc(0.6rem * var(--transcript-font-scale)) !important;
|
||
}
|
||
.prose h4 {
|
||
color: #1e293b;
|
||
margin-top: 0.4rem !important;
|
||
margin-bottom: 0.2rem !important;
|
||
font-weight: 600;
|
||
font-size: calc(0.52rem * var(--transcript-font-scale)) !important;
|
||
}
|
||
.prose p {
|
||
font-size: calc(0.45rem * var(--transcript-font-scale)) !important;
|
||
line-height: 1.3 !important;
|
||
margin-top: 0.15rem !important;
|
||
margin-bottom: 0.2rem !important;
|
||
}
|
||
.prose ul {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
gap: 0.1rem 0.75rem;
|
||
padding-left: 0 !important;
|
||
margin-top: 0.25rem !important;
|
||
margin-bottom: 0.25rem !important;
|
||
list-style-type: none !important;
|
||
}
|
||
.prose ul li {
|
||
font-size: calc(0.45rem * var(--transcript-font-scale)) !important;
|
||
line-height: 1.3 !important;
|
||
margin: 0 !important;
|
||
position: relative;
|
||
padding-left: 0.5rem !important;
|
||
}
|
||
.prose ul li::before {
|
||
content: "•";
|
||
color: #f97316;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
font-weight: bold;
|
||
}
|
||
.prose blockquote {
|
||
border-left: 2px solid #f97316;
|
||
padding-left: 0.4rem !important;
|
||
font-style: italic;
|
||
color: #475569;
|
||
margin: 0.4rem 0 !important;
|
||
font-size: calc(0.45rem * var(--transcript-font-scale)) !important;
|
||
}
|
||
|
||
/* Print media config for mixed Landscape & Portrait */
|
||
@media print {
|
||
@page {
|
||
margin: 0;
|
||
}
|
||
|
||
@page landscape-page {
|
||
size: A4 landscape;
|
||
}
|
||
|
||
@page portrait-page {
|
||
size: A4 portrait;
|
||
}
|
||
|
||
body, html {
|
||
background-color: #ffffff !important;
|
||
margin: 0 !important;
|
||
padding: 0 !important;
|
||
}
|
||
|
||
.no-print, header, footer, nav, .site-header, .site-footer {
|
||
display: none !important;
|
||
}
|
||
|
||
.print-container {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 100% !important;
|
||
padding: 0 !important;
|
||
margin: 0 !important;
|
||
background-color: transparent !important;
|
||
}
|
||
|
||
.certificate-container-wrapper, .transcript-container-wrapper {
|
||
height: auto !important;
|
||
overflow: visible !important;
|
||
}
|
||
|
||
.certificate-page {
|
||
page: landscape-page;
|
||
transform: none !important;
|
||
width: 297mm !important;
|
||
height: 210mm !important;
|
||
min-height: 210mm !important;
|
||
margin: 0 !important;
|
||
padding: 15mm !important;
|
||
box-shadow: none !important;
|
||
border: none !important;
|
||
border-radius: 0 !important;
|
||
box-sizing: border-box !important;
|
||
page-break-after: always !important;
|
||
break-after: page !important;
|
||
background-image: url('{{ asset("assets/img/cert_bg_futuristic.png") }}') !important;
|
||
background-size: cover !important;
|
||
background-position: center !important;
|
||
background-repeat: no-repeat !important;
|
||
background-color: #ffffff !important;
|
||
-webkit-print-color-adjust: exact;
|
||
print-color-adjust: exact;
|
||
}
|
||
|
||
.transcript-page {
|
||
page: portrait-page;
|
||
transform: none !important;
|
||
width: 210mm !important;
|
||
height: 297mm !important;
|
||
min-height: 297mm !important;
|
||
margin: 0 !important;
|
||
padding: 10mm !important;
|
||
box-shadow: none !important;
|
||
border: none !important;
|
||
border-radius: 0 !important;
|
||
box-sizing: border-box !important;
|
||
overflow: hidden !important;
|
||
}
|
||
}
|
||
</style>
|
||
@endpush
|
||
|
||
@push('scripts')
|
||
<script>
|
||
function scaleDocument(wrapperSelector, nodeSelector, baseWidth, baseHeight) {
|
||
const wrapper = document.querySelector(wrapperSelector);
|
||
const node = document.querySelector(nodeSelector);
|
||
if (!wrapper || !node) return;
|
||
|
||
const containerWidth = wrapper.offsetWidth;
|
||
if (containerWidth < baseWidth) {
|
||
const scale = containerWidth / baseWidth;
|
||
node.style.transform = `scale(${scale})`;
|
||
node.style.transformOrigin = 'top center';
|
||
node.style.width = `${baseWidth}px`;
|
||
node.style.minWidth = `${baseWidth}px`;
|
||
node.style.height = `${baseHeight}px`;
|
||
node.style.minHeight = `${baseHeight}px`;
|
||
wrapper.style.height = `${baseHeight * scale}px`;
|
||
} else {
|
||
node.style.transform = '';
|
||
node.style.transformOrigin = '';
|
||
node.style.width = '';
|
||
node.style.minWidth = '';
|
||
node.style.height = '';
|
||
node.style.minHeight = '';
|
||
wrapper.style.height = '';
|
||
}
|
||
}
|
||
|
||
function scaleAllDocuments() {
|
||
scaleDocument('.certificate-container-wrapper', '#certificate-node', 1122, 794);
|
||
scaleDocument('.transcript-container-wrapper', '#transcript-node', 794, 1122);
|
||
scaleDocument('.notebook-container-wrapper', '#notebook-node', 794, 1122);
|
||
}
|
||
|
||
window.addEventListener('resize', scaleAllDocuments);
|
||
window.addEventListener('DOMContentLoaded', scaleAllDocuments);
|
||
window.addEventListener('load', scaleAllDocuments);
|
||
|
||
// Immediate and delayed triggers to ensure correct measurement after image & stylesheet loading
|
||
scaleAllDocuments();
|
||
setTimeout(scaleAllDocuments, 100);
|
||
setTimeout(scaleAllDocuments, 500);
|
||
setTimeout(scaleAllDocuments, 1500);
|
||
|
||
async function downloadPDF() {
|
||
const btn = document.getElementById('pdf-btn');
|
||
const icon = document.getElementById('pdf-icon');
|
||
const spinner = document.getElementById('pdf-spinner');
|
||
const btnText = document.getElementById('pdf-btn-text');
|
||
|
||
// Show spinner
|
||
btn.disabled = true;
|
||
icon.classList.add('hidden');
|
||
spinner.classList.remove('hidden');
|
||
btnText.textContent = "PDF Hazırlanıyor...";
|
||
|
||
try {
|
||
const { jsPDF } = window.jspdf;
|
||
|
||
const certEl = document.getElementById('certificate-node');
|
||
const transEl = document.getElementById('transcript-node');
|
||
const notebookEl = document.getElementById('notebook-node');
|
||
|
||
// Force elements to normal scale prior to capturing for PDF
|
||
const origCertTransform = certEl.style.transform;
|
||
const origCertWidth = certEl.style.width;
|
||
const origCertHeight = certEl.style.height;
|
||
const origCertRadius = certEl.style.borderRadius;
|
||
const origTransTransform = transEl.style.transform;
|
||
const origTransWidth = transEl.style.width;
|
||
const origTransHeight = transEl.style.height;
|
||
const origTransRadius = transEl.style.borderRadius;
|
||
|
||
let origNotebookTransform, origNotebookWidth, origNotebookHeight, origNotebookRadius;
|
||
if (notebookEl) {
|
||
origNotebookTransform = notebookEl.style.transform;
|
||
origNotebookWidth = notebookEl.style.width;
|
||
origNotebookHeight = notebookEl.style.height;
|
||
origNotebookRadius = notebookEl.style.borderRadius;
|
||
|
||
notebookEl.style.transform = 'none';
|
||
notebookEl.style.width = '794px';
|
||
notebookEl.style.height = '1122px';
|
||
notebookEl.style.borderRadius = '0';
|
||
}
|
||
|
||
certEl.style.transform = 'none';
|
||
certEl.style.width = '1122px';
|
||
certEl.style.height = '794px';
|
||
certEl.style.borderRadius = '0';
|
||
transEl.style.transform = 'none';
|
||
transEl.style.width = '794px';
|
||
transEl.style.height = '1122px';
|
||
transEl.style.borderRadius = '0';
|
||
|
||
// Render Page 1 (Landscape)
|
||
const certCanvas = await html2canvas(certEl, {
|
||
scale: 2,
|
||
useCORS: true,
|
||
backgroundColor: '#ffffff',
|
||
logging: false
|
||
});
|
||
const certImgData = certCanvas.toDataURL('image/jpeg', 1.0);
|
||
|
||
// Initialize landscape A4 document
|
||
const pdf = new jsPDF({
|
||
orientation: 'landscape',
|
||
unit: 'mm',
|
||
format: 'a4'
|
||
});
|
||
pdf.addImage(certImgData, 'JPEG', 0, 0, 297, 210);
|
||
|
||
// Render Page 2 (Portrait)
|
||
const transCanvas = await html2canvas(transEl, {
|
||
scale: 2,
|
||
useCORS: true,
|
||
backgroundColor: '#ffffff',
|
||
logging: false
|
||
});
|
||
const transImgData = transCanvas.toDataURL('image/jpeg', 1.0);
|
||
|
||
// Calculate exact height using aspect ratio to prevent vertical squishing
|
||
const transWidth = 210;
|
||
const transHeight = (transCanvas.height * transWidth) / transCanvas.width;
|
||
|
||
// Add portrait page to PDF
|
||
pdf.addPage('a4', 'portrait');
|
||
pdf.addImage(transImgData, 'JPEG', 0, 0, transWidth, transHeight);
|
||
|
||
// Render Page 3 (Notebook) if it exists
|
||
if (notebookEl) {
|
||
const notebookCanvas = await html2canvas(notebookEl, {
|
||
scale: 2,
|
||
useCORS: true,
|
||
backgroundColor: '#ffffff',
|
||
logging: false
|
||
});
|
||
const notebookImgData = notebookCanvas.toDataURL('image/jpeg', 1.0);
|
||
const notebookHeight = (notebookCanvas.height * transWidth) / notebookCanvas.width;
|
||
|
||
pdf.addPage('a4', 'portrait');
|
||
pdf.addImage(notebookImgData, 'JPEG', 0, 0, transWidth, notebookHeight);
|
||
}
|
||
|
||
// Restore styles
|
||
certEl.style.transform = origCertTransform;
|
||
certEl.style.width = origCertWidth;
|
||
certEl.style.height = origCertHeight;
|
||
certEl.style.borderRadius = origCertRadius;
|
||
transEl.style.transform = origTransTransform;
|
||
transEl.style.width = origTransWidth;
|
||
transEl.style.height = origTransHeight;
|
||
transEl.style.borderRadius = origTransRadius;
|
||
|
||
if (notebookEl) {
|
||
notebookEl.style.transform = origNotebookTransform;
|
||
notebookEl.style.width = origNotebookWidth;
|
||
notebookEl.style.height = origNotebookHeight;
|
||
notebookEl.style.borderRadius = origNotebookRadius;
|
||
}
|
||
|
||
// Trigger Save File
|
||
pdf.save('{{ str()->slug($application->name) }}-staj-belgesi.pdf');
|
||
|
||
} catch (error) {
|
||
console.error("PDF generation failed", error);
|
||
alert("PDF oluşturulurken bir hata meydana geldi.");
|
||
} finally {
|
||
// Restore button
|
||
btn.disabled = false;
|
||
icon.classList.remove('hidden');
|
||
spinner.classList.add('hidden');
|
||
btnText.textContent = "PDF Olarak İndir";
|
||
}
|
||
}
|
||
</script>
|
||
@endpush
|
||
@endsection
|