calendar.view.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import React, { Component } from 'react';
  2. import ContentWrapper from '@/components/Layout/ContentWrapper';
  3. import { Card, CardBody, CardHeader, CardTitle } from 'reactstrap';
  4. import FullCalendar from '@fullcalendar/react';
  5. import dayGridPlugin from '@fullcalendar/daygrid';
  6. import timeGridPlugin from '@fullcalendar/timegrid';
  7. import interactionPlugin, { Draggable } from '@fullcalendar/interaction';
  8. import listPlugin from '@fullcalendar/list';
  9. import bootstrapPlugin from '@fullcalendar/bootstrap';
  10. import '@fullcalendar/core/main.css';
  11. import '@fullcalendar/daygrid/main.css';
  12. import '@fullcalendar/timegrid/main.css';
  13. import '@fullcalendar/list/main.css';
  14. import '@fullcalendar/bootstrap/main.css';
  15. import events from './calendar.events';
  16. class Calendar extends Component {
  17. calendarEvents = events;
  18. calendarPlugins = [
  19. interactionPlugin,
  20. dayGridPlugin,
  21. timeGridPlugin,
  22. listPlugin,
  23. bootstrapPlugin
  24. ];
  25. calendarHeader = {
  26. left: 'prev,next today',
  27. center: 'title',
  28. right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
  29. };
  30. // External events properties
  31. evColors = [
  32. 'danger',
  33. 'primary',
  34. 'info',
  35. 'success',
  36. 'warning',
  37. 'green',
  38. 'pink',
  39. 'inverse',
  40. 'purple'
  41. ];
  42. state = {
  43. selectedEvent: null,
  44. evRemoveOnDrop: true,
  45. evSelectedColor: this.evColors[0],
  46. evNewName: '',
  47. _externalEvents: [
  48. { color: 'green', name: 'Lunch' },
  49. { color: 'danger', name: 'Go home' },
  50. { color: 'info', name: 'Do homework' },
  51. { color: 'warning', name: 'Work on UI design' },
  52. { color: 'inverse', name: 'Sleep tight' }
  53. ],
  54. externalEvents:[
  55. { color: 'info', name: 'Jadwal Pemeriksaan - BI:54678' }
  56. ]
  57. };
  58. componentDidMount() {
  59. /* initialize the external events */
  60. new Draggable(this.refs.externalEventsList, {
  61. itemSelector: '.fce-event',
  62. eventData: function(eventEl) {
  63. return {
  64. title: eventEl.innerText.trim()
  65. };
  66. }
  67. });
  68. }
  69. addRandomEvent() {
  70. // add dynamically an event
  71. this.addEvent({
  72. title: 'Random Event',
  73. start: new Date(
  74. new Date().getFullYear(),
  75. new Date().getMonth(),
  76. Math.random() * (30 - 1) + 1
  77. ),
  78. backgroundColor: '#c594c5', //purple
  79. borderColor: '#c594c5' //purple
  80. });
  81. }
  82. dayClick = date => {
  83. this.setState({
  84. selectedEvent: {
  85. date: date.dateStr
  86. }
  87. });
  88. };
  89. // add event directly into calendar
  90. addEvent(event) {
  91. this.calendarEvents.push(event);
  92. }
  93. handleEventReceive = info => {
  94. var styles = getComputedStyle(info.draggedEl);
  95. info.event.setProp('backgroundColor', styles.backgroundColor);
  96. info.event.setProp('borderColor', styles.borderColor);
  97. // is the "remove after drop" checkbox checked?
  98. if (this.state.evRemoveOnDrop) {
  99. this.removeExternalEvent(info.draggedEl.textContent);
  100. }
  101. };
  102. getEvColorClasses(evcolor) {
  103. return 'bg-' + evcolor + (this.state.evSelectedColor === evcolor ? ' selected' : '');
  104. }
  105. addNewExternalEvent = () => {
  106. const externalEvents = this.state.externalEvents.concat({
  107. color: this.state.evSelectedColor,
  108. name: this.state.evNewName
  109. });
  110. this.setState({
  111. externalEvents
  112. });
  113. };
  114. removeExternalEvent = name => {
  115. let externalEvents = [...this.state.externalEvents];
  116. const index = externalEvents.findIndex(e => e.name === name);
  117. if (index > -1) {
  118. externalEvents.splice(index, 1);
  119. this.setState({
  120. externalEvents
  121. });
  122. }
  123. };
  124. selectColor = color => () => {
  125. this.setState({
  126. evSelectedColor: color
  127. });
  128. };
  129. handleCheck = event => {
  130. this.setState({
  131. //evRemoveOnDrop: event.target.checked
  132. evRemoveOnDrop: true
  133. });
  134. };
  135. handleInputName = event => {
  136. this.setState({
  137. evNewName: event.target.value
  138. });
  139. };
  140. render() {
  141. const { externalEvents, selectedEvent } = this.state;
  142. return (
  143. <ContentWrapper>
  144. <div className="content-heading">
  145. <div>
  146. Jadwal Pemeriksaan
  147. <small>Format pembuatan jadwal pemeriksaan v.0.1</small>
  148. </div>
  149. </div>
  150. <div className="calendar-app">
  151. <div className="row">
  152. <div className="col-xl-3 col-lg-4">
  153. <div className="row">
  154. <div className="col-lg-12 col-md-6 col-12">
  155. {/* START card */}
  156. <Card className="card-default" title="">
  157. <CardHeader>
  158. <CardTitle tag="h4">Draggable Events</CardTitle>
  159. </CardHeader>
  160. {/* Default external events list */}
  161. <CardBody>
  162. <div className="external-events" ref="externalEventsList">
  163. {
  164. externalEvents.map(ev =>
  165. <div className={'fce-event bg-' + ev.color} key={ev.name+ev.color}>{ev.name}</div>
  166. )
  167. }
  168. </div>
  169. {/* <div className="custom-control custom-checkbox mt-3">
  170. <input className="custom-control-input" id="drop-remove" type="checkbox" onChange={this.handleCheck}/>
  171. <label className="custom-control-label" htmlFor="drop-remove">Remove after Drop</label>
  172. </div> */}
  173. </CardBody>
  174. </Card>
  175. {/* END card */}
  176. </div>
  177. <div className="col-lg-12 col-md-6 col-12">
  178. {/* START card */}
  179. <Card className="card-default">
  180. <CardHeader>
  181. <CardTitle tag="h4">Create Event</CardTitle>
  182. </CardHeader>
  183. <CardBody>
  184. <div className="input-group mb-2">
  185. <input className="form-control" type="text" placeholder="Event name..." onChange={this.handleInputName}/>
  186. <div className="input-group-btn">
  187. <button className="btn btn-secondary" onClick={this.addNewExternalEvent} type="button">Add</button>
  188. </div>
  189. </div>
  190. <p className="text-muted"><small>Choose a Color</small></p>
  191. <ul className="list-inline" id="external-event-color-selector">
  192. {
  193. this.evColors.map(evc =>
  194. <li className="list-inline-item p-0" key={evc}>
  195. <div
  196. className={"circle circle-xl " + this.getEvColorClasses(evc)}
  197. onClick={this.selectColor(evc)}></div>
  198. </li>
  199. )
  200. }
  201. </ul>
  202. </CardBody>
  203. </Card>
  204. {/* END card */}
  205. </div>
  206. </div>
  207. <div className="mb-3">
  208. {selectedEvent &&
  209. <div>
  210. <p>Selected:</p>
  211. <div className="box-placeholder">{JSON.stringify(selectedEvent)}</div>
  212. </div>
  213. }
  214. {!selectedEvent &&
  215. <div>
  216. <p>Click calendar to show information</p>
  217. </div>
  218. }
  219. </div>
  220. </div>
  221. <div className="col-xl-9 col-lg-8">
  222. <Card className="card-default">
  223. <CardBody>
  224. {/* START calendar */}
  225. <FullCalendar
  226. defaultView={this.dayGridMonth}
  227. plugins={this.calendarPlugins}
  228. events={this.calendarEvents}
  229. themeSystem={"bootstrap"}
  230. header={this.calendarHeader}
  231. editable={true}
  232. droppable={true}
  233. deepChangeDetection={true}
  234. dateClick={this.dayClick}
  235. eventReceive={this.handleEventReceive}
  236. >
  237. </FullCalendar>
  238. </CardBody>
  239. </Card>
  240. </div>
  241. </div>
  242. </div>
  243. </ContentWrapper>
  244. );
  245. }
  246. }
  247. export default Calendar;