Skip to content

Commit

Permalink
Fetch schedules dynamically in calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
maxatdetroit committed May 28, 2024
1 parent 15eb842 commit 7c88f72
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 111 deletions.
4 changes: 3 additions & 1 deletion src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default class App {
this.calendar = new Cal('calendar', this);;
this.panel = new Panel(this);
this.geocoder = new Geocoder('geocoder', this);
this.routeNum = null;
this.initialLoad(this);
}

Expand Down Expand Up @@ -94,7 +95,8 @@ export default class App {
}
_app.map.flyTo(tempLocation, 15);
_app.panel.currentProvider = featureCollection.features[0].properties.contractor;
const wasteAPIEndpoint = buildWasteAPI(featureCollection.features[0].properties.FID, _app.year, _app.month);
_app.routeNum = featureCollection.features[0].properties.FID;
const wasteAPIEndpoint = buildWasteAPI(_app.routeNum, _app.year, _app.month);
fetch(wasteAPIEndpoint)
.then((res) => {
res.json().then(data => {
Expand Down
203 changes: 94 additions & 109 deletions src/components/Cal.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Calendar } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import moment from 'moment';
import { buildWasteAPI, PICKUP_TYPES, PICKUP_TYPES_PRINT } from '../utils/WasteAPI';
import './Cal.scss';
export default class Cal {
constructor(container, _controller) {
this.calendar = null;
this.controller = _controller;
this.pickups = [];
}

createCalendar(_app){
Expand All @@ -30,131 +30,116 @@ export default class Cal {
`;
tempCal.appendChild(calContainer);
tempCal.prepend(closeBtn);
_app.calendar.buildSchedule(_app);
_app.calendar.calendar = new Calendar(calContainer, {
plugins: [ dayGridPlugin ],
eventSources: _app.calendar.pickups
showNonCurrentDates: false,
eventSources: [
{
events: this.fetchTrashPickups.bind(this),
color: '#cb4d4f',
textColor: 'white'
},
{
events: this.fetchRecyclingPickups.bind(this),
color: '#9FD5B3',
textColor: '#004445'
},
{
events: this.fetchBulkPickups.bind(this),
color: '#5f355a',
textColor: 'white'
},
{
events: this.fetchYardPickups.bind(this),
color: '#feb70d',
textColor: 'black'
}
],
});
_app.calendar.calendar.render();
document.querySelector('#app .calendar').className = "calendar active";
}

buildSchedule(_app){
_app.calendar.buildPickUps(_app);
fetchPickups(info, successCb, failureCb, pickupType, routeNum, eventBuilder) {
const month = info.start.getMonth() + 1;
const wasteAPIEndpoint = buildWasteAPI(routeNum, info.start.getFullYear(), month);
fetch(wasteAPIEndpoint)
.then((res) => {
res.json().then((data) => {
const events = eventBuilder(data, pickupType);
successCb(events);
})
})
.catch((error) => {
console.error(error);
failureCb(error);
});
}

buildPickUps(_app){
let pastDate = _app.schedule.recycle;
let latestDate = _app.schedule.recycle;
let pastTrashDate = _app.schedule.garbage;
let trashDate = _app.schedule.garbage;
fetchTrashPickups(info, successCb, failureCb) {
this.fetchPickups(
info,
successCb,
failureCb,
PICKUP_TYPES.TRASH,
this.controller.routeNum,
this.buildPickUps
);
}

let gList = {
events: [
{
title : 'Trash',
start : moment(trashDate).format('YYYY-MM-DD'),
}
],
color: '#cb4d4f', // an option!
textColor: 'white' // an option!
};
let rList = {
events: [
{
title : 'Recycle',
start : moment(latestDate).format('YYYY-MM-DD'),
}
],
color: '#9FD5B3', // an option!
textColor: '#004445' // an option!
};
let bList = {
events: [
{
title : 'Bulk',
start : moment(latestDate).format('YYYY-MM-DD'),
}
],
color: '#5f355a', // an option!
textColor: 'white' // an option!
};
let yList = {
events: [],
color: '#feb70d', // an option!
textColor: 'black' // an option!
}
if(moment(latestDate).isBetween(_app.schedule.yard.start, _app.schedule.yard.end)){
yList.events.push(
{
title : 'Yard',
start : moment(latestDate).format('YYYY-MM-DD'),
}
);
}
for (let index = 0; index < 52; index++) {
let tempG = {
title : 'Trash',
start : moment(trashDate).add(7,'d').format('YYYY-MM-DD'),
};
let pasttempG = {
title : 'Trash',
start : moment(pastTrashDate).subtract(7,'d').format('YYYY-MM-DD'),
};
trashDate = moment(trashDate).add(7,'d');
pastTrashDate = moment(pastTrashDate).subtract(7,'d');
gList.events.push(tempG);
gList.events.push(pasttempG);
}
fetchRecyclingPickups(info, successCb, failureCb) {
this.fetchPickups(
info,
successCb,
failureCb,
PICKUP_TYPES.RECYCLING,
this.controller.routeNum,
this.buildPickUps
);
}

for (let index = 0; index < 26; index++) {
let tempR = {
title : 'Recycle',
start : moment(latestDate).add(14,'d').format('YYYY-MM-DD'),
};
let tempB = {
title : 'Bulk',
start : moment(latestDate).add(14,'d').format('YYYY-MM-DD'),
};
if(moment(latestDate).add(14,'d').isBetween(_app.schedule.yard.start, _app.schedule.yard.end)){
let tempY = {
title : 'Yard',
start : moment(latestDate).add(14,'d').format('YYYY-MM-DD'),
};
yList.events.push(tempY);
}
let pasttempR = {
title : 'Recycle',
start : moment(pastDate).subtract(14,'d').format('YYYY-MM-DD'),
};
let pasttempB = {
title : 'Bulk',
start : moment(pastDate).subtract(14,'d').format('YYYY-MM-DD'),
};
if(moment(pastDate).subtract(14,'d').isBetween(_app.schedule.yard.start, _app.schedule.yard.end)){
let pasttempY = {
title : 'Yard',
start : moment(pastDate).subtract(14,'d').format('YYYY-MM-DD'),
};
yList.events.push(pasttempY);
fetchYardPickups(info, successCb, failureCb) {
this.fetchPickups(
info,
successCb,
failureCb,
PICKUP_TYPES.YARD_WASTE,
this.controller.routeNum,
this.buildPickUps
);
}

fetchBulkPickups(info, successCb, failureCb) {
this.fetchPickups(
info,
successCb,
failureCb,
PICKUP_TYPES.BULK,
this.controller.routeNum,
this.buildPickUps
);
}

buildPickUps(eventData, pickupType){
let events = [];
eventData.schedule.forEach((pickupDateDetails) => {
for (const [pickupDate, pickupTypeDetails] of Object.entries(pickupDateDetails)) {
if (pickupType in pickupTypeDetails) {
events.push(
{
title : PICKUP_TYPES_PRINT[pickupType],
start : moment(pickupDate).format('YYYY-MM-DD'),
}
);
}
}
pastDate = moment(pastDate).subtract(14,'d');
latestDate = moment(latestDate).add(14,'d');
rList.events.push(tempR);
bList.events.push(tempB);
rList.events.push(pasttempR);
bList.events.push(pasttempB);
}
_app.calendar.pickups.push(gList);
_app.calendar.pickups.push(rList);
_app.calendar.pickups.push(bList);
_app.calendar.pickups.push(yList);
});
return events;
}

closeCalendar(ev,_calendar){
_calendar.calendar.destroy();
_calendar.calendar = null;
_calendar.pickups.length = 0;
let tempClass = ev.target.parentNode.parentNode.className;
tempClass = tempClass.split(' ');
ev.target.parentNode.parentNode.className = tempClass[0];
Expand Down
16 changes: 15 additions & 1 deletion src/utils/WasteAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,18 @@ function buildWasteAPI(routeNum, year, month) {
return `https://apis.detroitmi.gov/waste_schedule/details/${routeNum}/year/${year}/month/${month}/`;
}

export {buildWasteAPI};
const PICKUP_TYPES = Object.freeze({
TRASH: "trash",
RECYCLING: "recycling",
BULK: "bulk",
YARD_WASTE: "yard waste"
});

const PICKUP_TYPES_PRINT = Object.freeze({
"trash": "Trash",
"recycling": "Recycling",
"bulk": "Bulk",
"yard waste": "Yard Waste"
});

export {buildWasteAPI, PICKUP_TYPES, PICKUP_TYPES_PRINT};

0 comments on commit 7c88f72

Please sign in to comment.