im building a calendar using react, redux, firebase and react big calendar. On the main page i have 2 calendars that are the same but connected to a different collection in firebase each one. In the redux extension it shows me the activeEvent (the info of the event, when its clicked) but when i do a console.log(activeEvent) in the function that triggers the activeEvent i get undefined


the calendarSlice:
name: "calendar",
initialState: {
events: {},
activeEvent: null,
isLoadingEvents: true,
},
reducers: {
onSetActiveEvent: (state, { payload }) => {
state.activeEvent = payload;
},
onAddEvent: (state, { payload }) => {
if (!state.events[payload.calendarId]) {
state.events[payload.calendarId] = [];
}
state.events[payload.calendarId].push(payload.event);
state.activeEvent = null;
},
onUpdateEvent: (state, { payload }) => {
state.events[payload.calendarId] = state.events[payload.calendarId].map((event) =>
event.id === payload.event.id ? payload.event : event
);
},
onDeleteEvent: (state) => {
if (state.activeEvent?.calendarId) {
state.events[state.activeEvent.calendarId] = state.events[state.activeEvent.calendarId]
.filter((event) => event._id !== state.activeEvent._id);
state.activeEvent = null;
}
},
setEvent: (state, { payload }) => {
state.events[payload.calendarId] = payload.events;
},
useCalendarStore:
const useCalendarStore = (nombre) => {
const dispatch = useDispatch();
const { events, activeEvent } = useSelector((state) => state.calendar.events);
const calendars = useSelector(state => state.calendar.events[`${nombre}`]);
const setActiveEvent = (activeEvent) => {
dispatch(onSetActiveEvent(activeEvent));
};
const startLoadingEvents = async () => {
const querySnapshot = await getDocs(collection(db, `${nombre}`));
const events = [];
querySnapshot.forEach((doc) => {
events.push({
id: doc.id,
start: doc.data().start.toDate(),
end: doc.data().end.toDate(),
title: doc.data().title,
notes: doc.data().notes,
});
});
dispatch(setEvent({ calendarId: nombre, events }));
};
const startSavingEvent = async (calendarEvent) => {
if (calendarEvent.id) {
dispatch(onUpdateEvent({ ...calendarEvent }));
const docRef = doc(db, `/${nombre}/${calendarEvent.id}`)
await (setDoc(docRef, calendarEvent, {merge:true}))
} else {
const docRef = await addDoc(collection(db, `${nombre}`), {
...calendarEvent,
_id: new Date().getTime(),
});
dispatch(onAddEvent({ calendarId: nombre, events }));
}
};
const deleteEvent = async () => {
deleteDoc(doc(db, `/${nombre}/${activeEvent.id}`));
dispatch(onDeleteEvent());
};
github: https://github.com/guidomora/peluqueria-new-calendar.git
deploy: https://peluqueria-new-calendar.vercel.app/
Based on the suggested changes to the calendarSlice code to handle storing multiple calendars, you'll need to also pass that calendarId in the dispatched actions.
The stored state.calendar.activeEvent should have the following type:
{ calendar: string; event: Event; } | null
where Event is:
{
id: string;
start: string;
end: string;
title: string;
notes: string;
}
Pass the nombre as the calendarId and activeEvent as the event you want to set as the active event in state.
const setActiveEvent = (activeEvent) => {
dispatch(onSetActiveEvent({
calendarId: nombre,
event: activeEvent,
}));
};
The delete action should reference the calendarId and event properties of the state.activeEvent to reference the correct events calendar and event array element to remove.
const deleteEvent = async () => {
// activeEvent is potentially null, so guard null accesses
if (activeEvent?.event.id) {
deleteDoc(doc(db, `/${nombre}/${activeEvent.event.id}`));
dispatch(onDeleteEvent());
}
};
onDeleteEvent: (state) => {
if (state.activeEvent?.calendarId) {
state.events[state.activeEvent.calendarId] = state.events[state.activeEvent.calendarId]
.filter((event) => event.id !== state.activeEvent.event.id);
state.activeEvent = null;
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With