fix dates ant TZ, cleanup
This commit is contained in:
@ -11,6 +11,7 @@ import { ToastContainer } from 'react-toastify';
|
||||
const common = require('src/helpers/common');
|
||||
//todo import Availability type from prisma schema
|
||||
import { isBefore, addMinutes, isAfter, isEqual, set, getHours, getMinutes, getSeconds } from 'date-fns'; //ToDo obsolete
|
||||
import { stat } from 'fs';
|
||||
|
||||
const { DateTime, FixedOffsetZone } = require('luxon');
|
||||
|
||||
@ -21,7 +22,7 @@ const fetchConfig = async () => {
|
||||
return config.default;
|
||||
};
|
||||
|
||||
export default function AvailabilityForm({ publisherId, existingItems, inline, onDone, date, datePicker = false }) {
|
||||
export default function AvailabilityForm({ publisherId, existingItems, inline, onDone, date, cartEvent, datePicker = false }) {
|
||||
|
||||
const router = useRouter();
|
||||
const urls = {
|
||||
@ -67,14 +68,13 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
||||
}, []);
|
||||
|
||||
|
||||
// Define the minimum and maximum times
|
||||
const minTime = new Date();
|
||||
minTime.setHours(9, 0, 0, 0); // 8:00 AM
|
||||
const maxTime = new Date();
|
||||
maxTime.setHours(19, 30, 0, 0); // 8:00 PM
|
||||
// get cart event or set default time for Sofia timezone
|
||||
const minTime = cartEvent?.startTime || DateTime.now().set({ hour: 8, minute: 0, second: 0, millisecond: 0, zone: 'Europe/Sofia' }).toJSDate();
|
||||
const maxTime = cartEvent?.endTime || DateTime.now().set({ hour: 20, minute: 0, second: 0, millisecond: 0, zone: 'Europe/Sofia' }).toJSDate();
|
||||
|
||||
useEffect(() => {
|
||||
setTimeSlots(generateTimeSlots(minTime, maxTime, 90, availabilities));
|
||||
setTimeSlots(generateTimeSlots(new Date(minTime), new Date(maxTime), cartEvent.shiftDuration, availabilities));
|
||||
console.log("AvailabilityForm: minTime: " + common.getTimeFormatted(minTime) + ", maxTime: " + common.getTimeFormatted(maxTime), ", " + cartEvent.shiftDuration + " min. shifts");
|
||||
}, []);
|
||||
|
||||
|
||||
@ -189,34 +189,11 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
||||
|
||||
// Common function to set shared properties
|
||||
function setSharedAvailabilityProperties(availability, group, timeSlots) {
|
||||
// Define a fixed offset for Sofia (+2 hours from UTC, ignoring DST)
|
||||
const fixedZone = FixedOffsetZone.instance(120); // Offset in minutes
|
||||
|
||||
// availability.startTime = group[0].startTime;
|
||||
// availability.endTime = group[group.length - 1].endTime;
|
||||
// Adjust start time
|
||||
let startTime = DateTime.fromJSDate(group[0].startTime, { zone: 'utc' })
|
||||
.setZone(fixedZone, { keepLocalTime: true });
|
||||
startTime = startTime.set({
|
||||
hour: group[0].startTime.getUTCHours(),
|
||||
minute: group[0].startTime.getUTCMinutes(),
|
||||
second: group[0].startTime.getUTCSeconds()
|
||||
});
|
||||
|
||||
// Adjust end time
|
||||
let endTime = DateTime.fromJSDate(group[group.length - 1].endTime, { zone: 'utc' })
|
||||
.setZone(fixedZone, { keepLocalTime: true });
|
||||
endTime = endTime.set({
|
||||
hour: group[group.length - 1].endTime.getUTCHours(),
|
||||
minute: group[group.length - 1].endTime.getUTCMinutes(),
|
||||
second: group[group.length - 1].endTime.getUTCSeconds()
|
||||
});
|
||||
|
||||
// Update the availability object with the new times
|
||||
availability.startTime = startTime.toJSDate();
|
||||
availability.endTime = endTime.toJSDate();
|
||||
|
||||
availability.name = common.getTimeFomatted(group[0].startTime) + "-" + common.getTimeFomatted(group[group.length - 1].endTime);
|
||||
let startTime = common.setTimeHHmm(new Date(availability.startTime || day), common.getTimeFormatted(group[0].startTime));
|
||||
let endTime = common.setTimeHHmm(new Date(availability.endTime || day), common.getTimeFormatted(group[group.length - 1].endTime));
|
||||
availability.startTime = startTime;
|
||||
availability.endTime = endTime;
|
||||
availability.name = common.getTimeFormatted(group[0].startTime) + "--" + common.getTimeFormatted(group[group.length - 1].endTime);
|
||||
|
||||
availability.isWithTransportIn = group[0].isFirst && timeSlots[0].isWithTransport;
|
||||
availability.isWithTransportOut = group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport;
|
||||
@ -308,27 +285,19 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
||||
let currentTime = start;
|
||||
|
||||
//const baseDate = new Date(Date.UTC(2000, 0, 1, 0, 0, 0));
|
||||
const baseDate = new Date(start);
|
||||
//const baseDate = new Date(start);
|
||||
|
||||
while (isBefore(currentTime, end)) {
|
||||
let slotStart = normalizeTime(currentTime, baseDate);
|
||||
let slotEnd = normalizeTime(addMinutes(currentTime, increment), baseDate);
|
||||
let slotStart = currentTime;
|
||||
let slotEnd = addMinutes(currentTime, increment);
|
||||
|
||||
const isChecked = items.some(item => {
|
||||
let itemStart = item.startTime ? normalizeTime(new Date(item.startTime), baseDate) : null;
|
||||
let itemEnd = item.endTime ? normalizeTime(new Date(item.endTime), baseDate) : null;
|
||||
|
||||
return itemStart && itemEnd &&
|
||||
(slotStart.getTime() < itemEnd.getTime()) &&
|
||||
(slotEnd.getTime() > itemStart.getTime());
|
||||
});
|
||||
|
||||
slots.push({
|
||||
startTime: slotStart,
|
||||
endTime: slotEnd,
|
||||
isChecked: isChecked,
|
||||
return item.startTime && item.endTime &&
|
||||
(slotStart.getTime() < item.endTime.getTime()) &&
|
||||
(slotEnd.getTime() > item.startTime.getTime());
|
||||
});
|
||||
|
||||
slots.push({ startTime: slotStart, endTime: slotEnd, isChecked: isChecked, });
|
||||
currentTime = addMinutes(currentTime, increment);
|
||||
}
|
||||
|
||||
@ -342,16 +311,6 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
||||
return slots;
|
||||
};
|
||||
|
||||
// Normalize the time part of a date by using a base date
|
||||
function normalizeTime(date, baseDate) {
|
||||
return set(baseDate, {
|
||||
hours: getHours(date),
|
||||
minutes: getMinutes(date),
|
||||
seconds: getSeconds(date),
|
||||
milliseconds: 0
|
||||
});
|
||||
}
|
||||
|
||||
const TimeSlotCheckboxes = ({ slots, setSlots, items: [] }) => {
|
||||
const [allDay, setAllDay] = useState(slots.every(slot => slot.isChecked));
|
||||
const handleAllDayChange = (e) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, use } from 'react';
|
||||
import { Calendar, momentLocalizer, dateFnsLocalizer } from 'react-big-calendar';
|
||||
import 'react-big-calendar/lib/css/react-big-calendar.css';
|
||||
import AvailabilityForm from '../availability/AvailabilityForm';
|
||||
@ -18,11 +18,13 @@ import { MdToday } from 'react-icons/md';
|
||||
|
||||
import { useSwipeable } from 'react-swipeable';
|
||||
import axiosInstance from '../../src/axiosSecure';
|
||||
import { set } from 'date-fns';
|
||||
import { get } from 'http';
|
||||
|
||||
// import { set, format, addDays } from 'date-fns';
|
||||
// import { isEqual, isSameDay, getHours, getMinutes } from 'date-fns';
|
||||
import { filter } from 'jszip';
|
||||
import e from 'express';
|
||||
// import { filter } from 'jszip';
|
||||
// import e from 'express';
|
||||
|
||||
|
||||
|
||||
@ -46,7 +48,7 @@ const messages = {
|
||||
// Any other labels you want to translate...
|
||||
};
|
||||
|
||||
const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
const AvCalendar = ({ publisherId, events, selectedDate, cartEvents }) => {
|
||||
|
||||
const isAdmin = ProtectedRoute.IsInRole(UserRole.ADMIN);
|
||||
|
||||
@ -65,7 +67,15 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
return { start, end };
|
||||
});
|
||||
|
||||
const [cartEvent, setCartEvent] = useState(null);
|
||||
function getCartEvent(date) {
|
||||
const dayOfWeek = common.getDayOfWeekNameEnEnumForDate(date);
|
||||
const ce = cartEvents?.find(e => e.dayofweek === dayOfWeek);
|
||||
return ce;
|
||||
}
|
||||
|
||||
useEffect(() => { setCartEvent(getCartEvent(date)); },
|
||||
[date, selectedEvents]);
|
||||
|
||||
// Update internal state when `events` prop changes
|
||||
useEffect(() => {
|
||||
@ -113,6 +123,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
//setDisplayedEvents(evts);
|
||||
}, [visibleRange, evts, currentView]);
|
||||
|
||||
// todo: review that
|
||||
const handlers = useSwipeable({
|
||||
onSwipedLeft: () => navigate('NEXT'),
|
||||
onSwipedRight: () => navigate('PREV'),
|
||||
@ -201,18 +212,13 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
return existingEvents;
|
||||
};
|
||||
|
||||
// Define min and max times
|
||||
const minHour = 8; // 8:00 AM
|
||||
const maxHour = 20; // 8:00 PM
|
||||
const minTime = new Date();
|
||||
minTime.setHours(minHour, 0, 0);
|
||||
const maxTime = new Date();
|
||||
maxTime.setHours(maxHour, 0, 0);
|
||||
const totalHours = maxHour - minHour;
|
||||
|
||||
// const totalHours = maxHour - minHour;
|
||||
|
||||
const handleSelect = ({ mode, start, end }) => {
|
||||
const startdate = typeof start === 'string' ? new Date(start) : start;
|
||||
const enddate = typeof end === 'string' ? new Date(end) : end;
|
||||
//we set the time to proper timezone
|
||||
const startdate = common.setTimezone(start);
|
||||
const enddate = common.setTimezone(end);
|
||||
|
||||
if (!start || !end) return;
|
||||
//readonly for past dates (ToDo: if not admin)
|
||||
@ -224,27 +230,10 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
end = common.setTimeHHmm(startdate, "23:59");
|
||||
}
|
||||
|
||||
const startMinutes = common.getTimeInMinutes(start);
|
||||
const endMinutes = common.getTimeInMinutes(end);
|
||||
|
||||
// Adjust start and end times to be within min and max hours
|
||||
if (startMinutes < common.getTimeInMinutes(common.setTimeHHmm(start, minHour))) {
|
||||
start = common.setTimeHHmm(start, minHour);
|
||||
}
|
||||
if (endMinutes > common.getTimeInMinutes(common.setTimeHHmm(end, maxHour))) {
|
||||
end = common.setTimeHHmm(end, maxHour);
|
||||
}
|
||||
|
||||
setDate(start);
|
||||
|
||||
// get exising events for the selected date
|
||||
//ToDo: properly fix this. filterEvents does not return the expcted results
|
||||
let existingEvents = filterEvents(evts, publisherId, startdate);
|
||||
// if existingEvents is empty - create new with the selected range
|
||||
// if (existingEvents.length === 0) {
|
||||
// existingEvents = [{ startTime: start, endTime: end }];
|
||||
// }
|
||||
console.log("handleSelect: " + existingEvents);
|
||||
setCartEvent(getCartEvent(date));
|
||||
setSelectedEvents(existingEvents);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
@ -509,8 +498,8 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
onSelectSlot={handleSelect}
|
||||
onSelectEvent={handleEventClick}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
min={minTime} // Set minimum time
|
||||
max={maxTime} // Set maximum time
|
||||
min={cartEvent?.startTime} // Set minimum time
|
||||
max={cartEvent?.endTime} // Set maximum time
|
||||
messages={messages}
|
||||
view={currentView}
|
||||
views={['month', 'week', 'agenda']}
|
||||
@ -541,6 +530,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
|
||||
date={date}
|
||||
onDone={handleDialogClose}
|
||||
inline={true}
|
||||
cartEvent={cartEvent}
|
||||
// Pass other props as needed
|
||||
/>
|
||||
</div>
|
||||
|
@ -69,8 +69,8 @@ export default function CartEventForm(props: IProps) {
|
||||
try {
|
||||
console.log("fetching cart event from component " + router.query.id);
|
||||
const { data } = await axiosInstance.get(urls.apiUrl + id);
|
||||
data.startTime = common.formatTimeHHmm(data.startTime)
|
||||
data.endTime = common.formatTimeHHmm(data.endTime)
|
||||
data.startTime = common.getTimeFormatted(data.startTime)
|
||||
data.endTime = common.getTimeFormatted(data.endTime)
|
||||
setEvt(data);
|
||||
|
||||
console.log("id:" + evt.id);
|
||||
|
@ -11,9 +11,15 @@ function PublisherSearchBox({ id, selectedId, onChange, isFocused, filterDate, s
|
||||
const [searchResults, setSearchResults] = useState([]);
|
||||
const [selectedDate, setSelectedDate] = useState(filterDate);
|
||||
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchPublishers();
|
||||
// }, []); // Empty dependency array ensures this useEffect runs only once
|
||||
|
||||
// Update publishers when filterDate or showList changes
|
||||
useEffect(() => {
|
||||
fetchPublishers();
|
||||
}, []); // Empty dependency array ensures this useEffect runs only once
|
||||
}, [filterDate, showList]);
|
||||
|
||||
const fetchPublishers = async () => {
|
||||
console.log("fetchPublishers called");
|
||||
@ -60,10 +66,7 @@ function PublisherSearchBox({ id, selectedId, onChange, isFocused, filterDate, s
|
||||
// console.log("filterDate changed = ", filterDate);
|
||||
// }, [filterDate]);
|
||||
|
||||
// Update publishers when filterDate or showList changes
|
||||
useEffect(() => {
|
||||
fetchPublishers();
|
||||
}, [filterDate, showList]);
|
||||
|
||||
|
||||
// Update selectedItem when selectedId changes and also at the initial load
|
||||
useEffect(() => {
|
||||
|
Reference in New Issue
Block a user