Merge branch 'main' into feature-fixStats
This commit is contained in:
@ -10,7 +10,7 @@ const { PrismaClient, UserRole } = require('@prisma/client');
|
||||
const DayOfWeek = require("@prisma/client").DayOfWeek;
|
||||
const winston = require('winston');
|
||||
const { getSession } = require("next-auth/react");
|
||||
|
||||
const { DateTime, FixedOffsetZone } = require('luxon');
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: 'info', // Set the default log level
|
||||
@ -36,6 +36,27 @@ exports.logger = logger;
|
||||
// dotenv.config();
|
||||
// // dotenv.config({ path: ".env.local" });
|
||||
|
||||
exports.adjustUtcTimeToSofia = function (time) {
|
||||
// Convert the Date object to a Luxon DateTime object in UTC
|
||||
let result = DateTime.fromJSDate(time, { zone: 'utc' });
|
||||
// Convert to Sofia time, retaining the local time as provided
|
||||
result = result.setZone('Europe/Sofia', { keepLocalTime: true });
|
||||
// Set hours, minutes, and seconds to match the input time
|
||||
result = result.set({
|
||||
hour: time.getHours(),
|
||||
minute: time.getMinutes(),
|
||||
second: time.getSeconds()
|
||||
});
|
||||
return result.toJSDate();
|
||||
};
|
||||
|
||||
exports.adjustTimeToUTC = function (time) {
|
||||
let result = DateTime.fromJSDate(time, { zone: 'Europe/Sofia' });
|
||||
result = result.setZone('utc', { keepLocalTime: true });
|
||||
return result.toJSDate();
|
||||
};
|
||||
|
||||
|
||||
exports.isValidPhoneNumber = function (phone) {
|
||||
if (typeof phone !== 'string') {
|
||||
return false; // or handle as you see fit
|
||||
@ -56,17 +77,6 @@ exports.isValidPhoneNumber = function (phone) {
|
||||
// If neither condition is met, the phone number is invalid
|
||||
return false;
|
||||
}
|
||||
exports.setBaseUrl = function (req) {
|
||||
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
||||
const host = req.headers.host;
|
||||
const baseUrl = `${protocol}://${host}`;
|
||||
|
||||
// Write the baseUrl to the file
|
||||
if (req != null) {
|
||||
fs.writeFileSync(path.join(__dirname, 'baseUrl.txt'), baseUrl, 'utf8');
|
||||
}
|
||||
return baseUrl;
|
||||
};
|
||||
|
||||
exports.getBaseUrl = function (relative = "", req = null) {
|
||||
return process.env.NEXT_PUBLIC_PUBLIC_URL + relative;
|
||||
@ -329,14 +339,8 @@ exports.compareTimes = function (time1, time2) {
|
||||
const time2String = `${getHours(time2)}:${getMinutes(time2)}`;
|
||||
return time1String.localeCompare(time2String);
|
||||
};
|
||||
|
||||
exports.normalizeTime = function (date, baseDate) {
|
||||
// return set(baseDate, {
|
||||
// hours: getHours(date),
|
||||
// minutes: getMinutes(date),
|
||||
// seconds: getSeconds(date),
|
||||
// milliseconds: 0
|
||||
// });
|
||||
//don't use date-fns
|
||||
let newDate = new Date(baseDate);
|
||||
newDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), 0);
|
||||
return newDate;
|
||||
@ -366,10 +370,7 @@ exports.getDateFormatedShort = function (date) {
|
||||
}
|
||||
|
||||
|
||||
exports.getTimeFomatted = function (date) {
|
||||
return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Sofia' });//timeZone: 'local'
|
||||
|
||||
}
|
||||
|
||||
/*Todo: remove:
|
||||
toISOString
|
||||
@ -528,7 +529,7 @@ exports.fuzzySearch = function (publishers, searchQuery, distanceThreshold = 0.9
|
||||
}
|
||||
|
||||
|
||||
exports.getCurrentNonthFormatted = function () {
|
||||
exports.getCurrentMonthFormatted = function () {
|
||||
const getCurrentYearMonth = () => {
|
||||
const currentDate = new Date();
|
||||
const year = currentDate.getFullYear();
|
||||
@ -544,51 +545,140 @@ exports.getCurrentYearMonth = () => {
|
||||
const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // Month is 0-indexed
|
||||
return `${year}-${month}`;
|
||||
}
|
||||
exports.getTimeFormated = function (date) {
|
||||
return this.formatTimeHHmm(date);
|
||||
}
|
||||
// format date to 'HH:mm' time string required by the time picker
|
||||
exports.formatTimeHHmm = function (input) {
|
||||
// Check if the input is a string or a Date object
|
||||
const date = (typeof input === 'string') ? new Date(input) : input;
|
||||
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
hour12: false,
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
timeZone: 'Europe/Sofia'
|
||||
}).substring(0, 5);
|
||||
}
|
||||
|
||||
|
||||
//parse 'HH:mm' time string to date object
|
||||
exports.parseTimeHHmm = (timeString) => {
|
||||
// If timeString is already a date, return it as is
|
||||
if (timeString instanceof Date) {
|
||||
return timeString;
|
||||
}
|
||||
// new date FNs
|
||||
/**
|
||||
* Parses an input into a Luxon DateTime object, setting the timezone to 'Europe/Sofia' while keeping the local time.
|
||||
* @param {string|Date} input - The input date string or JavaScript Date object.
|
||||
* @returns {DateTime} - A Luxon DateTime object with the timezone set to 'Europe/Sofia', preserving the local time.
|
||||
*/
|
||||
const parseDate = (input) => {
|
||||
let dateTime;
|
||||
|
||||
const [hours, minutes] = timeString.split(':');
|
||||
const date = new Date();
|
||||
date.setHours(hours);
|
||||
date.setMinutes(minutes);
|
||||
return date;
|
||||
}
|
||||
|
||||
exports.setTimeHHmm = (date, timeStringOrHours) => {
|
||||
const newDate = new Date(date);
|
||||
|
||||
if (typeof timeStringOrHours === 'string' && timeStringOrHours.includes(':')) {
|
||||
// If hours is a string in "HH:mm" format
|
||||
const [h, m] = timeStringOrHours.split(':');
|
||||
newDate.setHours(parseInt(h, 10), parseInt(m, 10), 0, 0);
|
||||
if (input instanceof DateTime) {
|
||||
// If input is already a Luxon DateTime, we adjust the zone only.
|
||||
dateTime = input.setZone('Europe/Sofia');
|
||||
} else if (typeof input === 'string' || input instanceof Date) {
|
||||
// Create a DateTime from the input assuming local timezone to preserve local time when changing the zone.
|
||||
dateTime = DateTime.fromJSDate(new Date(input), { zone: 'local' });
|
||||
dateTime = dateTime.setZone('Europe/Sofia');
|
||||
} else {
|
||||
// If hours and minutes are provided separately
|
||||
newDate.setHours(parseInt(timeStringOrHours, 10), 0, 0, 0);
|
||||
// Use the current time if no input is given, considered as local time.
|
||||
dateTime = DateTime.local().setZone('Europe/Sofia');
|
||||
}
|
||||
|
||||
return newDate;
|
||||
// Set the timezone to 'Europe/Sofia' while keeping the original local time.
|
||||
return dateTime.setZone('Europe/Sofia', { keepLocalTime: true });
|
||||
};
|
||||
exports.parseDate = parseDate;
|
||||
|
||||
// Set timezone to 'Europe/Sofia' without translating time
|
||||
exports.setTimezone = (input) => {
|
||||
let dateTime = parseDate(input);
|
||||
dateTime = dateTime.setZone('Europe/Sofia', { keepLocalTime: true });
|
||||
return dateTime.toJSDate();
|
||||
};
|
||||
exports.setTime = (baseDateTime, timeDateTime) => {
|
||||
// Ensure both inputs are DateTime objects
|
||||
baseDateTime = parseDate(baseDateTime);
|
||||
timeDateTime = parseDate(timeDateTime);
|
||||
|
||||
return baseDateTime.set({
|
||||
hour: timeDateTime.hour,
|
||||
minute: timeDateTime.minute,
|
||||
second: timeDateTime.second,
|
||||
millisecond: timeDateTime.millisecond
|
||||
});
|
||||
};
|
||||
|
||||
// Format date to a specified format, defaulting to 'HH:mm'
|
||||
exports.getTimeFormatted = (input, format = 'HH:mm') => {
|
||||
const dateTime = parseDate(input);
|
||||
return dateTime.toFormat(format);
|
||||
};
|
||||
|
||||
// Set time in 'HH:mm' format to a date and return as JS Date in Sofia timezone
|
||||
exports.setTimeHHmm = (input, timeString) => {
|
||||
let dateTime = parseDate(input);
|
||||
const [hour, minute] = timeString.split(':').map(Number);
|
||||
dateTime = dateTime.set({ hour, minute });
|
||||
return dateTime.toJSDate();
|
||||
};
|
||||
|
||||
// Parse 'HH:mm' time string to a JS Date object in Sofia timezone for today
|
||||
exports.parseTimeHHmm = (timeString) => {
|
||||
const dateTime = DateTime.now({ zone: 'Europe/Sofia' });
|
||||
const [hour, minute] = timeString.split(':').map(Number);
|
||||
return dateTime.set({ hour, minute }).toJSDate();
|
||||
};
|
||||
|
||||
function isTimeBetween(startTime, endTime, checkTime) {
|
||||
const start = new Date(0, 0, 0, startTime.getHours(), startTime.getMinutes());
|
||||
const end = new Date(0, 0, 0, endTime.getHours(), endTime.getMinutes());
|
||||
const check = new Date(0, 0, 0, checkTime.getHours(), checkTime.getMinutes());
|
||||
|
||||
// If the end time is less than the start time, it means the time range spans midnight
|
||||
if (end < start) {
|
||||
// Check time is between start and midnight or between midnight and end
|
||||
return (check >= start && check <= new Date(0, 0, 1, 0, 0, 0)) || (check >= new Date(0, 0, 0, 0, 0, 0) && check <= end);
|
||||
} else {
|
||||
return check >= start && check <= end;
|
||||
}
|
||||
}
|
||||
exports.isTimeBetween = isTimeBetween;
|
||||
|
||||
|
||||
// ToDo: update all uses of this function to use the new one
|
||||
|
||||
// exports.getTimeFormatted = function (date) {
|
||||
// const dateTime = DateTime.fromJSDate(date, { zone: 'Europe/Sofia' });
|
||||
// return dateTime.toFormat('HH:mm');
|
||||
// };
|
||||
|
||||
// exports.setTimeHHmm = (date, timeStringOrHours) => {
|
||||
// const newDate = new Date(date);
|
||||
|
||||
// if (typeof timeStringOrHours === 'string' && timeStringOrHours.includes(':')) {
|
||||
// // If hours is a string in "HH:mm" format
|
||||
// const [h, m] = timeStringOrHours.split(':');
|
||||
// newDate.setHours(parseInt(h, 10), parseInt(m, 10), 0, 0);
|
||||
// } else {
|
||||
// // If hours and minutes are provided separately
|
||||
// newDate.setHours(parseInt(timeStringOrHours, 10), 0, 0, 0);
|
||||
// }
|
||||
|
||||
// return newDate;
|
||||
// };
|
||||
// // format date to 'HH:mm' time string required by the time picker
|
||||
// exports.formatTimeHHmm = function (input) {
|
||||
// // Check if the input is a string or a Date object
|
||||
// const date = (typeof input === 'string') ? new Date(input) : input;
|
||||
|
||||
// return date.toLocaleTimeString('en-US', {
|
||||
// hour12: false,
|
||||
// hour: '2-digit',
|
||||
// minute: '2-digit',
|
||||
// timeZone: 'Europe/Sofia'
|
||||
// }).substring(0, 5);
|
||||
// }
|
||||
|
||||
|
||||
// //parse 'HH:mm' time string to date object
|
||||
// exports.parseTimeHHmm = (timeString) => {
|
||||
// // If timeString is already a date, return it as is
|
||||
// if (timeString instanceof Date) {
|
||||
// return timeString;
|
||||
// }
|
||||
|
||||
// const [hours, minutes] = timeString.split(':');
|
||||
// const date = new Date();
|
||||
// date.setHours(hours);
|
||||
// date.setMinutes(minutes);
|
||||
// return date;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
exports.getTimeInMinutes = (dateOrTimestamp) => {
|
||||
const date = new Date(dateOrTimestamp);
|
||||
@ -775,8 +865,13 @@ exports.convertDatesToISOStrings = function (obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
// if (obj instanceof Date) {
|
||||
// return obj.toISOString();
|
||||
// }
|
||||
if (obj instanceof Date) {
|
||||
return obj.toISOString();
|
||||
// Convert the Date object to a Luxon DateTime in UTC
|
||||
const utcDate = DateTime.fromJSDate(obj, { zone: 'utc' });
|
||||
return utcDate.toISO(); // Output in UTC as ISO string
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
@ -793,8 +888,43 @@ exports.convertDatesToISOStrings = function (obj) {
|
||||
|
||||
return obj;
|
||||
}
|
||||
function adjustDateForDST(date, timezone) {
|
||||
// Convert the date to the specified timezone
|
||||
let dateTime = DateTime.fromJSDate(date, { zone: timezone });
|
||||
|
||||
// Check if the original date is in DST
|
||||
const isOriginalDST = dateTime.isInDST;
|
||||
|
||||
// Check if the current date in the same timezone is in DST
|
||||
const isNowDST = DateTime.now().setZone(timezone).isInDST;
|
||||
|
||||
// Compare and adjust if necessary
|
||||
if (isOriginalDST && !isNowDST) {
|
||||
// If original date was in DST but now is not, subtract one hour
|
||||
dateTime = dateTime.minus({ hours: 1 });
|
||||
} else if (!isOriginalDST && isNowDST) {
|
||||
// If original date was not in DST but now is, add one hour
|
||||
dateTime = dateTime.plus({ hours: 1 });
|
||||
}
|
||||
|
||||
// Return the adjusted date as a JavaScript Date
|
||||
return dateTime.toJSDate();
|
||||
}
|
||||
exports.adjustDateForDST = adjustDateForDST;
|
||||
|
||||
|
||||
exports.base64ToUint8Array = function (base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
const rawData = atob(base64);
|
||||
const buffer = new Uint8Array(rawData.length);
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
buffer[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
// exports.getInitials = function (names) {
|
||||
// const parts = names.split(' '); // Split the full name into parts
|
||||
// if (parts.length === 0) {
|
||||
|
@ -158,7 +158,7 @@ async function getAvailabilities(userId) {
|
||||
...item,
|
||||
startTime: item.startTime.toISOString(),
|
||||
endTime: item.endTime.toISOString(),
|
||||
name: common.getTimeFomatted(item.startTime) + "-" + common.getTimeFomatted(item.endTime),
|
||||
name: common.getTimeFormatted(item.startTime) + "-" + common.getTimeFormatted(item.endTime),
|
||||
//endDate can be null
|
||||
endDate: item.endDate ? item.endDate.toISOString() : null,
|
||||
type: 'availability',
|
||||
@ -214,7 +214,7 @@ async function getAvailabilities(userId) {
|
||||
endTime: item.shift.endTime.toISOString(),
|
||||
// name: item.shift.publishers.map(p => p.firstName + " " + p.lastName).join(", "),
|
||||
//name: item.shift.assignments.map(a => a.publisher.firstName[0] + " " + a.publisher.lastName).join(", "),
|
||||
name: common.getTimeFomatted(new Date(item.shift.startTime)) + "-" + common.getTimeFomatted(new Date(item.shift.endTime)),
|
||||
name: common.getTimeFormatted(new Date(item.shift.startTime)) + "-" + common.getTimeFormatted(new Date(item.shift.endTime)),
|
||||
type: 'assignment',
|
||||
//delete shift object
|
||||
shift: null,
|
||||
@ -614,7 +614,7 @@ function convertShiftDates(assignments) {
|
||||
}
|
||||
|
||||
|
||||
async function getCalendarEvents(publisherId, date, availabilities = true, assignments = true) {
|
||||
async function getCalendarEvents(publisherId, availabilities = true, assignments = true, includeUnpublished = false) {
|
||||
const result = [];
|
||||
// let pubs = await filterPublishers("id,firstName,lastName,email".split(","), "", date, assignments, availabilities, date ? true : false, publisherId);
|
||||
|
||||
@ -647,6 +647,7 @@ async function getCalendarEvents(publisherId, date, availabilities = true, assig
|
||||
assignments: {
|
||||
select: {
|
||||
id: true,
|
||||
// publisherId: true,
|
||||
shift: {
|
||||
select: {
|
||||
id: true,
|
||||
@ -665,7 +666,7 @@ async function getCalendarEvents(publisherId, date, availabilities = true, assig
|
||||
publisher.availabilities?.forEach(item => {
|
||||
result.push({
|
||||
...item,
|
||||
title: common.getTimeFomatted(new Date(item.startTime)) + "-" + common.getTimeFomatted(new Date(item.endTime)), //item.name,
|
||||
title: common.getTimeFormatted(new Date(item.startTime)) + "-" + common.getTimeFormatted(new Date(item.endTime)), //item.name,
|
||||
date: new Date(item.startTime),
|
||||
startTime: new Date(item.startTime),
|
||||
endTime: new Date(item.endTime),
|
||||
@ -681,23 +682,21 @@ async function getCalendarEvents(publisherId, date, availabilities = true, assig
|
||||
//only published shifts
|
||||
|
||||
publisher.assignments?.filter(
|
||||
assignment => assignment.shift.isPublished
|
||||
assignment => assignment.shift.isPublished || includeUnpublished
|
||||
).forEach(item => {
|
||||
result.push({
|
||||
...item,
|
||||
title: common.getTimeFomatted(new Date(item.shift.startTime)) + "-" + common.getTimeFomatted(new Date(item.shift.endTime)),
|
||||
title: common.getTimeFormatted(new Date(item.shift.startTime)) + "-" + common.getTimeFormatted(new Date(item.shift.endTime)),
|
||||
date: new Date(item.shift.startTime),
|
||||
startTime: new Date(item.shift.startTime),
|
||||
endTime: new Date(item.shift.endTime),
|
||||
publisherId: item.publisherid,
|
||||
// publisherId: item.publisherId,
|
||||
publisherId: publisher.id,
|
||||
type: "assignment",
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user