Compare commits

...

22 Commits

Author SHA1 Message Date
Aliberk Sandıkçı b311a9b59e
update versions 2024-01-09 23:47:14 +03:00
Aliberk Sandıkçı b06d335271
update translations 2024-01-09 23:13:13 +03:00
Aliberk Sandıkçı 98a37bde1d
Merge remote-tracking branch 'remotes/upstream/develop' into develop 2024-01-09 21:53:49 +03:00
Alex Tselegidis a02a6118b6 Perform styling changes to the public booking page 2024-01-06 12:32:36 +01:00
Alex Tselegidis b192b437e0 Patch the Captcha_builder.php for PHP8.2 2024-01-06 11:41:43 +01:00
Alex Tselegidis acafb0da48 Improve the way the service description renders in the booking page 2024-01-06 11:32:42 +01:00
Alex Tselegidis fa6f685e13 Fix "categories" table not found error 2024-01-06 11:22:12 +01:00
Alex Tselegidis ac7ca85b88 Narrow the service selection of the booking page 2024-01-06 11:13:39 +01:00
Alex Tselegidis cd768bda85 Use the helper methods to set and get date time picker values 2024-01-06 11:06:48 +01:00
Alex Tselegidis 02162ee232 Rename ui.js methods 2024-01-06 10:46:57 +01:00
Alex Tselegidis c7f2e7f831 Move the position of the back button 2024-01-06 10:40:02 +01:00
Aliberk Sandıkçı 26d909a19b
Merge remote-tracking branch 'upstream/develop' into develop 2024-01-05 21:32:28 +03:00
Aliberk Sandıkçı 42c707cea3
update translation 2024-01-05 21:27:49 +03:00
Alex Tselegidis cd6280b97d Make sure the API returns 404 on show if the ID was not found 2024-01-05 19:20:00 +01:00
Alex Tselegidis aee7bb80c0 Add return types 2024-01-05 19:12:25 +01:00
Alex Tselegidis 7a8832d311 Use fixed swagger UI version 2024-01-05 17:38:50 +01:00
Alex Tselegidis 5a1f604e3d Add missing security section for unavailabilities 2024-01-05 17:10:17 +01:00
Alex Tselegidis 6a1b2b28f1 Replace collection objects with array definitions that better translate to Swagger clients 2024-01-05 17:09:44 +01:00
Alex Tselegidis e0a1282338 Add missing API methods 2024-01-05 17:06:55 +01:00
Alex Tselegidis c5eafc9552 Add missing translations 2024-01-05 16:49:23 +01:00
Alex Tselegidis 87cb1e190b Correct typo 2024-01-04 21:57:01 +01:00
Alex Tselegidis 10383d407b
Merge pull request #1442 from asandikci/develop
fix(timezone): update Istanbul timezone
2024-01-03 10:34:13 +01:00
43 changed files with 545 additions and 437 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"php.version": "8.2"
}

View File

@ -9,7 +9,7 @@
|
*/
$config['version'] = '1.5.0-RC1'; // This must be changed manually.
$config['version'] = '1.5.0-RC2'; // This must be changed manually.
$config['url'] = Config::BASE_URL;

View File

@ -37,7 +37,7 @@ class Admins_api_v1 extends EA_Controller
/**
* Get an admin collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -79,9 +79,17 @@ class Admins_api_v1 extends EA_Controller
*
* @param int|null $id Admin ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->admins_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -98,12 +106,6 @@ class Admins_api_v1 extends EA_Controller
$this->admins_model->load($admin, $with);
}
if (!$admin) {
response('', 404);
return;
}
json_response($admin);
} catch (Throwable $e) {
json_exception($e);
@ -113,7 +115,7 @@ class Admins_api_v1 extends EA_Controller
/**
* Store a new admin.
*/
public function store()
public function store(): void
{
try {
$admin = request();
@ -145,7 +147,7 @@ class Admins_api_v1 extends EA_Controller
*
* @param int $id Admin ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->admins_model->get(['id' => $id]);
@ -179,7 +181,7 @@ class Admins_api_v1 extends EA_Controller
*
* @param int $id Admin ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->admins_model->get(['id' => $id]);

View File

@ -43,7 +43,7 @@ class Appointments_api_v1 extends EA_Controller
/**
* Get an appointment collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -143,7 +143,7 @@ class Appointments_api_v1 extends EA_Controller
*
* @deprecated Since 1.5
*/
private function aggregates(array &$appointment)
private function aggregates(array &$appointment): void
{
$aggregates = request('aggregates') !== null;
@ -171,9 +171,17 @@ class Appointments_api_v1 extends EA_Controller
*
* @param int|null $id Appointment ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->appointments_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -190,12 +198,6 @@ class Appointments_api_v1 extends EA_Controller
$this->appointments_model->load($appointment, $with);
}
if (!$appointment) {
response('Not Found', 404);
return;
}
json_response($appointment);
} catch (Throwable $e) {
json_exception($e);
@ -205,7 +207,7 @@ class Appointments_api_v1 extends EA_Controller
/**
* Store a new appointment.
*/
public function store()
public function store(): void
{
try {
$appointment = request();
@ -295,7 +297,7 @@ class Appointments_api_v1 extends EA_Controller
*
* @param int $id Appointment ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->appointments_model->get(['id' => $id]);
@ -331,7 +333,7 @@ class Appointments_api_v1 extends EA_Controller
*
* @param int $id Appointment ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->appointments_model->get(['id' => $id]);

View File

@ -54,7 +54,7 @@ class Availabilities_api_v1 extends EA_Controller
*
* If no date parameter is provided then the current date will be used.
*/
public function get()
public function get(): void
{
try {
$provider_id = request('providerId');

View File

@ -35,7 +35,7 @@ class Customers_api_v1 extends EA_Controller
/**
* Get a customer collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Customers_api_v1 extends EA_Controller
*
* @param int|null $id Customer ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->customers_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$customer = $this->customers_model->find($id);
@ -90,12 +98,6 @@ class Customers_api_v1 extends EA_Controller
$this->customers_model->only($customer, $fields);
}
if (!$customer) {
response('', 404);
return;
}
json_response($customer);
} catch (Throwable $e) {
json_exception($e);
@ -105,7 +107,7 @@ class Customers_api_v1 extends EA_Controller
/**
* Store a new customer.
*/
public function store()
public function store(): void
{
try {
$customer = request();
@ -133,7 +135,7 @@ class Customers_api_v1 extends EA_Controller
*
* @param int $id Customer ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->customers_model->get(['id' => $id]);
@ -167,7 +169,7 @@ class Customers_api_v1 extends EA_Controller
*
* @param int $id Customer ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->customers_model->get(['id' => $id]);

View File

@ -35,7 +35,7 @@ class Providers_api_v1 extends EA_Controller
/**
* Get a provider collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Providers_api_v1 extends EA_Controller
*
* @param int|null $id Provider ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->providers_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -96,12 +104,6 @@ class Providers_api_v1 extends EA_Controller
$this->providers_model->load($provider, $with);
}
if (!$provider) {
response('', 404);
return;
}
json_response($provider);
} catch (Throwable $e) {
json_exception($e);
@ -111,7 +113,7 @@ class Providers_api_v1 extends EA_Controller
/**
* Store a new provider.
*/
public function store()
public function store(): void
{
try {
$provider = request();
@ -151,7 +153,7 @@ class Providers_api_v1 extends EA_Controller
*
* @param int $id Provider ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->providers_model->get(['id' => $id]);
@ -185,7 +187,7 @@ class Providers_api_v1 extends EA_Controller
*
* @param int $id Provider ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->providers_model->get(['id' => $id]);

View File

@ -35,7 +35,7 @@ class Secretaries_api_v1 extends EA_Controller
/**
* Get a secretary collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Secretaries_api_v1 extends EA_Controller
*
* @param int|null $id Secretary ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->secretaries_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$secretary = $this->secretaries_model->find($id);
@ -90,12 +98,6 @@ class Secretaries_api_v1 extends EA_Controller
$this->secretaries_model->only($secretary, $fields);
}
if (!$secretary) {
response('', 404);
return;
}
json_response($secretary);
} catch (Throwable $e) {
json_exception($e);
@ -105,7 +107,7 @@ class Secretaries_api_v1 extends EA_Controller
/**
* Store a new secretary.
*/
public function store()
public function store(): void
{
try {
$secretary = request();
@ -141,7 +143,7 @@ class Secretaries_api_v1 extends EA_Controller
*
* @param int $id Secretary ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->secretaries_model->get(['id' => $id]);
@ -175,7 +177,7 @@ class Secretaries_api_v1 extends EA_Controller
*
* @param int $id Secretary ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->secretaries_model->get(['id' => $id]);

View File

@ -35,7 +35,7 @@ class Service_categories_api_v1 extends EA_Controller
/**
* Get a service-category collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Service_categories_api_v1 extends EA_Controller
*
* @param int|null $id Service-category ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->service_categories_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -96,12 +104,6 @@ class Service_categories_api_v1 extends EA_Controller
$this->service_categories_model->load($service_category, $with);
}
if (!$service_category) {
response('', 404);
return;
}
json_response($service_category);
} catch (Throwable $e) {
json_exception($e);
@ -111,7 +113,7 @@ class Service_categories_api_v1 extends EA_Controller
/**
* Store a new service-category.
*/
public function store()
public function store(): void
{
try {
$service_category = request();
@ -139,7 +141,7 @@ class Service_categories_api_v1 extends EA_Controller
*
* @param int $id Service-category ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->service_categories_model->get(['id' => $id]);
@ -173,7 +175,7 @@ class Service_categories_api_v1 extends EA_Controller
*
* @param int $id Service-category ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->service_categories_model->get(['id' => $id]);

View File

@ -35,7 +35,7 @@ class Services_api_v1 extends EA_Controller
/**
* Get an service collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Services_api_v1 extends EA_Controller
*
* @param int|null $id Service ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->services_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -96,12 +104,6 @@ class Services_api_v1 extends EA_Controller
$this->services_model->load($service, $with);
}
if (!$service) {
response('', 404);
return;
}
json_response($service);
} catch (Throwable $e) {
json_exception($e);
@ -111,7 +113,7 @@ class Services_api_v1 extends EA_Controller
/**
* Store a new service.
*/
public function store()
public function store(): void
{
try {
$service = request();
@ -139,7 +141,7 @@ class Services_api_v1 extends EA_Controller
*
* @param int $id Service ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->services_model->get(['id' => $id]);
@ -173,7 +175,7 @@ class Services_api_v1 extends EA_Controller
*
* @param int $id Service ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->services_model->get(['id' => $id]);

View File

@ -71,7 +71,7 @@ class Settings_api_v1 extends EA_Controller
*
* @param string $name Setting name.
*/
public function show(string $name)
public function show(string $name): void
{
try {
$value = setting($name);
@ -90,7 +90,7 @@ class Settings_api_v1 extends EA_Controller
*
* @param string $name Setting name.
*/
public function update(string $name)
public function update(string $name): void
{
try {
$value = request('value');

View File

@ -35,7 +35,7 @@ class Unavailabilities_api_v1 extends EA_Controller
/**
* Get an unavailability collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Unavailabilities_api_v1 extends EA_Controller
*
* @param int|null $id Unavailability ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->unavailabilities_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -96,12 +104,6 @@ class Unavailabilities_api_v1 extends EA_Controller
$this->unavailabilities_model->load($unavailability, $with);
}
if (!$unavailability) {
response('', 404);
return;
}
json_response($unavailability);
} catch (Throwable $e) {
json_exception($e);
@ -111,7 +113,7 @@ class Unavailabilities_api_v1 extends EA_Controller
/**
* Store a new unavailability.
*/
public function store()
public function store(): void
{
try {
$unavailability = request();
@ -139,7 +141,7 @@ class Unavailabilities_api_v1 extends EA_Controller
*
* @param int $id Unavailability ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->unavailabilities_model->get(['id' => $id]);
@ -173,7 +175,7 @@ class Unavailabilities_api_v1 extends EA_Controller
*
* @param int $id Unavailability ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->unavailabilities_model->get(['id' => $id]);

View File

@ -35,7 +35,7 @@ class Webhooks_api_v1 extends EA_Controller
/**
* Get a webhook collection.
*/
public function index()
public function index(): void
{
try {
$keyword = $this->api->request_keyword();
@ -77,9 +77,17 @@ class Webhooks_api_v1 extends EA_Controller
*
* @param int|null $id Webhook ID.
*/
public function show(int $id = null)
public function show(int $id = null): void
{
try {
$occurrences = $this->webhooks_model->get(['id' => $id]);
if (empty($occurrences)) {
response('', 404);
return;
}
$fields = $this->api->request_fields();
$with = $this->api->request_with();
@ -96,12 +104,6 @@ class Webhooks_api_v1 extends EA_Controller
$this->webhooks_model->load($webhook, $with);
}
if (!$webhook) {
response('', 404);
return;
}
json_response($webhook);
} catch (Throwable $e) {
json_exception($e);
@ -111,7 +113,7 @@ class Webhooks_api_v1 extends EA_Controller
/**
* Store a new webhook.
*/
public function store()
public function store(): void
{
try {
$webhook = request();
@ -139,7 +141,7 @@ class Webhooks_api_v1 extends EA_Controller
*
* @param int $id Webhook ID.
*/
public function update(int $id)
public function update(int $id): void
{
try {
$occurrences = $this->webhooks_model->get(['id' => $id]);
@ -173,7 +175,7 @@ class Webhooks_api_v1 extends EA_Controller
*
* @param int $id Webhook ID.
*/
public function destroy(int $id)
public function destroy(int $id): void
{
try {
$occurrences = $this->webhooks_model->get(['id' => $id]);

View File

@ -1,5 +1,11 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
// English
$lang['address'] = 'School Name';
$lang['city'] = 'School City';
$lang['zip_code'] = 'Number of Students';
$lang['notes'] = 'Extra Notes';
$lang['system_installation'] = 'System Installation';
$lang['system_installation_welcome_header'] = 'Welcome to the ' . branding("software", "name_en") . " installation page";
$lang['powered_by'] = 'Powered By <a href="' . branding("software", "website") . '" target="_blank">' . branding("software", "name_en") . '</a>';

View File

@ -449,4 +449,8 @@ $lang['blocked_periods_hint'] = 'Define periods of time where public bookings wi
$lang['custom_field'] = 'Custom Field';
$lang['custom_fields'] = 'Custom Fields';
$lang['label'] = 'Label';
$lang['webhook_saved'] = 'Webhook saved successfully.';
$lang['webhook_deleted'] = 'Webhook deleted successfully.';
$lang['delete_webhook'] = 'Delete Webhook';
$lang['contact_info'] = 'Contact Info';
// End

View File

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

View File

@ -1,5 +1,11 @@
<?php defined('BASEPATH') OR exit('No direct script access allowed');
// Turkish
$lang['address'] = 'Okulunuzun Adı';
$lang['city'] = 'Okulunuzun Bulunduğu Şehir';
$lang['zip_code'] = 'Gelecek Öğrenci Sayısı';
$lang['notes'] = 'Eklemek İstedikleriniz';
$lang['system_installation'] = 'Sistem Yüklemesi';
$lang['system_installation_welcome_header'] = branding("software", "name_tr") . " sistem yükleme sayfasına hoşgeldiniz";
$lang['powered_by'] = '<a href="' . branding("software", "website") . '" target="_blank">' . branding("software", "name_tr") . '</a> Gururla Sunar';

View File

@ -1,6 +1,6 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
// Turkish
$lang['page_title'] = 'Randevu Alınacak Kişi';
$lang['page_title'] = 'Randevu Al | ';
$lang['service_and_provider'] = 'Hizmet ve Hizmet Sağlayıcıyı Seçin';
$lang['select_service'] = 'Hizmeti Seçin';
$lang['select_provider'] = 'Hizmet Sağlayıcıyı Seçin';
@ -17,10 +17,10 @@ $lang['last_name'] = 'Soyad';
$lang['email'] = 'Eposta';
$lang['phone_number'] = 'Telefon No';
$lang['phone'] = 'Phone';
$lang['address'] = 'Adres';
$lang['city'] = 'Şehir';
$lang['zip_code'] = 'Posta Kodu';
$lang['notes'] = 'Notlar';
// $lang['address'] = 'Adres';
// $lang['city'] = 'Şehir';
// $lang['zip_code'] = 'Posta Kodu';
// $lang['notes'] = 'Notlar';
$lang['language'] = 'Dil';
$lang['no_language'] = 'Dil yok';
$lang['fields_are_required'] = '* Zorunlu Alanlar.';
@ -449,4 +449,8 @@ $lang['blocked_periods_hint'] = 'Define periods of time where public bookings wi
$lang['custom_field'] = 'Değiştirilebilir Alan';
$lang['custom_fields'] = 'Değiştirilebilir Alanlar';
$lang['label'] = 'Etiket';
$lang['webhook_saved'] = 'Webhook saved successfully.';
$lang['webhook_deleted'] = 'Webhook deleted successfully.';
$lang['delete_webhook'] = 'Delete Webhook';
$lang['contact_info'] = 'İletişim Bilgisi';
// End

View File

@ -41,6 +41,10 @@ class Captcha_builder
* @var array
*/
protected $lineColor = null;
/**
* @var array
*/
protected $background = null;
/**
* @var array
*/

View File

@ -63,7 +63,7 @@ class Notifications
bool $manage_mode = false,
): void {
try {
$current_language = config('english');
$current_language = config('language');
$customer_link = site_url('booking/reschedule/' . $appointment['hash']);

View File

@ -96,7 +96,9 @@ class Services_model extends EA_Model
// If a category was provided then make sure it really exists in the database.
if (!empty($service['id_service_categories'])) {
$count = $this->db->get_where('categories', ['id' => $service['id_service_categories']])->num_rows();
$count = $this->db
->get_where('service_categories', ['id' => $service['id_service_categories']])
->num_rows();
if (!$count) {
throw new InvalidArgumentException(
@ -387,7 +389,7 @@ class Services_model extends EA_Model
foreach ($resources as $resource) {
$service['category'] = match ($resource) {
'category' => $this->db
->get_where('categories', [
->get_where('service_categories', [
'id' => $service['id_service_categories'] ?? ($service['serviceCategoryId'] ?? null),
])
->row_array(),

View File

@ -277,4 +277,65 @@ class Webhooks_model extends EA_Model
{
// Webhooks do not currently have any related resources.
}
/**
* Convert the database webhook record to the equivalent API resource.
*
* @param array $webhook Webhook data.
*/
public function api_encode(array &$webhook): void
{
$encoded_resource = [
'id' => array_key_exists('id', $webhook) ? (int) $webhook['id'] : null,
'name' => $webhook['name'],
'url' => $webhook['url'],
'actions' => $webhook['actions'],
'secret_token' => $webhook['secret_token'],
'is_ssl_verified' => $webhook['is_ssl_verified'],
'notes' => $webhook['notes'],
];
$webhook = $encoded_resource;
}
/**
* Convert the API resource to the equivalent database webhook record.
*
* @param array $webhook API resource.
* @param array|null $base Base webhook data to be overwritten with the provided values (useful for updates).
*/
public function api_decode(array &$webhook, array $base = null)
{
$decoded_resource = $base ?: [];
if (array_key_exists('id', $webhook)) {
$decoded_resource['id'] = $webhook['id'];
}
if (array_key_exists('name', $webhook)) {
$decoded_resource['name'] = $webhook['name'];
}
if (array_key_exists('url', $webhook)) {
$decoded_resource['url'] = $webhook['url'];
}
if (array_key_exists('actions', $webhook)) {
$decoded_resource['actions'] = $webhook['actions'];
}
if (array_key_exists('secretToken', $webhook)) {
$decoded_resource['secret_token'] = $webhook['secretToken'];
}
if (array_key_exists('isSslVerified', $webhook)) {
$decoded_resource['is_ssl_verified'] = $webhook['isSslVerified'];
}
if (array_key_exists('notes', $webhook)) {
$decoded_resource['notes'] = $webhook['notes'];
}
$webhook = $decoded_resource;
}
}

View File

@ -11,13 +11,19 @@
<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">
<div id="appointment-details" class="col-12 col-md-6 text-center text-md-start"></div>
<div id="customer-details" class="col-12 col-md-6 text-center text-md-end"></div>
<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 if (setting('require_captcha')): ?>
<div class="row frame-content">
<div class="col-12 col-md-6">
<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">

View File

@ -11,7 +11,7 @@
<h2 class="frame-title"><?= lang('service_and_provider') ?></h2>
<div class="row frame-content">
<div class="col">
<div class="col col-md-8 offset-md-2 mt-md-5">
<div class="mb-3">
<label for="select-service">
<strong><?= lang('service') ?></strong>
@ -83,7 +83,9 @@
<select id="select-provider" class="form-control"></select>
</div>
<div id="service-description"></div>
<div id="service-description" class="small">
<!-- JS -->
</div>
</div>
</div>
</div>

View File

@ -28,6 +28,11 @@
<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>
@ -52,11 +57,6 @@
<?= lang('cancel') ?>
</button>
</div>
<a href="<?= site_url('business_settings') ?>" class="btn btn-outline-primary ms-4">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
</div>
<h4 class="text-black-50 mb-3 fw-light">

View File

@ -27,6 +27,11 @@
<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>
@ -51,11 +56,6 @@
<?= lang('cancel') ?>
</button>
</div>
<a href="<?= site_url('integrations') ?>" class="btn btn-outline-primary ms-4">
<i class="fas fa-chevron-left me-2"></i>
<?= lang('back') ?>
</a>
</div>
<h4 class="text-black-50 mb-3 fw-light">

View File

@ -185,7 +185,7 @@ body {
margin: 15px 0;
padding-right: 10px;
width: auto;
max-height: 255px;
max-height: 250px;
}
#book-appointment-wizard #available-hours div {
@ -273,6 +273,10 @@ body {
margin: 15px 0;
}
#book-appointment-wizard #wizard-frame-4 .frame-container .frame-content {
max-width: 630px;
}
@media (min-width: 768px) {
.wrapper {
min-height: 100vh;

View File

@ -52,6 +52,8 @@ App.Components.AppointmentsModal = (function () {
const $customField4 = $('#custom-field-4');
const $customField5 = $('#custom-field-5');
const moment = window.moment;
/**
* Update the displayed timezone.
*/
@ -85,8 +87,11 @@ App.Components.AppointmentsModal = (function () {
// ID must exist on the object in order for the model to update the record and not to perform
// an insert operation.
const startDatetime = moment($startDatetime[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD HH:mm:ss');
const endDatetime = moment($endDatetime[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD HH:mm:ss');
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDatetime);
const startDatetime = moment(startDateTimeObject).format('YYYY-MM-DD HH:mm:ss');
const endDateTimeObject = App.Utils.UI.getDateTimePickerValue($endDatetime);
const endDatetime = moment(endDateTimeObject).format('YYYY-MM-DD HH:mm:ss');
const appointment = {
id_services: $selectService.val(),
@ -204,8 +209,8 @@ App.Components.AppointmentsModal = (function () {
startMoment.add(1, 'hour').set({minutes: 0});
}
$startDatetime[0]._flatpickr.setDate(startMoment.toDate());
$endDatetime[0]._flatpickr.setDate(startMoment.add(duration, 'minutes').toDate());
App.Utils.UI.setDateTimePickerValue($startDatetime, startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($endDatetime, startMoment.add(duration, 'minutes').toDate());
// Display modal form.
$appointmentsModal.find('.modal-header h3').text(lang('new_appointment_title'));
@ -362,8 +367,9 @@ App.Components.AppointmentsModal = (function () {
const duration = service ? service.duration : 60;
const start = $startDatetime[0]._flatpickr.selectedDates[0];
$endDatetime[0]._flatpickr.setDate(new Date(start.getTime() + duration * 60000));
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDatetime);
const endDateTimeObject = new Date(startDateTimeObject.getTime() + duration * 60000);
App.Utils.UI.setDateTimePickerValue($endDatetime, endDateTimeObject);
// Update the providers select box.
@ -481,7 +487,7 @@ App.Components.AppointmentsModal = (function () {
const startDatetime = new Date();
const endDatetime = moment().add(duration, 'minutes').toDate();
App.Utils.UI.initializeDatetimepicker($startDatetime, {
App.Utils.UI.initializeDateTimePicker($startDatetime, {
onClose: () => {
const serviceId = $selectService.val();
@ -490,15 +496,16 @@ App.Components.AppointmentsModal = (function () {
(availableService) => Number(availableService.id) === Number(serviceId),
);
const start = $startDatetime[0]._flatpickr.selectedDates[0];
$endDatetime[0]._flatpickr.setDate(new Date(start.getTime() + service.duration * 60000));
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDatetime);
const endDateTimeObject = new Date(startDateTimeObject.getTime() + service.duration * 60000);
App.Utils.UI.setDateTimePickerValue($endDatetime, endDateTimeObject);
},
});
$startDatetime[0]._flatpickr.setDate(startDatetime);
App.Utils.UI.setDateTimePickerValue($startDatetime, startDatetime);
App.Utils.UI.initializeDatetimepicker($endDatetime);
$endDatetime[0]._flatpickr.setDate(endDatetime);
App.Utils.UI.initializeDateTimePicker($endDatetime);
App.Utils.UI.setDateTimePickerValue($endDatetime, endDatetime);
}
/**
@ -538,9 +545,10 @@ App.Components.AppointmentsModal = (function () {
}
// Check appointment start and end time.
const start = $startDatetime[0]._flatpickr.selectedDates[0];
const end = $endDatetime[0]._flatpickr.selectedDates[0];
if (start > end) {
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDatetime);
const endDateTimeObject = App.Utils.UI.getDateTimePickerValue($endDatetime);
if (startDateTimeObject > endDateTimeObject) {
$startDatetime.addClass('is-invalid');
$endDatetime.addClass('is-invalid');
throw new Error(lang('start_date_before_end_error'));

View File

@ -28,6 +28,8 @@ App.Components.UnavailabilitiesModal = (function () {
const $selectFilterItem = $('#select-filter-item');
const $reloadAppointments = $('#reload-appointments');
const moment = window.moment;
/**
* Update the displayed timezone.
*/
@ -68,22 +70,22 @@ App.Components.UnavailabilitiesModal = (function () {
return;
}
const startMoment = moment($startDatetime[0]._flatpickr.selectedDates[0]);
const startDateTimeMoment = moment(App.Utils.UI.getDateTimePickerValue($startDatetime));
if (!startMoment.isValid()) {
if (!startDateTimeMoment.isValid()) {
$startDatetime.addClass('is-invalid');
return;
}
const endMoment = moment($endDatetime[0]._flatpickr.selectedDates[0]);
const endDateTimeMoment = moment(App.Utils.UI.getDateTimePickerValue($endDatetime));
if (!endMoment.isValid()) {
if (!endDateTimeMoment.isValid()) {
$endDatetime.addClass('is-invalid');
return;
}
if (startMoment.isAfter(endMoment)) {
if (startDateTimeMoment.isAfter(endDateTimeMoment)) {
// Start time is after end time - display message to user.
$unavailabilitiesModal
.find('.modal-message')
@ -100,8 +102,8 @@ App.Components.UnavailabilitiesModal = (function () {
// Unavailability period records go to the appointments table.
const unavailability = {
start_datetime: startMoment.format('YYYY-MM-DD HH:mm:ss'),
end_datetime: endMoment.format('YYYY-MM-DD HH:mm:ss'),
start_datetime: startDateTimeMoment.format('YYYY-MM-DD HH:mm:ss'),
end_datetime: endDateTimeMoment.format('YYYY-MM-DD HH:mm:ss'),
notes: $unavailabilitiesModal.find('#unavailability-notes').val(),
id_users_provider: $selectProvider.val(),
};
@ -156,8 +158,8 @@ App.Components.UnavailabilitiesModal = (function () {
$selectProvider.val($selectFilterItem.val()).closest('.form-group').hide();
}
$startDatetime[0]._flatpickr.setDate(startMoment.toDate());
$endDatetime[0]._flatpickr.setDate(startMoment.add(1, 'hour').toDate());
App.Utils.UI.setDateTimePickerValue($startDatetime, startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($endDatetime, startMoment.add(1, 'hour').toDate());
$dialog.find('.modal-header h3').text(lang('new_unavailability_title'));
$dialog.modal('show');
@ -183,11 +185,11 @@ App.Components.UnavailabilitiesModal = (function () {
true,
);
App.Utils.UI.initializeDatetimepicker($startDatetime);
App.Utils.UI.initializeDateTimePicker($startDatetime);
$startDatetime.val(start);
App.Utils.UI.initializeDatetimepicker($endDatetime);
App.Utils.UI.initializeDateTimePicker($endDatetime);
$endDatetime.val(end);

View File

@ -77,19 +77,19 @@ App.Components.WorkingPlanExceptionsModal = (function () {
function validate() {
$modal.find('.is-invalid').removeClass('is-invalid');
const date = $date[0]._flatpickr.selectedDates[0];
const date = App.Utils.UI.getDateTimePickerValue($date);
if (!date) {
$date.addClass('is-invalid');
}
const start = $start[0]._flatpickr.selectedDates[0];
const start = App.Utils.UI.getDateTimePickerValue($start);
if (!start) {
$start.addClass('is-invalid');
}
const end = $end[0]._flatpickr.selectedDates[0];
const end = App.Utils.UI.getDateTimePickerValue($end);
if (!end) {
$end.addClass('is-invalid');
@ -157,15 +157,15 @@ App.Components.WorkingPlanExceptionsModal = (function () {
return;
}
const date = moment($date[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD');
const date = moment(App.Utils.UI.getDateTimePickerValue($date)).format('YYYY-MM-DD');
const isNonWorkingDay = $isNonWorkingDay.prop('checked');
const workingPlanException = isNonWorkingDay
? null
: {
start: moment($start[0]._flatpickr.selectedDates[0]).format('HH:mm'),
end: moment($end[0]._flatpickr.selectedDates[0]).format('HH:mm'),
start: moment(App.Utils.UI.getDateTimePickerValue($start)).format('HH:mm'),
end: moment(App.Utils.UI.getDateTimePickerValue($end)).format('HH:mm'),
breaks: getBreaks(),
};
@ -223,9 +223,9 @@ App.Components.WorkingPlanExceptionsModal = (function () {
function add() {
deferred = $.Deferred();
$date[0]._flatpickr.setDate(new Date());
$start[0]._flatpickr.setDate(moment('08:00', 'HH:mm').toDate());
$end[0]._flatpickr.setDate(moment('20:00', 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($date, new Date());
App.Utils.UI.setDateTimePickerValue($start, moment('08:00', 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($end, moment('20:00', 'HH:mm').toDate());
$isNonWorkingDay.prop('checked', false);
@ -249,11 +249,11 @@ App.Components.WorkingPlanExceptionsModal = (function () {
const isNonWorkingDay = !Boolean(workingPlanException);
$date[0]._flatpickr.setDate(moment(date, 'YYYY-MM-DD').toDate());
App.Utils.UI.setDateTimePickerValue($date, moment(date, 'YYYY-MM-DD').toDate());
if (isNonWorkingDay === false) {
$start[0]._flatpickr.setDate(moment(workingPlanException.start, 'HH:mm').toDate());
$end[0]._flatpickr.setDate(moment(workingPlanException.end, 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($start, moment(workingPlanException.start, 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($end, moment(workingPlanException.end, 'HH:mm').toDate());
if (!workingPlanException.breaks) {
$breaks.find('tbody').html(renderNoBreaksRow());
@ -267,8 +267,8 @@ App.Components.WorkingPlanExceptionsModal = (function () {
$breaks.find('tbody .working-plan-exceptions-break-start, tbody .working-plan-exceptions-break-end'),
);
} else {
$start[0]._flatpickr.setDate(moment('08:00', 'HH:mm').toDate());
$end[0]._flatpickr.setDate(moment('20:00', 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($start, moment('08:00', 'HH:mm').toDate());
App.Utils.UI.setDateTimePickerValue($end, moment('20:00', 'HH:mm').toDate());
$breaks.find('tbody').html(renderNoBreaksRow());
}
@ -380,7 +380,7 @@ App.Components.WorkingPlanExceptionsModal = (function () {
// Make all cells in current row editable.
let $tr = $(this).closest('tr');
$tr.children().trigger('edit');
App.Utils.UI.initializeTimepicker(
App.Utils.UI.initializeTimePicker(
$tr.find('.working-plan-exceptions-break-start input, .working-plan-exceptions-break-end input'),
);
$(this).closest('tr').find('.working-plan-exceptions-break-start').focus();
@ -462,9 +462,9 @@ App.Components.WorkingPlanExceptionsModal = (function () {
* Initialize the module.
*/
function initialize() {
App.Utils.UI.initializeDatepicker($date);
App.Utils.UI.initializeTimepicker($start);
App.Utils.UI.initializeTimepicker($end);
App.Utils.UI.initializeDatePicker($date);
App.Utils.UI.initializeTimePicker($start);
App.Utils.UI.initializeTimePicker($end);
$modal
.on('hidden.bs.modal', onModalHidden)

View File

@ -300,7 +300,7 @@ App.Http.Booking = (function () {
const currentDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i);
if (unavailableDates.indexOf(moment(currentDate).format('YYYY-MM-DD')) === -1) {
$('#select-date')[0]._flatpickr.setDate(currentDate);
App.Utils.UI.setDateTimePickerValue($('#select-date'), currentDate);
getAvailableHours(moment(currentDate).format('YYYY-MM-DD'));
break;
}
@ -328,7 +328,7 @@ App.Http.Booking = (function () {
!unavailableDates.includes(dateQueryParam) &&
dateQueryParamMoment.format('YYYY-MM') === selectedDateMoment.format('YYYY-MM')
) {
$('#select-date')[0]._flatpickr.setDate(dateQueryParamMoment.toDate());
App.Utils.UI.setDateTimePickerValue($('#select-date'), dateQueryParamMoment.toDate());
}
}

View File

@ -123,9 +123,9 @@ App.Pages.BlockedPeriods = (function () {
* Event: Blocked period Save Button "Click"
*/
$blockedPeriods.on('click', '#save-blocked-period', () => {
const startDateTimeObject = App.Utils.UI.getDatetimepickerValue($startDateTime);
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDateTime);
const startDateTimeMoment = moment(startDateTimeObject);
const endDateTimeObject = App.Utils.UI.getDatetimepickerValue($endDateTime);
const endDateTimeObject = App.Utils.UI.getDateTimePickerValue($endDateTime);
const endDateTimeMoment = moment(endDateTimeObject);
const blockedPeriod = {
@ -235,8 +235,8 @@ App.Pages.BlockedPeriods = (function () {
function display(blockedPeriod) {
$id.val(blockedPeriod.id);
$name.val(blockedPeriod.name);
App.Utils.UI.setDatetimepickerValue($startDateTime, new Date(blockedPeriod.start_datetime));
App.Utils.UI.setDatetimepickerValue($endDateTime, new Date(blockedPeriod.end_datetime));
App.Utils.UI.setDateTimePickerValue($startDateTime, new Date(blockedPeriod.start_datetime));
App.Utils.UI.setDateTimePickerValue($endDateTime, new Date(blockedPeriod.end_datetime));
$notes.val(blockedPeriod.notes);
}
@ -263,8 +263,8 @@ App.Pages.BlockedPeriods = (function () {
throw new Error(lang('fields_are_required'));
}
const startDateTimeObject = App.Utils.UI.getDatetimepickerValue($startDateTime);
const endDateTimeObject = App.Utils.UI.getDatetimepickerValue($endDateTime);
const startDateTimeObject = App.Utils.UI.getDateTimePickerValue($startDateTime);
const endDateTimeObject = App.Utils.UI.getDateTimePickerValue($endDateTime);
if (startDateTimeObject >= endDateTimeObject) {
$startDateTime.addClass('is-invalid');
@ -346,8 +346,8 @@ App.Pages.BlockedPeriods = (function () {
resetForm();
filter('');
addEventListeners();
App.Utils.UI.initializeDatetimepicker($startDateTime);
App.Utils.UI.initializeDatetimepicker($endDateTime);
App.Utils.UI.initializeDateTimePicker($startDateTime);
App.Utils.UI.initializeDateTimePicker($endDateTime);
}
document.addEventListener('DOMContentLoaded', initialize);

View File

@ -82,7 +82,7 @@ App.Pages.Booking = (function () {
// Initialize page's components (tooltips, date pickers etc).
tippy('[data-tippy-content]');
App.Utils.UI.initializeDatepicker($selectDate, {
App.Utils.UI.initializeDatePicker($selectDate, {
inline: true,
minDate: moment().subtract(1, 'day').set({hours: 23, minutes: 59, seconds: 59}).toDate(),
maxDate: moment().add(vars('future_booking_limit'), 'days').toDate(),
@ -126,7 +126,7 @@ App.Pages.Booking = (function () {
},
});
$selectDate[0]._flatpickr.setDate(new Date());
App.Utils.UI.setDateTimePickerValue($selectDate, new Date());
const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const isTimezoneSupported = $selectTimezone.find(`option[value="${browserTimezone}"]`).length > 0;
@ -269,7 +269,7 @@ App.Pages.Booking = (function () {
* Event: Timezone "Changed"
*/
$selectTimezone.on('change', () => {
const date = $selectDate[0]._flatpickr.selectedDates[0];
const date = App.Utils.UI.getDateTimePickerValue($selectDate);
if (!date) {
return;
@ -291,7 +291,7 @@ App.Pages.Booking = (function () {
App.Http.Booking.getUnavailableDates(
$target.val(),
$selectService.val(),
moment($selectDate[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD'),
moment(App.Utils.UI.getDateTimePickerValue($selectDate)).format('YYYY-MM-DD'),
);
updateConfirmFrame();
});
@ -327,7 +327,7 @@ App.Pages.Booking = (function () {
App.Http.Booking.getUnavailableDates(
$selectProvider.val(),
$target.val(),
moment($selectDate[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD'),
moment(App.Utils.UI.getDateTimePickerValue($selectDate)).format('YYYY-MM-DD'),
);
updateConfirmFrame();
@ -586,141 +586,120 @@ App.Pages.Booking = (function () {
* customer settings and input for the appointment booking.
*/
function updateConfirmFrame() {
if ($availableHours.find('.selected-hour').text() === '') {
return;
const serviceOptionText = $selectService.find('option:selected').text();
$('.display-selected-service').text(serviceOptionText).removeClass('invisible');
const providerOptionText = $selectProvider.find('option:selected').text();
$('.display-selected-provider').text(providerOptionText).removeClass('invisible');
if (!$availableHours.find('.selected-hour').text()) {
return; // No time is selected, skip the rest of this function...
}
// Appointment Details
let selectedDate = $selectDate[0]._flatpickr.selectedDates[0];
if (selectedDate !== null) {
selectedDate = App.Utils.Date.format(selectedDate, vars('date_format'), vars('time_format'));
}
// Render the appointment details
const serviceId = $selectService.val();
let servicePrice = '';
let serviceCurrency = '';
vars('available_services').forEach((service) => {
if (Number(service.id) === Number(serviceId) && Number(service.price) > 0) {
servicePrice = service.price;
serviceCurrency = service.currency;
return false; // Break loop
}
});
const service = vars('available_services').find(
(availableService) => Number(availableService.id) === Number(serviceId),
);
$(document)
.find('.display-selected-service')
.text($selectService.find('option:selected').text())
.removeClass('invisible');
if (!service) {
return; // Service was not found
}
$(document)
.find('.display-selected-provider')
.text($selectProvider.find('option:selected').text())
.removeClass('invisible');
const selectedDateObject = App.Utils.UI.getDateTimePickerValue($selectDate);
const selectedDateMoment = moment(selectedDateObject);
const selectedDate = selectedDateMoment.format('YYYY-MM-DD');
const selectedTime = $availableHours.find('.selected-hour').text();
const selectedDateTime = `${selectedDate} ${selectedTime}`;
$('#appointment-details').empty();
let formattedSelectedDate;
$('<div/>', {
'html': [
$('<h4/>', {
'text': lang('appointment'),
}),
$('<p/>', {
'html': [
$('<span/>', {
'text': lang('service') + ': ' + $selectService.find('option:selected').text(),
}),
$('<br/>'),
$('<span/>', {
'text': lang('provider') + ': ' + $selectProvider.find('option:selected').text(),
}),
$('<br/>'),
$('<span/>', {
'text':
lang('start') +
': ' +
selectedDate +
' ' +
$availableHours.find('.selected-hour').text(),
}),
$('<br/>'),
$('<span/>', {
'text': lang('timezone') + ': ' + $selectTimezone.find('option:selected').text(),
}),
$('<br/>'),
$('<span/>', {
'text': lang('price') + ': ' + servicePrice + ' ' + serviceCurrency,
'prop': {
'hidden': !servicePrice,
},
}),
],
}),
],
}).appendTo('#appointment-details');
if (selectedDateObject) {
formattedSelectedDate = App.Utils.Date.format(
selectedDateTime,
vars('date_format'),
vars('time_format'),
true,
);
}
const timezoneOptionText = $selectTimezone.find('option:selected').text();
$('#appointment-details').html(`
<div>
<div class="mb-2 fw-bold fs-3">
${serviceOptionText}
</div>
<div class="mb-2 fw-bold text-muted">
${providerOptionText}
</div>
<div class="mb-2">
<i class="fas fa-clock me-2"></i>
${service.duration} ${lang('minutes')}
</div>
<div class="mb-2">
<i class="fas fa-calendar-day me-2"></i>
${formattedSelectedDate}
</div>
<div class="mb-2">
<i class="fas fa-globe me-2"></i>
${timezoneOptionText}
</div>
<div class="mb-2" ${!Number(service.price) ? 'hidden' : ''}>
<i class="fas fa-cash-register me-2"></i>
${Number(service.price).toFixed(2)} ${service.currency}
</div>
</div>
`);
// Render the customer information
// Customer Details
const firstName = App.Utils.String.escapeHtml($firstName.val());
const lastName = App.Utils.String.escapeHtml($lastName.val());
const fullName = firstName + ' ' + lastName;
const phoneNumber = App.Utils.String.escapeHtml($phoneNumber.val());
const fullName = `${firstName} ${lastName}`.trim();
const email = App.Utils.String.escapeHtml($email.val());
const phoneNumber = App.Utils.String.escapeHtml($phoneNumber.val());
const address = App.Utils.String.escapeHtml($address.val());
const city = App.Utils.String.escapeHtml($city.val());
const zipCode = App.Utils.String.escapeHtml($zipCode.val());
$('#customer-details').empty();
const addressParts = [];
$('<div/>', {
'html': [
$('<h4/>)', {
'text': lang('customer'),
}),
$('<p/>', {
'html': [
fullName
? $('<span/>', {
'text': lang('customer') + ': ' + fullName,
})
: null,
fullName ? $('<br/>') : null,
phoneNumber
? $('<span/>', {
'text': lang('phone_number') + ': ' + phoneNumber,
})
: null,
phoneNumber ? $('<br/>') : null,
email
? $('<span/>', {
'text': lang('email') + ': ' + email,
})
: null,
email ? $('<br/>') : null,
address
? $('<span/>', {
'text': lang('address') + ': ' + address,
})
: null,
address ? $('<br/>') : null,
city
? $('<span/>', {
'text': lang('city') + ': ' + city,
})
: null,
city ? $('<br/>') : null,
zipCode
? $('<span/>', {
'text': lang('zip_code') + ': ' + zipCode,
})
: null,
zipCode ? $('<br/>') : null,
],
}),
],
}).appendTo('#customer-details');
if (city) {
addressParts.push(city);
}
if (zipCode) {
addressParts.push(zipCode);
}
$('#customer-details').html(`
<div>
<div class="mb-2 fw-bold fs-3">
${lang('contact_info')}
</div>
<div class="mb-2 fw-bold text-muted" ${!fullName ? 'hidden' : ''}>
${fullName}
</div>
<div class="mb-2" ${!email ? 'hidden' : ''}>
${email}
</div>
<div class="mb-2" ${!email ? 'hidden' : ''}>
${phoneNumber}
</div>
<div class="mb-2" ${!address ? 'hidden' : ''}>
${address}
</div>
<div class="mb-2" ${!addressParts.length ? 'hidden' : ''}>
${addressParts.join(', ')}
</div>
</div>
`);
// Update appointment form data for submission to server when the user confirms the appointment.
const data = {};
data.customer = {
@ -736,7 +715,7 @@ App.Pages.Booking = (function () {
data.appointment = {
start_datetime:
moment($selectDate[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD') +
moment(App.Utils.UI.getDateTimePickerValue($selectDate)).format('YYYY-MM-DD') +
' ' +
moment($('.selected-hour').data('value'), 'HH:mm').format('HH:mm') +
':00',
@ -753,6 +732,7 @@ App.Pages.Booking = (function () {
data.appointment.id = vars('appointment_data').id;
data.customer.id = vars('customer_data').id;
}
$('input[name="post_data"]').val(JSON.stringify(data));
}
@ -772,7 +752,7 @@ App.Pages.Booking = (function () {
);
// Add the duration to the start datetime.
const selectedDate = moment($selectDate[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD');
const selectedDate = moment(App.Utils.UI.getDateTimePickerValue($selectDate)).format('YYYY-MM-DD');
const selectedHour = $('.selected-hour').data('value'); // HH:mm
@ -807,7 +787,7 @@ App.Pages.Booking = (function () {
// Set Appointment Date
const startMoment = moment(appointment.start_datetime);
$selectDate[0]._flatpickr.setDate(startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($selectDate, startMoment.toDate());
App.Http.Booking.getAvailableHours(startMoment.format('YYYY-MM-DD'));
// Apply Customer's Data
@ -833,6 +813,8 @@ App.Pages.Booking = (function () {
}
/**
* Update the service description and information.
*
* This method updates the HTML content with a brief description of the
* user selected service (only if available in db). This is useful for the
* customers upon selecting the correct service.
@ -849,41 +831,45 @@ App.Pages.Booking = (function () {
);
if (!service) {
return;
return; // Service not found
}
$('<strong/>', {
'text': App.Utils.String.escapeHtml(service.name),
}).appendTo($serviceDescription);
// Render the additional service information
if (service.description) {
$('<br/>').appendTo($serviceDescription);
$('<span/>', {
'html': App.Utils.String.escapeHtml(service.description).replaceAll('\n', '<br/>'),
}).appendTo($serviceDescription);
}
if (service.duration || Number(service.price) > 0 || service.location) {
$('<br/>').appendTo($serviceDescription);
}
const additionalInfoParts = [];
if (service.duration) {
$('<span/>', {
'text': '[' + lang('duration') + ' ' + service.duration + ' ' + lang('minutes') + ']',
}).appendTo($serviceDescription);
additionalInfoParts.push(`${lang('duration')}: ${service.duration} ${lang('minutes')}`);
}
if (Number(service.price) > 0) {
$('<span/>', {
'text': '[' + lang('price') + ' ' + service.price + ' ' + service.currency + ']',
}).appendTo($serviceDescription);
additionalInfoParts.push(`${lang('price')}: ${service.price} ${service.currency}`);
}
if (service.location) {
$('<span/>', {
'text': '[' + lang('location') + ' ' + service.location + ']',
}).appendTo($serviceDescription);
additionalInfoParts.push(`${lang('location')}: ${service.location}`);
}
if (additionalInfoParts.length) {
$(`
<div class="mb-2 fst-italic">
${additionalInfoParts.join(', ')}
</div>
`).appendTo($serviceDescription);
}
// Render the service description
if (service.description.length) {
const escapedDescription = App.Utils.String.escapeHtml(service.description);
const multiLineDescription = escapedDescription.replaceAll('\n', '<br/>');
$(`
<div class="text-muted">
${multiLineDescription}
</div>
`).appendTo($serviceDescription);
}
}

View File

@ -138,10 +138,10 @@ App.Utils.CalendarDefaultView = (function () {
// Set the start and end datetime of the appointment.
startMoment = moment(appointment.start_datetime);
$appointmentsModal.find('#start-datetime')[0]._flatpickr.setDate(startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($appointmentsModal.find('#start-datetime'), startMoment.toDate());
endMoment = moment(appointment.end_datetime);
$appointmentsModal.find('#end-datetime')[0]._flatpickr.setDate(endMoment.toDate());
App.Utils.UI.setDateTimePickerValue($appointmentsModal.find('#end-datetime'), endMoment.toDate());
const customer = appointment.customer;
$appointmentsModal.find('#customer-id').val(appointment.id_users_customer);
@ -183,10 +183,16 @@ App.Utils.CalendarDefaultView = (function () {
// Apply unavailability data to dialog.
$unavailabilitiesModal.find('.modal-header h3').text(lang('edit_unavailability_title'));
$unavailabilitiesModal.find('#unavailability-start')[0]._flatpickr.setDate(startMoment.toDate());
App.Utils.UI.setDateTimePickerValue(
$unavailabilitiesModal.find('#unavailability-start'),
startMoment.toDate(),
);
App.Utils.UI.setDateTimePickerValue(
$unavailabilitiesModal.find('#unavailability-end'),
endMoment.toDate(),
);
$unavailabilitiesModal.find('#unavailability-id').val(unavailability.id);
$unavailabilitiesModal.find('#unavailability-provider').val(unavailability.id_users_provider);
$unavailabilitiesModal.find('#unavailability-end')[0]._flatpickr.setDate(endMoment.toDate());
$unavailabilitiesModal.find('#unavailability-notes').val(unavailability.notes);
$unavailabilitiesModal.modal('show');
}
@ -1057,9 +1063,9 @@ App.Utils.CalendarDefaultView = (function () {
$('#unavailability-provider').trigger('change');
$('#unavailability-start')[0]._flatpickr.setDate(info.start);
App.Utils.UI.setDateTimePickerValue($('#unavailability-start'), info.start);
$('#unavailability-end')[0]._flatpickr.setDate(info.end);
App.Utils.UI.setDateTimePickerValue($('#unavailability-end'), info.end);
messageModal.dispose();
},
@ -1113,8 +1119,11 @@ App.Utils.CalendarDefaultView = (function () {
}
// Preselect time
$('#start-datetime')[0]._flatpickr.setDate(info.start);
$('#end-datetime')[0]._flatpickr.setDate(App.Pages.Calendar.getSelectionEndDate(info));
App.Utils.UI.setDateTimePickerValue($('#start-datetime'), info.start);
App.Utils.UI.setDateTimePickerValue(
$('#end-datetime'),
App.Pages.Calendar.getSelectionEndDate(info),
);
messageModal.dispose();
},
@ -1586,10 +1595,13 @@ App.Utils.CalendarDefaultView = (function () {
// Set the start and end datetime of the appointment.
const startDatetimeMoment = moment(appointment.start_datetime);
$appointmentsModal.find('#start-datetime')[0]._flatpickr.setDate(startDatetimeMoment.toDate());
App.Utils.UI.setDateTimePickerValue(
$appointmentsModal.find('#start-datetime'),
startDatetimeMoment.toDate(),
);
const endDatetimeMoment = moment(appointment.end_datetime);
$appointmentsModal.find('#end-datetime')[0]._flatpickr.setDate(endDatetimeMoment.toDate());
App.Utils.UI.setDateTimePickerValue($appointmentsModal.find('#end-datetime'), endDatetimeMoment.toDate());
const customer = appointment.customer;
$appointmentsModal.find('#customer-id').val(appointment.id_users_customer);

View File

@ -43,25 +43,25 @@ App.Utils.CalendarTableView = (function () {
function addEventListeners() {
$calendar.on('click', '.calendar-header .btn.previous', () => {
const dayInterval = $selectFilterItem.val();
const currentDate = $selectDate[0]._flatpickr.selectedDates[0];
const currentDate = App.Utils.UI.getDateTimePickerValue($selectDate);
const startDate = moment(currentDate).subtract(1, 'days');
const endDate = startDate.clone().add(dayInterval - 1, 'days');
$selectDate[0]._flatpickr.setDate(startDate.toDate());
App.Utils.UI.setDateTimePickerValue($selectDate, startDate.toDate());
createView(startDate.toDate(), endDate.toDate());
});
$calendar.on('click', '.calendar-header .btn.next', () => {
const dayInterval = $selectFilterItem.val();
const currentDate = $selectDate[0]._flatpickr.selectedDates[0];
const currentDate = App.Utils.UI.getDateTimePickerValue($selectDate);
const startDate = moment(currentDate).add(1, 'days');
const endDate = startDate.clone().add(dayInterval - 1, 'days');
$selectDate[0]._flatpickr.setDate(startDate.toDate());
App.Utils.UI.setDateTimePickerValue($selectDate, startDate.toDate());
createView(startDate.toDate(), endDate.toDate());
});
$calendarToolbar.on('change', '#select-filter-item', () => {
const dayInterval = $selectFilterItem.val();
const currentDate = $selectDate[0]._flatpickr.selectedDates[0];
const currentDate = App.Utils.UI.getDateTimePickerValue($selectDate);
const startDate = moment(currentDate);
const endDate = startDate.clone().add(dayInterval - 1, 'days');
createView(startDate.toDate(), endDate.toDate());
@ -70,7 +70,7 @@ App.Utils.CalendarTableView = (function () {
$calendarToolbar.on('click', '#reload-appointments', () => {
// Fetch the events and place them in the existing HTML format.
const dayInterval = $selectFilterItem.val();
const currentDate = $selectDate[0]._flatpickr.selectedDates[0];
const currentDate = App.Utils.UI.getDateTimePickerValue($selectDate);
const startDateMoment = moment(currentDate);
const startDate = startDateMoment.toDate();
const endDateMoment = startDateMoment.clone().add(dayInterval - 1, 'days');
@ -212,10 +212,10 @@ App.Utils.CalendarTableView = (function () {
// Set the start and end datetime of the appointment.
startMoment = moment(appointment.start_datetime);
$appointmentsModal.find('#start-datetime')[0]._flatpickr.setDate(startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($appointmentsModal.find('#start-datetime'), startMoment.toDate());
endMoment = moment(appointment.end_datetime);
$appointmentsModal.find('#end-datetime')[0]._flatpickr.setDate(endMoment.toDate());
App.Utils.UI.setDateTimePickerValue($appointmentsModal.find('#end-datetime'), endMoment.toDate());
const customer = appointment.customer;
$appointmentsModal.find('#customer-id').val(appointment.id_users_customer);
@ -257,10 +257,10 @@ App.Utils.CalendarTableView = (function () {
// Apply unavailability data to dialog.
$unavailabilitiesModal.find('.modal-header h3').text(lang('edit_unavailability_title'));
$unavailabilitiesModal.find('#unavailability-start')[0]._flatpickr.setDate(startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($('#unavailability-start'), startMoment.toDate());
App.Utils.UI.setDateTimePickerValue($('#unavailability-end'), endMoment.toDate());
$unavailabilitiesModal.find('#unavailability-id').val(unavailability.id);
$unavailabilitiesModal.find('#unavailability-provider').val(unavailability.id_users_provider);
$unavailabilitiesModal.find('#unavailability-end')[0]._flatpickr.setDate(endMoment.toDate());
$unavailabilitiesModal.find('#unavailability-notes').val(unavailability.notes);
$unavailabilitiesModal.modal('show');
@ -389,7 +389,7 @@ App.Utils.CalendarTableView = (function () {
],
}).appendTo($calendarHeader);
App.Utils.UI.initializeDatepicker($calendarHeader.find('.select-date'), {
App.Utils.UI.initializeDatePicker($calendarHeader.find('.select-date'), {
onChange(selectedDates) {
const startDate = selectedDates[0];
const endDate = moment(startDate)
@ -1742,9 +1742,8 @@ App.Utils.CalendarTableView = (function () {
$('#unavailability-provider').trigger('change');
$('#unavailability-start')[0]._flatpickr.setDate(info.start);
$('#unavailability-end')[0]._flatpickr.setDate(info.end);
App.Utils.UI.setDateTimePickerValue($('#unavailability-start'), info.start);
App.Utils.UI.setDateTimePickerValue($('#unavailability-end'), info.end);
messageModal.dispose();
},
@ -1783,8 +1782,11 @@ App.Utils.CalendarTableView = (function () {
$selectProvider.trigger('change');
// Preselect time
$('#start-datetime')[0]._flatpickr.setDate(info.start);
$('#end-datetime')[0]._flatpickr.setDate(App.Pages.Calendar.getSelectionEndDate(info));
App.Utils.UI.setDateTimePickerValue($('#start-datetime'), info.start);
App.Utils.UI.setDateTimePickerValue(
$('#end-datetime'),
App.Pages.Calendar.getSelectionEndDate(info),
);
messageModal.dispose();
},

View File

@ -148,7 +148,7 @@ window.App.Utils.UI = (function () {
* @param {jQuery} $target
* @param {Object} [params]
*/
function initializeDatetimepicker($target, params = {}) {
function initializeDateTimePicker($target, params = {}) {
$target.flatpickr({
enableTime: true,
allowInput: true,
@ -168,7 +168,7 @@ window.App.Utils.UI = (function () {
* @param {jQuery} $target
* @param {Object} [params]
*/
function initializeDatepicker($target, params = {}) {
function initializeDatePicker($target, params = {}) {
$target.flatpickr({
allowInput: true,
dateFormat: getDateFormat(),
@ -186,7 +186,7 @@ window.App.Utils.UI = (function () {
* @param {jQuery} $target
* @param {Object} [params]
*/
function initializeTimepicker($target, params = {}) {
function initializeTimePicker($target, params = {}) {
$target.flatpickr({
noCalendar: true,
enableTime: true,
@ -230,7 +230,7 @@ window.App.Utils.UI = (function () {
*
* @return {Date}
*/
function getDatetimepickerValue($target) {
function getDateTimePickerValue($target) {
if (!$target?.length) {
throw new Error('Empty $target argument provided.');
}
@ -244,7 +244,7 @@ window.App.Utils.UI = (function () {
* @param {jQuery} $target
* @param {Date} value
*/
function setDatetimepickerValue($target, value) {
function setDateTimePickerValue($target, value) {
if (!$target?.length) {
throw new Error('Empty $target argument provided.');
}
@ -253,12 +253,12 @@ window.App.Utils.UI = (function () {
}
return {
initializeDatetimepicker,
initializeDatepicker,
initializeTimepicker,
initializeDateTimePicker,
initializeDatePicker,
initializeTimePicker,
initializeDropdown,
initializeTextEditor,
getDatetimepickerValue,
setDatetimepickerValue,
getDateTimePickerValue,
setDateTimePickerValue,
};
})();

View File

@ -15,6 +15,8 @@
* This module implements the functionality of working plans.
*/
App.Utils.WorkingPlan = (function () {
const moment = window.moment;
/**
* Class WorkingPlan
*
@ -480,7 +482,7 @@ App.Utils.WorkingPlan = (function () {
$tr.children().trigger('edit');
App.Utils.UI.initializeTimepicker($tr.find('.break-start input, .break-end input'));
App.Utils.UI.initializeTimePicker($tr.find('.break-start input, .break-end input'));
$tr.find('.break-day select').focus();
@ -686,16 +688,16 @@ App.Utils.WorkingPlan = (function () {
disabled = disabled || false;
if (disabled === false) {
App.Utils.UI.initializeTimepicker($('.working-plan input:text'), {
App.Utils.UI.initializeTimePicker($('.working-plan input:text'), {
onChange: (selectedDates, dateStr, instance) => {
const startMoment = moment(selectedDates[0]);
const $workEnd = $(instance.input).closest('tr').find('.work-end');
const endMoment = moment($workEnd[0]._flatpickr.selectedDates[0]);
const endMoment = moment(App.Utils.UI.getDateTimePickerValue($workEnd));
if (startMoment > endMoment) {
$workEnd[0]._flatpickr.setDate(startMoment.add(1, 'hour').toDate());
App.Utils.UI.setDateTimePickerValue($workEnd, startMoment.add(1, 'hour').toDate());
}
},
});

View File

@ -1,7 +1,7 @@
{
"name": "maket/maketrandevu",
"description": "MAKET Randevu Portalı",
"version": "1.5.0-RC1",
"version": "1.5.0-RC2",
"homepage": "https://iflpanel.com/about/maketrandevu",
"type": "project",
"license": "GPL-3.0",

View File

@ -46,7 +46,7 @@ services:
swagger-ui:
platform: linux/amd64
image: swaggerapi/swagger-ui
image: swaggerapi/swagger-ui:v5.10.5
ports:
- "8000:8080"
volumes:

View File

@ -5,7 +5,7 @@
# Approximately 10min (tested with 4vcpu / 8GB RAM / 30Mbps network speed)
# MAKETRANDEVU_VER="test"
MAKETRANDEVU_VER="1.5.0-RC1" # UPDATE MANUALLY !
MAKETRANDEVU_VER="1.5.0-RC2" # UPDATE MANUALLY !
_RED='\033[0;31m'
_NC='\033[0m \e[0m' # No Color, No Effect

View File

@ -25,7 +25,7 @@ const zip = require('zip-dir');
// const debug = require('gulp-debug');
function archive(done) {
const version = "1.5.0-RC1"
const version = "1.5.0-RC2"
const filename = 'maketrandevu-' + version + '.zip';
fs.removeSync('build');

View File

@ -8,7 +8,7 @@ SCRIPT_NAME="nginx_docker_localtest.sh" # name of the *this* file
DEBUG="FALSE"
### REMOTE RELEASE ###
LATEST_RELEASE="1.5.0-RC1"
LATEST_RELEASE="1.5.0-RC2"
FILE_NAME="maketrandevu-$LATEST_RELEASE.zip"
DOWNLOAD_LINK=https://git.aliberksandikci.com.tr/maket/maketrandevu/releases/download/$LATEST_RELEASE/$FILE_NAME

View File

@ -54,7 +54,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/Availabilities'
type: array
items:
type: string
'401':
description: Unauthorized
'500':
@ -131,7 +133,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentCollection'
type: array
items:
$ref: '#/components/schemas/AppointmentRecord'
'401':
description: Unauthorized
'500':
@ -302,7 +306,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/UnavailabilityCollection'
type: array
items:
$ref: '#/components/schemas/UnavailabilityRecord'
'401':
description: Unauthorized
'500':
@ -311,6 +317,10 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
x-codegen-request-body-name: body
security:
- BearerToken: [ ]
- BasicAuth: [ ]
post:
tags:
- unavailabilities
@ -470,7 +480,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerCollection'
type: array
items:
$ref: '#/components/schemas/CustomerRecord'
'401':
description: Unauthorized
'500':
@ -641,7 +653,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/ServiceCollection'
type: array
items:
$ref: '#/components/schemas/ServiceRecord'
'401':
description: Unauthorized
'500':
@ -812,7 +826,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/ServiceCategoryCollection'
type: array
items:
$ref: '#/components/schemas/ServiceCategoryRecord'
'401':
description: Unauthorized
'500':
@ -983,7 +999,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/AdminCollection'
type: array
items:
$ref: '#/components/schemas/AdminRecord'
'401':
description: Unauthorized
'500':
@ -1154,7 +1172,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/ProviderCollection'
type: array
items:
$ref: '#/components/schemas/ProviderRecord'
'401':
description: Unauthorized
'500':
@ -1325,7 +1345,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/SecretaryCollection'
type: array
items:
$ref: '#/components/schemas/SecretaryRecord'
'401':
description: Unauthorized
'500':
@ -1490,7 +1512,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/SettingCollection'
type: array
items:
$ref: '#/components/schemas/ServiceRecord'
'401':
description: Unauthorized
'500':
@ -1606,7 +1630,9 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookCollection'
type: array
items:
$ref: '#/components/schemas/WebhookRecord'
'401':
description: Unauthorized
'500':
@ -1821,10 +1847,6 @@ components:
customerId: 5
providerId: 2
serviceId: 6
AppointmentCollection:
type: array
items:
$ref: '#/components/schemas/AppointmentRecord'
UnavailabilityRecord:
type: object
properties:
@ -1875,10 +1897,6 @@ components:
location: Test Street 1A, 12345 Some State, Some Place
notes: This is a test appointment.
providerId: 2
UnavailabilityCollection:
type: array
items:
$ref: '#/components/schemas/UnavailabilityRecord'
CustomerRecord:
type: object
properties:
@ -1978,10 +1996,6 @@ components:
customField4: Value4
customField5: Value5
notes: This is a test customer.
CustomerCollection:
type: array
items:
$ref: '#/components/schemas/CustomerRecord'
ServiceRecord:
type: object
properties:
@ -2048,10 +2062,6 @@ components:
availabilitiesType: flexible
attendantsNumber: 1
serviceCategoryId: null
ServiceCollection:
type: array
items:
$ref: '#/components/schemas/ServiceRecord'
ServiceCategoryRecord:
type: object
properties:
@ -2075,10 +2085,6 @@ components:
example:
name: Test Category
description: This is a test category.
ServiceCategoryCollection:
type: array
items:
$ref: '#/components/schemas/ServiceCategoryRecord'
AdminRecord:
type: object
properties:
@ -2187,10 +2193,6 @@ components:
password: Password@123
notifications: true
calendarView: default
AdminCollection:
type: array
items:
$ref: '#/components/schemas/AdminRecord'
ProviderRecord:
type: object
properties:
@ -2391,10 +2393,6 @@ components:
end: '17:00'
breaks: [ ]
saturday: null
ProviderCollection:
type: array
items:
$ref: '#/components/schemas/ProviderRecord'
SecretaryRecord:
type: object
properties:
@ -2516,10 +2514,6 @@ components:
password: Password@123
notifications: true
calendarView: default
SecretaryCollection:
type: array
items:
$ref: '#/components/schemas/SecretaryRecord'
SettingRecord:
type: object
properties:
@ -2537,10 +2531,6 @@ components:
type: string
example:
value: ACME Inc
SettingCollection:
type: array
items:
$ref: '#/components/schemas/SettingRecord'
WebhookRecord:
type: object
properties:
@ -2588,10 +2578,6 @@ components:
secretToken: SecureSecretTokenHere
isSslVerified: true
notes: This is a webhook.
WebhookCollection:
type: array
items:
$ref: '#/components/schemas/WebhookRecord'
ErrorResponse:
type: object
properties: