first commit
Some checks failed
CI / build-test (push) Has been cancelled

This commit is contained in:
2025-05-31 18:56:37 +02:00
commit 8c4798a5fd
1240 changed files with 190468 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
<?php
/**
* @var string $attributes
*/
?>
<div class="appointment-status-options" <?= $attributes ?? '' ?>>
<ul class="list-group">
<!-- JS -->
</ul>
<button type="button" class="btn btn-outline-primary btn-sm add-appointment-status-option">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/appointment_status_options.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,379 @@
<?php
/**
* Local variables.
*
* @var array $available_services
* @var array $appointment_status_options
* @var array $timezones
* @var array $require_first_name
* @var array $require_last_name
* @var array $require_email
* @var array $require_phone_number
* @var array $require_address
* @var array $require_city
* @var array $require_zip_code
* @var array $require_notes
*/
?>
<div id="appointments-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"><?= lang('edit_appointment_title') ?></h3>
<button class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="modal-message alert d-none"></div>
<form>
<fieldset>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('appointment_details_title') ?></h5>
<input id="appointment-id" type="hidden">
<div class="row">
<div class="col-12 col-sm-6">
<div class="mb-3">
<label for="select-service" class="form-label">
<?= lang('service') ?>
<span class="text-danger">*</span>
</label>
<select id="select-service" class="required form-select">
<?php
// Group services by category, only if there is at least one service
// with a parent category.
$has_category = false;
foreach ($available_services as $service) {
if (!empty($service['category_id'])) {
$has_category = true;
break;
}
}
if ($has_category) {
$grouped_services = [];
foreach ($available_services as $service) {
if (!empty($service['category_id'])) {
if (!isset($grouped_services[$service['category_name']])) {
$grouped_services[$service['category_name']] = [];
}
$grouped_services[$service['category_name']][] = $service;
}
}
// We need the uncategorized services at the end of the list, so we will use
// another iteration only for the uncategorized services.
$grouped_services['uncategorized'] = [];
foreach ($available_services as $service) {
if ($service['category_id'] == null) {
$grouped_services['uncategorized'][] = $service;
}
}
foreach ($grouped_services as $key => $group) {
$group_label =
$key !== 'uncategorized'
? e($group[0]['category_name'])
: 'Uncategorized';
if (count($group) > 0) {
echo '<optgroup label="' . $group_label . '">';
foreach ($group as $service) {
echo '<option value="' .
$service['id'] .
'">' .
e($service['name']) .
'</option>';
}
echo '</optgroup>';
}
}
} else {
foreach ($available_services as $service) {
echo '<option value="' .
$service['id'] .
'">' .
e($service['name']) .
'</option>';
}
}
?>
</select>
</div>
<?php slot('after_select_appointment_service'); ?>
<div class="mb-3">
<label for="select-provider" class="form-label">
<?= lang('provider') ?>
<span class="text-danger">*</span>
</label>
<select id="select-provider" class="required form-select"></select>
</div>
<?php slot('after_select_appointment_provider'); ?>
<div class="mb-3">
<?php component('color_selection', ['attributes' => 'id="appointment-color"']); ?>
</div>
<div class="mb-3">
<label for="appointment-location" class="form-label">
<?= lang('location') ?>
</label>
<input id="appointment-location" class="form-control">
</div>
<div class="mb-3">
<label for="appointment-status" class="form-label">
<?= lang('status') ?>
</label>
<select id="appointment-status" class="form-select">
<?php foreach ($appointment_status_options as $appointment_status_option): ?>
<option value="<?= e($appointment_status_option) ?>">
<?= e($appointment_status_option) ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="col-12 col-sm-6">
<div class="mb-3">
<label for="start-datetime"
class="form-label"><?= lang('start_date_time') ?></label>
<input id="start-datetime" class="required form-control">
</div>
<div class="mb-3">
<label for="end-datetime" class="form-label"><?= lang('end_date_time') ?></label>
<input id="end-datetime" class="required form-control">
</div>
<div class="mb-3">
<label class="form-label">
<?= lang('timezone') ?>
</label>
<div
class="border rounded d-flex justify-content-between align-items-center bg-light timezone-info">
<div class="border-end w-50 p-1 text-center">
<small>
<?= lang('provider') ?>:
<span class="provider-timezone">
-
</span>
</small>
</div>
<div class="w-50 p-1 text-center">
<small>
<?= lang('current_user') ?>:
<span>
<?= $timezones[session('timezone', 'UTC')] ?>
</span>
</small>
</div>
</div>
</div>
<div class="mb-3">
<label for="appointment-notes" class="form-label"><?= lang('notes') ?></label>
<textarea id="appointment-notes" class="form-control" rows="3"></textarea>
</div>
<?php slot('after_primary_appointment_fields'); ?>
</div>
</div>
</fieldset>
<?php slot('after_appointment_details'); ?>
<br>
<fieldset>
<h5 class="text-black-50 mb-3 fw-light">
<?= lang('customer_details_title') ?>
<button id="new-customer" class="btn btn-outline-secondary btn-sm" type="button"
data-tippy-content="<?= lang('clear_fields_add_existing_customer_hint') ?>">
<i class="fas fa-plus-square me-2"></i>
<?= lang('new') ?>
</button>
<button id="select-customer" class="btn btn-outline-secondary btn-sm" type="button"
data-tippy-content="<?= lang('pick_existing_customer_hint') ?>">
<i class="fas fa-hand-pointer me-2"></i>
<span>
<?= lang('select') ?>
</span>
</button>
<input id="filter-existing-customers"
placeholder="<?= lang('type_to_filter_customers') ?>"
style="display: none;" class="input-sm form-control">
</h5>
<div id="existing-customers-list" style="display: none;"></div>
<input id="customer-id" type="hidden">
<div class="row">
<div class="col-12 col-sm-6">
<div class="mb-3">
<label for="first-name" class="form-label">
<?= lang('first_name') ?>
<?php if ($require_first_name): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="first-name"
class="<?= $require_first_name ? 'required' : '' ?> form-control"
maxlength="100"/>
</div>
<div class="mb-3">
<label for="last-name" class="form-label">
<?= lang('last_name') ?>
<?php if ($require_last_name): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="last-name"
class="<?= $require_last_name ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<div class="mb-3">
<label for="email" class="form-label">
<?= lang('email') ?>
<?php if ($require_email): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="email"
class="<?= $require_email ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<div class="mb-3">
<label for="phone-number" class="form-label">
<?= lang('phone_number') ?>
<?php if ($require_phone_number): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="phone-number" maxlength="60"
class="<?= $require_phone_number ? 'required' : '' ?> form-control"/>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required">
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php component('custom_fields'); ?>
<?php slot('after_primary_customer_custom_fields'); ?>
</div>
<div class="col-12 col-sm-6">
<div class="mb-3">
<label for="address" class="form-label">
<?= lang('address') ?>
<?php if ($require_address): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="address"
class="<?= $require_address ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<div class="mb-3">
<label for="city" class="form-label">
<?= lang('city') ?>
<?php if ($require_city): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="city"
class="<?= $require_city ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<div class="mb-3">
<label for="zip-code" class="form-label">
<?= lang('zip_code') ?>
<?php if ($require_zip_code): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="zip-code"
class="<?= $require_zip_code ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required"',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<div class="mb-3">
<label for="customer-notes" class="form-label">
<?= lang('notes') ?>
<?php if ($require_notes): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<textarea id="customer-notes" rows="2"
class="<?= $require_notes ? 'required' : '' ?> form-control"></textarea>
</div>
<?php slot('after_primary_customer_fields'); ?>
</div>
</div>
</fieldset>
<?php slot('after_customer_details'); ?>
</form>
</div>
<div class="modal-footer">
<?php slot('before_appointment_actions'); ?>
<button class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('cancel') ?>
</button>
<button id="save-appointment" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
</div>
</div>
</div>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/appointments_modal.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,52 @@
<?php
/**
* Local variables.
*
* @var string $user_display_name
*/
?>
<div id="footer" class="d-lg-flex justify-content-lg-start align-items-lg-center p-2 text-center text-lg-left mt-auto">
<div class="mb-3 me-lg-5 mb-lg-0">
<img class="me-1" src="<?= base_url('assets/img/logo-16x16.png') ?>" alt="Easy!Appointments Logo">
<a href="https://easyappointments.org">Easy!Appointments</a>
<span>v<?= config('version') ?></span>
</div>
<div class="mb-3 me-lg-5 mb-lg-0">
<img class="me-1" src="<?= base_url('assets/img/alextselegidis-logo-16x16.png') ?>" alt="Alex Tselegidis Logo">
<a href="https://alextselegidis.com">Alex Tselegidis</a>
&copy; <?= date('Y') ?> - Software Development
</div>
<div class="mb-3 me-lg-5 mb-lg-0">
<?= lang('licensed_under') ?>
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html">
GPL-3.0
</a>
</div>
<div class="mb-3 me-lg-5 mb-lg-0">
<span id="select-language" class="badge bg-dark">
<i class="fas fa-language me-2"></i>
<?= ucfirst(config('language')) ?>
</span>
</div>
<div class="mb-3 me-lg-5 mb-lg-0">
<a href="<?= site_url('appointments') ?>">
<?= lang('go_to_booking_page') ?>
</a>
</div>
<div class="ms-lg-auto">
<strong id="footer-user-display-name">
<?= lang('hello') . ', ' . e($user_display_name) ?>!
</strong>
</div>
</div>

View File

@@ -0,0 +1,127 @@
<?php
/**
* Local variables.
*
* @var string $active_menu
* @var string $company_logo
*/
?>
<nav id="header" class="navbar navbar-expand-md navbar-dark">
<div id="header-logo" class="navbar-brand">
<img src="<?= base_url('assets/img/logo.png') ?>" alt="logo">
<h6>EASY!APPOINTMENTS</h6>
<small>Online Appointment Scheduler</small>
</div>
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#header-menu">
<span class="sr-only">Toggle navigation</span>
<span class="navbar-toggler-icon"></span>
</button>
<div id="header-menu" class="collapse navbar-collapse flex-row-reverse px-2">
<ul class="navbar-nav">
<?php $hidden = can('view', PRIV_APPOINTMENTS) ? '' : 'd-none'; ?>
<?php $active = $active_menu == PRIV_APPOINTMENTS ? 'active' : ''; ?>
<li class="nav-item <?= $active . $hidden ?>">
<a href="<?= site_url(
'calendar' . (vars('calendar_view') === CALENDAR_VIEW_TABLE ? '?view=table' : ''),
) ?>"
class="nav-link"
data-tippy-content="<?= lang('manage_appointment_record_hint') ?>">
<i class="fas fa-calendar-alt me-2"></i>
<?= lang('calendar') ?>
</a>
</li>
<?php $hidden = can('view', PRIV_CUSTOMERS) ? '' : 'd-none'; ?>
<?php $active = $active_menu == PRIV_CUSTOMERS ? 'active' : ''; ?>
<li class="nav-item <?= $active . $hidden ?>">
<a href="<?= site_url('customers') ?>" class="nav-link"
data-tippy-content="<?= lang('manage_customers_hint') ?>">
<i class="fas fa-user-friends me-2"></i>
<?= lang('customers') ?>
</a>
</li>
<?php $hidden = can('view', PRIV_SERVICES) ? '' : 'd-none'; ?>
<?php $active = $active_menu == PRIV_SERVICES ? 'active' : ''; ?>
<li class="nav-item dropdown <?= $active . $hidden ?>">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown"
data-tippy-content="<?= lang('manage_services_hint') ?>">
<i class="fas fa-business-time me-2"></i>
<?= lang('services') ?>
</a>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="<?= site_url('services') ?>">
<?= lang('services') ?>
</a>
<a class="dropdown-item" href="<?= site_url('service_categories') ?>">
<?= lang('categories') ?>
</a>
</div>
</li>
<?php $hidden = can('view', PRIV_USERS) ? '' : 'd-none'; ?>
<?php $active = $active_menu == PRIV_USERS ? 'active' : ''; ?>
<li class="nav-item dropdown <?= $active . $hidden ?>">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown"
data-tippy-content="<?= lang('manage_users_hint') ?>">
<i class="fas fa-users me-2"></i>
<?= lang('users') ?>
</a>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="<?= site_url('providers') ?>">
<?= lang('providers') ?>
</a>
<a class="dropdown-item" href="<?= site_url('secretaries') ?>">
<?= lang('secretaries') ?>
</a>
<a class="dropdown-item" href="<?= site_url('admins') ?>">
<?= lang('admins') ?>
</a>
</div>
</li>
<?php slot('before_user_nav_item'); ?>
<?php $hidden = can('view', PRIV_SYSTEM_SETTINGS) || can('view', PRIV_USER_SETTINGS) ? '' : 'd-none'; ?>
<?php $active = $active_menu == PRIV_SYSTEM_SETTINGS ? 'active' : ''; ?>
<li class="nav-item dropdown <?= $active . $hidden ?>">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown"
data-tippy-content="<?= lang('settings_hint') ?>">
<i class="fas fa-user me-2"></i>
<?= e(vars('user_display_name')) ?>
</a>
<div class="dropdown-menu dropdown-menu-end">
<?php if (can('view', PRIV_SYSTEM_SETTINGS)): ?>
<a class="dropdown-item" href="<?= site_url('general_settings') ?>">
<?= lang('settings') ?>
</a>
<?php endif; ?>
<?php slot('after_settings_dropdown_item'); ?>
<a class="dropdown-item" href="<?= site_url('account') ?>">
<?= lang('account') ?>
</a>
<a class="dropdown-item" href="<?= site_url('about') ?>">
<?= lang('about') ?>
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="<?= site_url('logout') ?>">
<?= lang('log_out') ?>
</a>
</div>
</li>
</ul>
</div>
</nav>
<div id="notification" style="display: none;"></div>
<div id="loading" style="display: none;">
<div class="any-element animation is-loading">
&nbsp;
</div>
</div>

View File

@@ -0,0 +1,42 @@
<?php
/**
* Local variables.
*
* @var bool $manage_mode
* @var array $appointment_data
* @var bool $display_delete_personal_information
*/
?>
<?php if ($manage_mode): ?>
<div id="cancel-appointment-frame" class="row booking-header-bar">
<div class="col-md-10">
<small><?= lang('cancel_appointment_hint') ?></small>
</div>
<div class="col-md-2">
<form id="cancel-appointment-form" method="post"
action="<?= site_url('booking_cancellation/of/' . $appointment_data['hash']) ?>">
<input id="hidden-cancellation-reason" name="cancellation_reason" type="hidden">
<button id="cancel-appointment" class="btn btn-warning btn-sm">
<i class="fas fa-trash me-2"></i>
<?= lang('cancel') ?>
</button>
</form>
</div>
</div>
<?php if ($display_delete_personal_information): ?>
<div class="booking-header-bar row">
<div class="col-md-10">
<small><?= lang('delete_personal_information_hint') ?></small>
</div>
<div class="col-md-2">
<button id="delete-personal-information" class="btn btn-danger btn-sm">
<i class="fas fa-trash me-2"></i>
<?= lang('delete') ?>
</button>
</div>
</div>
<?php endif; ?>
<?php endif; ?>

View File

@@ -0,0 +1,90 @@
<?php
/**
* Local variables.
*
* @var bool $manage_mode
* @var string $display_terms_and_conditions
* @var string $display_privacy_policy
*/
?>
<div id="wizard-frame-4" class="wizard-frame" style="display:none;">
<div class="frame-container">
<h2 class="frame-title"><?= lang('appointment_confirmation') ?></h2>
<div class="row frame-content m-auto pt-md-4 mb-4">
<div id="appointment-details" class="col-12 col-md-6 text-center text-md-start mb-2 mb-md-0">
<!-- JS -->
</div>
<div id="customer-details" class="col-12 col-md-6 text-center text-md-end">
<!-- JS -->
</div>
</div>
<?php slot('after_details'); ?>
<?php if (setting('require_captcha')): ?>
<div class="row frame-content m-auto">
<div class="col">
<label class="captcha-title" for="captcha-text">
CAPTCHA
<button class="btn btn-link text-dark text-decoration-none py-0">
<i class="fas fa-sync-alt"></i>
</button>
</label>
<img class="captcha-image" src="<?= site_url('captcha') ?>" alt="CAPTCHA">
<input id="captcha-text" class="captcha-text form-control" type="text" value=""/>
<span id="captcha-hint" class="help-block" style="opacity:0">&nbsp;</span>
</div>
</div>
<?php endif; ?>
<?php slot('after_captcha'); ?>
</div>
<div class="d-flex fs-6 justify-content-around">
<?php if ($display_terms_and_conditions): ?>
<div class="form-check mb-3">
<input type="checkbox" class="required form-check-input" id="accept-to-terms-and-conditions">
<label class="form-check-label" for="accept-to-terms-and-conditions">
<?= strtr(lang('read_and_agree_to_terms_and_conditions'), [
'{$link}' => '<a href="#" data-bs-toggle="modal" data-bs-target="#terms-and-conditions-modal">',
'{/$link}' => '</a>',
]) ?>
</label>
</div>
<?php endif; ?>
<?php if ($display_privacy_policy): ?>
<div class="form-check mb-3">
<input type="checkbox" class="required form-check-input" id="accept-to-privacy-policy">
<label class="form-check-label" for="accept-to-privacy-policy">
<?= strtr(lang('read_and_agree_to_privacy_policy'), [
'{$link}' => '<a href="#" data-bs-toggle="modal" data-bs-target="#privacy-policy-modal">',
'{/$link}' => '</a>',
]) ?>
</label>
</div>
<?php endif; ?>
<?php slot('after_select_policies'); ?>
</div>
<div class="command-buttons">
<button type="button" id="button-back-4" class="btn button-back btn-outline-secondary"
data-step_index="4">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</button>
<form id="book-appointment-form" style="display:inline-block" method="post">
<button id="book-appointment-submit" type="button" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= $manage_mode ? lang('update') : lang('confirm') ?>
</button>
<input type="hidden" name="csrfToken"/>
<input type="hidden" name="post_data"/>
</form>
</div>
</div>

View File

@@ -0,0 +1,31 @@
<?php
/**
* Local variables.
*
* @var bool $display_login_button
*/
?>
<div id="frame-footer">
<small>
<span class="footer-powered-by small">
Powered By
<a href="https://easyappointments.org" target="_blank">Easy!Appointments</a>
</span>
<span class="footer-options">
<span id="select-language" class="badge bg-secondary">
<i class="fas fa-language me-2"></i>
<?= ucfirst(config('language')) ?>
</span>
<?php if ($display_login_button): ?>
<a class="backend-link badge bg-primary text-decoration-none px-2"
href="<?= session('user_id') ? site_url('calendar') : site_url('login') ?>">
<i class="fas fa-sign-in-alt me-2"></i>
<?= session('user_id') ? lang('backend_section') : lang('login') ?>
</a>
<?php endif; ?>
</span>
</small>
</div>

View File

@@ -0,0 +1,43 @@
<?php
/**
* Local variables.
*
* @var string $company_name
*/
?>
<div id="header">
<div id="company-name">
<img src="<?= vars('company_logo') ?: base_url('assets/img/logo.png') ?>" alt="logo" id="company-logo">
<span>
<?= e($company_name) ?>
</span>
<div class="d-flex justify-content-center justify-content-md-start">
<span class="display-booking-selection">
<?= lang('service') ?> │ <?= lang('provider') ?>
</span>
</div>
</div>
<div id="steps">
<div id="step-1" class="book-step active-step"
data-tippy-content="<?= lang('service_and_provider') ?>">
<strong>1</strong>
</div>
<div id="step-2" class="book-step" data-bs-toggle="tooltip"
data-tippy-content="<?= lang('appointment_date_and_time') ?>">
<strong>2</strong>
</div>
<div id="step-3" class="book-step" data-bs-toggle="tooltip"
data-tippy-content="<?= lang('customer_information') ?>">
<strong>3</strong>
</div>
<div id="step-4" class="book-step" data-bs-toggle="tooltip"
data-tippy-content="<?= lang('appointment_confirmation') ?>">
<strong>4</strong>
</div>
</div>
</div>

View File

@@ -0,0 +1,158 @@
<?php
/**
* Local variables.
*
* @var string $display_first_name
* @var string $require_first_name
* @var string $display_last_name
* @var string $require_last_name
* @var string $display_email
* @var string $require_email
* @var string $display_phone_number
* @var string $require_phone_number
* @var string $display_address
* @var string $require_address
* @var string $display_city
* @var string $require_city
* @var string $display_zip_code
* @var string $require_zip_code
* @var string $display_notes
* @var string $require_notes
*/
?>
<div id="wizard-frame-3" class="wizard-frame" style="display:none;">
<div class="frame-container">
<h2 class="frame-title"><?= lang('customer_information') ?></h2>
<div class="row frame-content">
<div class="col-12 col-md-6 field-col mx-auto">
<?php if ($display_first_name): ?>
<div class="mb-3">
<label for="first-name" class="form-label">
<?= lang('first_name') ?>
<?php if ($require_first_name): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="first-name"
class="<?= $require_first_name ? 'required' : '' ?> form-control" maxlength="100"/>
</div>
<?php endif; ?>
<?php if ($display_last_name): ?>
<div class="mb-3">
<label for="last-name" class="form-label">
<?= lang('last_name') ?>
<?php if ($require_last_name): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="last-name"
class="<?= $require_last_name ? 'required' : '' ?> form-control" maxlength="120"/>
</div>
<?php endif; ?>
<?php if ($display_email): ?>
<div class="mb-3">
<label for="email" class="form-label">
<?= lang('email') ?>
<?php if ($require_email): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="email"
class="<?= $require_email ? 'required' : '' ?> form-control" maxlength="120"/>
</div>
<?php endif; ?>
<?php if ($display_phone_number): ?>
<div class="mb-3">
<label for="phone-number" class="form-label">
<?= lang('phone_number') ?>
<?php if ($require_phone_number): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="phone-number" maxlength="60"
class="<?= $require_phone_number ? 'required' : '' ?> form-control"/>
</div>
<?php endif; ?>
<?php slot('info_first_column'); ?>
<?php component('custom_fields'); ?>
<?php slot('after_custom_fields'); ?>
</div>
<div class="col-12 col-md-6 field-col mx-auto">
<?php if ($display_address): ?>
<div class="mb-3">
<label for="address" class="form-label">
<?= lang('address') ?>
<?php if ($require_address): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="address" class="<?= $require_address ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<?php endif; ?>
<?php if ($display_city): ?>
<div class="mb-3">
<label for="city" class="form-label">
<?= lang('city') ?>
<?php if ($require_city): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="city" class="<?= $require_city ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<?php endif; ?>
<?php if ($display_zip_code): ?>
<div class="mb-3">
<label for="zip-code" class="form-label">
<?= lang('zip_code') ?>
<?php if ($require_zip_code): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<input type="text" id="zip-code" class="<?= $require_zip_code ? 'required' : '' ?> form-control"
maxlength="120"/>
</div>
<?php endif; ?>
<?php if ($display_notes): ?>
<div class="mb-3">
<label for="notes" class="form-label">
<?= lang('notes') ?>
<?php if ($require_notes): ?>
<span class="text-danger">*</span>
<?php endif; ?>
</label>
<textarea id="notes" maxlength="500"
class="<?= $require_notes ? 'required' : '' ?> form-control" rows="1"></textarea>
</div>
<?php endif; ?>
<?php slot('info_second_column'); ?>
</div>
</div>
</div>
<div class="command-buttons">
<button type="button" id="button-back-3" class="btn button-back btn-outline-secondary"
data-step_index="3">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</button>
<button type="button" id="button-next-3" class="btn button-next btn-dark"
data-step_index="3">
<?= lang('next') ?>
<i class="fas fa-chevron-right ms-2"></i>
</button>
</div>
</div>

View File

@@ -0,0 +1,56 @@
<?php
/**
* Local variables.
*
* @var array $grouped_timezones
*/
?>
<div id="wizard-frame-2" class="wizard-frame" style="display:none;">
<div class="frame-container">
<h2 class="frame-title"><?= lang('appointment_date_and_time') ?></h2>
<div class="row frame-content">
<div class="col-12 col-md-6">
<div id="select-date"></div>
<?php slot('after_select_date'); ?>
</div>
<div class="col-12 col-md-6">
<div id="select-time">
<div class="mb-3">
<label for="select-timezone" class="form-label">
<?= lang('timezone') ?>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="select-timezone" class="form-select" value="UTC"',
'grouped_timezones' => $grouped_timezones,
]); ?>
</div>
<?php slot('after_select_timezone'); ?>
<div id="available-hours"></div>
<?php slot('after_available_hours'); ?>
</div>
</div>
</div>
</div>
<div class="command-buttons">
<button type="button" id="button-back-2" class="btn button-back btn-outline-secondary"
data-step_index="2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</button>
<button type="button" id="button-next-2" class="btn button-next btn-dark"
data-step_index="2">
<?= lang('next') ?>
<i class="fas fa-chevron-right ms-2"></i>
</button>
</div>
</div>

View File

@@ -0,0 +1,116 @@
<?php
/**
* Local variables.
*
* @var array $available_services
*/
?>
<div id="wizard-frame-1" class="wizard-frame" style="visibility: hidden;">
<div class="frame-container">
<h2 class="frame-title mt-md-5"><?= lang('service_and_provider') ?></h2>
<div class="row frame-content">
<div class="col col-md-8 offset-md-2">
<div class="mb-3">
<label for="select-service">
<strong><?= lang('service') ?></strong>
</label>
<select id="select-service" class="form-select">
<option value="">
<?= lang('please_select') ?>
</option>
<?php
// Group services by category, only if there is at least one service with a parent category.
$has_category = false;
foreach ($available_services as $service) {
if (!empty($service['service_category_id'])) {
$has_category = true;
break;
}
}
if ($has_category) {
$grouped_services = [];
foreach ($available_services as $service) {
if (!empty($service['service_category_id'])) {
if (!isset($grouped_services[$service['service_category_name']])) {
$grouped_services[$service['service_category_name']] = [];
}
$grouped_services[$service['service_category_name']][] = $service;
}
}
// We need the uncategorized services at the end of the list, so we will use another
// iteration only for the uncategorized services.
$grouped_services['uncategorized'] = [];
foreach ($available_services as $service) {
if ($service['service_category_id'] == null) {
$grouped_services['uncategorized'][] = $service;
}
}
foreach ($grouped_services as $key => $group) {
$group_label =
$key !== 'uncategorized' ? $group[0]['service_category_name'] : 'Uncategorized';
if (count($group) > 0) {
echo '<optgroup label="' . e($group_label) . '">';
foreach ($group as $service) {
echo '<option value="' .
$service['id'] .
'">' .
e($service['name']) .
'</option>';
}
echo '</optgroup>';
}
}
} else {
foreach ($available_services as $service) {
echo '<option value="' . $service['id'] . '">' . e($service['name']) . '</option>';
}
}
?>
</select>
</div>
<?php slot('after_select_service'); ?>
<div class="mb-3" hidden>
<label for="select-provider">
<strong><?= lang('provider') ?></strong>
</label>
<select id="select-provider" class="form-select">
<option value="">
<?= lang('please_select') ?>
</option>
</select>
</div>
<?php slot('after_select_provider'); ?>
<div id="service-description" class="small">
<!-- JS -->
</div>
<?php slot('after_service_description'); ?>
</div>
</div>
</div>
<div class="command-buttons">
<span>&nbsp;</span>
<button type="button" id="button-next-1" class="btn button-next btn-dark"
data-step_index="1">
<?= lang('next') ?>
<i class="fas fa-chevron-right ms-2"></i>
</button>
</div>
</div>

View File

@@ -0,0 +1,65 @@
<?php
/**
* @var string $attributes
*/
?>
<?php section('styles'); ?>
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/components/color_selection.css') ?>">
<?php end_section('styles'); ?>
<label class="form-label"><?= lang('color') ?></label>
<div <?= $attributes ?? '' ?> class="color-selection d-flex justify-content-between mb-4">
<button type="button" class="color-selection-option selected" data-value="#7cbae8">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#acbefb">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#82e4ec">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#7cebc1">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#abe9a4">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#ebe07c">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#f3bc7d">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#f3aea6">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#eb8687">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#dfaffe">
<i class="fas fa-check"></i>
</button>
<button type="button" class="color-selection-option" data-value="#e3e3e3">
<i class="fas fa-check"></i>
</button>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/color_selection.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,197 @@
<?php
/**
* @var string $company_color
*/
?>
<?php if (!empty($company_color) && $company_color !== DEFAULT_COMPANY_COLOR): ?>
<style>
/* Generic Overrides */
a {
color: <?= $company_color ?>;
}
a:hover {
color: <?= $company_color ?>;
}
.btn-primary {
background-color: <?= $company_color ?>;
border-color: <?= $company_color ?>;
}
.btn-primary:hover,
.btn-primary:active,
.btn-primary:focus {
background-color: <?= $company_color ?>;
border-color: <?= $company_color ?>;
filter: brightness(120%);
outline: none;
box-shadow: none;
}
.btn-primary:disabled, .btn-primary.disabled {
background-color: <?= $company_color ?>;
border-color: <?= $company_color ?>;
filter: brightness(70%);
opacity: .75;
}
.dropdown-item.active,
.dropdown-item:active {
background-color: <?= $company_color ?> !important;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
background-color: <?= $company_color ?> !important;
}
.nav .nav-link:not(.active) {
color: <?= $company_color ?> !important;
}
.form-control:focus {
border-color: <?= $company_color ?> !important;
filter: brightness(120%);
box-shadow: none;
}
.form-check-input:checked {
background-color: <?= $company_color ?> !important;
border-color: <?= $company_color ?> !important;
}
body .ui-datepicker .ui-slider-handle {
border-color: <?= $company_color ?> !important;
background-color: <?= $company_color ?> !important;
}
body .modal-header {
background: <?= $company_color ?> !important;
}
.fc-daygrid-event {
color: rgb(51, 51, 51) !important;
}
body .ui-draggable .ui-dialog-titlebar {
background: <?= $company_color ?> !important;
}
/* Booking Layout */
#book-appointment-wizard #header {
background: <?= $company_color ?>;
}
#book-appointment-wizard #company-name .display-selected-service,
#book-appointment-wizard #company-name .display-selected-provider {
color: <?= $company_color ?>;
border-right-color: <?= $company_color ?> !important;
filter: brightness(35%);
}
#book-appointment-wizard .book-step {
background: <?= $company_color ?>;
filter: brightness(75%);
}
#book-appointment-wizard .book-step strong {
color: <?= $company_color ?>;
filter: brightness(200%);
}
body .ui-widget.ui-widget-content {
border-color: <?= $company_color ?>;
}
body .ui-datepicker .ui-widget-header {
background-color: <?= $company_color ?>;
}
body .ui-datepicker th {
background-color: <?= $company_color ?>;
}
body .ui-datepicker .ui-datepicker-next-hover,
body .ui-datepicker .ui-datepicker-prev-hover {
background: <?= $company_color ?>;
border-color: <?= $company_color ?>;
filter: brightness(140%);
}
body .ui-datepicker td a, body .ui-datepicker td span {
color: <?= $company_color ?> !important;
}
html body .ui-datepicker td a.ui-state-active {
background: <?= $company_color ?> !important;
}
body .ui-datepicker td a.ui-state-highlight {
background: <?= $company_color ?> !important;
filter: brightness(140%);
}
#book-appointment-wizard #available-hours .selected-hour {
background-color: <?= $company_color ?>;
border-color: <?= $company_color ?>;
}
#frame-footer .backend-link {
background-color: <?= $company_color ?> !important;
}
#frame-footer .backend-link:hover {
color: #fff;
}
/* Backend Layout */
#header {
background-color: <?= $company_color ?> !important;
}
#header #header-menu .nav-item:hover,
#header #header-menu .nav-item.active {
background: <?= $company_color ?> !important;
}
#header #header-logo small {
color: <?= $company_color ?> !important;
filter: brightness(60%);
}
.backend-page .filter-records .results .entry.selected {
border-right-color: <?= $company_color ?> !important;
}
.flatpickr-calendar .flatpickr-months,
.flatpickr-calendar .flatpickr-months .flatpickr-month,
.flatpickr-calendar .flatpickr-weekdays,
.flatpickr-calendar .flatpickr-current-month .flatpickr-monthDropdown-months,
.flatpickr-calendar span.flatpickr-weekday {
background: <?= $company_color ?> !important;
}
.flatpickr-day.endRange, .flatpickr-day.endRange.inRange, .flatpickr-day.endRange.nextMonthDay, .flatpickr-day.endRange.prevMonthDay, .flatpickr-day.endRange:focus, .flatpickr-day.endRange:hover, .flatpickr-day.selected, .flatpickr-day.selected.inRange, .flatpickr-day.selected.nextMonthDay, .flatpickr-day.selected.prevMonthDay, .flatpickr-day.selected:focus, .flatpickr-day.selected:hover, .flatpickr-day.startRange, .flatpickr-day.startRange.inRange, .flatpickr-day.startRange.nextMonthDay, .flatpickr-day.startRange.prevMonthDay, .flatpickr-day.startRange:focus, .flatpickr-day.startRange:hover {
background: <?= $company_color ?> !important;
border-color: <?= $company_color ?> !important;
}
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {
background-color: <?= $company_color ?> !important;
}
#existing-customers-list div:hover {
background: <?= $company_color ?> !important;
}
#book-appointment-wizard #company-name .display-booking-selection {
color: <?= $company_color ?>;
border-right-color: <?= $company_color ?>;
filter: brightness(280%);
}
</style>
<?php endif; ?>

View File

@@ -0,0 +1,25 @@
<?php
/**
* Local variables.
*
* @var string $cookie_notice_content
*/
?>
<div id="cookie-notice-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= lang('cookie_notice') ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<?= pure_html($cookie_notice_content) ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('close') ?>
</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,24 @@
<?php
/**
* Local variables.
*
* @var bool $disabled (false)
*/
$disabled = $disabled ?? false; ?>
<?php for ($i = 1; $i <= 5; $i++): ?>
<?php if (setting('display_custom_field_' . $i)): ?>
<div class="mb-3">
<label for="custom-field-<?= $i ?>" class="form-label">
<?= setting('label_custom_field_' . $i) ?: lang('custom_field') . ' #' . $i ?>
<?php if (setting('require_custom_field_' . $i)): ?>
<span class="text-danger" <?= $disabled ? 'hidden' : '' ?>>*</span>
<?php endif; ?>
</label>
<input type="text" id="custom-field-<?= $i ?>"
class="<?= setting('require_custom_field_' . $i) ? 'required' : '' ?> form-control"
maxlength="120" <?= $disabled ? 'disabled' : '' ?>/>
</div>
<?php endif; ?>
<?php endfor; ?>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @var string $google_analytics_code
*/
?>
<?php if (substr($google_analytics_code ?? '', 0, 2) === 'UA'): ?>
<script>
(function (i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "<?= e($google_analytics_code) ?>", "auto");
ga("send", "pageview");
</script>
<?php endif; ?>
<?php if (substr($google_analytics_code ?? '', 0, 2) === 'G-'): ?>
<script async src="https://www.googletagmanager.com/gtag/js?id=' . $google_analytics_code . '"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "<?= e($google_analytics_code) ?>");
</script>
<?php endif; ?>

View File

@@ -0,0 +1,19 @@
<script>
window.lang = (function () {
const lang = <?= json_encode(html_vars('language')) ?>;
return (key) => {
if (!key) {
return lang;
}
if (!lang[key]) {
console.error(`Cannot find translation for requested key: "${key}"`);
return key;
}
return lang[key];
};
})();
</script>

View File

@@ -0,0 +1,14 @@
<script>
window.vars = (function () {
const vars = <?= json_encode(script_vars()) ?>;
return (key) => {
if (!key) {
return vars;
}
return vars[key] || undefined;
};
})();
</script>

View File

@@ -0,0 +1,105 @@
<?php
/**
* Local variables.
*
* @var array $roles
*/
?>
<div id="ldap-import-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"><?= lang('import') ?></h3>
<button class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label" for="ldap-import-ldap-dn">
<?= lang('ldap_dn') ?>
<span class="text-danger">*</span>
</label>
<input id="ldap-import-ldap-dn" class="form-control required" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-role-slug">
<?= lang('role') ?>
<span class="text-danger">*</span>
</label>
<select id="ldap-import-role-slug" class="form-select required">
<?php foreach ($roles as $role): ?>
<option value="<?= $role['slug'] ?>">
<?= $role['name'] ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-first-name">
<?= lang('first_name') ?>
<span class="text-danger">*</span>
</label>
<input id="ldap-import-first-name" class="form-control required" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-last-name">
<?= lang('last_name') ?>
<span class="text-danger">*</span>
</label>
<input id="ldap-import-last-name" class="form-control required" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-email">
<?= lang('email') ?>
<span class="text-danger">*</span>
</label>
<input id="ldap-import-email" class="form-control required" max="512">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-phone-number">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
</label>
<input id="ldap-import-phone-number" class="form-control required" max="128">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-username">
<?= lang('username') ?>
</label>
<input id="ldap-import-username" class="form-control" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-import-password">
<?= lang('password') ?>
</label>
<input type="password" id="ldap-import-password" class="form-control"
maxlength="512" autocomplete="new-password">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('cancel') ?>
</button>
<button id="ldap-import-save" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
</div>
</div>
</div>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/ldap_import_modal.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* @var string $matomo_analytics_url
* @var string $matomo_analytics_site_id
*/
?>
<?php if (!empty($matomo_analytics_url)): ?>
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "<?= e($matomo_analytics_url) ?>";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '<?= e($matomo_analytics_site_id) ?>']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.async = true;
g.src = u + 'matomo.js';
s.parentNode.insertBefore(g, s);
})();
</script>
<noscript>
<p><img src="<?= e($matomo_analytics_url) ?>matomo.php?idsite=<?= e(
$matomo_analytics_site_id,
) ?>&amp;rec=1" style="border:0;" alt=""/></p>
</noscript>
<?php endif; ?>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Local variables.
*
* @var string $privacy_policy_content
*/
?>
<div id="privacy-policy-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= lang('privacy_policy') ?></h4>
<button class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<?= pure_html($privacy_policy_content) ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('close') ?>
</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
<h4 class=" text-black-50 py-3 mb-3 border-bottom fw-light">
<?= lang('settings') ?>
</h4>
<ul id="settings-nav" class="nav flex-column">
<li class="nav-item mb-3">
<a class="nav-link px-0 py-2" href="<?= site_url('general_settings') ?>">
<?= lang('general_settings') ?>
</a>
</li>
<li class="nav-item mb-3">
<a class="nav-link px-0 py-2" href="<?= site_url('booking_settings') ?>">
<?= lang('booking_settings') ?>
</a>
</li>
<li class="nav-item mb-3">
<a class="nav-link px-0 py-2" href="<?= site_url('business_settings') ?>">
<?= lang('business_logic') ?>
</a>
</li>
<li class="nav-item mb-3">
<a class="nav-link px-0 py-2" href="<?= site_url('legal_settings') ?>">
<?= lang('legal_contents') ?>
</a>
</li>
<li class="nav-item mb-3">
<a class="nav-link px-0 py-2" href="<?= site_url('integrations') ?>">
<?= lang('integrations') ?>
</a>
</li>
</ul>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Local variables.
*
* @var string $terms_and_conditions_content
*/
?>
<div id="terms-and-conditions-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?= lang('terms_and_conditions') ?></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<?= pure_html($terms_and_conditions_content) ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('close') ?>
</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<?php
/**
* Local variables.
*
* @var string $attributes
* @var array $grouped_timezones
*/
?>
<select <?= $attributes ?>>
<?php foreach ($grouped_timezones as $continent => $entries): ?>
<optgroup label="<?= $continent ?>">
<?php foreach ($entries as $value => $name): ?>
<option value="<?= $value ?>"><?= $name ?></option>
<?php endforeach; ?>
</optgroup>
<?php endforeach; ?>
</select>

View File

@@ -0,0 +1,105 @@
<?php
/**
* Local variables.
*
* @var array $timezones
* @var string $timezone
*/
?>
<div id="unavailabilities-modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"><?= lang('new_unavailability_title') ?></h3>
<button class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="modal-message alert d-none"></div>
<form>
<fieldset>
<input id="unavailability-id" type="hidden">
<div class="mb-3">
<label for="unavailability-provider" class="form-label">
<?= lang('provider') ?>
</label>
<select id="unavailability-provider" class="form-select"></select>
</div>
<?php slot('after_select_appointment_provider'); ?>
<div class="mb-3">
<label for="unavailability-start" class="form-label">
<?= lang('start') ?>
<span class="text-danger">*</span>
</label>
<input id="unavailability-start" class="form-control">
</div>
<div class="mb-3">
<label for="unavailability-end" class="form-label">
<?= lang('end') ?>
<span class="text-danger">*</span>
</label>
<input id="unavailability-end" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">
<?= lang('timezone') ?>
</label>
<div
class="border rounded d-flex justify-content-between align-items-center bg-light timezone-info">
<div class="border-end w-50 p-1 text-center">
<small>
<?= lang('provider') ?>:
<span class="provider-timezone">
-
</span>
</small>
</div>
<div class="w-50 p-1 text-center">
<small>
<?= lang('current_user') ?>:
<span>
<?= $timezones[session('timezone', 'UTC')] ?>
</span>
</small>
</div>
</div>
</div>
<div class="mb-3">
<label for="unavailability-notes" class="form-label">
<?= lang('notes') ?>
</label>
<textarea id="unavailability-notes" rows="3" class="form-control"></textarea>
</div>
<?php slot('after_primary_unavailability_fields'); ?>
</fieldset>
</form>
</div>
<div class="modal-footer">
<?php slot('after_unavailability_actions'); ?>
<button class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('cancel') ?>
</button>
<button id="save-unavailability" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
</div>
</div>
</div>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/unavailabilities_modal.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,84 @@
<div class="modal" id="working-plan-exceptions-modal">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?= lang('working_plan_exception') ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label" for="working-plan-exceptions-date"><?= lang('date') ?></label>
<input class="form-control" id="working-plan-exceptions-date">
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="working-plan-exceptions-is-non-working-day">
<label class="form-check-label" for="working-plan-exceptions-is-non-working-day">
<?= lang('make_non_working_day') ?>
</label>
</div>
<div class="row">
<div class="col-sm-6">
<div class="mb-3">
<label class="form-label" for="working-plan-exceptions-start"><?= lang('start') ?></label>
<input class="form-control" id="working-plan-exceptions-start">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label class="form-label" for="working-plan-exceptions-end"><?= lang('end') ?></label>
<input class="form-control" id="working-plan-exceptions-end">
</div>
</div>
</div>
<h3><?= lang('breaks') ?></h3>
<p>
<?= lang('add_breaks_during_each_day') ?>
</p>
<div>
<button type="button" class="btn btn-outline-primary btn-sm working-plan-exceptions-add-break">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add_break') ?>
</button>
</div>
<br>
<table class="table table-striped" id="working-plan-exceptions-breaks">
<thead>
<tr>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
<th><?= lang('actions') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<?php slot('after_primary_working_plan_exception_fields'); ?>
</div>
<div class="modal-footer">
<?php slot('before_working_plan_exception_actions'); ?>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<?= lang('cancel') ?>
</button>
<button type="button" class="btn btn-primary" id="working-plan-exceptions-save">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
</div>
</div>
</div>
</div>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/components/working_plan_exceptions_modal.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,46 @@
<?php
/**
* Local variables.
*
* @var string $subject
* @var string $message
* @var array $settings
*/
?>
<html lang="en">
<head>
<title><?= $subject ?> | Easy!Appointments</title>
</head>
<body style="font: 13px arial, helvetica, tahoma;">
<div class="email-container" style="width: 650px; border: 1px solid #eee; margin: 30px auto;">
<div id="header" style="background-color: <?= $settings['company_color'] ?? '#429a82' ?>; height: 45px; padding: 10px 15px;">
<strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
<?= e($settings['company_name']) ?>
</strong>
</div>
<div id="content" style="padding: 10px 15px; min-height: 400px">
<h2>
<?= $subject ?>
</h2>
<p>
<?= $message ?>
</p>
</div>
<div id="footer" style="padding: 10px; text-align: center; margin-top: 10px;
border-top: 1px solid #EEE; background: #FAFAFA;">
Powered by
<a href="https://easyappointments.org" style="text-decoration: none;">
Easy!Appointments
</a>
|
<a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
<?= e($settings['company_name']) ?>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,189 @@
<?php
/**
* Local variables.
*
* @var array $appointment
* @var array $service
* @var array $provider
* @var array $customer
* @var array $settings
* @var array $timezone
* @var string $reason
*/
?>
<html lang="en">
<head>
<title><?= lang('appointment_cancelled_title') ?> | Easy!Appointments</title>
</head>
<body style="font: 13px arial, helvetica, tahoma;">
<div class="email-container" style="width: 650px; border: 1px solid #eee; margin: 30px auto;">
<div id="header" style="background-color: <?= $settings['company_color'] ?? '#429a82' ?>; height: 45px; padding: 10px 15px;">
<strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
<?= e($settings['company_name']) ?>
</strong>
</div>
<div id="content" style="padding: 10px 15px; min-height: 400px;">
<h2>
<?= lang('appointment_cancelled_title') ?>
</h2>
<p>
<?= lang('appointment_removed_from_schedule') ?>
</p>
<h2>
<?= lang('appointment_details_title') ?>
</h2>
<table id="appointment-details">
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('service') ?>
</td>
<td style="padding: 3px;">
<?= e($service['name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('provider') ?>
</td>
<td style="padding: 3px;">
<?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('start') ?>
</td>
<td style="padding: 3px;">
<?= format_date_time($appointment['start_datetime']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('end') ?>
</td>
<td style="padding: 3px;">
<?= format_date_time($appointment['end_datetime']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('timezone') ?>
</td>
<td style="padding: 3px;">
<?= format_timezone($timezone) ?>
</td>
</tr>
<?php if (!empty($appointment['status'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('status') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['status']) ?>
</td>
</tr>
<?php endif; ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('description') ?>
</td>
<td style="padding: 3px;">
<?= e($service['description']) ?>
</td>
</tr>
<?php if (!empty($appointment['location'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('location') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['location']) ?>
</td>
</tr>
<?php endif; ?>
<?php if (!empty($appointment['notes'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('notes') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['notes']) ?>
</td>
</tr>
<?php endif; ?>
</table>
<h2>
<?= lang('customer_details_title') ?>
</h2>
<table id="customer-details">
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('name') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('email') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['email']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('phone_number') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['phone_number']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('address') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['address']) ?>
</td>
</tr>
</table>
<h2>
<?= lang('reason') ?>
</h2>
<p>
<?= e($reason) ?>
</p>
</div>
<div id="footer" style="padding: 10px; text-align: center; margin-top: 10px;
border-top: 1px solid #EEE; background: #FAFAFA;">
Powered by
<a href="https://easyappointments.org" style="text-decoration: none;">
Easy!Appointments
</a>
|
<a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
<?= e($settings['company_name']) ?>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,193 @@
<?php
/**
* Local variables.
*
* @var string $subject
* @var string $message
* @var array $appointment
* @var array $service
* @var array $provider
* @var array $customer
* @var array $settings
* @var array $timezone
* @var string $appointment_link
*/
?>
<html lang="en">
<head>
<title>
<?= lang('appointment_details_title') ?> | Easy!Appointments
</title>
</head>
<body style="font: 13px arial, helvetica, tahoma;">
<div class="email-container" style="width: 650px; border: 1px solid #eee; margin: 30px auto;">
<div id="header" style="background-color: <?= $settings['company_color'] ?? '#429a82' ?>; height: 45px; padding: 10px 15px;">
<strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
<?= e($settings['company_name']) ?>
</strong>
</div>
<div id="content" style="padding: 10px 15px; min-height: 400px;">
<h2>
<?= $subject ?>
</h2>
<p>
<?= $message ?>
</p>
<h2>
<?= lang('appointment_details_title') ?>
</h2>
<table id="appointment-details">
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('service') ?>
</td>
<td style="padding: 3px;">
<?= e($service['name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('provider') ?>
</td>
<td style="padding: 3px;">
<?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('start') ?>
</td>
<td style="padding: 3px;">
<?= format_date_time($appointment['start_datetime']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('end') ?>
</td>
<td style="padding: 3px;">
<?= format_date_time($appointment['end_datetime']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('timezone') ?>
</td>
<td style="padding: 3px;">
<?= format_timezone($timezone) ?>
</td>
</tr>
<?php if (!empty($appointment['status'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('status') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['status']) ?>
</td>
</tr>
<?php endif; ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('description') ?>
</td>
<td style="padding: 3px;">
<?= e($service['description']) ?>
</td>
</tr>
<?php if (!empty($appointment['location'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('location') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['location']) ?>
</td>
</tr>
<?php endif; ?>
<?php if (!empty($appointment['notes'])): ?>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('notes') ?>
</td>
<td style="padding: 3px;">
<?= e($appointment['notes']) ?>
</td>
</tr>
<?php endif; ?>
</table>
<h2>
<?= lang('customer_details_title') ?>
</h2>
<table id="customer-details">
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('name') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('email') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['email']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('phone_number') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['phone_number']) ?>
</td>
</tr>
<tr>
<td class="label" style="padding: 3px;font-weight: bold;">
<?= lang('address') ?>
</td>
<td style="padding: 3px;">
<?= e($customer['address']) ?>
</td>
</tr>
</table>
<h2>
<?= lang('appointment_link_title') ?>
</h2>
<a href="<?= e($appointment_link) ?>" style="width: 600px;">
<?= e($appointment_link) ?>
</a>
</div>
<div id="footer" style="padding: 10px; text-align: center; margin-top: 10px;
border-top: 1px solid #EEE; background: #FAFAFA;">
Powered by
<a href="https://easyappointments.org" style="text-decoration: none;">
Easy!Appointments
</a>
|
<a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
<?= e($settings['company_name']) ?>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@@ -0,0 +1,3 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
echo "\nERROR: ", $heading, "\n\n", $message, "\n\n";

View File

@@ -0,0 +1,3 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
echo "\nDatabase error: ", $heading, "\n\n", $message, "\n\n";

View File

@@ -0,0 +1,19 @@
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
An uncaught Exception was encountered
Type: <?= get_class($exception), "\n" ?>
Message: <?= $message, "\n" ?>
Filename: <?= $exception->getFile(), "\n" ?>
Line Number: <?= $exception->getLine() ?>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true): ?>
Backtrace:
<?php foreach ($exception->getTrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
File: <?= $error['file'], "\n" ?>
Line: <?= $error['line'], "\n" ?>
Function: <?= $error['function'], "\n\n" ?>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>

View File

@@ -0,0 +1,3 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
echo "\nERROR: ", $heading, "\n\n", $message, "\n\n";

View File

@@ -0,0 +1,19 @@
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
A PHP Error was encountered
Severity: <?= $severity, "\n" ?>
Message: <?= $message, "\n" ?>
Filename: <?= $filepath, "\n" ?>
Line Number: <?= $line ?>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true): ?>
Backtrace:
<?php foreach (debug_backtrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
File: <?= $error['file'], "\n" ?>
Line: <?= $error['line'], "\n" ?>
Function: <?= $error['function'], "\n\n" ?>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>

View File

@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@@ -0,0 +1,82 @@
<?php
/**
* @var string $heading
* @var string $message
*/
?>
<!doctype html>
<html lang="en" style="
height: 100%;
">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>404 Page Not Found | Easy!Appointments</title>
<style>
#error-container {
background: #ffffff;
min-width: 450px;
max-width: 600px;
margin: auto;
border: 1px solid #D0D0D0;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
#error-container a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
#error-container h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 20px;
}
#error-container code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 20px;
}
#error-container p {
margin: 20px;
}
</style>
</head>
<body style="
height: 100%;
padding: 0;
margin: 0;
display: flex;
background: #f5f8fa;
">
<div id="error-container">
<h1>
<?= $heading ?>
</h1>
<?= $message ?>
<p>
<small>
Powered by
<a href="https://easyappointments.org">Easy!Appointments</a>
</small>
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,82 @@
<?php
/**
* @var string $heading
* @var string $message
*/
?>
<!doctype html>
<html lang="en" style="
height: 100%;
">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Database Error | Easy!Appointments</title>
<style>
#error-container {
background: #ffffff;
min-width: 450px;
max-width: 600px;
margin: auto;
border: 1px solid #D0D0D0;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
#error-container a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
#error-container h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 20px;
}
#error-container code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 20px;
}
#error-container p {
margin: 20px;
}
</style>
</head>
<body style="
height: 100%;
padding: 0;
margin: 0;
display: flex;
background: #f5f8fa;
">
<div id="error-container">
<h1>
<?= $heading ?>
</h1>
<?= $message ?>
<p>
<small>
Powered by
<a href="https://easyappointments.org">Easy!Appointments</a>
</small>
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<?php
/**
* @var Throwable $exception
* @var string $message
*/
?>
<div style="
border: 1px solid #dfdfdf;
margin: 0 0 10px 0;
padding: 15px;
font-size: 14px;
">
<h4>
An uncaught Exception was encountered
</h4>
<h6>
Type
</h6>
<p>
<?= get_class($exception) ?>
</p>
<h6>
Message
</h6>
<p>
<?= $message ?>
</p>
<h6>
Filename
</h6>
<p>
<?= $exception->getFile() ?>
</p>
<h6>
Line Number
</h6>
<p>
<?= $exception->getLine() ?>
</p>
<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true): ?>
<h6>
Backtrace
</h6>
<?php foreach ($exception->getTrace() as $error): ?>
<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
<p style="margin-left:10px">
File: <?= $error['file'] ?><br>
Line: <?= $error['line'] ?><br>
Function: <?= $error['function'] ?>
</p>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,82 @@
<?php
/**
* @var string $heading
* @var string $message
*/
?>
<!doctype html>
<html lang="en" style="
height: 100%;
">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Error | Easy!Appointments</title>
<style>
#error-container {
background: #ffffff;
min-width: 450px;
max-width: 600px;
margin: auto;
border: 1px solid #D0D0D0;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
#error-container a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
#error-container h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 20px;
}
#error-container code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 20px;
}
#error-container p {
margin: 20px;
}
</style>
</head>
<body style="
height: 100%;
padding: 0;
margin: 0;
display: flex;
background: #f5f8fa;
">
<div id="error-container">
<h1>
<?= $heading ?>
</h1>
<?= $message ?>
<p>
<small>
Powered by
<a href="https://easyappointments.org">Easy!Appointments</a>
</small>
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,52 @@
<?php
/**
* @var string $severity
* @var string $message
* @var string $filepath
* @var string $line
*/
?>
<div style="
border: 1px solid #dfdfdf;
margin: 0 0 10px 0;
padding: 15px;
font-size: 14px;
">
<h4>
A PHP Error was encountered
</h4>
<h6>
Severity
</h6>
<p>
<?= $severity ?>
</p>
<h6>
Message
</h6>
<p>
<?= $message ?>
</p>
<h6>
Filename
</h6>
<p>
<?= $filepath ?>
</p>
<h6>
Line Number
</h6>
<p>
<?= $line ?>
</p>
</div>

View File

@@ -0,0 +1,10 @@
<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@@ -0,0 +1,64 @@
<!doctype html>
<html lang="<?= config('language_code') ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#35A768">
<meta name="google" content="notranslate">
<?php slot('meta'); ?>
<title><?= vars('page_title') ?? lang('account') ?> | Easy!Appointments</title>
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="icon" sizes="192x192" href="<?= asset_url('assets/img/logo.png') ?>">
<link rel="stylesheet" type="text/css"
href="<?= asset_url('assets/css/themes/' . setting('theme', 'default') . '.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/layouts/account_layout.css') ?>">
<?php slot('styles'); ?>
</head>
<body>
<div id="login-frame" class="frame-container">
<?php slot('content'); ?>
<div class="mt-4">
<small>
Powered by
<a href="https://easyappointments.org">Easy!Appointments</a>
</small>
</div>
</div>
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/layouts/account_layout.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/account_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
<?php component('js_vars_script'); ?>
<?php component('js_lang_script'); ?>
<?php slot('scripts'); ?>
</body>
</html>

View File

@@ -0,0 +1,72 @@
<!doctype html>
<html lang="<?= config('language_code') ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#35A768">
<meta name="google" content="notranslate">
<?php slot('meta'); ?>
<title><?= vars('page_title') ?? lang('backend_section') ?> | Easy!Appointments</title>
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="icon" sizes="192x192" href="<?= asset_url('assets/img/logo.png') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/trumbowyg/trumbowyg.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/select2/select2.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/flatpickr/material_green.min.css') ?>">
<link rel="stylesheet" type="text/css"
href="<?= asset_url('assets/css/themes/' . setting('theme', 'default') . '.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/layouts/backend_layout.css') ?>">
<?php component('company_color_style', ['company_color' => setting('company_color')]); ?>
<?php slot('styles'); ?>
</head>
<body class="d-flex flex-column h-100">
<main class="flex-shrink-0">
<?php component('backend_header', ['active_menu' => vars('active_menu')]); ?>
<?php slot('content'); ?>
</main>
<?php component('backend_footer', ['user_display_name' => vars('user_display_name')]); ?>
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/tippy.js/tippy-bundle.umd.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/trumbowyg/trumbowyg.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/select2/select2.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/layouts/backend_layout.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
<?php component('js_vars_script'); ?>
<?php component('js_lang_script'); ?>
<?php slot('scripts'); ?>
</body>
</html>

View File

@@ -0,0 +1,102 @@
<!doctype html>
<html lang="<?= config('language_code') ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#35A768">
<meta name="google" content="notranslate">
<meta property="og:title" content="<?= lang('page_title') . ' ' . vars('company_name') ?> | Easy!Appointments"/>
<meta property="og:description" content="Book Your Appointment With A Few Clicks"/>
<meta property="og:url" content="<?= base_url() ?>">
<meta property="og:image" content="<?= base_url('assets/img/social-card.png') ?>"/>
<meta property="og:type" content="website">
<?php slot('meta'); ?>
<title><?= lang('page_title') . ' ' . vars('company_name') ?> | Easy!Appointments</title>
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="icon" sizes="192x192" href="<?= asset_url('assets/img/logo.png') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/cookieconsent/cookieconsent.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/vendor/flatpickr/material_green.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/themes/' . vars('theme') . '.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/layouts/booking_layout.css') ?>">
<?php component('company_color_style', ['company_color' => vars('company_color')]); ?>
<?php slot('styles'); ?>
</head>
<body>
<div id="main" class="container">
<div class="row wrapper">
<div id="book-appointment-wizard" class="col-12 col-lg-10 col-xl-8 col-xxl-7">
<?php component('booking_header', [
'company_name' => vars('company_name'),
'company_logo' => vars('company_logo'),
]); ?>
<?php slot('content'); ?>
<?php component('booking_footer', ['display_login_button' => vars('display_login_button')]); ?>
</div>
</div>
</div>
<?php if (vars('display_cookie_notice') === '1'): ?>
<?php component('cookie_notice_modal', ['cookie_notice_content' => vars('cookie_notice_content')]); ?>
<?php endif; ?>
<?php if (vars('display_terms_and_conditions') === '1'): ?>
<?php component('terms_and_conditions_modal', [
'terms_and_conditions_content' => vars('terms_and_conditions_content'),
]); ?>
<?php endif; ?>
<?php if (vars('display_privacy_policy') === '1'): ?>
<?php component('privacy_policy_modal', ['privacy_policy_content' => vars('privacy_policy_content')]); ?>
<?php endif; ?>
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/cookieconsent/cookieconsent.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/tippy.js/tippy-bundle.umd.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/layouts/booking_layout.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
<?php component('js_vars_script'); ?>
<?php component('js_lang_script'); ?>
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
<?php component('matomo_analytics_script', [
'matomo_analytics_url' => vars('matomo_analytics_url'),
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
]); ?>
<?php slot('scripts'); ?>
</body>
</html>

View File

@@ -0,0 +1,71 @@
<!doctype html>
<html lang="<?= config('language_code') ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#35A768">
<meta name="google" content="notranslate">
<?php slot('meta'); ?>
<title><?= vars('page_title') ?> | Easy!Appointments</title>
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="icon" sizes="192x192" href="<?= asset_url('assets/img/logo.png') ?>">
<link rel="stylesheet" type="text/css"
href="<?= asset_url('assets/css/themes/' . setting('theme', 'default') . '.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/layouts/booking_layout.css') ?>">
<?php component('company_color_style', ['company_color' => vars('company_color')]); ?>
<?php slot('styles'); ?>
</head>
<body>
<div id="main" class="container">
<div class="row wrapper">
<div id="message-frame" class="col-12 border my-auto frame-container">
<?php slot('content'); ?>
<div class="mt-2">
<small>
Powered by
<a href="https://easyappointments.org">Easy!Appointments</a>
</small>
</div>
</div>
</div>
</div>
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/layouts/message_layout.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
<?php component('js_vars_script'); ?>
<?php component('js_lang_script'); ?>
<?php slot('scripts'); ?>
</body>
</html>

View File

@@ -0,0 +1,108 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="about-page" class="container backend-page">
<div id="about" class="col-lg-8 offset-lg-2">
<div class="text-center my-5">
<img src="<?= base_url('assets/img/logo.png') ?>" alt="Easy!Appointments Logo" class="mb-5">
<h3>
Easy!Appointments
</h3>
<h6 class="text-primary">
Online Appointment Scheduler
</h6>
</div>
<p class="mb-5">
<?= lang('about_app_info') ?>
</p>
<div class="card mb-5">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('current_version') ?>
</h5>
</div>
<div class="card-body">
<strong>
<?= config('version') ?>
</strong>
</div>
</div>
<h4 class="fw-light text-black-50 mb-3">
<?= lang('support') ?>
</h4>
<p>
<?= lang('about_app_support') ?>
</p>
<div class="row mb-5">
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block" href="https://easyappointments.org" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
<?= lang('official_website') ?>
</a>
</div>
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block"
href="https://groups.google.com/forum/#!forum/easy-appointments" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
<?= lang('support_group') ?>
</a>
</div>
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block"
href="https://github.com/alextselegidis/easyappointments/issues" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
<?= lang('project_issues') ?>
</a>
</div>
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block" href="https://facebook.com/easyappts" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
Facebook
</a>
</div>
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block" href="https://x.com/easyappts" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
X.com
</a>
</div>
<div class="col-lg-6 mb-3">
<a class="btn btn-outline-secondary d-block" href="https://easyappointments.org/get-a-free-quote" target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
Customize E!A
</a>
</div>
</div>
<h4 class="fw-light text-black-50 mb-3">
<?= lang('license') ?>
</h4>
<p>
<?= lang('about_app_license') ?>
</p>
<div class="mb-5">
<a class="btn btn-outline-secondary d-block w-50 m-auto" href="https://www.gnu.org/licenses/gpl-3.0.en.html"
target="_blank">
<i class="fas fa-external-link-alt me-2"></i>
GPL-3.0
</a>
</div>
</div>
</div>
<?php end_section('content'); ?>

View File

@@ -0,0 +1,195 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="account-page" class="container backend-page">
<div id="account">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('account') ?>
</h4>
<?php if (can('edit', PRIV_USER_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
<div class="row">
<div class="col-lg-6">
<input type="hidden" id="user-id">
<div class="mb-3">
<label class="form-label" for="first-name">
<?= lang('first_name') ?>
<span class="text-danger">*</span>
</label>
<input id="first-name" class="form-control required">
</div>
<div class="mb-3">
<label class="form-label" for="last-name">
<?= lang('last_name') ?>
<span class="text-danger">*</span>
</label>
<input id="last-name" class="form-control required">
</div>
<div class="mb-3">
<label class="form-label" for="email">
<?= lang('email') ?>
<span class="text-danger">*</span>
</label>
<input id="email" class="form-control required">
</div>
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
</label>
<input id="phone-number" class="form-control required">
</div>
<div class="mb-3">
<label class="form-label" for="mobile-number">
<?= lang('mobile_number') ?>
</label>
<input id="mobile-number" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="address">
<?= lang('address') ?>
</label>
<input id="address" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="city">
<?= lang('city') ?>
</label>
<input id="city" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="state">
<?= lang('state') ?>
</label>
<input id="state" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="zip-code">
<?= lang('zip_code') ?>
</label>
<input id="zip-code" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" class="form-control" rows="3"></textarea>
</div>
</div>
<div class="col-lg-6">
<div class="mb-3">
<label class="form-label" for="username">
<?= lang('username') ?>
<span class="text-danger">*</span>
</label>
<input id="username" class="form-control required">
</div>
<div class="mb-3">
<label class="form-label" for="password">
<?= lang('password') ?>
</label>
<input type="password" id="password" class="form-control"
autocomplete="new-password">
</div>
<div class="mb-3">
<label class="form-label" for="retype-password">
<?= lang('retype_password') ?>
</label>
<input type="password" id="retype-password" class="form-control"
autocomplete="new-password">
</div>
<div class="mb-3">
<label class="form-label" for="calendar-view"><?= lang('calendar') ?>
<span class="text-danger">*</span>
</label>
<select id="calendar-view" class="form-select required">
<option value="default"><?= lang('default') ?></option>
<option value="table"><?= lang('table') ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required">
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required"',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" id="notifications" type="checkbox">
<label class="form-check-label" for="notifications">
<?= lang('receive_notifications') ?>
</label>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/account_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/account.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,254 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="admins-page">
<div class="row" id="admins">
<div id="filter-admins" class="filter-records column col-12 col-md-5">
<form class="mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('admins') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details column col-12 col-md-7">
<div class="btn-toolbar mb-4">
<div class="add-edit-delete-group btn-group">
<button id="add-admin" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-admin" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-admin" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-admin" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-admin" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id" class="record-id">
<div class="row">
<div class="details col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="first-name">
<?= lang('first_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="first-name" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="last-name">
<?= lang('last_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="last-name" class="form-control required" maxlength="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="email">
<?= lang('email') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="email" class="form-control required" maxlength="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="phone-number" class="form-control required" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="mobile-number">
<?= lang('mobile_number') ?>
</label>
<input id="mobile-number" class="form-control" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="address">
<?= lang('address') ?>
</label>
<input id="address" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="city">
<?= lang('city') ?>
</label>
<input id="city" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="state">
<?= lang('state') ?>
</label>
<input id="state" class="form-control" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="zip-code">
<?= lang('zip_code') ?>
</label>
<input id="zip-code" class="form-control" maxlength="64" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" class="form-control" rows="3" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
<div class="settings col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="username">
<?= lang('username') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="username" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password">
<?= lang('password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password" class="form-control required" maxlength="512"
autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password-confirm">
<?= lang('retype_password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password-confirm" class="form-control required"
maxlength="512" autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="calendar-view">
<?= lang('calendar') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="calendar-view" class="form-select required" disabled>
<option value="default"><?= lang('default') ?></option>
<option value="table"><?= lang('table') ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required" disabled>
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required" disabled',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<?php if (setting('ldap_is_active')): ?>
<div class="mb-3">
<label for="ldap-dn" class="form-label">
<?= lang('ldap_dn') ?>
</label>
<input type="text" id="ldap-dn" class="form-control" maxlength="100" disabled/>
</div>
<?php endif; ?>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="notifications" disabled>
<label class="form-check-label" for="notifications">
<?= lang('receive_notifications') ?>
</label>
</div>
</div>
<?php slot('after_secondary_fields'); ?>
</div>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/account_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/admins_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/admins.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,64 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="api-settings-page" class="container backend-page">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div id="api-settings" class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('api') ?>
</h4>
<div>
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-3">
<label class="form-label" for="api-token">
<?= lang('api_token') ?>
</label>
<input id="api-token" class="form-control" data-field="api_token">
<div class="form-text text-muted">
<small>
<?= lang('api_token_hint') ?>
</small>
</div>
</div>
</div>
</div>
<?php slot('after_primary_appointment_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/api_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/api_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,122 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="blocked-periods-page">
<div class="row" id="blocked-periods">
<div id="filter-blocked-periods" class="filter-records column col-12 col-md-5">
<form class="input-append mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('blocked_periods') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details col-12 col-md-5">
<div class="btn-toolbar mb-4">
<a href="<?= site_url('business_settings') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<div class="add-edit-delete-group btn-group">
<button id="add-blocked-period" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-blocked-period" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-blocked-period" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-blocked-period" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-blocked-period" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id">
<div class="mb-3">
<label class="form-label" for="name">
<?= lang('name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="name" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="start-date-time">
<?= lang('start') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="start-date-time" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="end-date-time">
<?= lang('end') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="end-date-time" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" rows="4" class="form-control" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/blocked_periods_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/blocked_periods.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,64 @@
<?php extend('layouts/booking_layout'); ?>
<?php section('content'); ?>
<!-- Booking Cancellation Frame -->
<?php component('booking_cancellation_frame', [
'manage_mode' => vars('manage_mode'),
'appointment_data' => vars('appointment_data'),
'display_delete_personal_information' => vars('display_delete_personal_information'),
]); ?>
<!-- Select Service & Provider -->
<?php component('booking_type_step', ['available_services' => vars('available_services')]); ?>
<!-- Pick An Appointment Date -->
<?php component('booking_time_step', ['grouped_timezones' => vars('grouped_timezones')]); ?>
<!-- Enter Customer Information -->
<?php component('booking_info_step', [
'display_first_name' => vars('display_first_name'),
'require_first_name' => vars('require_first_name'),
'display_last_name' => vars('display_last_name'),
'require_last_name' => vars('require_last_name'),
'display_email' => vars('display_email'),
'require_email' => vars('require_email'),
'display_phone_number' => vars('display_phone_number'),
'require_phone_number' => vars('require_phone_number'),
'display_address' => vars('display_address'),
'require_address' => vars('require_address'),
'display_city' => vars('display_city'),
'require_city' => vars('require_city'),
'display_zip_code' => vars('display_zip_code'),
'require_zip_code' => vars('require_zip_code'),
'display_notes' => vars('display_notes'),
'require_notes' => vars('require_notes'),
]); ?>
<!-- Appointment Data Confirmation -->
<?php component('booking_final_step', [
'manage_mode' => vars('manage_mode'),
'display_terms_and_conditions' => vars('display_terms_and_conditions'),
'display_privacy_policy' => vars('display_privacy_policy'),
]); ?>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/booking_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/booking.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,32 @@
<?php extend('layouts/message_layout'); ?>
<?php section('content'); ?>
<div>
<img id="success-icon" class="mt-0 mb-5" src="<?= base_url('assets/img/success.png') ?>" alt="success"/>
</div>
<div class="mb-5">
<h4 class="mb-5"><?= lang('appointment_cancelled_title') ?></h4>
<p class="mb-5">
<?= lang('appointment_cancelled') ?>
</p>
<a href="<?= site_url() ?>" class="btn btn-primary btn-large">
<i class="fas fa-calendar-alt me-2"></i>
<?= lang('go_to_booking_page') ?>
</a>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
<?php component('matomo_analytics_script', [
'matomo_analytics_url' => vars('matomo_analytics_url'),
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
]); ?>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,43 @@
<?php extend('layouts/message_layout'); ?>
<?php section('content'); ?>
<div>
<img id="success-icon" class="mt-0 mb-5" src="<?= base_url('assets/img/success.png') ?>" alt="success"/>
</div>
<div class="mb-5">
<h4 class="mb-5"><?= lang('appointment_registered') ?></h4>
<p>
<?= lang('appointment_details_was_sent_to_you') ?>
</p>
<p class="mb-5 text-muted">
<small>
<?= lang('check_spam_folder') ?>
</small>
</p>
<a href="<?= site_url() ?>" class="btn btn-primary btn-large">
<i class="fas fa-calendar-alt me-2"></i>
<?= lang('go_to_booking_page') ?>
</a>
<a href="<?= vars('add_to_google_url') ?>" id="add-to-google-calendar" class="btn btn-primary" target="_blank">
<i class="fas fa-plus me-2"></i>
<?= lang('add_to_google_calendar') ?>
</a>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
<?php component('matomo_analytics_script', [
'matomo_analytics_url' => vars('matomo_analytics_url'),
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
]); ?>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,26 @@
<?php extend('layouts/message_layout'); ?>
<?php section('content'); ?>
<div>
<img id="message-icon" class="mt-0 mb-5" src="<?= vars('message_icon') ?>" alt="warning">
</div>
<div class="mb-5">
<h4 class="mb-5"><?= vars('message_title') ?></h4>
<p><?= vars('message_text') ?></p>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
<?php component('matomo_analytics_script', [
'matomo_analytics_url' => vars('matomo_analytics_url'),
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
]); ?>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,443 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="booking-settings-page" class="container backend-page">
<div id="booking-settings">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('booking_settings') ?>
</h4>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
<h5 class="text-black-50 mb-3 fw-light">
<?= lang('fields') ?>
</h5>
<div class="row mb-5 fields-row">
<div class="col-lg-6">
<div class="form-group mb-5">
<label for="first-name" class="form-label">
<?= lang('first_name') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="first-name" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-first-name"
data-field="display_first_name">
<label class="form-check-label" for="display-first-name">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-first-name"
data-field="require_first_name">
<label class="form-check-label" for="require-first-name">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-5">
<label for="last-name" class="form-label">
<?= lang('last_name') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="last-name" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-last-name"
data-field="display_last_name">
<label class="form-check-label" for="display-last-name">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-last-name"
data-field="require_last_name">
<label class="form-check-label" for="require-last-name">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-5">
<label for="email" class="form-label">
<?= lang('email') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="email" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-email"
data-field="display_email">
<label class="form-check-label" for="display-email">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-email"
data-field="require_email">
<label class="form-check-label" for="require-email">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-3">
<label for="phone-number" class="form-label">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="phone-number" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-phone-number"
data-field="display_phone_number">
<label class="form-check-label" for="display-phone-number">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-phone-number"
data-field="require_phone_number">
<label class="form-check-label" for="require-phone-number">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group mb-5">
<label for="address" class="form-label">
<?= lang('address') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="address" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-address"
data-field="display_address">
<label class="form-check-label" for="display-address">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-address"
data-field="require_address">
<label class="form-check-label" for="require-address">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-5">
<label for="city" class="form-label">
<?= lang('city') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="city" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-city"
data-field="display_city">
<label class="form-check-label" for="display-city">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-city"
data-field="require_city">
<label class="form-check-label" for="require-city">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-5">
<label for="zip-code" class="form-label">
<?= lang('zip_code') ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="zip-code" class="form-control mb-2" readonly/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-zip-code"
data-field="display_zip_code">
<label class="form-check-label" for="display-zip-code">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-zip-code"
data-field="require_zip_code">
<label class="form-check-label" for="require-zip-code">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
<div class="form-group mb-3">
<label for="notes" class="form-label">
<?= lang('notes') ?>
<span class="text-danger">*</span>
</label>
<textarea id="notes" class="form-control mb-2" rows="1" readonly></textarea>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-notes"
data-field="display_notes">
<label class="form-check-label" for="display-notes">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-notes"
data-field="require_notes">
<label class="form-check-label" for="require-notes">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
</div>
</div>
<h5 class="text-black-50 mb-3 fw-light">
<?= lang('custom_fields') ?>
</h5>
<div class="row mb-5 fields-row">
<?php for ($i = 1; $i <= 5; $i++): ?>
<div class="col-sm-6">
<div class="form-group mb-5">
<label for="first-name" class="form-label">
<?= lang('custom_field') ?> #<?= $i ?>
<span class="text-danger">*</span>
</label>
<input type="text" id="custom-field-<?= $i ?>" class="form-control mb-2"
placeholder="<?= lang('label') ?>"
data-field="label_custom_field_<?= $i ?>"
aria-label="label"
/>
<div class="d-flex">
<div class="form-check form-switch me-4">
<input class="form-check-input display-switch" type="checkbox"
id="display-custom-field-<?= $i ?>"
data-field="display_custom_field_<?= $i ?>">
<label class="form-check-label" for="display-custom-field-<?= $i ?>">
<?= lang('display') ?>
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input require-switch" type="checkbox"
id="require-custom-field-<?= $i ?>"
data-field="require_custom_field_<?= $i ?>">
<label class="form-check-label" for="require-custom-field-<?= $i ?>">
<?= lang('require') ?>
</label>
</div>
</div>
</div>
</div>
<?php endfor; ?>
</div>
<h5 class="text-black-50 mb-3 fw-light">
<?= lang('options') ?>
</h5>
<div class="row">
<div class="col-12">
<div class="border rounded mb-3 p-3">
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="customer-notifications"
data-field="customer_notifications">
<label class="form-check-label" for="customer-notifications">
<?= lang('customer_notifications') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('customer_notifications_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="limit-customer-access"
data-field="limit_customer_access">
<label class="form-check-label" for="limit-customer-access">
<?= lang('limit_customer_access') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('limit_customer_access_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="require-captcha"
data-field="require_captcha">
<label class="form-check-label" for="require-captcha">
CAPTCHA
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('require_captcha_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="display-any-provider"
data-field="display_any_provider">
<label class="form-check-label" for="display-any-provider">
<?= lang('any_provider') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('display_any_provider_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="display-login-button"
data-field="display_login_button">
<label class="form-check-label" for="display-login-button">
<?= lang('login_button') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('display_login_button_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
id="display-delete-personal-information"
data-field="display_delete_personal_information">
<label class="form-check-label" for="display-delete-personal-information">
<?= lang('delete_personal_information') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('delete_personal_information_hint') ?>
</small>
</div>
</div>
<div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="disable-booking"
data-field="disable_booking">
<label class="form-check-label" for="disable-booking">
<?= lang('disable_booking') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('disable_booking_hint') ?>
</small>
</div>
</div>
<div class="form-group mb-3" hidden>
<label class="form-label" for="disable-booking-message">
<?= lang('display_message') ?>
</label>
<textarea id="disable-booking-message" cols="30" rows="10"
class="mb-3"></textarea>
</div>
</div>
</div>
</div>
<?php slot('after_primary_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/booking_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/booking_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,161 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="business-logic-page" class="container backend-page">
<div id="business-logic">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('business_logic') ?>
</h4>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('working_plan') ?></h5>
<p class="form-text text-muted mb-4">
<?= lang('edit_working_plan_hint') ?>
</p>
<table class="working-plan table table-striped">
<thead>
<tr>
<th><?= lang('day') ?></th>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<div class="text-end mb-5">
<button class="btn btn-outline-secondary" id="apply-global-working-plan" type="button">
<i class="fas fa-check"></i>
<?= lang('apply_to_all_providers') ?>
</button>
</div>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('breaks') ?></h5>
<p class="form-text text-muted">
<?= lang('edit_breaks_hint') ?>
</p>
<div class="mt-2">
<button type="button" class="add-break btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add_break') ?>
</button>
</div>
<br>
<table class="breaks table table-striped mb-5">
<thead>
<tr>
<th><?= lang('day') ?></th>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
<th><?= lang('actions') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<?php if (can('view', PRIV_BLOCKED_PERIODS)): ?>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('blocked_periods') ?></h5>
<p class="form-text text-muted">
<?= lang('blocked_periods_hint') ?>
</p>
<div class="mb-5">
<a href="<?= site_url('blocked_periods') ?>" class="btn btn-primary">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
<?php endif; ?>
<h5 class="text-black-50 mb-3 fw-light"><?= lang(
'allow_rescheduling_cancellation_before',
) ?></h5>
<div class="mb-5">
<label for="book-advance-timeout" class="form-label">
<?= lang('timeout_minutes') ?>
</label>
<input id="book-advance-timeout" data-field="book_advance_timeout" class="form-control"
type="number" min="15">
<div class="form-text text-muted">
<small>
<?= lang('book_advance_timeout_hint') ?>
</small>
</div>
</div>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('future_booking_limit') ?></h5>
<div class="mb-5">
<label for="future-booking-limit" class="form-label">
<?= lang('limit_days') ?>
</label>
<input id="future-booking-limit" data-field="future_booking_limit" class="form-control"
type="number" min="15">
<div class="form-text text-muted">
<small>
<?= lang('future_booking_limit_hint') ?>
</small>
</div>
</div>
<div class="d-flex justify-content-start align-items-center mb-3">
<h5 class="text-black-50 mb-0 me-3 fw-light">
<?= lang('appointment_status_options') ?>
</h5>
</div>
<p class="form-text text-muted mb-4">
<?= lang('appointment_status_options_info') ?>
</p>
<?php component('appointment_status_options', [
'attributes' => 'id="appointment-status-options"',
]); ?>
<?php slot('after_primary_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/vendor/jquery-jeditable/jquery.jeditable.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/working_plan.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/business_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/business_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,156 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="calendar-page">
<div class="row" id="calendar-toolbar">
<div id="calendar-filter" class="col-md-3">
<div class="calendar-filter-items">
<select id="select-filter-item"
class="form-select col"
data-tippy-content="<?= lang('select_filter_item_hint') ?>"
aria-label="Filter">
<!-- JS -->
</select>
</div>
</div>
<div id="calendar-actions" class="col-md-9">
<?php if (vars('calendar_view') === CALENDAR_VIEW_DEFAULT): ?>
<button
id="enable-sync"
class="btn btn-light"
data-tippy-content="<?= lang('enable_appointment_sync_hint') ?>"
hidden>
<i class="fas fa-rotate me-2"></i>
<?= lang('enable_sync') ?>
</button>
<div class="btn-group" id="sync-button-group" hidden>
<button type="button" class="btn btn-light" id="trigger-sync" data-tippy-content="<?= lang(
'trigger_sync_hint',
) ?>">
<i class="fas fa-rotate me-2"></i>
<?= lang('synchronize') ?>
</button>
<button type="button" class="btn btn-light dropdown-toggle dropdown-toggle-split"
data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">
Toggle Dropdown
</span>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="#" id="disable-sync">
<?= lang('disable_sync') ?>
</a>
</li>
</ul>
</div>
<?php endif; ?>
<?php if (can('add', PRIV_APPOINTMENTS)): ?>
<div class="dropdown d-sm-inline-block">
<button class="btn btn-light" type="button" data-bs-toggle="dropdown">
<i class="fas fa-plus-square"></i>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="#" id="insert-appointment">
<?= lang('appointment') ?>
</a>
</li>
<li>
<a class="dropdown-item" href="#" id="insert-unavailability">
<?= lang('unavailability') ?>
</a>
</li>
<li>
<a class="dropdown-item" href="#"
id="insert-working-plan-exception" <?= session('role_slug') !== DB_SLUG_ADMIN
? 'hidden'
: '' ?>>
<?= lang('working_plan_exception') ?>
</a>
</li>
</ul>
</div>
<?php endif; ?>
<button id="reload-appointments" class="btn btn-light"
data-tippy-content="<?= lang('reload_appointments_hint') ?>">
<i class="fas fa-sync-alt"></i>
</button>
<?php if (vars('calendar_view') === CALENDAR_VIEW_DEFAULT): ?>
<a class="btn btn-light mb-0" href="<?= site_url('calendar?view=table') ?>"
data-tippy-content="<?= lang('table') ?>">
<i class="fas fa-table"></i>
</a>
<?php endif; ?>
<?php if (vars('calendar_view') === CALENDAR_VIEW_TABLE): ?>
<a class="btn btn-light mb-0" href="<?= site_url('calendar?view=default') ?>"
data-tippy-content="<?= lang('default') ?>">
<i class="fas fa-calendar-alt"></i>
</a>
<?php endif; ?>
<?php slot('after_calendar_actions'); ?>
</div>
</div>
<div id="calendar">
<!-- Dynamically Generated Content -->
</div>
</div>
<!-- Page Components -->
<?php component('appointments_modal', [
'available_services' => vars('available_services'),
'appointment_status_options' => vars('appointment_status_options'),
'timezones' => vars('timezones'),
'require_first_name' => vars('require_first_name'),
'require_last_name' => vars('require_last_name'),
'require_email' => vars('require_email'),
'require_phone_number' => vars('require_phone_number'),
'require_address' => vars('require_address'),
'require_city' => vars('require_city'),
'require_zip_code' => vars('require_zip_code'),
'require_notes' => vars('require_notes'),
]); ?>
<?php component('unavailabilities_modal', [
'timezones' => vars('timezones'),
'timezone' => vars('timezone'),
]); ?>
<?php component('working_plan_exceptions_modal'); ?>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/vendor/fullcalendar/index.global.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/fullcalendar-moment/index.global.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/jquery-jeditable/jquery.jeditable.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/calendar_default_view.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/calendar_table_view.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/calendar_event_popover.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/calendar_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/customers_http_client.js') ?>"></script>
<?php if (vars('calendar_view') === CALENDAR_VIEW_DEFAULT): ?>
<script src="<?= asset_url('assets/js/utils/calendar_sync.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/google_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/caldav_http_client.js') ?>"></script>
<?php endif; ?>
<script src="<?= asset_url('assets/js/pages/calendar.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,236 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="customers-page">
<div class="row" id="customers">
<div id="filter-customers" class="filter-records col col-12 col-md-5">
<form class="mb-4">
<div class="input-group mb-3">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('customers') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details col-12 col-md-7">
<div class="btn-toolbar mb-4">
<div id="add-edit-delete-group" class="btn-group">
<?php if (
can('add', PRIV_CUSTOMERS) &&
(!setting('limit_customer_access') || vars('role_slug') === DB_SLUG_ADMIN)
): ?>
<button id="add-customer" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<?php endif; ?>
<?php if (can('edit', PRIV_CUSTOMERS)): ?>
<button id="edit-customer" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<?php endif; ?>
<?php if (can('delete', PRIV_CUSTOMERS)): ?>
<button id="delete-customer" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
<?php endif; ?>
</div>
<div id="save-cancel-group" style="display:none;">
<button id="save-customer" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-customer" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<input id="customer-id" type="hidden">
<div class="row">
<div class="col-12 col-md-6" style="margin-left: 0;">
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div id="form-message" class="alert" style="display:none;"></div>
<div class="mb-3">
<label for="first-name" class="form-label">
<?= lang('first_name') ?>
<?php if (vars('require_first_name')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="first-name"
class="<?= vars('require_first_name') ? 'required' : '' ?> form-control" maxlength="100"
disabled/>
</div>
<div class="mb-3">
<label for="last-name" class="form-label">
<?= lang('last_name') ?>
<?php if (vars('require_last_name')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="last-name"
class="<?= vars('require_last_name') ? 'required' : '' ?> form-control" maxlength="120"
disabled/>
</div>
<div class="mb-3">
<label for="email" class="form-label">
<?= lang('email') ?>
<?php if (vars('require_email')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="email"
class="<?= vars('require_email') ? 'required' : '' ?> form-control" maxlength="120"
disabled/>
</div>
<div class="mb-3">
<label for="phone-number" class="form-label">
<?= lang('phone_number') ?>
<?php if (vars('require_phone_number')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="phone-number" maxlength="60"
class="<?= vars('require_phone_number') ? 'required' : '' ?> form-control" disabled/>
</div>
<div class="mb-3">
<label for="address" class="form-label">
<?= lang('address') ?>
<?php if (vars('require_address')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="address"
class="<?= vars('require_address') ? 'required' : '' ?> form-control"
maxlength="120" disabled/>
</div>
<div class="mb-3">
<label for="city" class="form-label">
<?= lang('city') ?>
<?php if (vars('require_city')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="city" class="<?= vars('require_city') ? 'required' : '' ?> form-control"
maxlength="120" disabled/>
</div>
<div class="mb-3">
<label for="zip-code" class="form-label">
<?= lang('zip_code') ?>
<?php if (vars('require_zip_code')): ?>
<span class="text-danger" hidden>*</span>
<?php endif; ?>
</label>
<input type="text" id="zip-code"
class="<?= vars('require_zip_code') ? 'required' : '' ?> form-control"
maxlength="120" disabled/>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required" disabled>
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required" disabled',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<?php if (setting('ldap_is_active')): ?>
<div class="mb-3">
<label for="ldap-dn" class="form-label">
<?= lang('ldap_dn') ?>
</label>
<input type="text" id="ldap-dn" class="form-control" maxlength="100" disabled/>
</div>
<?php endif; ?>
<?php component('custom_fields', [
'disabled' => true,
]); ?>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" rows="4" class="form-control" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
<div class="col-12 col-md-6">
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('appointments') ?>
</h4>
<div id="customer-appointments" class="card bg-white border"></div>
<?php slot('after_secondary_fields'); ?>
</div>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/customers_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/customers.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,250 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="general-settings-page" class="container backend-page">
<div id="general-settings">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('general_settings') ?>
</h4>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
<div class="row mb-5">
<div class="col-12">
<h5 class="text-black-50 mb-3 fw-light"><?= lang('company') ?></h5>
<div class="mb-3">
<label class="form-label" for="company-name">
<?= lang('company_name') ?>
<span class="text-danger">*</span>
</label>
<input id="company-name" data-field="company_name" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_name_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-email">
<?= lang('company_email') ?>
<span class="text-danger">*</span>
</label>
<input id="company-email" data-field="company_email" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_email_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-link">
<?= lang('company_link') ?>
<span class="text-danger">*</span>
</label>
<input id="company-link" data-field="company_link" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_link_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-logo">
<?= lang('company_logo') ?>
</label>
<input type="file" id="company-logo" data-field="company_logo" class="form-control"
accept="image/*">
<div class="form-text text-muted">
<small>
<?= lang('company_logo_hint') ?>
</small>
</div>
<div class="d-flex justify-content-center">
<img src="#" alt="Company Logo Preview" id="company-logo-preview"
class="img-thumbnail my-3" hidden>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn btn-danger btn-sm mb-3"
id="remove-company-logo" hidden>
<i class="fas fa-trash me-2"></i>
<?= lang('remove') ?>
</button>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-color">
<?= lang('company_color') ?>
</label>
<input type="color" id="company-color" data-field="company_color"
class="form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_color_hint') ?>
</small>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn btn-danger btn-sm my-3"
id="reset-company-color" hidden>
<i class="fas fa-undo-alt me-2"></i>
<?= lang('reset') ?>
</button>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="theme">
<?= lang('theme') ?>
</label>
<select id="theme" data-field="theme" class="form-select">
<?php foreach (vars('available_themes') as $available_theme): ?>
<option value="<?= $available_theme ?>">
<?= ucfirst($available_theme) ?>
</option>
<?php endforeach; ?>
</select>
<div class="form-text text-muted">
<small>
<?= lang('company_color_hint') ?>
</small>
</div>
</div>
</div>
</div>
<div class="row mb-5">
<div class="col-12">
<h5 class="text-black-50 mb-3 fw-light"><?= lang('localization') ?></h5>
<div class="mb-3">
<label class="form-label" for="date-format">
<?= lang('date_format') ?>
</label>
<select class="form-select" id="date-format" data-field="date_format">
<option value="DMY">DMY</option>
<option value="MDY">MDY</option>
<option value="YMD">YMD</option>
</select>
<div class="form-text text-muted">
<small>
<?= lang('date_format_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="time-format">
<?= lang('time_format') ?>
</label>
<select class="form-select" id="time-format" data-field="time_format">
<option value="<?= TIME_FORMAT_REGULAR ?>">H:MM AM/PM</option>
<option value="<?= TIME_FORMAT_MILITARY ?>">HH:MM</option>
</select>
<div class="form-text text-muted">
<small>
<?= lang('time_format_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="first-weekday">
<?= lang('first_weekday') ?>
</label>
<select class="form-select" id="first-weekday" data-field="first_weekday">
<option value="sunday"><?= lang('sunday') ?></option>
<option value="monday"><?= lang('monday') ?></option>
<option value="tuesday"><?= lang('tuesday') ?></option>
<option value="wednesday"><?= lang('wednesday') ?></option>
<option value="thursday"><?= lang('thursday') ?></option>
<option value="friday"><?= lang('friday') ?></option>
<option value="saturday"><?= lang('saturday') ?></option>
</select>
<div class="form-text text-muted">
<small>
<?= lang('first_weekday_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="default-language">
<?= lang('default_language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="default-language" class="form-select required" data-field="default_language">
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
<div class="form-text text-muted">
<small>
<?= lang('default_language_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="default-timezone">
<?= lang('default_timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' =>
'id="default-timezone" data-field="default_timezone" class="form-control required"',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<div class="form-text text-muted">
<small>
<?= lang('default_timezone_hint') ?>
</small>
</div>
</div>
</div>
<?php slot('after_primary_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/general_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/general_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,65 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="google-analytics-settings-page" class="container backend-page">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div id="google-analytics-settings" class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('google_analytics') ?>
</h4>
<div>
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-3">
<label class="form-label" for="google-analytics-code">
<?= lang('google_analytics_code') ?>
</label>
<input id="google-analytics-code" placeholder="UA-XXXXXXXX-XX or G-XXXXXXXXXX"
class="form-control" data-field="google_analytics_code">
<div class="form-text text-muted">
<small>
<?= lang('google_analytics_code_hint') ?>
</small>
</div>
</div>
</div>
</div>
<?php slot('after_primary_appointment_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/google_analytics_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/google_analytics_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,212 @@
<!doctype html>
<html lang="<?= config('language_code') ?>">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Installation | Easy!Appointments</title>
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/themes/default.min.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/pages/installation.css') ?>">
</head>
<body>
<div id="loading" class="d-none">
<img src="<?= base_url('assets/img/loading.gif') ?>" alt="loading">
</div>
<header>
<div class="container">
<h1 class="page-title">Easy!Appointments Installation</h1>
</div>
</header>
<div class="content container">
<div class="welcome">
<h3>Welcome to the Easy!Appointments installation page.</h3>
<p>
This page will help you set the main settings of your Easy!Appointments installation. You will be able to
edit these settings and many more in the backend session of your system. Remember to use the
<strong class="text-primary"><?= site_url('user/login') ?></strong> URL to connect to the backend section
of Easy!Appointments.
If you face any problems during the usage of Easy!Appointments you can always check the
<a href="https://easyappointments.org/docs.html">Documentation</a> and
<a href="https://groups.google.com/group/easy-appointments">Support Group</a> for getting help. You may also
submit new issues on
<a href="https://github.com/alextselegidis/easyappointments/issues">GitHub Issues</a>
in order to help our development process.
</p>
</div>
<div class="alert" hidden></div>
<div class="row">
<div class="admin-settings col-12 col-sm-5">
<h3 class="text-black-50 mb-3 fw-light">Administrator</h3>
<div class="mb-3">
<label class="form-label" for="first-name">
<?= lang('first_name') ?>
<span class="text-danger">*</span>
</label>
<input id="first-name" class="form-control required" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="last-name">
<?= lang('last_name') ?>
<span class="text-danger">*</span>
</label>
<input id="last-name" class="form-control required" maxlength="512">
</div>
<div class="mb-3">
<label class="form-label" for="email">
<?= lang('email') ?>
<span class="text-danger">*</span>
</label>
<input id="email" class="form-control required" maxlength="512">
</div>
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
</label>
<input id="phone-number" class="form-control required" maxlength="128">
</div>
<div class="mb-3">
<label class="form-label" for="username">
<?= lang('username') ?>
<span class="text-danger">*</span>
</label>
<input id="username" class="form-control required" maxlength="256">
</div>
<div class="mb-3">
<label class="form-label" for="password">
<?= lang('password') ?>
<span class="text-danger">*</span>
</label>
<input type="password" id="password" class="form-control required" maxlength="512">
</div>
<div class="mb-3">
<label class="form-label" for="password-confirm">
<?= lang('retype_password') ?>
<span class="text-danger">*</span>
</label>
<input type="password" id="password-confirm" class="form-control required" maxlength="512">
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger">*</span>
</label>
<select id="language" class="form-select required">
<?php
$config_lang = config('language');
foreach (vars('available_languages') as $lang): ?>
<option value="<?= $lang ?>"<?= $lang == $config_lang ? ' selected' : '' ?>>
<?= ucfirst($lang) ?>
</option>
<?php endforeach;
?>
</select>
</div>
</div>
<div class="company-settings col-12 col-sm-5">
<h3 class="text-black-50 mb-3 fw-light"><?= lang('company') ?></h3>
<div class="mb-3">
<label class="form-label" for="company-name">
<?= lang('company_name') ?>
<span class="text-danger">*</span>
</label>
<input id="company-name" data-field="company_name" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_name_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-email">
<?= lang('company_email') ?>
<span class="text-danger">*</span>
</label>
<input id="company-email" data-field="company_email" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_email_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="company-link">
<?= lang('company_link') ?>
<span class="text-danger">*</span>
</label>
<input id="company-link" data-field="company_link" class="required form-control">
<div class="form-text text-muted">
<small>
<?= lang('company_link_hint') ?>
</small>
</div>
</div>
</div>
</div>
<br>
<p>
You will be able to set your business logic in the backend settings page after the installation is complete.
<br>
Press the following button to complete the installation process.
</p>
<br>
<div class="mb-2">
<h3>License</h3>
Easy!Appointments is licensed under the <span class="badge bg-secondary">GPL-3.0 license</span>. By using the
code
of Easy!Appointments in any way <br> you agree with the terms described in the following url:
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html">https://www.gnu.org/licenses/gpl-3.0.en.html</a>
</div>
<br>
<button type="button" id="install" class="btn btn-primary">
<i class="icon-white icon-ok me-2"></i>
Install Easy!Appointments
</button>
</div>
<footer>
Powered by <a href="https://easyappointments.org">Easy!Appointments</a>
</footer>
<?php component('js_vars_script'); ?>
<?php component('js_lang_script'); ?>
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/installation.js') ?>"></script>
</body>
</html>

View File

@@ -0,0 +1,144 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="integrations-page" class="container backend-page">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div id="integrations" class="col-sm-6">
<h4 class="text-black-50 border-bottom py-3 mb-3 fw-light">
<?= lang('integrations') ?>
</h4>
<p class="form-text text-muted mb-4">
<?= lang('integrations_info') ?>
</p>
<div class="row">
<div class="col-sm-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('webhooks') ?>
</h5>
</div>
<div class="card-body">
<div class="mb-3 integration-info">
<small>
<?= lang('webhooks_info') ?>
</small>
</div>
</div>
<div class="card-footer bg-white border-0">
<a href="<?= site_url('webhooks') ?>" class="btn btn-outline-primary w-100">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
</div>
</div>
<div class="col-sm-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('google_analytics') ?>
</h5>
</div>
<div class="card-body">
<div class="mb-3 integration-info">
<small>
<?= lang('google_analytics_info') ?>
</small>
</div>
</div>
<div class="card-footer bg-white border-0">
<a href="<?= site_url('google_analytics_settings') ?>"
class="btn btn-outline-primary w-100">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
</div>
</div>
<div class="col-sm-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('matomo_analytics') ?>
</h5>
</div>
<div class="card-body">
<div class="mb-3 integration-info">
<small>
<?= lang('matomo_analytics_info') ?>
</small>
</div>
</div>
<div class="card-footer bg-white border-0">
<a href="<?= site_url('matomo_analytics_settings') ?>"
class="btn btn-outline-primary w-100">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
</div>
</div>
<div class="col-sm-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('api') ?>
</h5>
</div>
<div class="card-body">
<div class="mb-3 integration-info">
<small>
<?= lang('api_info') ?>
</small>
</div>
</div>
<div class="card-footer bg-white border-0">
<a href="<?= site_url('api_settings') ?>" class="btn btn-outline-primary w-100">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
</div>
</div>
<div class="col-sm-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="fw-light text-black-50 mb-0">
<?= lang('ldap') ?>
</h5>
</div>
<div class="card-body">
<div class="mb-3 integration-info">
<small>
<?= lang('ldap_info') ?>
</small>
</div>
</div>
<div class="card-footer bg-white border-0">
<a href="<?= site_url('ldap_settings') ?>" class="btn btn-outline-primary w-100">
<i class="fas fa-cogs me-2"></i>
<?= lang('configure') ?>
</a>
</div>
</div>
</div>
<?php slot('after_integration_cards'); ?>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>

View File

@@ -0,0 +1,165 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="ldap-settings-page" class="container backend-page">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div id="ldap-settings" class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('ldap') ?>
</h4>
<div>
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
</div>
<?php if (!extension_loaded('ldap')): ?>
<div class="alert alert-warning">
<?= lang('ldap_extension_not_loaded') ?>
</div>
<?php endif; ?>
<div class="row">
<div class="col-12">
<div class="mb-3">
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="ldap-is-active" data-field="ldap_is_active">
<label class="form-check-label" for="ldap-is-active">
<?= lang('active') ?>
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="ldap-host">
<?= lang('host') ?>
</label>
<input id="ldap-host" class="form-control" data-field="ldap_host">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-port">
<?= lang('port') ?>
</label>
<input id="ldap-port" class="form-control" data-field="ldap_port">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-user_dn">
<?= lang('user_dn') ?>
</label>
<input id="ldap-user_dn" class="form-control" data-field="ldap_user_dn">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-password">
<?= lang('password') ?>
</label>
<input id="ldap-password" type="password" class="form-control" data-field="ldap_password">
</div>
<div class="mb-3">
<label class="form-label" for="ldap-base-dn">
<?= lang('base_dn') ?>
</label>
<input id="ldap-base-dn" class="form-control" data-field="ldap_base_dn">
</div>
<div class="mb-3">
<div class="d-flex mb-2">
<label class="form-label mb-0" for="ldap-filter">
<?= lang('filter') ?>
</label>
<button type="button" class="btn btn-sm btn-outline-secondary py-0 ms-auto" id="ldap-reset-filter">
<i class="fas fa-undo me-2"></i>
<?= lang('reset') ?>
</button>
</div>
<input id="ldap-filter" class="form-control" data-field="ldap_filter">
</div>
<div class="mb-3">
<div class="d-flex mb-2">
<label class="form-label mb-0" for="ldap-field-mapping">
<?= lang('field_mapping') ?>
</label>
<button type="button" class="btn btn-sm btn-outline-secondary py-0 ms-auto" id="ldap-reset-field-mapping">
<i class="fas fa-undo me-2"></i>
<?= lang('reset') ?>
</button>
</div>
<textarea id="ldap-field-mapping" class="form-control" rows="5" data-field="ldap_field_mapping"></textarea>
</div>
</div>
</div>
<?php slot('after_primary_appointment_fields'); ?>
</fieldset>
</form>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('search') ?>
</h4>
</div>
<p class="text-muted small">
<?= lang('ldap_search_hint') ?>
</p>
<form id="ldap-search-form" class="mb-3">
<label class="form-label" for="ldap-search-keyword">
<?= lang('keyword') ?>
</label>
<div class="input-group">
<input id="ldap-search-keyword" class="form-control">
<button type="submit" class="btn btn-outline-primary">
<?= lang('search') ?>
</button>
</div>
</form>
<div id="ldap-search-results" class="mb-3">
<!-- JS -->
</div>
</div>
</div>
</div>
<?php component('ldap_import_modal', [
'roles' => vars('roles'),
]); ?>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/customers_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/providers_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/secretaries_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/admins_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/ldap_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/ldap_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,100 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="legal-settings-page" class="container backend-page">
<div id="legal-contents">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('legal_contents') ?>
</h4>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
<div class="row">
<div class="col-12">
<h5 class="text-black-50 mb-3 fw-light"><?= lang('cookie_notice') ?></h5>
<div class="form-check form-switch mb-3">
<input class="form-check-input display-switch" type="checkbox"
id="display-cookie-notice">
<label class="form-check-label" for="display-cookie-notice">
<?= lang('display_cookie_notice') ?>
</label>
</div>
<div class="mb-5">
<label class="form-label"
for="cookie-notice-content"><?= lang('cookie_notice_content') ?></label>
<textarea id="cookie-notice-content" cols="30" rows="10" class="mb-3"></textarea>
</div>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('terms_and_conditions') ?></h5>
<div class="form-check form-switch mb-3">
<input class="form-check-input display-switch" type="checkbox"
id="display-terms-and-conditions">
<label class="form-check-label" for="display-terms-and-conditions">
<?= lang('display_terms_and_conditions') ?>
</label>
</div>
<div class="mb-5">
<label class="form-label"
for="terms-and-conditions-content"><?= lang(
'terms_and_conditions_content',
) ?></label>
<textarea id="terms-and-conditions-content" cols="30" rows="10"
class="mb-3"></textarea>
</div>
<h5 class="text-black-50 mb-3 fw-light"><?= lang('privacy_policy') ?></h5>
<div class="form-check form-switch mb-3">
<input class="form-check-input display-switch" type="checkbox"
id="display-privacy-policy">
<label class="form-check-label" for="display-privacy-policy">
<?= lang('display_privacy_policy') ?>
</label>
</div>
<div class="mb-3">
<label class="form-label"
for="privacy-policy-content"><?= lang('privacy_policy_content') ?></label>
<textarea id="privacy-policy-content" cols="30" rows="10" class="mb-3"></textarea>
</div>
</div>
</div>
<?php slot('after_primary_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/legal_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/legal_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,53 @@
<?php extend('layouts/account_layout'); ?>
<?php section('content'); ?>
<h2><?= lang('backend_section') ?></h2>
<p>
<small>
<?= lang('you_need_to_login') ?>
</small>
</p>
<hr>
<div class="alert d-none"></div>
<form id="login-form">
<div class="mb-3 mt-5">
<label for="username" class="form-label">
<?= lang('username') ?>
</label>
<input type="text" id="username" placeholder="<?= lang(
'enter_username_here',
) ?>" class="form-control" required/>
</div>
<div class="mb-5">
<label for="password" class="form-label">
<?= lang('password') ?>
</label>
<input type="password" id="password" placeholder="<?= lang(
'enter_password_here',
) ?>" class="form-control" required/>
</div>
<div class="d-flex justify-content-between align-items-center mb-5">
<a href="<?= site_url('recovery') ?>" class="forgot-password"><?= lang('forgot_your_password') ?></a>
<button type="submit" id="login" class="btn btn-primary">
<i class="fas fa-sign-in-alt me-2"></i>
<?= lang('login') ?>
</button>
</div>
</form>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/login_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/login.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,27 @@
<?php extend('layouts/account_layout'); ?>
<?php section('content'); ?>
<h3><?= lang('log_out') ?></h3>
<p>
<small>
<?= lang('logout_success') ?>
</small>
</p>
<div class="d-flex justify-content-between my-5">
<a href="<?= site_url('login') ?>" class="btn btn-outline-secondary btn-large">
<i class="fas fa-wrench me-2"></i>
<?= lang('backend_section') ?>
</a>
<a href="<?= site_url() ?>" class="btn btn-primary btn-large">
<i class="fas fa-calendar-alt me-2"></i>
<?= lang('book_appointment_title') ?>
</a>
</div>
<?php end_section('content'); ?>

View File

@@ -0,0 +1,78 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div id="matomo-analytics-settings-page" class="container backend-page">
<div class="row">
<div class="col-sm-3 offset-sm-1">
<?php component('settings_nav'); ?>
</div>
<div id="matomo-analytics-settings" class="col-sm-6">
<form>
<fieldset>
<div class="d-flex justify-content-between align-items-center border-bottom mb-4 py-2">
<h4 class="text-black-50 mb-0 fw-light">
<?= lang('matomo_analytics') ?>
</h4>
<div>
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<?php if (can('edit', PRIV_SYSTEM_SETTINGS)): ?>
<button type="button" id="save-settings" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-3">
<label class="form-label" for="matomo-analytics-url">
<?= lang('matomo_analytics_url') ?>
</label>
<input id="matomo-analytics-url" placeholder="//example.org/url/to/matomo/"
data-field="matomo_analytics_url" class="form-control">
<div class="form-text text-muted">
<small>
<?= lang('matomo_analytics_url_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="matomo-analytics-site-id">
<?= lang('matomo_analytics_site_id') ?>
</label>
<input id="matomo-analytics-site-id" data-field="matomo_analytics_site_id"
class="form-control">
<div class="form-text text-muted">
<small>
<?= lang('matomo_analytics_site_id_hint') ?>
</small>
</div>
</div>
</div>
</div>
<?php slot('after_primary_appointment_fields'); ?>
</fieldset>
</form>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/matomo_analytics_settings_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/matomo_analytics_settings.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,399 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="providers-page">
<div class="row" id="providers">
<div id="filter-providers" class="filter-records column col-12 col-md-5">
<form class="mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('providers') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details column col-12 col-md-7">
<div class="float-md-start mb-4 me-4">
<div class="add-edit-delete-group btn-group">
<button id="add-provider" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-provider" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-provider" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-provider" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-provider" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<ul class="nav nav-pills switch-view">
<li class="nav-item">
<a class="nav-link active" href="#details" data-bs-toggle="tab">
<?= lang('details') ?>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#working-plan" data-bs-toggle="tab">
<?= lang('working_plan') ?>
</a>
</li>
</ul>
<?php
// This form message is outside the details view, so that it can be
// visible when the user has working plan view active.
?>
<div class="form-message alert" style="display:none;"></div>
<div class="tab-content">
<div class="details-view tab-pane fade show active clearfix" id="details">
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<input type="hidden" id="id" class="record-id">
<div class="row">
<div class="details col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="first-name">
<?= lang('first_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="first-name" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="last-name">
<?= lang('last_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="last-name" class="form-control required" maxlength="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="email">
<?= lang('email') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="email" class="form-control required" max="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="phone-number" class="form-control required" max="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="mobile-number">
<?= lang('mobile_number') ?>
</label>
<input id="mobile-number" class="form-control" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="address">
<?= lang('address') ?>
</label>
<input id="address" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="city">
<?= lang('city') ?>
</label>
<input id="city" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="state">
<?= lang('state') ?>
</label>
<input id="state" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="zip-code">
<?= lang('zip_code') ?>
</label>
<input id="zip-code" class="form-control" maxlength="64" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" class="form-control" rows="3" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
<div class="settings col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="username">
<?= lang('username') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="username" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password">
<?= lang('password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password" class="form-control required"
maxlength="512" autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password-confirm">
<?= lang('retype_password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password-confirm"
class="form-control required" maxlength="512"
autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="calendar-view">
<?= lang('calendar') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="calendar-view" class="form-select required" disabled>
<option value="default"><?= lang('default') ?></option>
<option value="table"><?= lang('table') ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required" disabled>
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required" disabled',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<?php if (setting('ldap_is_active')): ?>
<div class="mb-3">
<label for="ldap-dn" class="form-label">
<?= lang('ldap_dn') ?>
</label>
<input type="text" id="ldap-dn" class="form-control" maxlength="100" disabled/>
</div>
<?php endif; ?>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="is-private">
<label class="form-check-label" for="is-private">
<?= lang('hide_from_public') ?>
</label>
</div>
<div class="form-text text-muted mb-3">
<small>
<?= lang('private_hint') ?>
</small>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="notifications" disabled>
<label class="form-check-label" for="notifications">
<?= lang('receive_notifications') ?>
</label>
</div>
</div>
<div>
<label class="form-label mb-3">
<?= lang('services') ?>
</label>
</div>
<div id="provider-services" class="card card-body bg-white border">
<!-- JS -->
</div>
<?php slot('after_secondary_fields'); ?>
</div>
</div>
</div>
<div class="working-plan-view tab-pane fade clearfix" id="working-plan">
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('working_plan') ?>
</h4>
<button id="reset-working-plan" class="btn btn-primary"
data-tippy-content="<?= lang('reset_working_plan') ?>">
<i class="fas fa-undo-alt me-2"></i>
<?= lang('reset_plan') ?></button>
<table class="working-plan table table-striped mt-2">
<thead>
<tr>
<th><?= lang('day') ?></th>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<?php slot('after_working_plan'); ?>
<br>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('breaks') ?>
</h4>
<p>
<?= lang('add_breaks_during_each_day') ?>
</p>
<div>
<button type="button" class="add-break btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add_break') ?>
</button>
</div>
<br>
<table class="breaks table table-striped">
<thead>
<tr>
<th><?= lang('day') ?></th>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
<th><?= lang('actions') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<?php slot('after_breaks'); ?>
<br>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('working_plan_exceptions') ?>
</h4>
<p>
<?= lang('add_working_plan_exceptions_during_each_day') ?>
</p>
<div>
<button type="button" class="add-working-plan-exception btn btn-primary me-2">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add_working_plan_exception') ?>
</button>
</div>
<br>
<table class="working-plan-exceptions table table-striped">
<thead>
<tr>
<th><?= lang('day') ?></th>
<th><?= lang('start') ?></th>
<th><?= lang('end') ?></th>
<th><?= lang('actions') ?></th>
</tr>
</thead>
<tbody><!-- Dynamic Content --></tbody>
</table>
<?php component('working_plan_exceptions_modal'); ?>
<?php slot('after_working_plan_exceptions'); ?>
</div>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/vendor/jquery-jeditable/jquery.jeditable.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/ui.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/working_plan.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/account_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/providers_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/providers.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,54 @@
<?php extend('layouts/account_layout'); ?>
<?php section('content'); ?>
<h2><?= lang('forgot_your_password') ?></h2>
<p>
<small>
<?= lang('type_username_and_email_for_new_password') ?>
</small>
</p>
<hr>
<div class="alert d-none"></div>
<form class="mb-5">
<div class="mb-3 mt-5">
<label for="username" class="form-label">
<?= lang('username') ?>
</label>
<input type="text" id="username" placeholder="<?= lang('enter_username_here') ?>" class="form-control"/>
</div>
<div class="mb-5">
<label for="email" class="form-label">
<?= lang('email') ?>
</label>
<input type="text" id="email" placeholder="<?= lang('enter_email_here') ?>" class="form-control"/>
</div>
<div class="d-flex justify-content-between align-items-center mb-5">
<a href="<?= site_url('login') ?>" class="user-login">
<?= lang('go_to_login') ?>
</a>
<button type="submit" id="get-new-password" class="btn btn-primary btn-large">
<i class="fas fa-unlock-alt me-2"></i>
<?= lang('regenerate_password') ?>
</button>
</div>
</form>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/recovery_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/recovery.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,263 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="secretaries-page">
<div class="row" id="secretaries">
<div id="filter-secretaries" class="filter-records column col-12 col-md-5">
<form class="mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('secretaries') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details column col-12 col-md-7">
<div class="btn-toolbar mb-4">
<div class="add-edit-delete-group btn-group">
<button id="add-secretary" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-secretary" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-secretary" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-secretary" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-secretary" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id" class="record-id">
<div class="row">
<div class="details col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="first-name">
<?= lang('first_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="first-name" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="last-name">
<?= lang('last_name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="last-name" class="form-control required" maxlength="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="email">
<?= lang('email') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="email" class="form-control required" maxlength="512" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="phone-number" class="form-control required" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="mobile-number">
<?= lang('mobile_number') ?>
</label>
<input id="mobile-number" class="form-control" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="address">
<?= lang('address') ?>
</label>
<input id="address" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="city">
<?= lang('city') ?>
</label>
<input id="city" class="form-control" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="state">
<?= lang('state') ?>
</label>
<input id="state" class="form-control" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="zip-code">
<?= lang('zip_code') ?>
</label>
<input id="zip-code" class="form-control" maxlength="64" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" class="form-control" rows="3" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
<div class="settings col-12 col-md-6">
<div class="mb-3">
<label class="form-label" for="username">
<?= lang('username') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="username" class="form-control required" maxlength="256" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password">
<?= lang('password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password" class="form-control required"
maxlength="512" autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="password-confirm">
<?= lang('retype_password') ?>
<span class="text-danger" hidden>*</span>
</label>
<input type="password" id="password-confirm" class="form-control required"
maxlength="512" autocomplete="new-password" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="calendar-view">
<?= lang('calendar') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="calendar-view" class="form-select required" disabled>
<option value="default"><?= lang('default') ?></option>
<option value="table"><?= lang('table') ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="language">
<?= lang('language') ?>
<span class="text-danger" hidden>*</span>
</label>
<select id="language" class="form-select required" disabled>
<?php foreach (vars('available_languages') as $available_language): ?>
<option value="<?= $available_language ?>">
<?= ucfirst($available_language) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="timezone">
<?= lang('timezone') ?>
<span class="text-danger" hidden>*</span>
</label>
<?php component('timezone_dropdown', [
'attributes' => 'id="timezone" class="form-control required" disabled',
'grouped_timezones' => vars('grouped_timezones'),
]); ?>
</div>
<?php if (setting('ldap_is_active')): ?>
<div class="mb-3">
<label for="ldap-dn" class="form-label">
<?= lang('ldap_dn') ?>
</label>
<input type="text" id="ldap-dn" class="form-control" maxlength="100" disabled/>
</div>
<?php endif; ?>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="notifications" disabled>
<label class="form-check-label" for="notifications">
<?= lang('receive_notifications') ?>
</label>
</div>
</div>
<div>
<label class="form-label mb-3">
<?= lang('providers') ?>
</label>
</div>
<div id="secretary-providers" class="card card-body bg-white border">
<!-- JS -->
</div>
<?php slot('after_secondary_fields'); ?>
</div>
</div>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/account_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/secretaries_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/secretaries.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,100 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="service-categories-page">
<div class="row" id="service-categories">
<div id="filter-service-categories" class="filter-records column col-12 col-md-5">
<form class="input-append mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('service_categories') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details col-12 col-md-5">
<div class="btn-toolbar mb-4">
<div class="add-edit-delete-group btn-group">
<button id="add-service-category" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-service-category" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-service-category" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-service-category" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-service-category" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id">
<div class="mb-3">
<label class="form-label" for="name">
<?= lang('name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="name" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="description">
<?= lang('description') ?>
</label>
<textarea id="description" rows="4" class="form-control" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/service_categories_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/service_categories.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,187 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="services-page">
<div class="row" id="services">
<div id="filter-services" class="filter-records col col-12 col-md-5">
<form class="mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('services') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details column col-12 col-md-5">
<div class="btn-toolbar mb-4">
<div class="add-edit-delete-group btn-group">
<button id="add-service" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-service" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-service" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-service" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-service" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id">
<div class="mb-3">
<label class="form-label" for="name">
<?= lang('name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="name" class="form-control required" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="duration">
<?= lang('duration_minutes') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="duration" class="form-control required" type="number" min="<?= EVENT_MINIMUM_DURATION ?>"
disabled>
</div>
<div class="mb-3">
<label class="form-label" for="price">
<?= lang('price') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="price" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="currency">
<?= lang('currency') ?>
</label>
<input id="currency" class="form-control" maxlength="32" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="service-category-id">
<?= lang('category') ?>
</label>
<select id="service-category-id" class="form-select" disabled></select>
</div>
<div class="mb-3">
<label class="form-label" for="availabilities-type">
<?= lang('availabilities_type') ?>
</label>
<select id="availabilities-type" class="form-select" disabled>
<option value="<?= AVAILABILITIES_TYPE_FLEXIBLE ?>">
<?= lang('flexible') ?>
</option>
<option value="<?= AVAILABILITIES_TYPE_FIXED ?>">
<?= lang('fixed') ?>
</option>
</select>
</div>
<div class="mb-3">
<label class="form-label" for="attendants-number" disabled>
<?= lang('attendants_number') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="attendants-number" class="form-control required" type="number" min="1">
</div>
<div class="mb-3">
<label class="form-label" for="location">
<?= lang('location') ?>
</label>
<input id="location" class="form-control" disabled>
</div>
<div class="mb-3">
<?php component('color_selection', ['attributes' => 'id="color"']); ?>
</div>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="is-private">
<label class="form-check-label" for="is-private">
<?= lang('hide_from_public') ?>
</label>
</div>
<div class="form-text text-muted">
<small>
<?= lang('private_hint') ?>
</small>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="description">
<?= lang('description') ?>
</label>
<textarea id="description" rows="4" class="form-control" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/services_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/service_categories_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/services.js') ?>"></script>
<?php end_section('scripts'); ?>

View File

@@ -0,0 +1,73 @@
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Update | Easy!Appointments</title>
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/themes/default.min.css') ?>">
<link rel="icon" type="image/x-icon" href="<?= asset_url('assets/img/favicon.ico') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/general.css') ?>">
<link rel="stylesheet" type="text/css" href="<?= asset_url('assets/css/pages/update.css') ?>">
</head>
<body>
<header>
<div class="container">
<h1 class="page-title">Easy!Appointments Update</h1>
</div>
</header>
<div class="container">
<div class="row">
<div class="col">
<?php if (vars('success')): ?>
<div class="jumbotron">
<h1 class="display-4">Success!</h1>
<p class="lead">
The database got updated successfully.
</p>
<hr class="my-4">
<p>
You can now use the latest Easy!Appointments version.
</p>
<a href="<?= site_url('about') ?>" class="btn btn-success btn-large">
<i class="fas fa-wrench me-2"></i>
<?= lang('backend_section') ?>
</a>
</div>
<?php else: ?>
<div class="jumbotron">
<h1 class="display-4">Failure!</h1>
<p class="lead">
There was an error during the update process.
</p>
<hr class="my-4">
<p>
Please restore your database backup.
</p>
<a href="<?= site_url('login') ?>" class="btn btn-success btn-large">
<i class="fas fa-wrench me-2"></i>
<?= lang('backend_section') ?>
</a>
<p>
Please restore your database backup.
</p>
</div>
<div class="well text-start">
Error Message: <?= vars('exception') ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<footer>
Powered by <a href="https://easyappointments.org">Easy!Appointments</a>
</footer>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
</body>
</html>

View File

@@ -0,0 +1,168 @@
<?php extend('layouts/backend_layout'); ?>
<?php section('content'); ?>
<div class="container-fluid backend-page" id="webhooks-page">
<div class="row" id="webhooks">
<div id="filter-webhooks" class="filter-records col col-12 col-md-5">
<form class="mb-4">
<div class="input-group">
<input type="text" class="key form-control" aria-label="keyword">
<button class="filter btn btn-outline-secondary" type="submit"
data-tippy-content="<?= lang('filter') ?>">
<i class="fas fa-search"></i>
</button>
</div>
</form>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('webhooks') ?>
</h4>
<?php slot('after_page_title'); ?>
<div class="results">
<!-- JS -->
</div>
</div>
<div class="record-details column col-12 col-md-5">
<div class="btn-toolbar mb-4">
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary me-2">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
<div class="add-edit-delete-group btn-group">
<button id="add-webhook" class="btn btn-primary">
<i class="fas fa-plus-square me-2"></i>
<?= lang('add') ?>
</button>
<button id="edit-webhook" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-edit me-2"></i>
<?= lang('edit') ?>
</button>
<button id="delete-webhook" class="btn btn-outline-secondary" disabled="disabled">
<i class="fas fa-trash-alt me-2"></i>
<?= lang('delete') ?>
</button>
</div>
<div class="save-cancel-group" style="display:none;">
<button id="save-webhook" class="btn btn-primary">
<i class="fas fa-check-square me-2"></i>
<?= lang('save') ?>
</button>
<button id="cancel-webhook" class="btn btn-secondary">
<?= lang('cancel') ?>
</button>
</div>
<?php slot('after_page_actions'); ?>
</div>
<h4 class="text-black-50 mb-3 fw-light">
<?= lang('details') ?>
</h4>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="id">
<div class="mb-3">
<label class="form-label" for="name">
<?= lang('name') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="name" class="form-control required" maxlength="128" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="url">
<?= lang('url') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="url" class="form-control required" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="secret-header">
<?= lang('secret_header') ?>
</label>
<input id="secret-header" class="form-control" disabled>
</div>
<div class="mb-3">
<label class="form-label" for="secret-token">
<?= lang('secret_token') ?>
</label>
<input id="secret-token" class="form-control" disabled>
</div>
<div>
<label class="form-label mb-3" for="actions">
<?= lang('actions') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div id="actions">
<?php foreach (vars('available_actions') as $available_action): ?>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
id="include-<?= str_replace('_', '-', $available_action) ?>"
data-action="<?= $available_action ?>">
<label class="form-check-label"
for="include-<?= str_replace('_', '-', $available_action) ?>">
<?= lang($available_action) ?>
</label>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div>
<label class="form-label mb-3">
<?= lang('options') ?>
</label>
</div>
<div class="border rounded mb-3 p-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="is-ssl-verified">
<label class="form-check-label" for="is-ssl-verified">
<?= lang('verify_ssl') ?>
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label" for="notes">
<?= lang('notes') ?>
</label>
<textarea id="notes" rows="4" class="form-control" disabled></textarea>
</div>
<?php slot('after_primary_fields'); ?>
</div>
</div>
</div>
<?php end_section('content'); ?>
<?php section('scripts'); ?>
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
<script src="<?= asset_url('assets/js/http/webhooks_http_client.js') ?>"></script>
<script src="<?= asset_url('assets/js/pages/webhooks.js') ?>"></script>
<?php end_section('scripts'); ?>