rewrite availability form

This commit is contained in:
Dobromir Popov
2024-03-03 02:52:41 +02:00
parent e52d962c49
commit 193dd91605
4 changed files with 229 additions and 314 deletions

View File

@ -1,70 +1,39 @@
import axiosInstance from '../../src/axiosSecure';
import { useEffect, useState } from "react";
import { useEffect, useState, useCallback } from "react";
import toast from "react-hot-toast";
import { useRouter } from "next/router";
import DayOfWeek from "../DayOfWeek";
const common = require('src/helpers/common');
import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';
// import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import TextField from '@mui/material/TextField';
import bg from 'date-fns/locale/bg'; // Bulgarian locale
import { bgBG } from '../x-date-pickers/locales/bgBG'; // Your custom translation file
import bg from 'date-fns/locale/bg';
import { bgBG } from '../x-date-pickers/locales/bgBG';
import { ToastContainer } from 'react-toastify';
import axios from 'axios';
const common = require('src/helpers/common');
const fetchConfig = async () => {
const config = await import('../../config.json');
return config.default;
};
/*
// ------------------ data model ------------------
model Availability {
id Int @id @default(autoincrement())
publisher Publisher @relation(fields: [publisherId], references: [id], onDelete: Cascade)
publisherId String
name String
dayofweek DayOfWeek
dayOfMonth Int?
weekOfMonth Int?
startTime DateTime
endTime DateTime
isactive Boolean @default(true)
type AvailabilityType @default(Weekly)
isWithTransport Boolean @default(false)
isFromPreviousAssignment Boolean @default(false)
isFromPreviousMonth Boolean @default(false)
repeatWeekly Boolean? // New field to indicate weekly repetition
repeatFrequency Int? // New field to indicate repetition frequency
endDate DateTime? // New field for the end date of repetition
export default function AvailabilityForm({ publisherId, existingItems, inline, onDone, date }) {
@@map("Availability")
}
const router = useRouter();
const urls = {
apiUrl: "/api/data/availabilities/",
indexUrl: "/cart/availabilities"
};
const [editMode, setEditMode] = useState(existingItems.length > 0);
const [publisher, setPublisher] = useState({ id: publisherId });
const [day, setDay] = useState(new Date(date || new Date()));
const [doRepeat, setDoRepeat] = useState(false);
const [repeatFrequency, setRepeatFrequency] = useState(1);
const [repeatUntil, setRepeatUntil] = useState(null);
const [canUpdate, setCanUpdate] = useState(true);
*/
//enum for abailability type - day of week or day of month; and array of values
const AvailabilityType = {
WeeklyRecurrance: 'WeeklyRecurrance',
ExactDate: 'ExactDate'
}
//const AvailabilityTypeValues = Object.values(AvailabilityType);
export default function AvailabilityForm({ publisherId, existingItem, inline, onDone, itemsForDay }) {
const [availability, setAvailability] = useState(existingItem || {
publisherId: publisherId || null,
const [timeSlots, setTimeSlots] = useState([]);
const [availabilities, setAvailabilities] = useState(existingItems && existingItems.length > 0 ? existingItems : [{
publisherId: publisher.id,
name: "Нов",
dayofweek: "Monday",
dayOfMonth: null,
@ -74,47 +43,20 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
repeatWeekly: false,
endDate: null,
isFirst: false,
});
const [items, setItems] = useState(itemsForDay || []); // [existingItem, ...items]
isLast: false,
}]);
const [selectedType, setSelectedOption] = useState(AvailabilityType.WeeklyRecurrance);
const [isInline, setInline] = useState(inline || false);
const [timeSlots, setTimeSlots] = useState([]);
const [isMobile, setIsMobile] = useState(false);
// Check screen width to determine if the device is mobile
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 768); // 768px is a common breakpoint for mobile devices
};
// Call the function to setAvailability the initial state
handleResize();
// Add event listener
window.addEventListener('resize', handleResize);
// Cleanup
return () => window.removeEventListener('resize', handleResize);
}, []);
// Inside your component
const [config, setConfig] = useState(null);
useEffect(() => {
fetchConfig().then(config => {
// Use config here to adjust form fields
console.log("UI config: ", config);
setConfig(config);
});
}, []);
const [dataFetched, setDataFetched] = useState(false);
const router = useRouter();
const initialId = existingItem?.id || router.query.id;
const urls = {
apiUrl: "/api/data/availabilities/",
indexUrl: "/cart/availabilities"
};
// Define the minimum and maximum times
const minTime = new Date();
@ -123,169 +65,162 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
maxTime.setHours(20, 0, 0, 0); // 8:00 PM
//always setAvailability publisherId
useEffect(() => {
availability.publisherId = publisherId;
console.log("availability.publisherId: ", availability.publisherId);
}, [availability]);
if (typeof window !== 'undefined') {
useEffect(() => {
// If component is not in inline mode and there's no existing availability, fetch the availability based on the query ID
// Fetch availability from DB only if it's not fetched yet, and there's no existing availability
if (!isInline && !existingItem && !dataFetched && router.query.id) {
fetchItemFromDB(parseInt(router.query.id.toString()));
setDataFetched(true); // Set data as fetched
const fetchItemFromDB = async () => {
const id = parseInt(router.query.id);
if (existingItems.length == 0 && id) {
try {
const response = await axiosInstance.get(`/api/data/availabilities/${id}`);
setAvailabilities([response.data]);
setEditMode(true);
} catch (error) {
console.error(error);
toast.error("Error fetching availability data.");
}
}
}, [router.query.id, isInline, existingItem, dataFetched]);
}
};
// const [isEdit, setIsEdit] = useState(false);
const fetchItemFromDB = async (id) => {
try {
console.log("fetching availability " + id);
const { data } = await axiosInstance.get(urls.apiUrl + id);
data.startTime = formatTime(data.startTime);
data.endTime = formatTime(data.endTime);
setAvailability(data);
console.log(data);
} catch (error) {
console.error(error);
}
};
fetchItemFromDB();
}, [router.query.id]);
const handleChange = ({ target }) => {
// const { name, value } = e.target;
// setItem((prev) => ({ ...prev, [name]: value }));
console.log("AvailabilityForm: handleChange: " + target.name + " = " + target.value);
setAvailability({ ...availability, [target.name]: target.value });
}
const handleSubmit = async (e) => {
e.preventDefault();
try {
const groupedTimeSlots = mergeCheckedTimeSlots(timeSlots);
// Determine if we need to delete and recreate, or just update
const shouldRecreate = availabilities.length !== groupedTimeSlots.length || availabilities.some(av => !av.id);
if (!availability.name) {
// availability.name = "От календара";
availability.name = common.getTimeFomatted(availability.startTime) + "-" + common.getTimeFomatted(availability.endTime);
}
if (shouldRecreate) {
// Delete existing availabilities if they have an ID
console.log("Recreating availabilities");
await Promise.all(availabilities.filter(av => av.id).map(av => axiosInstance.delete(`${urls.apiUrl}${av.id}`)));
availability.dayofweek = common.getDayOfWeekNameEnEnum(availability.startTime);
if (availability.repeatWeekly) {
availability.dayOfMonth = null;
// Create new availabilities
const createdAvailabilities = await Promise.all(groupedTimeSlots.map(async group => {
const newAvailability = createAvailabilityFromGroup(group, publisher.id);
const response = await axiosInstance.post(urls.apiUrl, newAvailability);
return response.data; // Assuming the new availability is returned
}));
setAvailabilities(createdAvailabilities);
} else {
availability.endDate = null;
availability.dayOfMonth = availability.startTime.getDate();
// Update existing availabilities
console.log("Updating existing availabilities");
const updatedAvailabilities = await Promise.all(availabilities.map(async (availability, index) => {
const group = groupedTimeSlots[index];
const updatedAvailability = updateAvailabilityFromGroup(availability, group);
await axiosInstance.put(`${urls.apiUrl}${availability.id}`, updatedAvailability);
return updatedAvailability;
}));
setAvailabilities(updatedAvailabilities);
}
delete availability.date; //remove date from availability as it is not part of the db model
// ---------------------- CB UI --------------
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]];
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) {
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) {
// 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
});
handleCompletion(availability);
handleCompletion({ updated: true });
} 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);
// 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);
// }
}
};
function mergeCheckedTimeSlots(timeSlots) {
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]];
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) {
groupedIntervals.push(currentGroup);
}
return groupedIntervals;
}
// const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport;
// const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport;
function createAvailabilityFromGroup(group) {
const startTime = new Date(day);
startTime.setTime(group[0].startTime)
const endTime = new Date(day);
endTime.setTime(group[group.length - 1].endTime);
return {
name: common.getTimeFomatted(startTime) + "-" + common.getTimeFomatted(endTime),
publisherId: publisher.id,
startTime: startTime,
endTime: endTime,
isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport,
isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport,
dayofweek: common.getDayOfWeekNameEnEnum(day.getDay()),
repeatWeekly: doRepeat,
dayOfMonth: doRepeat ? null : startTime.getDate(),
endDate: doRepeat ? repeatUntil : null,
};
}
function updateAvailabilityFromGroup(availability, group) {
availability.name = common.getTimeFomatted(startTime) + "-" + common.getTimeFomatted(endTime);
availability.startTime.setTime(group[0].startTime);
availability.endTime.setTime(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;
availability.repeatWeekly = doRepeat;
availability.dayOfMonth = doRepeat ? null : group.startTime.getDate();
availability.endDate = doRepeat ? repeatUntil : null;
return availability;
}
const handleDelete = async (e) => {
e.preventDefault();
try {
if (availability.id) {
// console.log("deleting publisher id = ", router.query.id, "; url=" + urls.apiUrl + router.query.id);
await axiosInstance.delete(urls.apiUrl + availability.id);
toast.success("Записът изтрит", {
position: "bottom-center",
});
handleCompletion({ deleted: true }); // Assuming handleCompletion is defined and properly handles post-deletion logic
const deletePromises = availabilities.map(async (availability) => {
if (availability.id) {
// console.log("deleting publisher id = ", router.query.id, "; url=" + urls.apiUrl + router.query.id);
await axiosInstance.delete(urls.apiUrl + availability.id);
}
});
await Promise.all(deletePromises);
toast.success("Записът изтрит", {
position: "bottom-center",
});
if (handleCompletion) {
handleCompletion({ deleted: true });
}
} catch (error) {
alert("Нещо се обърка при изтриването. Моля, опитайте отново или се свържете с нас");
@ -305,48 +240,53 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
}
}
console.log("AvailabilityForm: publisherId: " + availability.publisherId + ", id: " + availability.id, ", inline: " + isInline);
// console.log("AvailabilityForm: publisherId: " + publisher.id + ", id: " + availabilit .id, ", inline: " + isInline);
const generateTimeSlots = (start, end, increment, item) => {
const generateTimeSlots = (start, end, increment, items) => {
const slots = [];
// Ensure we're working with the correct date base
const baseDate = new Date(item?.startTime || new Date());
baseDate.setHours(start, 0, 0, 0); // Set start time on the base date
const baseDate = new Date(day || new Date());
baseDate.setHours(start, 0, 0, 0); // Initialize base date with start hour
let currentTime = baseDate.getTime();
const endDate = new Date(item?.startTime || new Date());
endDate.setHours(end, 0, 0, 0); // Set end time on the same date
// Assuming end time is the same for all items, otherwise, this logic needs adjustment
const endDate = new Date(day || new Date());
endDate.setHours(end, 0, 0, 0);
const endTime = endDate.getTime();
// Parse availability's startTime and endTime into Date objects for comparison
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
let slotEnd = new Date(currentTime + increment * 60 * 60 * 1000);
// Check if the slot overlaps with the availability's time range
const isChecked = slotStart < itemEndDate && slotEnd > itemStartDate;
// Determine if the slot is checked based on overlapping with any item time ranges
const isChecked = items.some(item => {
const itemStartTime = new Date(item.startTime);
const itemEndTime = new Date(item.endTime);
return slotStart < itemEndTime && slotEnd > itemStartTime;
});
slots.push({
startTime: slotStart,
endTime: slotEnd,
isChecked: isChecked,
});
currentTime += increment * 60 * 60 * 1000; // Move to the next slot
}
slots[0].isFirst = true;
slots[slots.length - 1].isLast = true;
slots[0].isWithTransport = item.isWithTransportIn;
slots[slots.length - 1].isWithTransport = item.isWithTransportOut;
currentTime += increment * 60 * 60 * 1000;
}
// Assign 'isFirst' and 'isLast' based on the slot's position in the array
if (slots.length > 0) {
slots[0].isFirst = true;
slots[slots.length - 1].isLast = true;
// Assuming isWithTransport flags are global settings, not unique per slot
slots[0].isWithTransport = items[0]?.isWithTransportIn;
slots[slots.length - 1].isWithTransport = items[items.length - 1]?.isWithTransportOut;
}
return slots;
};
const TimeSlotCheckboxes = ({ slots, setSlots, item }) => {
const TimeSlotCheckboxes = ({ slots, setSlots, items: [] }) => {
const [allDay, setAllDay] = useState(false);
const handleAllDayChange = (e) => {
@ -378,6 +318,10 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
if ((changedSlot.isFirst || changedSlot.isLast) && !changedSlot.isChecked) {
changedSlot.isWithTransport = false;
}
//if no slots are checked, disable Update button
const anyChecked = updatedSlots.some(slot => slot.isChecked);
setCanUpdate(anyChecked);
setSlots(updatedSlots);
};
@ -434,35 +378,34 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
};
useEffect(() => {
setTimeSlots(generateTimeSlots(9, 18, 1.5, availability));
setTimeSlots(generateTimeSlots(9, 18, 1.5, availabilities));
}, []);
return (
// <div style={{ width: isMobile ? '90%' : 'max-w-xs', margin: '0 auto' }} >
<div className="w-full">
<ToastContainer></ToastContainer>
<form id="formAv" className="form p-5 bg-white shadow-md rounded-lg" onSubmit={handleSubmit}>
<h3 className="text-xl font-semibold mb-5 text-gray-800 border-b pb-2">
{availability.id ? "Редактирай" : "Нова"} възможност
{editMode ? "Редактирай" : "Нова"} възможност
</h3>
<LocalizationProvider dateAdapter={AdapterDateFns} localeText={bgBG} adapterLocale={bg}>
<div className="mb-2">
<DatePicker label="Изберете дата" value={availability.startTime} onChange={(value) => setAvailability({ ...availability, endTime: value })} />
<DatePicker label="Изберете дата" value={day} onChange={(value) => setDay({ value })} />
</div>
<div>
<div className="mb-1">
{/* Time slot checkboxes */}
<TimeSlotCheckboxes slots={timeSlots} setSlots={setTimeSlots} item={availability} />
<TimeSlotCheckboxes slots={timeSlots} setSlots={setTimeSlots} items={availabilities} />
</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"
onChange={() => setAvailability({ ...availability, repeatWeekly: !availability.repeatWeekly })} />
<input type="checkbox" checked={doRepeat} className="form-checkbox h-5 w-5 text-gray-600 mx-2"
onChange={(e) => setDoRepeat(e.target.checked)} />
Повтаряй всяка {' '}
{/* {availability.repeatWeekly && (
{/* {repeatWeekly && (
<select
style={{
appearance: 'none',
@ -480,8 +423,8 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
// className="appearance-none border border-black bg-transparent px-1 py-0 mx-0 mr-1 h-auto text-base text-center text-current align-middle cursor-pointer"
//className="form-select mx-2 h-8 text-gray-600"
value={availability.repeatFrequency || 1}
onChange={(e) => setAvailability({ ...availability, repeatFrequency: parseInt(e.target.value, 10) })}
value={repeatFrequency || 1}
onChange={(e) => setRepeatFrequency(e.target.value)}
>
<option value="1">1</option>
<option value="2">2</option>
@ -494,33 +437,26 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on
</label>
</div>
{false && availability.repeatWeekly && (
{false && repeatWeekly && (
<div className="mb-2">
<DatePicker label="До" value={availability.endDate} onChange={(value) => setAvailability({ ...availability, endDate: value })} />
<DatePicker label="До" value={repeatUntil} onChange={(value) => setRepeatUntil({ value })} />
</div>
)}
</LocalizationProvider>
<div className="mb-2 hidden">
<div className="form-check">
<input className="checkbox form-input" type="checkbox" id="isactive" name="isactive" onChange={handleChange} checked={availability.isactive} autoComplete="off" />
<label className="label" htmlFor="isactive">активно</label>
</div>
</div>
{/* <input type="hidden" name="isactive" value={availability.isactive} /> */}
<div className="flex justify-between items-center flex-nowrap w-full p-1">
<button className="button border border-blue-500 text-blue-500 bg-transparent hover:text-white focus:outline-none focus:shadow-outline" onClick={() => handleCompletion()}> Отмени </button>
{availability.id && (
{editMode && (
<><button className="button btn-outline bg-red-500 hover:bg-red-700 focus:outline-none focus:shadow-outline" type="button" onClick={handleDelete}>
Изтрий
</button></>
)}
<button
className="button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline"
> {availability.id ? "Обнови" : "Запиши"}
className={`button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline ${!canUpdate ? 'opacity-50 cursor-not-allowed' : ''}`}
disabled={!canUpdate}
> {editMode ? "Обнови" : "Запиши"}
</button>
</div>
</form>

View File

@ -95,27 +95,19 @@ export default function AvailabilityList({ publisher, showNew }) {
<AvailabilityForm
publisherId={publisher.id}
inline={true}
existingItem={selectedItem}
existingItems={selectedItem ? [selectedItem] : []}
date={selectedItem ? new Date(selectedItem.startTime) : new Date()}
onDone={(item) => {
toggleAv();
setSelectedItem(null);
if (!item) {
// remove selected item from state
const updatedItems = items.filter(i => i.id !== selectedItem.id);
setItems([...updatedItems]);
return;
};
const itemIndex = items.findIndex(i => i.id === item.id); // assuming each item has a unique 'id' property
if (itemIndex !== -1) {
// Replace the existing item with the updated item
const updatedItems = [...items];
updatedItems[itemIndex] = item;
setItems(updatedItems);
} else {
// Append the new item to the end of the list
setItems([...items, item]);
}
//get the updated list of availabilities from the server
axiosInstance.get(common.getBaseUrl("/api/data/availabilities"))
.then(({ data: items }) => {
setItems(items);
})
.catch(error => {
console.error("Error getting availabilities:", error);
});
}}
/>
)}

View File

@ -16,6 +16,7 @@ import { MdToday } from 'react-icons/md';
import { useSwipeable } from 'react-swipeable';
import axiosInstance from '../../src/axiosSecure';
import { set } from 'date-fns';
// Set moment to use the Bulgarian locale
moment.locale('bg');
@ -43,7 +44,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
const [evts, setEvents] = useState(events); // Existing events
const [displayedEvents, setDisplayedEvents] = useState(evts); // Events to display in the calendar
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedEvent, setSelectedEvent] = useState(null);
const [selectedEvents, setSelectedEvents] = useState([]);
const [visibleRange, setVisibleRange] = useState(() => {
const start = new Date();
start.setDate(1); // Set to the first day of the current month
@ -182,18 +183,21 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
// get exising events for the selected date
const existingEvents = evts?.filter(event => event.publisherId === publisherId && event.startTime === start.toDateString());
setSelectedEvent({
date: start,
startTime: start,
endTime: end,
dayOfMonth: start.getDate(),
isactive: true,
publisherId: publisherId,
// Add any other initial values needed
//set dayOfMonth to null, so that we repeat the availability every week
dayOfMonth: null,
console.log("handleSelect: " + existingEvents);
setSelectedEvents(existingEvents);
});
// setSelectedEvent({
// date: start,
// startTime: start,
// endTime: end,
// dayOfMonth: start.getDate(),
// isactive: true,
// publisherId: publisherId,
// // Add any other initial values needed
// //set dayOfMonth to null, so that we repeat the availability every week
// dayOfMonth: null,
// });
setIsModalOpen(true);
};
@ -214,7 +218,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
delete eventForEditing.type;
delete eventForEditing.publisher
console.log("handleEventClick: " + eventForEditing);
setSelectedEvent(eventForEditing);
setSelectedEvents([eventForEditing]);
setIsModalOpen(true);
};
@ -223,22 +227,6 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
setIsModalOpen(false);
if (dialogEvent === null || dialogEvent === undefined) {
} else {
// if (dialogEvent.deleted) {
// // Remove the old event from the calendar
// setEvents(currentEvents => currentEvents.filter(e => e.id !== selectedEvent.id));
// }
// else {
// // Update the event data
// dialogEvent.start = dialogEvent.startTime;
// dialogEvent.end = dialogEvent.endTime;
// // Update the events array by first removing the old event and then adding the updated one
// setEvents(currentEvents => {
// const filteredEvents = currentEvents?.filter(e => e.id !== selectedEvent.id) || [];
// return [...filteredEvents, dialogEvent];
// });
// }
//refresh the events from the server
let e = await axiosInstance.get(`/api/?action=getCalendarEvents&publisherId=${publisherId}`);
var newEvents = e.data;
// set start and end to Date objects for all events. Fix for the calendar component
@ -468,7 +456,8 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
<div className="modal-content">
<AvailabilityForm
publisherId={publisherId}
existingItem={selectedEvent}
existingItems={selectedEvents}
date={date}
onDone={handleDialogClose}
inline={true}
// Pass other props as needed