131 lines
4.0 KiB
React
131 lines
4.0 KiB
React
import React, { useCallback, useState } from 'react'
|
|
import { Calendar, dayjsLocalizer } from 'react-big-calendar'
|
|
import dayjs from 'dayjs'
|
|
|
|
import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop'
|
|
|
|
|
|
|
|
const localizer = dayjsLocalizer(dayjs)
|
|
|
|
const DnDCalendar = withDragAndDrop(Calendar)
|
|
|
|
export default function EventCalendar({draggedEvent, setDraggedEvent}) {
|
|
const myEventsList = []
|
|
const [myEvents, setMyEvents] = useState(myEventsList)
|
|
|
|
const moveEvent = useCallback(
|
|
({ event, start, end, isAllDay: droppedOnAllDaySlot = false }) => {
|
|
// console.log('yes')
|
|
const { allDay } = event
|
|
if (!allDay && droppedOnAllDaySlot) {
|
|
event.allDay = true
|
|
}
|
|
if (allDay && !droppedOnAllDaySlot) {
|
|
event.allDay = false;
|
|
}
|
|
|
|
setMyEvents((prev) => {
|
|
const existing = prev.find((ev) => ev.id === event.id) ?? {}
|
|
const filtered = prev.filter((ev) => ev.id !== event.id)
|
|
return [...filtered, { ...existing, start, end, allDay: event.allDay }]
|
|
// return [...prev, { ...event }]
|
|
})
|
|
},
|
|
[setMyEvents]
|
|
)
|
|
|
|
const [displayDragItemInCell, setDisplayDragItemInCell] = useState(true)
|
|
|
|
|
|
const dragFromOutsideItem = useCallback(() => draggedEvent === 'undroppable' ? null : draggedEvent, [draggedEvent])
|
|
|
|
const customOnDragOverFromOutside = useCallback(
|
|
(dragEvent) => {
|
|
// check for undroppable is specific to this example
|
|
// and not part of API. This just demonstrates that
|
|
// onDragOver can optionally be passed to conditionally
|
|
// allow draggable items to be dropped on cal, based on
|
|
// whether event.preventDefault is called
|
|
if (draggedEvent !== 'undroppable') {
|
|
console.log('preventDefault')
|
|
dragEvent.preventDefault()
|
|
}
|
|
},
|
|
[draggedEvent]
|
|
)
|
|
|
|
|
|
const eventPropGetter = useCallback(
|
|
(event) => ({
|
|
...(event.isDraggable
|
|
? { className: 'isDraggable' }
|
|
: { className: 'nonDraggable' }),
|
|
}),
|
|
[]
|
|
)
|
|
|
|
const newEvent = useCallback(
|
|
(event) => {
|
|
setMyEvents((prev) => {
|
|
const idList = prev.map((item) => item.id)
|
|
const newId = Math.max(...idList) + 1
|
|
return [...prev, { ...event, id: newId }]
|
|
})
|
|
},
|
|
[setMyEvents]
|
|
)
|
|
|
|
const onDropFromOutside = useCallback(
|
|
({ start, end, allDay: isAllDay }) => {
|
|
if (draggedEvent === 'undroppable') {
|
|
setDraggedEvent(null)
|
|
return
|
|
}
|
|
|
|
const { title } = draggedEvent
|
|
const event = {
|
|
title: title,
|
|
start,
|
|
end,
|
|
isAllDay,
|
|
}
|
|
setDraggedEvent(null)
|
|
newEvent(event)
|
|
},
|
|
[draggedEvent, setDraggedEvent, newEvent]
|
|
)
|
|
|
|
const resizeEvent = useCallback(
|
|
({ event, start, end }) => {
|
|
setMyEvents((prev) => {
|
|
const existing = prev.find((ev) => ev.id === event.id) ?? {}
|
|
const filtered = prev.filter((ev) => ev.id !== event.id)
|
|
return [...filtered, { ...existing, start, end }]
|
|
})
|
|
},
|
|
[setMyEvents]
|
|
)
|
|
|
|
return (
|
|
<div className='w-100'>
|
|
<DnDCalendar
|
|
dragFromOutsideItem={
|
|
displayDragItemInCell ? dragFromOutsideItem : null
|
|
}
|
|
eventPropGetter={eventPropGetter}
|
|
// draggableAccessor="isDraggable"
|
|
localizer={localizer}
|
|
events={myEvents}
|
|
startAccessor="start"
|
|
endAccessor="end"
|
|
style={{ height: 500 }}
|
|
// onEventResize={resizeEvent}
|
|
resizable
|
|
onEventDrop={moveEvent}
|
|
onDropFromOutside={onDropFromOutside}
|
|
// onDragOverFromOutside={customOnDragOverFromOutside}
|
|
/>
|
|
</div>
|
|
)
|
|
} |