fix calendar, separate AvForm UI
This commit is contained in:
@ -16,6 +16,7 @@ import bg from 'date-fns/locale/bg'; // Bulgarian locale
|
||||
|
||||
import { bgBG } from '../x-date-pickers/locales/bgBG'; // Your custom translation file
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
|
||||
@ -181,123 +182,98 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
|
||||
|
||||
delete availability.date; //remove date from availability as it is not part of the db model
|
||||
// ---------------------- CB UI --------------
|
||||
if (config.checkboxUI.enabled) {
|
||||
const selectedSlots = timeSlots.filter(slot => slot.isChecked);
|
||||
// Sort the selected intervals by start time
|
||||
const sortedSlots = [...selectedSlots].sort((a, b) => a.startTime - b.startTime);
|
||||
const selectedSlots = timeSlots.filter(slot => slot.isChecked);
|
||||
// Sort the selected intervals by start time
|
||||
const sortedSlots = [...selectedSlots].sort((a, b) => a.startTime - b.startTime);
|
||||
|
||||
// Group continuous slots
|
||||
const groupedIntervals = [];
|
||||
let currentGroup = [sortedSlots[0]];
|
||||
// Group continuous slots
|
||||
const groupedIntervals = [];
|
||||
let currentGroup = [sortedSlots[0]];
|
||||
|
||||
for (let i = 1; i < sortedSlots.length; i++) {
|
||||
const previousSlot = currentGroup[currentGroup.length - 1];
|
||||
const currentSlot = sortedSlots[i];
|
||||
// Calculate the difference in hours between slots
|
||||
const difference = (currentSlot.startTime - previousSlot.endTime) / (60 * 60 * 1000);
|
||||
for (let i = 1; i < sortedSlots.length; i++) {
|
||||
const previousSlot = currentGroup[currentGroup.length - 1];
|
||||
const currentSlot = sortedSlots[i];
|
||||
// Calculate the difference in hours between slots
|
||||
const difference = (currentSlot.startTime - previousSlot.endTime) / (60 * 60 * 1000);
|
||||
|
||||
// Assuming each slot represents an exact match to the increment (1.5 hours), we group them
|
||||
if (difference === 0) {
|
||||
currentGroup.push(currentSlot);
|
||||
} else {
|
||||
groupedIntervals.push(currentGroup);
|
||||
currentGroup = [currentSlot];
|
||||
}
|
||||
}
|
||||
// Don't forget the last group
|
||||
if (currentGroup.length > 0) {
|
||||
// Assuming each slot represents an exact match to the increment (1.5 hours), we group them
|
||||
if (difference === 0) {
|
||||
currentGroup.push(currentSlot);
|
||||
} else {
|
||||
groupedIntervals.push(currentGroup);
|
||||
currentGroup = [currentSlot];
|
||||
}
|
||||
|
||||
// Create availability objects from grouped slots
|
||||
const availabilities = groupedIntervals.map(group => {
|
||||
const startTime = group[0].startTime;
|
||||
const endTime = group[group.length - 1].endTime;
|
||||
return {
|
||||
publisherId: availability.publisherId,
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport,
|
||||
isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport,
|
||||
// Add other necessary fields, like isWithTransport if applicable
|
||||
};
|
||||
});
|
||||
|
||||
//if more than one interval, we delete and recreate the availability, as it is not possble to map them
|
||||
if (availability.id && availabilities.length > 1) {
|
||||
await axiosInstance.delete(urls.apiUrl + availability.id);
|
||||
delete availability.id;
|
||||
}
|
||||
|
||||
// const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport;
|
||||
// const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport;
|
||||
|
||||
availabilities.forEach(async av => {
|
||||
// expand availability
|
||||
const avToStore = {
|
||||
...availability,
|
||||
...av,
|
||||
startTime: av.startTime,
|
||||
endTime: av.endTime,
|
||||
name: "От календара",
|
||||
id: undefined,
|
||||
|
||||
// isWithTransportIn: firstSlotWithTransport,
|
||||
// isWithTransportOut: lastSlotWithTransport,
|
||||
|
||||
};
|
||||
console.log("AvailabilityForm: handleSubmit: " + av);
|
||||
if (availability.id) {
|
||||
// UPDATE EXISTING ITEM
|
||||
await axiosInstance.put(urls.apiUrl + availability.id, {
|
||||
...avToStore,
|
||||
});
|
||||
} else {
|
||||
// CREATE NEW ITEM
|
||||
await axiosInstance.post(urls.apiUrl, avToStore);
|
||||
}
|
||||
handleCompletion(avToStore); // Assuming `handleCompletion` is defined to handle post-save logic
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
// ---------------------- TimePicker UI --------------
|
||||
else {
|
||||
availability.publisher = { connect: { id: availability.publisherId } };
|
||||
delete availability.publisherId;
|
||||
// Don't forget the last group
|
||||
if (currentGroup.length > 0) {
|
||||
groupedIntervals.push(currentGroup);
|
||||
}
|
||||
|
||||
// Create availability objects from grouped slots
|
||||
const availabilities = groupedIntervals.map(group => {
|
||||
const startTime = group[0].startTime;
|
||||
const endTime = group[group.length - 1].endTime;
|
||||
return {
|
||||
publisherId: availability.publisherId,
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport,
|
||||
isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport,
|
||||
// Add other necessary fields, like isWithTransport if applicable
|
||||
};
|
||||
});
|
||||
|
||||
//if more than one interval, we delete and recreate the availability, as it is not possble to map them
|
||||
if (availability.id && availabilities.length > 1) {
|
||||
await axiosInstance.delete(urls.apiUrl + availability.id);
|
||||
delete availability.id;
|
||||
}
|
||||
|
||||
// const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport;
|
||||
// const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport;
|
||||
|
||||
availabilities.forEach(async av => {
|
||||
// expand availability
|
||||
const avToStore = {
|
||||
...availability,
|
||||
...av,
|
||||
startTime: av.startTime,
|
||||
endTime: av.endTime,
|
||||
name: "От календара",
|
||||
id: undefined,
|
||||
|
||||
// isWithTransportIn: firstSlotWithTransport,
|
||||
// isWithTransportOut: lastSlotWithTransport,
|
||||
|
||||
};
|
||||
console.log("AvailabilityForm: handleSubmit: " + av);
|
||||
if (availability.id) {
|
||||
console.log('editing avail# ' + availability.id);
|
||||
//delete availability.id;
|
||||
|
||||
// UPDATE EXISTING ITEM
|
||||
var itemUpdate = { ...availability, id: undefined };
|
||||
await axiosInstance.put(urls.apiUrl + availability.id, {
|
||||
...itemUpdate,
|
||||
});
|
||||
toast.success("Task Updated", {
|
||||
position: "bottom-center",
|
||||
...avToStore,
|
||||
});
|
||||
} else {
|
||||
// CREATE NEW ITEM
|
||||
console.log('creating new avail: ' + availability);
|
||||
const response = await axiosInstance.post(urls.apiUrl, availability);
|
||||
const createdItem = response.data;
|
||||
availability.id = createdItem.id;
|
||||
toast.success("Task Saved", {
|
||||
position: "bottom-center",
|
||||
});
|
||||
await axiosInstance.post(urls.apiUrl, avToStore);
|
||||
}
|
||||
}
|
||||
handleCompletion(avToStore); // Assuming `handleCompletion` is defined to handle post-save logic
|
||||
});
|
||||
|
||||
handleCompletion(availability);
|
||||
} catch (error) {
|
||||
alert("Нещо се обърка. Моля, опитайте отново по-късно.");
|
||||
toast.error("Нещо се обърка. Моля, опитайте отново по-късно.");
|
||||
console.error(error.message);
|
||||
}
|
||||
};
|
||||
try {
|
||||
const { data: session, status } = useSession();
|
||||
const userId = session.user.id;
|
||||
axiosInstance.post('/log', { message: error.message, userId: userId });
|
||||
}
|
||||
catch (err) {
|
||||
console.error("Error logging error: ", err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const handleDelete = async (e) => {
|
||||
e.preventDefault();
|
||||
@ -346,7 +322,6 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
|
||||
const itemStartDate = new Date(item?.startTime);
|
||||
const itemEndDate = new Date(item?.endTime);
|
||||
|
||||
|
||||
while (currentTime < endTime) {
|
||||
let slotStart = new Date(currentTime);
|
||||
let slotEnd = new Date(currentTime + increment * 60 * 60 * 1000); // Calculate slot end time
|
||||
@ -370,7 +345,6 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
|
||||
return slots;
|
||||
};
|
||||
|
||||
|
||||
const TimeSlotCheckboxes = ({ slots, setSlots, item }) => {
|
||||
const [allDay, setAllDay] = useState(false);
|
||||
|
||||
@ -474,39 +448,13 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
|
||||
<div className="mb-2">
|
||||
<DatePicker label="Изберете дата" value={availability.startTime} onChange={(value) => setAvailability({ ...availability, endTime: value })} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{config?.checkboxUI && config.checkboxUI.enabled ? (
|
||||
<div className="mb-1">
|
||||
{/* Time slot checkboxes */}
|
||||
<TimeSlotCheckboxes slots={timeSlots} setSlots={setTimeSlots} item={availability} />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Start Time Picker */}
|
||||
<div className="mb-2">
|
||||
<MobileTimePicker label="От" minutesStep={15} value={availability.startTime} minTime={minTime} maxTime={maxTime}
|
||||
onChange={(value) => setAvailability({ ...availability, startTime: value })} />
|
||||
</div>
|
||||
|
||||
{/* End Time Picker */}
|
||||
<div className="mb-2">
|
||||
<MobileTimePicker label="До" minutesStep={15} value={availability.endTime} minTime={minTime} maxTime={maxTime}
|
||||
onChange={(value) => setAvailability({ ...availability, endTime: value })} />
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<label className="checkbox-container">
|
||||
<input type="checkbox" checked={availability.isWithTransport} className="form-checkbox h-5 w-5 text-gray-600 mx-2"
|
||||
onChange={() => setAvailability({ ...availability, isWithTransport: !availability.isWithTransport })} />
|
||||
мога да взема/върна количките
|
||||
<span className="checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="mb-1">
|
||||
{/* Time slot checkboxes */}
|
||||
<TimeSlotCheckboxes slots={timeSlots} setSlots={setTimeSlots} item={availability} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="mb-2">
|
||||
<label className="checkbox-container">
|
||||
<input type="checkbox" checked={availability.repeatWeekly} className="form-checkbox h-5 w-5 text-gray-600 mx-2"
|
||||
@ -577,4 +525,3 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user