849 lines
36 KiB
PHP
849 lines
36 KiB
PHP
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<title>{{ get_phrase('Certificate') }}</title>
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/backend/vendors/bootstrap/bootstrap.min.css') }}" />
|
|
<link rel="stylesheet" href="{{ asset('assets/global/jquery-ui-themes-1.13.2/themes/base/jquery-ui.css') }}">
|
|
|
|
{{-- FlatIcons --}}
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-solid-rounded/css/uicons-solid-rounded.css') }}" />
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-bold-rounded/css/uicons-bold-rounded.css') }}" />
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-bold-straight/css/uicons-bold-straight.css') }}" />
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-regular-rounded/css/uicons-regular-rounded.css') }}" />
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-thin-rounded/css/uicons-thin-rounded.css') }}" />
|
|
|
|
<link rel="stylesheet" type="text/css" href="{{ asset('assets/backend/css/style.css') }}">
|
|
|
|
{{-- Font Awesome untuk ikon tambahan --}}
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
|
|
<script type="text/javascript" src="{{ asset('assets/backend/js/jquery-3.7.1.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ asset('assets/global/jquery-ui-1.13.2/jquery-ui.min.js') }}"></script>
|
|
<script src="{{ asset('assets/backend/vendors/bootstrap/bootstrap.bundle.min.js') }}"></script>
|
|
|
|
<style type="text/css">
|
|
body {
|
|
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
.draggable {
|
|
border: 2px dashed rgba(255, 255, 255, 0.8);
|
|
cursor: move;
|
|
background-color: #15b57e33;
|
|
top: 0;
|
|
transition: all 0.3s ease;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.draggable:hover {
|
|
border-color: #15b57e;
|
|
box-shadow: 0 6px 12px rgba(21, 181, 126, 0.2);
|
|
}
|
|
|
|
.hidden-position:not(.certificate-layout-module) {
|
|
background-color: #ffd3d3 !important;
|
|
}
|
|
|
|
.resizeable-canvas {
|
|
width: 400px;
|
|
padding: 10px;
|
|
box-shadow: 1px 3px 11px -4px #565656;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.certificate-layout-module.resizeable-canvas {
|
|
padding: 0px !important;
|
|
}
|
|
|
|
.certificate-layout-module {
|
|
background-color: #fff;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.sidebar {
|
|
position: fixed;
|
|
top: 0;
|
|
right: -350px;
|
|
bottom: 0;
|
|
z-index: 200;
|
|
background-color: #ffffff;
|
|
width: 350px;
|
|
height: 100%;
|
|
transition: right 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
box-shadow: -5px 0 25px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.sidebar.open {
|
|
right: 0;
|
|
}
|
|
|
|
.sidebar-header {
|
|
width: 100%;
|
|
padding: 15px;
|
|
background: rgba(0, 17, 81, 1);
|
|
color: white;
|
|
}
|
|
|
|
.sidebar-toggle {
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
z-index: 150;
|
|
background: rgba(0, 17, 81, 1);
|
|
padding: 10px;
|
|
border-radius: 50%;
|
|
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.sidebar-toggle:hover {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.remove-item {
|
|
position: absolute;
|
|
top: -10px;
|
|
right: -10px;
|
|
background-color: #dc3545;
|
|
color: white;
|
|
border-radius: 50%;
|
|
padding: 4px;
|
|
height: 24px;
|
|
width: 24px;
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
z-index: 10;
|
|
}
|
|
|
|
.remove-item:hover {
|
|
background-color: #c82333;
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
i:not(.fas, .fa, .fab) {
|
|
line-height: 1.5em !important;
|
|
vertical-align: -0.14em !important;
|
|
display: inline-flex !important;
|
|
}
|
|
|
|
.dotted-background {
|
|
background-image: radial-gradient(circle, #afafaf 1px, transparent 1px);
|
|
background-size: 20px 20px;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 100;
|
|
background-color: #f0f2f5;
|
|
width: 100%;
|
|
height: 100%;
|
|
padding: 30px;
|
|
}
|
|
|
|
.cursor-pointer {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.sidebar-body {
|
|
height: calc(100% - 60px);
|
|
overflow-y: auto;
|
|
padding: 20px;
|
|
}
|
|
|
|
.font-family-option {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 8px 12px;
|
|
border-radius: 6px;
|
|
margin-bottom: 8px;
|
|
border: 1px solid #e0e0e0;
|
|
transition: all 0.2s ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.font-family-option:hover {
|
|
background-color: #f8f9fa;
|
|
border-color: #667eea;
|
|
}
|
|
|
|
.font-family-option.active {
|
|
background-color: #e8eeff;
|
|
border-color: #667eea;
|
|
}
|
|
|
|
.font-family-preview {
|
|
font-size: 14px;
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.badge {
|
|
margin: 2px;
|
|
padding: 6px 10px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border-radius: 4px;
|
|
transition: all 0.2s ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.badge:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.form-control, .form-select {
|
|
border-radius: 8px;
|
|
border: 1px solid #dee2e6;
|
|
padding: 10px 15px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.form-control:focus, .form-select:focus {
|
|
border-color: #667eea;
|
|
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
|
}
|
|
|
|
.btn {
|
|
border-radius: 8px;
|
|
padding: 10px 20px;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-ol-btn-light-primary {
|
|
background-color: #e8eeff;
|
|
color: #667eea;
|
|
border: 1px solid #c2d0ff;
|
|
}
|
|
|
|
.btn-ol-btn-light-primary:hover {
|
|
background-color: #d5deff;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
|
|
}
|
|
|
|
.btn-ol-btn-primary {
|
|
background: rgba(0, 17, 81, 1);
|
|
color: white;
|
|
border: none;
|
|
}
|
|
|
|
.btn-ol-btn-primary:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.3);
|
|
}
|
|
|
|
.font-style-options {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.font-style-btn {
|
|
flex: 1;
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
background: white;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.font-style-btn:hover {
|
|
border-color: #667eea;
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
.font-style-btn.active {
|
|
background-color: #667eea;
|
|
color: white;
|
|
border-color: #667eea;
|
|
}
|
|
|
|
.color-picker-container {
|
|
position: relative;
|
|
}
|
|
|
|
.color-preview {
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 4px;
|
|
border: 1px solid #dee2e6;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.font-weight-slider {
|
|
width: 100%;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.text-decoration-options {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
|
|
.text-decoration-btn {
|
|
flex: 1;
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
background: white;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
text-align: center;
|
|
}
|
|
|
|
.text-decoration-btn:hover {
|
|
border-color: #667eea;
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
.text-decoration-btn.active {
|
|
background-color: #667eea;
|
|
color: white;
|
|
border-color: #667eea;
|
|
}
|
|
|
|
.font-option-group {
|
|
background: #f8f9fa;
|
|
border-radius: 10px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.font-option-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #495057;
|
|
margin-bottom: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<a onclick="$('.sidebar').addClass('open')" href="#" class="sidebar-toggle">
|
|
<i class="fas fa-sliders-h" style="color: white; font-size: 20px;"></i>
|
|
</a>
|
|
|
|
<div class="sidebar open">
|
|
<div class="sidebar-header border-bottom d-flex align-items-center">
|
|
<a class="btn text-white" href="#" onclick="$('.sidebar').removeClass('open')">
|
|
<i class="fas fa-chevron-right"></i>
|
|
</a>
|
|
<span class="ms-2 fw-bold">{{ get_phrase('Certificate Designer') }}</span>
|
|
<a class="ms-auto btn btn-sm btn-outline-light" href="{{ route('admin.certificate.settings') }}">
|
|
<i class="fas fa-arrow-left me-1"></i>{{ get_phrase('Back') }}
|
|
</a>
|
|
</div>
|
|
|
|
<div class="sidebar-body">
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-body">
|
|
<h6 class="card-title d-flex align-items-center">
|
|
<i class="fas fa-code me-2"></i>{{ get_phrase('Available Variables') }}
|
|
</h6>
|
|
<div class="d-flex flex-wrap">
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_duration}')">{course_duration}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{certificate_id}')">{certificate_id}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{instructor_name}')">{instructor_name}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{student_name}')">{student_name}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_title}')">{course_title}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{number_of_lesson}')">{number_of_lesson}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{qr_code}')">{qr_code}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_completion_date}')">{course_completion_date}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{certificate_download_date}')">{certificate_download_date}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_level}')">{course_level}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_language}')">{course_language}</span>
|
|
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{section_list}')">{section_list}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm" id="custom_elem_form">
|
|
<div class="card-body">
|
|
<h6 class="card-title d-flex align-items-center">
|
|
<i class="fas fa-plus-circle me-2"></i>{{ get_phrase('Add New Element') }}
|
|
</h6>
|
|
|
|
<form action="#">
|
|
<div class="font-option-group">
|
|
<div class="font-option-title">
|
|
<i class="fas fa-font"></i>{{ get_phrase('Text Content') }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="certificate_element_content" class="form-label">{{ get_phrase('Enter Text with variables') }}</label>
|
|
<textarea name="certificate_element_content"
|
|
placeholder="{{ get_phrase('Example: This certifies that {student_name} has completed {course_title}') }}"
|
|
id="certificate_element_content"
|
|
rows="3"
|
|
class="form-control"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="font-option-group">
|
|
<div class="font-option-title">
|
|
<i class="fas fa-palette"></i>{{ get_phrase('Font Styling') }}
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="font_family" class="form-label">{{ get_phrase('Font Family') }}</label>
|
|
<div id="font-family-options">
|
|
<!-- Font options will be populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ get_phrase('Font Weight') }}</label>
|
|
<input type="range"
|
|
class="form-range font-weight-slider"
|
|
id="font_weight"
|
|
min="100"
|
|
max="900"
|
|
step="100"
|
|
value="400">
|
|
<div class="d-flex justify-content-between">
|
|
<small>Thin</small>
|
|
<small>Normal</small>
|
|
<small>Bold</small>
|
|
<small>Black</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ get_phrase('Font Style') }}</label>
|
|
<div class="font-style-options">
|
|
<button type="button" class="font-style-btn" data-style="normal">
|
|
<i class="fas fa-font"></i> Normal
|
|
</button>
|
|
<button type="button" class="font-style-btn" data-style="italic">
|
|
<i class="fas fa-italic"></i> Italic
|
|
</button>
|
|
<button type="button" class="font-style-btn" data-style="oblique">
|
|
<i class="fas fa-slash"></i> Oblique
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ get_phrase('Text Decoration') }}</label>
|
|
<div class="text-decoration-options">
|
|
<button type="button" class="text-decoration-btn" data-decoration="none">
|
|
None
|
|
</button>
|
|
<button type="button" class="text-decoration-btn" data-decoration="underline">
|
|
<u>Underline</u>
|
|
</button>
|
|
<button type="button" class="text-decoration-btn" data-decoration="overline">
|
|
Overline
|
|
</button>
|
|
<button type="button" class="text-decoration-btn" data-decoration="line-through">
|
|
<s>Strike</s>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ get_phrase('Text Color') }}</label>
|
|
<div class="color-picker-container">
|
|
<input type="color"
|
|
id="text_color"
|
|
value="#000000"
|
|
style="position: absolute; opacity: 0; width: 30px; height: 30px; cursor: pointer;">
|
|
<div class="color-preview" id="color_preview" style="background-color: #000000;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="font_size" class="form-label">{{ get_phrase('Font Size') }}: <span id="font_size_value">16</span>px</label>
|
|
<input type="range"
|
|
class="form-range"
|
|
id="font_size"
|
|
min="8"
|
|
max="72"
|
|
step="1"
|
|
value="16">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="font-option-group">
|
|
<div class="font-option-title">
|
|
<i class="fas fa-text-height"></i>{{ get_phrase('Text Alignment') }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="d-flex gap-2">
|
|
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('left')">
|
|
<i class="fas fa-align-left"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('center')">
|
|
<i class="fas fa-align-center"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('right')">
|
|
<i class="fas fa-align-right"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('justify')">
|
|
<i class="fas fa-align-justify"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<button type="button" class="btn ol-btn-light-primary w-100" onclick="addElemToCertificate()">
|
|
<i class="fas fa-plus me-2"></i>{{ get_phrase('Add Element') }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<button type="button" class="btn ol-btn-primary w-100" onclick="saveTemplate()">
|
|
<i class="fas fa-save me-2"></i>{{ get_phrase('Save Template') }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="certificate_builder_content_details" class="builder dotted-background">
|
|
{{-- Common style for page builder start --}}
|
|
<style>
|
|
/* Import Google Fonts for certificate styling */
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Pinyon+Script&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Italianno&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Miss+Fajardose&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Great+Vibes&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400;500;600;700&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@100;300;400;700;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600;700;800;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Source+Serif+Pro:wght@200;300;400;600;700;900&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;500;600;700&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Tangerine:wght@400;700&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Alex+Brush&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Sacramento&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Parisienne&display=swap');
|
|
</style>
|
|
{{-- Common style for page builder END --}}
|
|
|
|
@if (get_settings('certificate_builder_content_details'))
|
|
@php
|
|
$htmlContent = get_settings('certificate_builder_content_details');
|
|
$newSrc = get_image(get_settings('certificate_template_details'));
|
|
$certificate_builder_content_details = preg_replace('/(<img[^>]*class=["\']certificate-template["\'][^>]*src=["\'])([^"\']*)(["\'])/i', '${1}' . $newSrc . '${3}', $htmlContent);
|
|
@endphp
|
|
{!! $certificate_builder_content_details !!}
|
|
@else
|
|
<div id="certificate-layout-module" class="certificate-layout-module resizeable-canvas draggable position-relative">
|
|
<img class="certificate-template w-100 h-100" src="{{ get_image(get_settings('certificate_template_details')) }}">
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<script>
|
|
"use strict";
|
|
|
|
// Available fonts with categories
|
|
const fontOptions = [
|
|
{ name: 'Auto', value: 'auto', category: 'default' },
|
|
{ name: 'Inter', value: 'Inter, sans-serif', category: 'modern' },
|
|
{ name: 'Pinyon Script', value: 'Pinyon Script, cursive', category: 'elegant' },
|
|
{ name: 'Italianno', value: 'Italianno, cursive', category: 'script' },
|
|
{ name: 'Miss Fajardose', value: 'Miss Fajardose, cursive', category: 'script' },
|
|
{ name: 'Great Vibes', value: 'Great Vibes, cursive', category: 'script' },
|
|
{ name: 'Dancing Script', value: 'Dancing Script, cursive', category: 'script' },
|
|
{ name: 'Playfair Display', value: 'Playfair Display, serif', category: 'serif' },
|
|
{ name: 'Montserrat', value: 'Montserrat, sans-serif', category: 'modern' },
|
|
{ name: 'Roboto', value: 'Roboto, sans-serif', category: 'modern' },
|
|
{ name: 'Lato', value: 'Lato, sans-serif', category: 'modern' },
|
|
{ name: 'Open Sans', value: 'Open Sans, sans-serif', category: 'modern' },
|
|
{ name: 'Merriweather', value: 'Merriweather, serif', category: 'serif' },
|
|
{ name: 'Cinzel', value: 'Cinzel, serif', category: 'decorative' },
|
|
{ name: 'Raleway', value: 'Raleway, sans-serif', category: 'modern' },
|
|
{ name: 'Source Serif Pro', value: 'Source Serif Pro, serif', category: 'serif' },
|
|
{ name: 'Cormorant Garamond', value: 'Cormorant Garamond, serif', category: 'serif' },
|
|
{ name: 'Tangerine', value: 'Tangerine, cursive', category: 'script' },
|
|
{ name: 'Alex Brush', value: 'Alex Brush, cursive', category: 'script' },
|
|
{ name: 'Sacramento', value: 'Sacramento, cursive', category: 'script' },
|
|
{ name: 'Parisienne', value: 'Parisienne, cursive', category: 'script' }
|
|
];
|
|
|
|
// Current styling options
|
|
let currentFontStyle = 'normal';
|
|
let currentTextDecoration = 'none';
|
|
let currentTextAlign = 'left';
|
|
let currentTextColor = '#000000';
|
|
|
|
$(document).ready(function() {
|
|
initialize();
|
|
populateFontOptions();
|
|
setupEventListeners();
|
|
});
|
|
|
|
function populateFontOptions() {
|
|
const container = $('#font-family-options');
|
|
container.empty();
|
|
|
|
// Group fonts by category
|
|
const fontsByCategory = {};
|
|
fontOptions.forEach(font => {
|
|
if (!fontsByCategory[font.category]) {
|
|
fontsByCategory[font.category] = [];
|
|
}
|
|
fontsByCategory[font.category].push(font);
|
|
});
|
|
|
|
// Create options for each category
|
|
Object.keys(fontsByCategory).forEach(category => {
|
|
const categoryTitle = category.charAt(0).toUpperCase() + category.slice(1);
|
|
const categoryDiv = $(`<div class="mb-3"><small class="text-muted">${categoryTitle} Fonts</small></div>`);
|
|
|
|
fontsByCategory[category].forEach(font => {
|
|
const isActive = font.value === 'auto' ? 'active' : '';
|
|
const option = $(`
|
|
<div class="font-family-option ${isActive}" data-value="${font.value}">
|
|
<input type="radio" name="font_family" value="${font.value}"
|
|
id="font_family_${font.value.replace(/\s+/g, '_')}"
|
|
${font.value === 'auto' ? 'checked' : ''}>
|
|
<label for="font_family_${font.value.replace(/\s+/g, '_')}" class="ms-2 flex-grow-1">${font.name}</label>
|
|
<span class="font-family-preview" style="font-family: ${font.value}">Aa</span>
|
|
</div>
|
|
`);
|
|
categoryDiv.append(option);
|
|
});
|
|
|
|
container.append(categoryDiv);
|
|
});
|
|
|
|
// Add click event to font options
|
|
$('.font-family-option').click(function() {
|
|
$('.font-family-option').removeClass('active');
|
|
$(this).addClass('active');
|
|
$(this).find('input[type="radio"]').prop('checked', true);
|
|
});
|
|
}
|
|
|
|
function setupEventListeners() {
|
|
// Font size display
|
|
$('#font_size').on('input', function() {
|
|
$('#font_size_value').text($(this).val());
|
|
});
|
|
|
|
// Font style buttons
|
|
$('.font-style-btn').click(function() {
|
|
$('.font-style-btn').removeClass('active');
|
|
$(this).addClass('active');
|
|
currentFontStyle = $(this).data('style');
|
|
});
|
|
|
|
// Text decoration buttons
|
|
$('.text-decoration-btn').click(function() {
|
|
$('.text-decoration-btn').removeClass('active');
|
|
$(this).addClass('active');
|
|
currentTextDecoration = $(this).data('decoration');
|
|
});
|
|
|
|
// Color picker
|
|
$('#text_color').on('input', function() {
|
|
$('#color_preview').css('background-color', $(this).val());
|
|
currentTextColor = $(this).val();
|
|
});
|
|
|
|
// Initialize first button as active
|
|
$('.font-style-btn[data-style="normal"]').addClass('active');
|
|
$('.text-decoration-btn[data-decoration="none"]').addClass('active');
|
|
}
|
|
|
|
function addVariableToText(variable) {
|
|
const textarea = $('#certificate_element_content');
|
|
const currentValue = textarea.val();
|
|
const cursorPos = textarea[0].selectionStart;
|
|
|
|
const newValue = currentValue.substring(0, cursorPos) +
|
|
variable +
|
|
currentValue.substring(cursorPos);
|
|
|
|
textarea.val(newValue);
|
|
textarea.focus();
|
|
}
|
|
|
|
function setTextAlignment(alignment) {
|
|
currentTextAlign = alignment;
|
|
$('.btn-outline-secondary').removeClass('active');
|
|
$(`button[onclick="setTextAlignment('${alignment}')"]`).addClass('active');
|
|
}
|
|
|
|
function saveTemplate() {
|
|
var certificate_builder_content_details = $('#certificate_builder_content_details').html();
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: "{{ route('admin.certificate.builder.details.update') }}",
|
|
data: {
|
|
certificate_builder_content_details: certificate_builder_content_details
|
|
},
|
|
headers: {
|
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
},
|
|
success: function(response) {
|
|
$(location).attr('href', response);
|
|
console.log(response)
|
|
},
|
|
error: function(xhr) {
|
|
console.error('Error saving template:', xhr);
|
|
alert('Error saving template. Please try again.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function addElemToCertificate() {
|
|
var font_family = $("input[type='radio'][name='font_family']:checked").val();
|
|
var font_size = $("#font_size").val();
|
|
var font_weight = $("#font_weight").val();
|
|
var certificate_element_content = $('#certificate_element_content').val();
|
|
|
|
// Generate unique ID for the element
|
|
var elementId = 'elem_' + Date.now() + Math.floor(Math.random() * 1000);
|
|
|
|
var certificateElem = `
|
|
<div id="${elementId}"
|
|
class="draggable resizeable-canvas"
|
|
style="
|
|
padding: 10px !important;
|
|
position: absolute;
|
|
font-size: ${font_size}px;
|
|
font-weight: ${font_weight};
|
|
font-style: ${currentFontStyle};
|
|
text-decoration: ${currentTextDecoration};
|
|
text-align: ${currentTextAlign};
|
|
color: ${currentTextColor};
|
|
top: 50px;
|
|
left: 50px;
|
|
min-width: 100px;
|
|
min-height: 40px;
|
|
font-family: ${font_family};
|
|
border-radius: 8px;
|
|
z-index: 5;
|
|
">
|
|
${certificate_element_content}
|
|
<div class="remove-item" onclick="$(this).parent().remove(); positionTracking(this.parentNode)">
|
|
<i class="fas fa-times"></i>
|
|
</div>
|
|
</div>`;
|
|
|
|
if (certificate_element_content.trim() !== '') {
|
|
$('#certificate-layout-module').append(certificateElem);
|
|
|
|
// Reset form
|
|
$('#certificate_element_content').val('');
|
|
$("#font_size").val(16);
|
|
$("#font_size_value").text('16');
|
|
$("#font_weight").val(400);
|
|
currentTextColor = '#000000';
|
|
$('#color_preview').css('background-color', '#000000');
|
|
$('#text_color').val('#000000');
|
|
|
|
// Reset to default font
|
|
$('.font-family-option').removeClass('active');
|
|
$('.font-family-option[data-value="auto"]').addClass('active').find('input').prop('checked', true);
|
|
|
|
initialize();
|
|
} else {
|
|
alert('Please enter some text content.');
|
|
}
|
|
}
|
|
|
|
function initialize() {
|
|
$(".draggable").draggable({
|
|
containment: "#certificate-layout-module",
|
|
cursor: "move",
|
|
scroll: false
|
|
});
|
|
|
|
$(".resizeable-canvas").resizable({
|
|
resize: function(event, ui) {
|
|
$(".draggable").draggable("disable");
|
|
positionTracking(this);
|
|
},
|
|
stop: function(event, ui) {
|
|
$(".draggable").draggable("enable");
|
|
positionTracking(this);
|
|
},
|
|
handles: "all",
|
|
minHeight: 30,
|
|
minWidth: 50
|
|
});
|
|
|
|
$(".draggable").on("dragstop", function(e, pos) {
|
|
positionTracking(this);
|
|
});
|
|
}
|
|
|
|
function positionTracking(e) {
|
|
var layoutCanvasOffset = $('#certificate-layout-module').offset();
|
|
var layoutCanvasRight = $('#certificate-layout-module').width() + layoutCanvasOffset.left;
|
|
var layoutCanvasBottom = $('#certificate-layout-module').height() + layoutCanvasOffset.top;
|
|
|
|
if ($(e).attr('id') != 'certificate-layout-module') {
|
|
var itemOffset = $(e).offset();
|
|
var itemRight = $(e).width() + itemOffset.left;
|
|
var itemBottom = $(e).height() + itemOffset.top;
|
|
|
|
if (
|
|
layoutCanvasOffset.left < itemOffset.left &&
|
|
layoutCanvasOffset.top < itemOffset.top &&
|
|
layoutCanvasRight > itemRight &&
|
|
layoutCanvasBottom > itemBottom
|
|
) {
|
|
$(e).removeClass('hidden-position');
|
|
$(e).css('border-color', 'rgba(21, 181, 126, 0.5)');
|
|
} else {
|
|
$(e).addClass('hidden-position');
|
|
$(e).css('border-color', '#ff6b6b');
|
|
}
|
|
} else {
|
|
var draggableItems = document.getElementsByClassName("draggable");
|
|
for (var i = 0; i < draggableItems.length; i++) {
|
|
var item = $(draggableItems.item(i));
|
|
if (item.attr('id') == 'certificate-layout-module') continue;
|
|
|
|
var itemOffset = item.offset();
|
|
var itemRight = item.width() + itemOffset.left;
|
|
var itemBottom = item.height() + itemOffset.top;
|
|
|
|
if (
|
|
layoutCanvasOffset.left < itemOffset.left &&
|
|
layoutCanvasOffset.top < itemOffset.top &&
|
|
layoutCanvasRight > itemRight &&
|
|
layoutCanvasBottom > itemBottom
|
|
) {
|
|
item.removeClass('hidden-position');
|
|
item.css('border-color', 'rgba(21, 181, 126, 0.5)');
|
|
} else {
|
|
item.addClass('hidden-position');
|
|
item.css('border-color', '#ff6b6b');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html> |