Fetch event data from api and show on fullcalendar

This commit is contained in:
sosokker 2023-11-07 03:24:58 +07:00
parent a403e45f9f
commit 02e76f88c5
8 changed files with 250 additions and 36 deletions

View File

@ -12,6 +12,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
"@fullcalendar/core": "^6.1.9",
"@fullcalendar/daygrid": "^6.1.9", "@fullcalendar/daygrid": "^6.1.9",
"@fullcalendar/interaction": "^6.1.9", "@fullcalendar/interaction": "^6.1.9",
"@fullcalendar/react": "^6.1.9", "@fullcalendar/react": "^6.1.9",

View File

@ -11,6 +11,9 @@ dependencies:
'@emotion/styled': '@emotion/styled':
specifier: ^11.11.0 specifier: ^11.11.0
version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0)
'@fullcalendar/core':
specifier: ^6.1.9
version: 6.1.9
'@fullcalendar/daygrid': '@fullcalendar/daygrid':
specifier: ^6.1.9 specifier: ^6.1.9
version: 6.1.9(@fullcalendar/core@6.1.9) version: 6.1.9(@fullcalendar/core@6.1.9)

View File

@ -6,7 +6,8 @@ import LoginPage from './components/authentication/LoginPage';
import SignUpPage from './components/authentication/SignUpPage'; import SignUpPage from './components/authentication/SignUpPage';
import NavBar from './components/Nav/Navbar'; import NavBar from './components/Nav/Navbar';
import Home from './components/Home'; import Home from './components/Home';
import ProfileUpdate from './components/ProfileUpdatePage' import ProfileUpdate from './components/ProfileUpdatePage';
import Calendar from './components/calendar/calendar';
const App = () => { const App = () => {
return ( return (
@ -19,6 +20,7 @@ const App = () => {
<Route path="/signup" element={<SignUpPage/>}/> <Route path="/signup" element={<SignUpPage/>}/>
<Route path="/testAuth" element={<TestAuth/>}/> <Route path="/testAuth" element={<TestAuth/>}/>
<Route path="/update_profile" element={<ProfileUpdate/>}/> <Route path="/update_profile" element={<ProfileUpdate/>}/>
<Route path="/calendar" element={<Calendar/>}/>
</Routes> </Routes>
</div> </div>
</BrowserRouter> </BrowserRouter>

View File

@ -0,0 +1,23 @@
import axios from 'axios';
// Create an Axios instance with common configurations
const axiosInstance = axios.create({
baseURL: 'http://127.0.0.1:8000/api/',
timeout: 5000,
headers: {
'Authorization': "Bearer " + localStorage.getItem('access_token'),
'Content-Type': 'application/json',
'accept': 'application/json',
}
});
export const fetchTodoTasks = () => {
return axiosInstance
.get('todo/')
.then((response) => {
return response.data;
})
.catch(error => {
throw error;
});
};

View File

@ -0,0 +1,42 @@
import { fetchTodoTasks } from '../../api/TaskApi';
let eventGuid = 0
// function getDateAndTime(dateString) {
// const dateObject = new Date(dateString);
// const year = dateObject.getFullYear();
// const month = (dateObject.getMonth() + 1).toString().padStart(2, '0');
// const day = dateObject.getDate().toString().padStart(2, '0');
// const dateFormatted = `${year}-${month}-${day}`;
// const hours = dateObject.getUTCHours().toString().padStart(2, '0');
// const minutes = dateObject.getUTCMinutes().toString().padStart(2, '0');
// const seconds = dateObject.getUTCSeconds().toString().padStart(2, '0');
// const timeFormatted = `T${hours}:${minutes}:${seconds}`;
// return dateFormatted + timeFormatted;
// }
const mapResponseToEvents = (response) => {
return response.map(item => ({
id: createEventId(),
title: item.title,
start: item.start_event,
end: item.end_event,
}));
}
export async function getEvents() {
try {
const response = await fetchTodoTasks();
return mapResponseToEvents(response);
} catch (error) {
console.error(error);
return [];
}
}
export function createEventId() {
return String(eventGuid++);
}

View File

@ -1,28 +1,127 @@
import React from 'react'; import React, { useState } from 'react';
import FullCalendar from '@fullcalendar/react'; import { formatDate } from "@fullcalendar/core";
import dayGridPlugin from '@fullcalendar/daygrid'; import FullCalendar from "@fullcalendar/react";
import timeGridPlugin from '@fullcalendar/timegrid'; import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import { getEvents, createEventId } from "./TaskDataHandler";
import './index.css'
const Calendar = () => { export default class Calendar extends React.Component {
return ( state = {
<div className="App"> weekendsVisible: true,
<FullCalendar currentEvents: [],
plugins={[dayGridPlugin, timeGridPlugin]}
initialView="dayGridMonth"
events={[
{ title: 'Event 1', date: '2023-11-10' },
{ title: 'Event 2', date: '2023-11-15' },
{ title: 'Event 2', date: '2023-11-15' },
]}
headerToolbar={{
start: 'prev,next',
center: "title",
end: 'timeGridDay,dayGridMonth,timeGridWeek,',
}}
/>
</div>
);
}; };
export default Calendar; render() {
return (
<div className="demo-app">
{this.renderSidebar()}
<div className="demo-app-main">
<FullCalendar
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
headerToolbar={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay",
}}
initialView="dayGridMonth"
editable={true}
selectable={true}
selectMirror={true}
dayMaxEvents={true}
weekends={this.state.weekendsVisible}
initialEvents={getEvents} // alternatively, use the `events` setting to fetch from a feed
select={this.handleDateSelect}
eventContent={renderEventContent} // custom render function
eventClick={this.handleEventClick}
eventsSet={this.handleEvents} // called after events are initialized/added/changed/removed
/* you can update a remote database when these fire:
eventAdd={function(){}}
eventChange={function(){}}
eventRemove={function(){}}
*/
/>
</div>
</div>
);
}
renderSidebar() {
return (
<div className="demo-app-sidebar">
<div className="demo-app-sidebar-section">
<h2>Instructions</h2>
<ul>
<li>Select dates and you will be prompted to create a new event</li>
<li>Drag, drop, and resize events</li>
<li>Click an event to delete it</li>
</ul>
</div>
<div className="demo-app-sidebar-section">
<label>
<input type="checkbox" checked={this.state.weekendsVisible} onChange={this.handleWeekendsToggle}></input>
toggle weekends
</label>
</div>
<div className="demo-app-sidebar-section">
<h2>All Events ({this.state.currentEvents.length})</h2>
<ul>{this.state.currentEvents.map(renderSidebarEvent)}</ul>
</div>
</div>
);
}
handleWeekendsToggle = () => {
this.setState({
weekendsVisible: !this.state.weekendsVisible,
});
};
handleDateSelect = selectInfo => {
let title = prompt("Please enter a new title for your event");
let calendarApi = selectInfo.view.calendar;
calendarApi.unselect(); // clear date selection
if (title) {
calendarApi.addEvent({
id: createEventId(),
title,
start: selectInfo.startStr,
end: selectInfo.endStr,
allDay: selectInfo.allDay,
});
}
};
handleEventClick = clickInfo => {
if (confirm(`Are you sure you want to delete the event '${clickInfo.event.title}'`)) {
clickInfo.event.remove();
}
};
handleEvents = events => {
this.setState({
currentEvents: events,
});
};
}
function renderEventContent(eventInfo) {
return (
<>
<b>{eventInfo.timeText}</b>
<i>{eventInfo.event.title}</i>
</>
);
}
function renderSidebarEvent(event) {
return (
<li key={event.id}>
<b>{formatDate(event.start, { year: "numeric", month: "short", day: "numeric" })}</b>
<i>{event.title}</i>
</li>
);
}

View File

@ -1,11 +0,0 @@
import React from 'react'
function calendarPage() {
return (
<div>
</div>
)
}
export default calendarPage

View File

@ -0,0 +1,55 @@
html,
body,
body > div { /* the react root */
margin: 0;
padding: 0;
height: 100%;
}
h2 {
margin: 0;
font-size: 16px;
}
ul {
margin: 0;
padding: 0 0 0 1.5em;
}
li {
margin: 1.5em 0;
padding: 0;
}
b { /* used for event dates/times */
margin-right: 3px;
}
.demo-app {
display: flex;
min-height: 100%;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
.demo-app-sidebar {
width: 300px;
line-height: 1.5;
background: #eaf9ff;
border-right: 1px solid #d3e2e8;
}
.demo-app-sidebar-section {
padding: 2em;
}
.demo-app-main {
flex-grow: 1;
padding: 3em;
}
.fc { /* the calendar root */
max-width: 1100px;
margin: 0 auto;
}