calendar component added
This commit is contained in:
@@ -12,8 +12,10 @@
|
|||||||
"apexcharts": "^4.1.0",
|
"apexcharts": "^4.1.0",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-apexcharts": "^1.7.0",
|
"react-apexcharts": "^1.7.0",
|
||||||
|
"react-big-calendar": "^1.17.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-icons": "^5.4.0",
|
"react-icons": "^5.4.0",
|
||||||
"react-redux": "^9.1.2",
|
"react-redux": "^9.1.2",
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
import React from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
|
||||||
|
import EventCalendar from "./EventCalendar";
|
||||||
|
|
||||||
|
|
||||||
export default function Calendar(){
|
export default function Calendar(){
|
||||||
|
|
||||||
|
const [draggedEvent, setDraggedEvent] = useState()
|
||||||
|
const handleDragStart = useCallback((event) => setDraggedEvent(event), [])
|
||||||
|
|
||||||
|
const formatName = (name) => `${name}`
|
||||||
|
|
||||||
|
const dummyEvents = [
|
||||||
|
{id: '1', name: 'Family Vacation', color: 'fc-event-primary'},
|
||||||
|
{id: '2', name: 'Meeting In Office', color: 'fc-event-warning'},
|
||||||
|
{id: '3', name: 'Client Call', color: 'fc-event-danger'},
|
||||||
|
{id: '4', name: 'Interview', color: 'fc-event-success'}
|
||||||
|
]
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<BreadcrumbComBS title='Calendar' paths={['Dashboard', 'Calendar']} />
|
<BreadcrumbComBS title='Calendar' paths={['Dashboard', 'Calendar']} />
|
||||||
@@ -26,20 +39,16 @@ export default function Calendar(){
|
|||||||
<p className="mt-3">
|
<p className="mt-3">
|
||||||
Drag and drop your event or click in the calendar.
|
Drag and drop your event or click in the calendar.
|
||||||
</p>
|
</p>
|
||||||
<div className="fc-event fc-event-primary" data-color="fc-event-primary">
|
{dummyEvents.map(item => (
|
||||||
<span></span> Family
|
<div className={`fc-event ${item.color}`} data-color={`${item.color}`}
|
||||||
Vacation
|
// draggable="true"
|
||||||
</div>
|
onDragStart={() =>
|
||||||
<div className="fc-event fc-event-warning" data-color="fc-event-warning">
|
handleDragStart({ title: formatName(item.name)})
|
||||||
<span></span> Meeting In
|
}
|
||||||
Office
|
>
|
||||||
</div>
|
<span></span> {item.name}
|
||||||
<div className="fc-event fc-event-danger" data-color="fc-event-danger">
|
</div>
|
||||||
<span></span> Client Call
|
))}
|
||||||
</div>
|
|
||||||
<div className="fc-event fc-event-success" data-color="fc-event-success">
|
|
||||||
<span></span> Interview
|
|
||||||
</div>
|
|
||||||
<div className="form-check">
|
<div className="form-check">
|
||||||
<input className="form-check-input" type="checkbox" value=""
|
<input className="form-check-input" type="checkbox" value=""
|
||||||
id="defaultCheck1" />
|
id="defaultCheck1" />
|
||||||
@@ -51,7 +60,7 @@ export default function Calendar(){
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-xl-9">
|
<div className="col-xl-9">
|
||||||
<div className="event-calendar">
|
<div className="event-calendar">
|
||||||
<div id="event-calendar"></div>
|
<EventCalendar draggedEvent={draggedEvent} setDraggedEvent={setDraggedEvent} formatName={formatName} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
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, formatName}) {
|
||||||
|
const myEventsList = []
|
||||||
|
const [myEvents, setMyEvents] = useState(myEventsList)
|
||||||
|
|
||||||
|
const moveEvent = useCallback(
|
||||||
|
({ event, start, end, isAllDay: droppedOnAllDaySlot = false }) => {
|
||||||
|
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 }]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[setMyEvents]
|
||||||
|
)
|
||||||
|
|
||||||
|
const [displayDragItemInCell, setDisplayDragItemInCell] = useState(true)
|
||||||
|
const [counters, setCounters] = useState({ item1: 0, item2: 0 })
|
||||||
|
|
||||||
|
const eventPropGetter = useCallback(
|
||||||
|
(event) => ({
|
||||||
|
...(event.isDraggable
|
||||||
|
? { className: 'isDraggable' }
|
||||||
|
: { className: 'nonDraggable' }),
|
||||||
|
}),
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
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 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 { name } = draggedEvent
|
||||||
|
const event = {
|
||||||
|
title: formatName(name, counters[name]),
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
isAllDay,
|
||||||
|
}
|
||||||
|
setDraggedEvent(null)
|
||||||
|
setCounters((prev) => {
|
||||||
|
const { [name]: count } = prev
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[name]: count + 1,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
newEvent(event)
|
||||||
|
},
|
||||||
|
[draggedEvent, counters, setDraggedEvent, setCounters, 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
|
||||||
|
}
|
||||||
|
draggableAccessor="isDraggable"
|
||||||
|
eventPropGetter={eventPropGetter}
|
||||||
|
localizer={localizer}
|
||||||
|
events={myEvents}
|
||||||
|
startAccessor="start"
|
||||||
|
endAccessor="end"
|
||||||
|
style={{ height: 500 }}
|
||||||
|
onEventDrop={moveEvent}
|
||||||
|
onDropFromOutside={onDropFromOutside}
|
||||||
|
onDragOverFromOutside={customOnDragOverFromOutside}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -83,6 +83,10 @@
|
|||||||
@import "pages/employees";
|
@import "pages/employees";
|
||||||
@import "pages/coming-soon";
|
@import "pages/coming-soon";
|
||||||
|
|
||||||
|
// THIS IMPORTS ARE FOR THE CALENDAR PACKAGE - PLEASE DO NOT REMOVE
|
||||||
|
@import 'react-big-calendar/lib/sass/styles';
|
||||||
|
@import 'react-big-calendar/lib/addons/dragAndDrop/styles'; // if using DnD
|
||||||
|
|
||||||
.extraProductCard{
|
.extraProductCard{
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|||||||
Reference in New Issue
Block a user