|
@@ -1,33 +1,27 @@
|
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
|
import { TAPi18n } from '/imports/i18n';
|
|
import { TAPi18n } from '/imports/i18n';
|
|
|
-import {
|
|
|
|
|
- formatDateTime,
|
|
|
|
|
- formatDate,
|
|
|
|
|
- formatDateByUserPreference,
|
|
|
|
|
- formatTime,
|
|
|
|
|
- getISOWeek,
|
|
|
|
|
- isValidDate,
|
|
|
|
|
- isBefore,
|
|
|
|
|
- isAfter,
|
|
|
|
|
- isSame,
|
|
|
|
|
- add,
|
|
|
|
|
- subtract,
|
|
|
|
|
- startOf,
|
|
|
|
|
- endOf,
|
|
|
|
|
- format,
|
|
|
|
|
- parseDate,
|
|
|
|
|
- now,
|
|
|
|
|
- createDate,
|
|
|
|
|
- fromNow,
|
|
|
|
|
- calendar
|
|
|
|
|
-} from '/imports/lib/dateUtils';
|
|
|
|
|
|
|
|
|
|
-// Helper function to get time format for 24 hours
|
|
|
|
|
-function adjustedTimeFormat() {
|
|
|
|
|
- return 'HH:mm';
|
|
|
|
|
|
|
+// Helper to check if a date is valid
|
|
|
|
|
+function isValidDate(date) {
|
|
|
|
|
+ return date instanceof Date && !isNaN(date);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// .replace(/HH/i, 'H');
|
|
|
|
|
|
|
+// Format date as YYYY-MM-DD
|
|
|
|
|
+function formatDate(date) {
|
|
|
|
|
+ if (!isValidDate(date)) return '';
|
|
|
|
|
+ const year = date.getFullYear();
|
|
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
|
|
+ const day = String(date.getDate()).padStart(2, '0');
|
|
|
|
|
+ return `${year}-${month}-${day}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Format time as HH:mm
|
|
|
|
|
+function formatTime(date) {
|
|
|
|
|
+ if (!isValidDate(date)) return '';
|
|
|
|
|
+ const hours = String(date.getHours()).padStart(2, '0');
|
|
|
|
|
+ const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
|
|
|
+ return `${hours}:${minutes}`;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
export class DatePicker extends BlazeComponent {
|
|
export class DatePicker extends BlazeComponent {
|
|
|
template() {
|
|
template() {
|
|
@@ -51,35 +45,25 @@ export class DatePicker extends BlazeComponent {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
onRendered() {
|
|
onRendered() {
|
|
|
- // Set initial values for text and time inputs
|
|
|
|
|
|
|
+ // Set initial values for native HTML inputs
|
|
|
if (isValidDate(this.date.get())) {
|
|
if (isValidDate(this.date.get())) {
|
|
|
const dateInput = this.find('#date');
|
|
const dateInput = this.find('#date');
|
|
|
const timeInput = this.find('#time');
|
|
const timeInput = this.find('#time');
|
|
|
|
|
|
|
|
if (dateInput) {
|
|
if (dateInput) {
|
|
|
- // Use user's preferred format for text input
|
|
|
|
|
- const currentUser = ReactiveCache.getCurrentUser();
|
|
|
|
|
- const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
|
|
|
|
|
- dateInput.value = formatDateByUserPreference(this.date.get(), userFormat, false);
|
|
|
|
|
|
|
+ dateInput.value = formatDate(this.date.get());
|
|
|
}
|
|
}
|
|
|
- if (timeInput) {
|
|
|
|
|
- if (!timeInput.value && this.defaultTime) {
|
|
|
|
|
- const defaultDate = new Date(this.defaultTime);
|
|
|
|
|
- timeInput.value = formatTime(defaultDate);
|
|
|
|
|
- } else if (isValidDate(this.date.get())) {
|
|
|
|
|
- timeInput.value = formatTime(this.date.get());
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (timeInput && !timeInput.value && this.defaultTime) {
|
|
|
|
|
+ const defaultDate = new Date(this.defaultTime);
|
|
|
|
|
+ timeInput.value = formatTime(defaultDate);
|
|
|
|
|
+ } else if (timeInput && isValidDate(this.date.get())) {
|
|
|
|
|
+ timeInput.value = formatTime(this.date.get());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
showDate() {
|
|
showDate() {
|
|
|
- if (isValidDate(this.date.get())) {
|
|
|
|
|
- // Use user's preferred format for display, but HTML date input needs YYYY-MM-DD
|
|
|
|
|
- const currentUser = ReactiveCache.getCurrentUser();
|
|
|
|
|
- const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
|
|
|
|
|
- return formatDateByUserPreference(this.date.get(), userFormat, false);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (isValidDate(this.date.get())) return formatDate(this.date.get());
|
|
|
return '';
|
|
return '';
|
|
|
}
|
|
}
|
|
|
showTime() {
|
|
showTime() {
|
|
@@ -87,56 +71,22 @@ export class DatePicker extends BlazeComponent {
|
|
|
return '';
|
|
return '';
|
|
|
}
|
|
}
|
|
|
dateFormat() {
|
|
dateFormat() {
|
|
|
- const currentUser = ReactiveCache.getCurrentUser();
|
|
|
|
|
- const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
|
|
|
|
|
- // Convert format to localized placeholder
|
|
|
|
|
- switch (userFormat) {
|
|
|
|
|
- case 'DD-MM-YYYY':
|
|
|
|
|
- return TAPi18n.__('date-format-dd-mm-yyyy') || 'PP-KK-VVVV';
|
|
|
|
|
- case 'MM-DD-YYYY':
|
|
|
|
|
- return TAPi18n.__('date-format-mm-dd-yyyy') || 'KK-PP-VVVV';
|
|
|
|
|
- case 'YYYY-MM-DD':
|
|
|
|
|
- default:
|
|
|
|
|
- return TAPi18n.__('date-format-yyyy-mm-dd') || 'VVVV-KK-PP';
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return 'YYYY-MM-DD';
|
|
|
}
|
|
}
|
|
|
timeFormat() {
|
|
timeFormat() {
|
|
|
- return 'LT';
|
|
|
|
|
|
|
+ return 'HH:mm';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
events() {
|
|
events() {
|
|
|
return [
|
|
return [
|
|
|
{
|
|
{
|
|
|
'change .js-date-field'() {
|
|
'change .js-date-field'() {
|
|
|
- // Text input date validation
|
|
|
|
|
- const dateInput = this.find('#date');
|
|
|
|
|
- if (!dateInput) return;
|
|
|
|
|
-
|
|
|
|
|
- const dateValue = dateInput.value;
|
|
|
|
|
|
|
+ // Native HTML date input validation
|
|
|
|
|
+ const dateValue = this.find('#date').value;
|
|
|
if (dateValue) {
|
|
if (dateValue) {
|
|
|
- // Try to parse different date formats
|
|
|
|
|
- const formats = [
|
|
|
|
|
- 'YYYY-MM-DD',
|
|
|
|
|
- 'DD-MM-YYYY',
|
|
|
|
|
- 'MM-DD-YYYY',
|
|
|
|
|
- 'DD/MM/YYYY',
|
|
|
|
|
- 'MM/DD/YYYY',
|
|
|
|
|
- 'DD.MM.YYYY',
|
|
|
|
|
- 'MM.DD.YYYY'
|
|
|
|
|
- ];
|
|
|
|
|
-
|
|
|
|
|
- let parsedDate = null;
|
|
|
|
|
- for (const format of formats) {
|
|
|
|
|
- parsedDate = parseDate(dateValue, [format], true);
|
|
|
|
|
- if (parsedDate) break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Fallback to native Date parsing
|
|
|
|
|
- if (!parsedDate) {
|
|
|
|
|
- parsedDate = new Date(dateValue);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (isValidDate(parsedDate)) {
|
|
|
|
|
|
|
+ // HTML date input format is always YYYY-MM-DD
|
|
|
|
|
+ const dateObj = new Date(dateValue + 'T12:00:00');
|
|
|
|
|
+ if (isValidDate(dateObj)) {
|
|
|
this.error.set('');
|
|
this.error.set('');
|
|
|
} else {
|
|
} else {
|
|
|
this.error.set('invalid-date');
|
|
this.error.set('invalid-date');
|
|
@@ -145,12 +95,10 @@ export class DatePicker extends BlazeComponent {
|
|
|
},
|
|
},
|
|
|
'change .js-time-field'() {
|
|
'change .js-time-field'() {
|
|
|
// Native HTML time input validation
|
|
// Native HTML time input validation
|
|
|
- const timeInput = this.find('#time');
|
|
|
|
|
- if (!timeInput) return;
|
|
|
|
|
-
|
|
|
|
|
- const timeValue = timeInput.value;
|
|
|
|
|
|
|
+ const timeValue = this.find('#time').value;
|
|
|
if (timeValue) {
|
|
if (timeValue) {
|
|
|
- const timeObj = new Date(`1970-01-01T${timeValue}`);
|
|
|
|
|
|
|
+ // HTML time input format is always HH:mm
|
|
|
|
|
+ const timeObj = new Date(`1970-01-01T${timeValue}:00`);
|
|
|
if (isValidDate(timeObj)) {
|
|
if (isValidDate(timeObj)) {
|
|
|
this.error.set('');
|
|
this.error.set('');
|
|
|
} else {
|
|
} else {
|
|
@@ -170,44 +118,16 @@ export class DatePicker extends BlazeComponent {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Try to parse different date formats
|
|
|
|
|
- const formats = [
|
|
|
|
|
- 'YYYY-MM-DD',
|
|
|
|
|
- 'DD-MM-YYYY',
|
|
|
|
|
- 'MM-DD-YYYY',
|
|
|
|
|
- 'DD/MM/YYYY',
|
|
|
|
|
- 'MM/DD/YYYY',
|
|
|
|
|
- 'DD.MM.YYYY',
|
|
|
|
|
- 'MM.DD.YYYY'
|
|
|
|
|
- ];
|
|
|
|
|
|
|
+ // Combine date and time: HTML date input is YYYY-MM-DD, time input is HH:mm
|
|
|
|
|
+ const dateTimeString = `${dateValue}T${timeValue}:00`;
|
|
|
|
|
+ const newCompleteDate = new Date(dateTimeString);
|
|
|
|
|
|
|
|
- let parsedDate = null;
|
|
|
|
|
- for (const format of formats) {
|
|
|
|
|
- parsedDate = parseDate(dateValue, [format], true);
|
|
|
|
|
- if (parsedDate) break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Fallback to native Date parsing
|
|
|
|
|
- if (!parsedDate) {
|
|
|
|
|
- parsedDate = new Date(dateValue);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!isValidDate(parsedDate)) {
|
|
|
|
|
|
|
+ if (!isValidDate(newCompleteDate)) {
|
|
|
this.error.set('invalid');
|
|
this.error.set('invalid');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Combine with time
|
|
|
|
|
- const timeObj = new Date(`1970-01-01T${timeValue}`);
|
|
|
|
|
- if (!isValidDate(timeObj)) {
|
|
|
|
|
- this.error.set('invalid-time');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Set the time on the parsed date
|
|
|
|
|
- parsedDate.setHours(timeObj.getHours(), timeObj.getMinutes(), 0, 0);
|
|
|
|
|
-
|
|
|
|
|
- this._storeDate(parsedDate);
|
|
|
|
|
|
|
+ this._storeDate(newCompleteDate);
|
|
|
Popup.back();
|
|
Popup.back();
|
|
|
},
|
|
},
|
|
|
'click .js-delete-date'(evt) {
|
|
'click .js-delete-date'(evt) {
|