Compare commits

...

9 Commits

Author SHA1 Message Date
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
20 changed files with 752 additions and 261 deletions

View File

@ -0,0 +1,456 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');
// Arabic
$lang['page_title'] = 'احجز موعد مع';
$lang['service_and_provider'] = 'اختر الخدمة والمزود';
$lang['select_service'] = 'اختر الخدمة';
$lang['select_provider'] = 'اختر المزود';
$lang['duration'] = 'المدة';
$lang['minutes'] = 'دقائق';
$lang['price'] = 'السعر';
$lang['back'] = 'الخلف';
$lang['appointment_date_and_time'] = 'اختر وقت وتاريخ الموعد';
$lang['no_available_hours'] = 'لا يوجد مواعيد متاحة في الوقت الذي تم إختياره الرجاء اختيار وقت آخر';
$lang['appointment_hour_missing'] = 'الرجاء اختيار ساعة الموعد قبل الإكمال';
$lang['customer_information'] = 'أدخل بياناتك';
$lang['first_name'] = 'الاسم الأول';
$lang['last_name'] = 'العائلة';
$lang['email'] = 'البريد الإلكتروني';
$lang['phone_number'] = 'رقم الجوال';
$lang['phone'] = 'Phone';
$lang['address'] = 'العنوان';
$lang['city'] = 'المدينة';
$lang['zip_code'] = 'الرمز البريدي';
$lang['notes'] = 'ملاحظات';
$lang['language'] = 'Language';
$lang['no_language'] = 'No language';
$lang['fields_are_required'] = 'الحقول ب* مطلوب تعبئتها';
$lang['appointment_confirmation'] = 'تأكيد الموعد';
$lang['confirm'] = 'تأكيد';
$lang['update'] = 'تحديث';
$lang['cancel_appointment_hint'] = ' .إضغط زر "إلغاء" لحذف الموعد من الجدول';
$lang['cancel'] = 'إلغاء';
$lang['appointment_registered'] = '!تم تسجيل الموعد بنجاح';
$lang['cancel_appointment_title'] = 'إلغاء الموعد';
$lang['appointment_cancelled'] = '!تم إلغاء الموعد بنجاح';
$lang['appointment_cancelled_title'] = 'تم إلغاء الموعد';
$lang['reason'] = 'السبب';
$lang['appointment_removed_from_schedule'] = 'المواعيد التالية تم حذفها من الجدول';
$lang['appointment_details_was_sent_to_you'] = 'تم إرسال تفاصيل الموعد الى البريد الالكتروني الخاص بك';
$lang['add_to_google_calendar'] = 'اضافة تقويم جوجل';
$lang['appointment_booked'] = '!تم حجز الموعد بنجاح';
$lang['thank_you_for_appointment'] = 'شكرا لحجزك معنا موعد . تستطيع رؤية تفاصيل الموعد والحجز أدناه . يمكنك التعديل عليه بالضغط على الرابط.';
$lang['appointment_details_title'] = 'تفاصيل الموعد';
$lang['customer_details_title'] = 'تفاصيل الزبون';
$lang['service'] = 'الخدمة';
$lang['provider'] = 'المزود';
$lang['customer'] = 'الزبون';
$lang['start'] = 'البداية';
$lang['end'] = 'النهاية';
$lang['name'] = 'الإسم';
$lang['appointment_link_title'] = 'رابط الموعد';
$lang['success'] = ' !تم بنجاح';
$lang['appointment_added_to_google_calendar'] = 'تم اضافة الموعد الى تقويم جوجل الخاص بحسابك';
$lang['view_appointment_in_google_calendar'] = ' اضغط هنا لمشاهدة الموعد على تقويم جوجل الخاص بحسابك ';
$lang['appointment_added_to_your_plan'] = 'تم اضافة موعد الى خطتك';
$lang['appointment_link_description'] = 'تستطيع عمل اي تعديلات بالضغط على رابط الموعد أدناه';
$lang['appointment_locked'] = 'Modification impossible.';
$lang['appointment_locked_message'] = 'The appointment cannot be changed less than {$limit} hours in advance.';
$lang['appointment_not_found'] = 'لم يتم العثور على الموعد.';
$lang['appointment_does_not_exist_in_db'] = 'الموعد الذي قمت بطلبه لم يعد موجودا في بيانات البرنامج';
$lang['display_calendar'] = 'اظهار التقويم';
$lang['calendar'] = 'التقويم';
$lang['users'] = 'المستخدمون';
$lang['settings'] = 'الاعدادات';
$lang['log_out'] = 'تسجيل الخروج';
$lang['synchronize'] = 'المزامنة';
$lang['enable_sync'] = 'تمكين المزامنة';
$lang['disable_sync'] = 'تعطيل المزامنة';
$lang['disable_sync_prompt'] = 'Are you sure that you want to disable the calendar synchronization?';
$lang['reload'] = 'اعادة التحميل';
$lang['appointment'] = 'الموعد';
$lang['unavailability'] = 'غير متوفر';
$lang['week'] = 'الأسبوع';
$lang['month'] = 'الشهر';
$lang['today'] = 'اليوم';
$lang['not_working'] = 'لا يعمل';
$lang['break'] = 'استراحة';
$lang['add'] = 'اضافة';
$lang['edit'] = 'تعديل';
$lang['hello'] = 'مرحبا';
$lang['all_day'] = 'طوال اليوم';
$lang['manage_appointment_record_hint'] = 'إدارة جميع سجلات المواعيد للمزودين والخدمات';
$lang['select_filter_item_hint'] = 'اختار مزود أو خدمة وانظر للمواعيد على التقويم ';
$lang['enable_appointment_sync_hint'] = 'تمكين المزامنة للمواعيد على تقويم جوجل الخاص بالمزود';
$lang['manage_customers_hint'] = 'ادارة الزبائن المسجلين واستعراض حجوزاتهم السابقة';
$lang['manage_services_hint'] = 'ادارة الخدمات والأقسام أو الفئات المتاحة في البرنامج';
$lang['manage_users_hint'] = 'ادارة المستخدمين (مدراء البرنامج, المزودين, السكرتيريين).';
$lang['settings_hint'] = 'ضبط البرنامج أو اعدادات المستخدمين';
$lang['log_out_hint'] = 'تسجيل الخروج من البرنامج';
$lang['unavailability_periods_hint'] = 'خلال الفترات الغير متوفرة لن يقبل المزود اي موعد';
$lang['new_appointment_hint'] = 'انشاء موعد جديد وتخزينه في قاعدة البيانات';
$lang['reload_appointments_hint'] = 'اعادة تحميل تقويم المواعيد';
$lang['trigger_google_sync_hint'] = 'تشغيل عملية مزامنة تقويم جوجل.';
$lang['appointment_updated'] = 'تم تحديث الموعد بنجاح.';
$lang['undo'] = 'تراجع';
$lang['appointment_details_changed'] = 'تم تعديل تفاصيل الموعد بنجاح';
$lang['appointment_changes_saved'] = 'تم حفظ التعديلات على الموعد بنجاح.';
$lang['save'] = 'تخزين';
$lang['new'] = 'جديد';
$lang['select'] = 'تحديد';
$lang['hide'] = 'اخفاء';
$lang['type_to_filter_customers'] = 'اكتب لتصفية الزبائن';
$lang['clear_fields_add_existing_customer_hint'] = 'تنظيف الحقول واضافة زبون جديد';
$lang['pick_existing_customer_hint'] = 'اختيار زبون موجود سابقا';
$lang['new_appointment_title'] = 'موعد جديد';
$lang['edit_appointment_title'] = 'تعديل موعد';
$lang['delete_appointment_title'] = 'حذف موعد';
$lang['write_appointment_removal_reason'] = ':الرجاء كتابة سبب حذف الموعد ';
$lang['appointment_saved'] = 'تم حفظ الموعد بنجاح';
$lang['new_unavailability_title'] = 'فترة غير متاحة جديدة';
$lang['edit_unavailability_title'] = 'تعديل فترة غير متاحة';
$lang['unavailability_saved'] = 'تم حفظ الفترة الغير متاحة بنجاح';
$lang['start_date_before_end_error'] = 'تاريخ البداية أكبر من تاريخ الانتهاء.';
$lang['invalid_duration'] = 'Invalid duration.';
$lang['invalid_email'] = 'بريد الكتروني غير صحيح';
$lang['customers'] = 'الزبائن';
$lang['details'] = 'التفاصيل';
$lang['no_records_found'] = 'لا يوجد أي تسجيل ..';
$lang['services'] = 'الخدمات';
$lang['duration_minutes'] = 'المدة (الدقائق)';
$lang['currency'] = 'العملة';
$lang['category'] = 'الفئة';
$lang['no_category'] = 'لا يوجد فئة';
$lang['description'] = 'الوصف';
$lang['categories'] = 'الفئات';
$lang['admins'] = 'المسؤولين';
$lang['providers'] = 'المزودون';
$lang['secretaries'] = 'السيكرتاريين';
$lang['mobile_number'] = 'رقم الهاتف';
$lang['mobile'] = 'Mobile';
$lang['state'] = 'الحالة';
$lang['username'] = 'اسم المستخدم';
$lang['password'] = 'كلمة المرور';
$lang['retype_password'] = 'كتابة كلمة المرور مرة أخرى';
$lang['receive_notifications'] = 'تلّقي الاشعارات';
$lang['passwords_mismatch'] = 'كلمتا السر غير متطابقتين';
$lang['admin_saved'] = 'تم حفظ المسؤول بنجاح';
$lang['provider_saved'] = 'تم حفظ المزود بنجاح';
$lang['secretary_saved'] = 'تم حفظ السكرتير بنجاح';
$lang['admin_deleted'] = 'تم حذف المسؤول بنجاح';
$lang['provider_deleted'] = 'تم حذف المزود بنجاح';
$lang['secretary_deleted'] = 'تم حذف السيكرتير بنجاح';
$lang['service_saved'] = 'تم حفظ الخدمة بنجاح';
$lang['service_category_saved'] = 'تم حفظ فئة الخدمة بنجاح';
$lang['service_deleted'] = 'تم حذف الخدمة بنجاح';
$lang['service_category_deleted'] = 'تم حذف فئة الخدمة بنجاح';
$lang['customer_saved'] = 'تم حفظ الزبون بنجاح';
$lang['customer_deleted'] = 'تم حذف الزبون بنجاح';
$lang['current_view'] = 'الرعض الحالي';
$lang['working_plan'] = 'خطة العمل';
$lang['reset_plan'] = 'اعادة تهيئة الخطة';
$lang['monday'] = 'الاثنين';
$lang['tuesday'] = 'الثلاثاء';
$lang['wednesday'] = 'الأربعاء';
$lang['thursday'] = 'الخميس';
$lang['friday'] = 'الجمعة';
$lang['saturday'] = 'السبت';
$lang['sunday'] = 'الأحد';
$lang['breaks'] = 'الاستراحات';
$lang['add_breaks_during_each_day'] = 'اضافة فترة الاستراحة في كل يوم . في فترة الاستراحة لن يستقبل المزود أي موعد';
$lang['day'] = 'اليوم';
$lang['days'] = 'الأيام';
$lang['actions'] = 'الحركات';
$lang['reset_working_plan_hint'] = 'اعادة تهئية خطة العمل لتعود الى الاعدادات الافتراضية';
$lang['company_name'] = 'اسم الشركة';
$lang['company_name_hint'] = 'اسم الشركة سيظهر في كل مكان في البرنامج (مطلوب).';
$lang['company_email'] = 'البريد الالكتروني للشركة';
$lang['company_email_hint'] = 'هذا سيكون البريد الالكتروني للشركة وسيكون المرسل للايميلات والردود من البرنامج(مطلوب).';
$lang['company_link'] = 'الموقع الالكتروني للشركة';
$lang['company_link_hint'] = 'الموقع الالكتروني للشركة يجب ان يكون موقع رسمي للشركة (مطلوب).';
$lang['go_to_booking_page'] = 'الذهاب الى صفحة الحجوزات';
$lang['settings_saved'] = 'تم حفظ الاعدادات بنجاح';
$lang['general'] = 'عام';
$lang['booking'] = 'Booking';
$lang['visible'] = 'مرئي';
$lang['hidden'] = 'مختفي';
$lang['business_logic'] = 'منطق الأعمال';
$lang['current_user'] = 'المستخدم الحالي';
$lang['about_app'] = 'About E!A';
$lang['edit_working_plan_hint'] = 'ضع علامة أسفل الأيام والساعات التي تقبل فيها شركتك المواعيد سوف تكون قادرا على ضبط المواعيد في غير ساعات العمل ولكن الزبائن لن يكونون قادرين على حجز المواعيد في غير فترات العمل ستكون خطة العمل هذه هي الطريقة الافتراضية لكل مزود خدمة جديد ولكنك ستتمكن من تغيير خطة كل مزود خدمة بشكل منفصل عن طريق تعديل سجله بعد ذلك يمكنك إضافة فترات استراحة';
$lang['edit_breaks_hint'] = 'اضافة فترات الاستراحة لكل يوم. فترات الاستراحة هذه سيتم تطبيقها لكل مزودي الخدمات';
$lang['book_advance_timeout'] = 'حجز مهلة مسبقا';
$lang['book_advance_timeout_hint'] = 'تعريف المهلة (بالدقائق) قبل أن يحجز الزبائن الموعد او يقومون باعادة ترتيب حجزهم';
$lang['timeout_minutes'] = 'المهلة (الدقائق)';
$lang['about_app_info'] = 'Easy!Appointments is a highly customizable web application that allows your customers to book appointments with you via the web. Moreover, it provides the ability to sync your data with Google Calendar so you can use them with other services.';
$lang['current_version'] = 'النسخة الحالية';
$lang['support'] = 'الدعم';
$lang['about_app_support'] = 'If you encounter any problems when using Easy!Appointments you can search the official Google Group for answers. You might also need to create a new issue on the Google Code page in order to help the development progress.';
$lang['official_website'] = 'الموقع الرسمي';
$lang['google_plus_community'] = 'Google+ مجتمع';
$lang['support_group'] = 'مجموعة الدعم';
$lang['project_issues'] = 'مشاكل المشروع';
$lang['license'] = 'الرخصة';
$lang['about_app_license'] = 'Easy!Appointments is licensed under the GPLv3 license. By using the code of Easy!Appointments in any way you are agreeing to the terms described in the following url:';
$lang['logout_success'] = 'تم تسجيل الخروج بنجاح';
$lang['book_appointment_title'] = 'احجز موعد';
$lang['backend_section'] = 'صفحة الدخول للبرنامج';
$lang['you_need_to_login'] = 'مرحبا بك ! يجب عليك تسجيل الدخول لمعاينة صفحات البرنامج وادارته';
$lang['enter_username_here'] = 'ادخل اسم المستخدم هنا ...';
$lang['enter_password_here'] = 'ادخل كلمة المرور هنا ...';
$lang['login'] = 'تسجيل الدخول';
$lang['forgot_your_password'] = 'نسيت كلمة المرور؟';
$lang['login_failed'] = 'تعذر تسجيل الدخول . الرجاء التأكد من اسم المستخدم وكلمة المرور مرة أخرى.';
$lang['type_username_and_email_for_new_password'] = 'ادخل اسم المستخدم والبريد الالكتروني لاعادة تعيين كلمة المرور';
$lang['enter_email_here'] = 'ادخل البريد الالكتروني هنا ...';
$lang['regenerate_password'] = 'اعادة تجديد كلمة المرور';
$lang['go_to_login'] = 'العودة الى صفحة تسجيل الدخول';
$lang['new_password_sent_with_email'] = 'تم ارسال كلمة المرور الى البريد الالكتروني';
$lang['new_account_password'] = 'كلمة المرور للحساب الجديد';
$lang['new_password_is'] = 'يرجى حفظ هذا البريد الالكتروني في مكان آمن ، ويمكنك تغيير كلمة السر من صفحة الاعدادات في البرنامج $password كلمة المرور لحسابك الجديد ';
$lang['delete_record_prompt'] = 'هل انت متاكد من حذف هذا التسجيل ؟ لا يمكن التراجع عن الحذف بعد حذفه';
$lang['delete_admin'] = 'حذف المسؤول';
$lang['delete_customer'] = 'حذف الزبون';
$lang['delete_service'] = 'حذف الخدمة';
$lang['delete_service_category'] = 'حذف فئة الخدمة';
$lang['delete_provider'] = 'حذف المزود';
$lang['delete_secretary'] = 'حذف السكرتير';
$lang['delete_appointment'] = 'حذف الموعد';
$lang['delete_unavailability'] = 'حذف الفترة الغير متاحة';
$lang['delete'] = 'حذف';
$lang['unexpected_issues'] = 'مشكلة غير متوقعة';
$lang['unexpected_issues_message'] = 'هذه العملية لا يمكن ان تتم في ظل وجود مشكلة غير متوقعة';
$lang['close'] = 'إغلاق';
$lang['page_not_found'] = 'لم يتم الحثور على الصفحة';
$lang['page_not_found_message'] = 'لم يتم العثور على الصفحة للأسف .يرجى التاكد من الرابط في المتصفح او الذهاب الى مكان آخر باستخدام الازرار أدناه';
$lang['error'] = 'خطأ';
$lang['no_privileges'] = 'لا يوجد صلاحيات';
$lang['no_privileges_message'] = 'لا يوجد لك صلاحيات لمعاينة هذه الصفحة . يرجى التوجه الى مكان آخر';
$lang['backend_calendar'] = 'التقويم الخاص بالمستخدمين ';
$lang['start_date_time'] = 'وقت البداية / الوقت';
$lang['end_date_time'] = 'وقت النهاية / الوقت';
$lang['licensed_under'] = 'مرخصة تحت';
$lang['unexpected_issues_occurred'] = 'حدثت مشكلة غير متوقعة.';
$lang['service_communication_error'] = 'فشل الاتصال بالخادم . يرجى اعادة التحميل مرة أخرى';
$lang['no_privileges_edit_appointments'] = 'لا تملك الصلاحايات للتعديل على الموعد';
$lang['unavailability_updated'] = 'تم تحديث الفترة الغير متاحة بنجاح.';
$lang['appointments'] = 'المواعيد';
$lang['unexpected_warnings'] = 'تحذيرات غير متوقعة';
$lang['unexpected_warnings_message'] = 'العملية تمت بنجاح لكن ظهرت بعض التحذيرات';
$lang['filter'] = 'تنقية/فلترة';
$lang['clear'] = 'تنظيف';
$lang['uncategorized'] = 'غير مصنّف';
$lang['username_already_exists'] = 'اسم المستخدم موجود مسبقا';
$lang['password_length_notice'] = 'حرف على الأقل $number اسم المستخدم يجب ان يكون';
$lang['general_settings'] = 'الاعدادات العامة';
$lang['personal_information'] = 'المعلومات الشخصية';
$lang['system_login'] = 'تسجيل الدخول الى النظام';
$lang['user_settings_are_invalid'] = 'اعدادات المستخدم غير صحيحة . يرجى تعديل الاعدادات والمحاولة مرة أخرى';
$lang['add_break'] = 'إضافة فترة استراحة';
$lang['january'] = 'يناير / January';
$lang['february'] = 'فبراير / February';
$lang['march'] = 'مارس / March';
$lang['april'] = ' أبريل / April';
$lang['may'] = 'مايو / May';
$lang['june'] = 'يونيو / June';
$lang['july'] = 'يوليو / July';
$lang['august'] = 'أغسطس / August';
$lang['september'] = 'سبتمبر / September';
$lang['october'] = 'أوكتوبر / October';
$lang['november'] = 'نوفمبر / November';
$lang['december'] = 'ديسمبر / December';
$lang['previous'] = 'السابق';
$lang['next'] = 'التالي';
$lang['now'] = 'الآن';
$lang['select_time'] = 'إختر الوقت';
$lang['time'] = 'الوقت';
$lang['hour'] = 'الساعة';
$lang['minute'] = 'الدقيقة';
$lang['google_sync_completed'] = 'اكتملت مزامنة جوجل بنجاح .';
$lang['google_sync_failed'] = 'فشلت المزامنة مع جوجل: تعذر انشاءالاتصال مع الخادم';
$lang['select_google_calendar'] = 'اختيار تقويم جوجل';
$lang['select_google_calendar_prompt'] = 'يرجى اختيار التقويم الذي تريد مزامنته مع مواعيدك. اذا لم تريد اختيار اي تقويم سيتم استخدام التقويم الافتراضي.';
$lang['google_calendar_selected'] = 'تم اختيار تقويم جوجل بنجاح';
$lang['oops_something_went_wrong'] = 'للأسف ! حصل خطأ ما .';
$lang['could_not_add_to_google_calendar'] = 'لا يمكن اضافة موعدك على تقويم جوجل';
$lang['ea_update_success'] = 'تم تحديث برنامج الحجوزات بنجاح';
$lang['require_captcha'] = 'مطلوب CAPTCHA';
$lang['require_captcha_hint'] = 'عند التمكين ، سيتوجب على الزبون ادخال رمز عشوائي عند الحجز او التعديل على الموعد ';
$lang['captcha_is_wrong'] = 'الرجاء المحاولة مرة أخرى CAPTCHA لم يتم تأكيد';
$lang['any_provider'] = 'أيْ مزوّد خدمة';
$lang['requested_hour_is_unavailable'] = 'الموعد الذي طلبته غير متاح للأسف . يرجى اختيار ساعة مختلفة لحجز الموعد ';
$lang['customer_notifications'] = 'اشعارات الزبون';
$lang['customer_notifications_hint'] = 'سيتم تلقي اشعارات للزبون عند تغيّر موعد الحجز أو عند تحديثه';
$lang['date_format'] = 'صيغة التاريخ';
$lang['date_format_hint'] = 'تغيير صيغة وعرض التاريخ (D - Date, M - Month, Y - Year).';
$lang['time_format'] = 'Time Format';
$lang['time_format_hint'] = 'Change the time display format (H - Hours, M - Minutes).';
$lang['first_weekday'] = 'First day of week';
$lang['first_weekday_hint'] = 'Set the first day of the calendar week.';
$lang['google_analytics_code_hint'] = 'ليتم تضمينه في صفحة الحجز Google Analytics ID أضف معرّف';
$lang['availabilities_type'] = 'نوع التوفر أو الإتاحة';
$lang['flexible'] = 'مرن';
$lang['fixed'] = 'ثابت';
$lang['attendants_number'] = 'عدد الحاضرين';
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
$lang['legal_contents'] = 'Legal Contents';
$lang['cookie_notice'] = 'Cookie Notice';
$lang['display_cookie_notice'] = 'Display Cookie Notice';
$lang['cookie_notice_content'] = 'Cookie Notice Content';
$lang['terms_and_conditions'] = 'Terms & Conditions';
$lang['display_terms_and_conditions'] = 'Display Terms & Conditions';
$lang['terms_and_conditions_content'] = 'Terms & Conditions Content';
$lang['privacy_policy'] = 'Privacy Policy';
$lang['display_privacy_policy'] = 'Display Privacy Policy';
$lang['privacy_policy_content'] = 'Privacy Policy Content';
$lang['website_using_cookies_to_ensure_best_experience'] = 'This website uses cookies to ensure you get the best experience on our website.';
$lang['read_and_agree_to_terms_and_conditions'] = 'I have read and agree to the {$link}Terms & Conditions{/$link}.';
$lang['read_and_agree_to_privacy_policy'] = 'I have read and agree to the {$link}Privacy Policy{/$link}.';
$lang['delete_personal_information_hint'] = 'Delete all personal information from the system.';
$lang['delete_personal_information'] = 'Delete Personal Information';
$lang['delete_personal_information_prompt'] = 'Are you sure that you want to delete your personal information? This action cannot be undone.';
$lang['location'] = 'Location';
$lang['working_plan_exception'] = 'Working Plan Exception';
$lang['working_plan_exceptions'] = 'Working Plan Exceptions';
$lang['working_plan_exceptions_hint'] = 'Add a working plan exception day, outside the working plan.';
$lang['new_working_plan_exception_title'] = 'New Working Plan Exception';
$lang['working_plan_exception_saved'] = 'Working plan exception saved successfully.';
$lang['working_plan_exception_deleted'] = 'Working plan exception deleted successfully.';
$lang['add_working_plan_exceptions_during_each_day'] = 'Add working plan exceptions, outside the working plan.';
$lang['add_working_plan_exception'] = 'Add Working Plan Exception';
$lang['require_phone_number'] = 'Require phone number';
$lang['require_phone_number_hint'] = 'When enabled, customers and users will need to enter the customer\'s phone number when booking an appointment';
$lang['check_spam_folder'] = 'Please check your spam folder if the email does not arrive within a few minutes.';
$lang['api_token_hint'] = 'Set a secret token in order to enable the token based authentication of the Easy!Appointments API.';
$lang['timezone'] = 'Timezone';
$lang['overwrite_existing_working_plans'] = 'This will overwrite the existing provider working plans, are you sure that you want to continue?';
$lang['working_plans_got_updated'] = 'All the working plans got updated.';
$lang['apply_to_all_providers'] = 'Apply To All Providers';
$lang['display_any_provider'] = 'Display Any Provider Option';
$lang['display_any_provider_hint'] = 'The booking page will get an additional option that allows customers to book without specifying a provider.';
$lang['load_more'] = 'Load More';
$lang['list'] = 'List';
$lang['default'] = 'Default';
$lang['table'] = 'Table';
$lang['date'] = 'Date';
$lang['about'] = 'About';
$lang['booking_settings'] = 'Booking Settings';
$lang['display'] = 'Display';
$lang['require'] = 'Require';
$lang['color'] = 'Color';
$lang['matomo_analytics_url_hint'] = 'Add the URL to your own Matomo installation to enable Matomo tracking on the booking pages.';
$lang['invalid_phone'] = 'Invalid phone number.';
$lang['legal'] = 'Legal';
$lang['business'] = 'Business';
$lang['account'] = 'Account';
$lang['disable_booking'] = 'Disable Booking';
$lang['disable_booking_hint'] = 'The booking page will be disabled for as long as this setting is active and customers will not be able to register new appointments.';
$lang['display_message'] = 'Display Message';
$lang['booking_is_disabled'] = 'Booking Is Disabled!';
$lang['appearance'] = 'Appearance';
$lang['company_logo'] = 'Company Logo';
$lang['company_logo_hint'] = 'The company logo will be displayed in many places of the app, including the booking page and the notification emails (image file, max 2MB).';
$lang['company_color'] = 'Company Color';
$lang['company_color_hint'] = 'The company color will be applied across the app so that it the app uses your branding.';
$lang['localization'] = 'Localization';
$lang['integrations'] = 'Integrations';
$lang['company'] = 'Company';
$lang['remove'] = 'Remove';
$lang['login_button'] = 'Login Button';
$lang['display_login_button_hint'] = 'Defines whether the login button is being displayed in the booking page.';
$lang['private'] = 'Private';
$lang['private_hint'] = 'Private records will not be displayed or processed in public pages such as the booking page.';
$lang['reset'] = 'Reset';
$lang['all'] = 'All';
$lang['booking_link'] = 'Booking Link';
$lang['add_new_event'] = 'Add New Event';
$lang['what_kind_of_event'] = 'What kind of event would you like to add?';
$lang['theme'] = 'Theme';
$lang['limit_customer_access'] = 'Limit Customer Access';
$lang['limit_customer_access_hint'] = 'If enabled, providers and secretaries will only be able to access customers they have an appointment with.';
$lang['url'] = 'URL';
$lang['secret_token'] = 'Secret Token';
$lang['verify_ssl'] = 'Verify SSL';
$lang['appointment_save'] = 'Appointment Save';
$lang['appointment_delete'] = 'Appointment Delete';
$lang['unavailability_save'] = 'Unavailability Save';
$lang['unavailability_delete'] = 'Unavailability Delete';
$lang['customer_save'] = 'Customer Save';
$lang['customer_delete'] = 'Customer Delete';
$lang['service_save'] = 'Service Save';
$lang['service_delete'] = 'Service Delete';
$lang['service_category_save'] = 'Category Save';
$lang['service_category_delete'] = 'Category Delete';
$lang['provider_save'] = 'Provider Save';
$lang['provider_delete'] = 'Provider Delete';
$lang['secretary_save'] = 'Secretary Save';
$lang['secretary_delete'] = 'Secretary Delete';
$lang['admin_save'] = 'Admin Save';
$lang['admin_delete'] = 'Admin Delete';
$lang['options'] = 'Options';
$lang['webhooks'] = 'Webhooks';
$lang['webhooks_info'] = 'Webhooks enable you to send HTTP notifications to external web applications in response to various application events, such as the creation of an appointment or the removal of a customer.';
$lang['integrations_info'] = 'Integrations enable you to make third-party connections with external applications and APIs.';
$lang['configure'] = 'Configure';
$lang['google_analytics'] = 'Google Analytics';
$lang['google_analytics_info'] = 'Google Analytics enable you to automatically add the tracking code and HTML markup to the public page and track all the public booking sessions.';
$lang['matomo_analytics'] = 'Matomo Analytics';
$lang['matomo_analytics_info'] = 'Matomo Analytics enable you to automatically add the tracking code and HTML markup to the public page and track all the public booking sessions.';
$lang['api'] = 'API';
$lang['api_info'] = 'API enable you to interact with all the Easy!Appointments data via the HTTP protocol and the available API endpoints and create your own integrations.';
$lang['google_analytics_code'] = 'Google Analytics Code';
$lang['matomo_analytics_url'] = 'Matomo Analytics URL';
$lang['future_booking_limit'] = 'Future Booking Limit';
$lang['limit_days'] = 'Limit (Days)';
$lang['future_booking_limit_hint'] = 'Set the future limit in days customers can make appointments via the public booking page.';
$lang['api_token'] = 'API Token';
$lang['allow_rescheduling_cancellation_before'] = 'Allow Rescheduling/Cancellation Before';
$lang['at_least_one_field'] = 'At least one field must be displayed in the booking page.';
$lang['status'] = 'Status';
$lang['appointment_status_options'] = 'Appointment Status Options';
$lang['appointment_status_options_info'] = 'Define a list of available appointment status options that can be used in the the calendar page (the first one will automatically become the default value).';
$lang['sunday_short'] = 'Sun';
$lang['monday_short'] = 'Mon';
$lang['tuesday_short'] = 'Tue';
$lang['wednesday_short'] = 'Wed';
$lang['thursday_short'] = 'Thu';
$lang['friday_short'] = 'Fri';
$lang['saturday_short'] = 'Sat';
$lang['january_short'] = 'Jan';
$lang['february_short'] = 'Feb';
$lang['march_short'] = 'Mar';
$lang['april_short'] = 'Apr';
$lang['may_short'] = 'May';
$lang['june_short'] = 'Jun';
$lang['july_short'] = 'Jul';
$lang['august_short'] = 'Aug';
$lang['september_short'] = 'Sep';
$lang['october_short'] = 'Oct';
$lang['november_short'] = 'Nov';
$lang['december_short'] = 'Dec';
$lang['am'] = 'am';
$lang['pm'] = 'pm';
$lang['to'] = 'to';
$lang['click_to_toggle'] = 'Click To Toggle';
$lang['week_short'] = 'Wk';
$lang['scroll_to_increment'] = 'Scroll To Increment';
$lang['year'] = 'Year';
$lang['make_non_working_day'] = 'This provider will not be available for work on the selected day.';
$lang['no_breaks'] = 'No Breaks';
$lang['service_categories'] = 'Service Categories';
$lang['service_category'] = 'Service Category';
$lang['blocked_period_saved'] = 'Blocked period saved successfully.';
$lang['blocked_period_deleted'] = 'Blocked period deleted successfully.';
$lang['delete_blocked_period'] = 'Delete Blocked Period';
$lang['blocked_period'] = 'Blocked Period';
$lang['blocked_periods'] = 'Blocked Periods';
$lang['blocked_period_save'] = 'Blocked Period Save';
$lang['blocked_period_delete'] = 'Blocked Period Delete';
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
$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

@ -452,4 +452,5 @@ $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

@ -457,5 +457,9 @@ $lang['label'] = 'Label';
$lang['webhook_saved'] = 'Webhook saved successfully.';
$lang['webhook_deleted'] = 'Webhook deleted successfully.';
$lang['delete_webhook'] = 'Delete Webhook';
<<<<<<< HEAD
>>>>>>> upstream/develop
=======
$lang['contact_info'] = 'Contact Info';
>>>>>>> remotes/upstream/develop
// End

View File

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

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

@ -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());
}
},
});