mirror of
https://github.com/Soulful-Sailer/Event-Tracker.git
synced 2026-03-29 16:16:46 -05:00
version 1.0.0 commit
This commit is contained in:
153
static/scripts/EventItem.js
Normal file
153
static/scripts/EventItem.js
Normal file
@@ -0,0 +1,153 @@
|
||||
class EventItem {
|
||||
constructor(eventObject) {
|
||||
this.id = eventObject["id"];
|
||||
this.name = eventObject["name"];
|
||||
this.startTime = new Date(Date.parse(eventObject["starttime"]));
|
||||
this.endTime = new Date(Date.parse(eventObject["endtime"]));
|
||||
this.people = eventObject["people"];
|
||||
this.desc = eventObject["description"];
|
||||
this.constructElem();
|
||||
}
|
||||
|
||||
editEvent() {
|
||||
window.location.replace(`./event.html?id=${this.id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the HTML Element for this Event using the standard format
|
||||
*
|
||||
* <div id='event-#' class='event'>
|
||||
* <span class='event-topLine'>
|
||||
* <h3>Example Event</h3>
|
||||
* <span class='event-buttons'>
|
||||
* <button class='event-edit'>Edit</button>
|
||||
* </span>
|
||||
* </span>
|
||||
* <this.sameDayElem() or this.bothDaysElem()>
|
||||
* <li class='event-people'>People Involved</li>
|
||||
* <li class='event-desc'>Description</li>
|
||||
* </div>
|
||||
*/
|
||||
constructElem() {
|
||||
this.elem = document.createElement("div");
|
||||
this.elem.id = `event-${this.id}`;
|
||||
this.elem.classList.add("event");
|
||||
|
||||
//top line includes event name and button section
|
||||
let topLine = document.createElement("span");
|
||||
topLine.classList.add("event-topLine");
|
||||
|
||||
//event name
|
||||
let title = document.createElement("h3");
|
||||
title.innerText = this.name;
|
||||
topLine.append(title);
|
||||
|
||||
//button section as edit button
|
||||
let buttons = document.createElement("span");
|
||||
buttons.classList.add("event-buttons");
|
||||
|
||||
//edit button
|
||||
let editButton = document.createElement("button");
|
||||
editButton.classList.add("event-edit");
|
||||
editButton.innerText = "Edit";
|
||||
buttons.append(editButton);
|
||||
topLine.append(buttons);
|
||||
|
||||
this.elem.append(topLine);
|
||||
//topLine end
|
||||
|
||||
//datetime includes event date and time
|
||||
//if start and end time are less than 24h apart, only show the day for the start time
|
||||
if ((this.endTime.getTime() - this.startTime.getTime()) / 3600000 < 24)
|
||||
this.elem.append(this.sameDayElem());
|
||||
else
|
||||
this.elem.append(this.bothDaysElem());
|
||||
|
||||
//people involved in event
|
||||
let eventPeople = document.createElement("li");
|
||||
eventPeople.classList.add("event-people");
|
||||
eventPeople.innerText = this.people;
|
||||
this.elem.append(eventPeople);
|
||||
|
||||
//description of event
|
||||
let eventDesc = document.createElement("li");
|
||||
eventDesc.classList.add("event-desc");
|
||||
eventDesc.innerText = this.desc;
|
||||
this.elem.append(eventDesc);
|
||||
//elem end
|
||||
|
||||
editButton.addEventListener("click", () => this.editEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the HTML Element for datetime section of the Event using the standard format
|
||||
* When only the day is shown for the start time
|
||||
*
|
||||
* <li class='event-datetime'>
|
||||
* DayOfWeek, Month ##<br/>
|
||||
* <time datetime='YYYY-MM-DD HH:MM'>HH:MM AM/PM</time> - <time datetime='YYYY-MM-DD HH:MM'>HH:MM AM/PM</time>
|
||||
* </li>
|
||||
*
|
||||
* @returns {HTMLElement} datetime - li that contains start date and time info
|
||||
*/
|
||||
sameDayElem() {
|
||||
let datetime = document.createElement("li");
|
||||
datetime.classList.add = "event-datetime";
|
||||
|
||||
//Day for starting time
|
||||
datetime.append(getDay(this.startTime));
|
||||
|
||||
//linebreak
|
||||
datetime.append(document.createElement('br'));
|
||||
|
||||
//starting time within HTML timestamp
|
||||
let start = document.createElement("TIME");
|
||||
start.setAttribute("datetime", this.startTime.toISOString().slice(0, 16).replace('T', ' '));
|
||||
start.innerText = getTime(this.startTime);
|
||||
datetime.append(start);
|
||||
|
||||
//seperator
|
||||
datetime.append(" - ");
|
||||
|
||||
//ending time within HTML timestamp
|
||||
let end = document.createElement("TIME");
|
||||
end.setAttribute("datetime", this.endTime.toISOString().slice(0, 16).replace('T', ' '));
|
||||
end.innerText = getTime(this.endTime);
|
||||
datetime.append(end);
|
||||
|
||||
return datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the HTML Element for datetime section of the Event using the standard format
|
||||
* When the day is shown for both start and end times
|
||||
*
|
||||
* <li class='event-datetime'>
|
||||
* <time datetime='2023-04-28 21:30'>Friday, April 28 9:30 PM</time><br/>
|
||||
* <time datetime='2023-04-29 22:30'>Saturday, April 28 10:30 PM</time>
|
||||
* </li>
|
||||
*
|
||||
* @returns {HTMLElement} datetime - li that contains end date and time info
|
||||
*/
|
||||
bothDaysElem() {
|
||||
let datetime = document.createElement("li");
|
||||
datetime.classList.add("event-datetime");
|
||||
|
||||
//starting day and time within HTML timestamp
|
||||
let start = document.createElement("TIME");
|
||||
start.setAttribute("datetime", this.startTime.toISOString().slice(0, 16).replace('T', ' '));
|
||||
start.innerText = `${getDay(this.startTime)} ${getTime(this.startTime)}`;
|
||||
datetime.append(start);
|
||||
|
||||
//linebreak
|
||||
datetime.append(document.createElement('br'));
|
||||
|
||||
//ending day and time within HTML timestamp
|
||||
let end = document.createElement("TIME");
|
||||
end.setAttribute("datetime", this.endTime.toISOString().slice(0, 16).replace('T', ' '));
|
||||
end.innerText = `${getDay(this.endTime)} ${getTime(this.endTime)}`;
|
||||
datetime.append(end);
|
||||
|
||||
return datetime;
|
||||
}
|
||||
}
|
||||
110
static/scripts/editEvent.js
Normal file
110
static/scripts/editEvent.js
Normal file
@@ -0,0 +1,110 @@
|
||||
let newEvent = true; //false if editing exisiting event
|
||||
let currentURL = new URL(window.location.href);
|
||||
let id = currentURL.searchParams.get("id"); //id of event being edited
|
||||
|
||||
/** load event data **/
|
||||
|
||||
/**
|
||||
* Checks if we are editing event, and sets up page for it if so
|
||||
*/
|
||||
function editEvent() {
|
||||
if (id) {
|
||||
fetchEventData(id, populateData);
|
||||
newEvent = false;
|
||||
indicateEditing();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* requests data from server about an event with specified id
|
||||
* @param {number} id - id of event
|
||||
* @param {function} callback
|
||||
* @returns {Object} eventData - data about requested event
|
||||
*/
|
||||
function fetchEventData(id, callback) {
|
||||
fetchFile("event.json", "json", undefined, { "id": id }).then((eventData) => {
|
||||
//If server replies with requested data, return it. Else, alert user
|
||||
if (eventData) {
|
||||
callback(eventData);
|
||||
}
|
||||
else {
|
||||
alert("Could not retrieve event data");
|
||||
window.location.replace("./index.html");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* populates data about the event into the form's fields
|
||||
* @param {Object} eventData - data about requested event
|
||||
*/
|
||||
function populateData(eventData) {
|
||||
document.getElementById("event-id").value = id;
|
||||
for (let item in eventData) {
|
||||
//the key for each item should equal the id of the field
|
||||
let itemElem = document.getElementById(item);
|
||||
if (itemElem) {
|
||||
//map data to expected value for that field type
|
||||
switch (itemElem.type) {
|
||||
case "datetime-local":
|
||||
let datetime = new Date(Date.parse(eventData[item]));
|
||||
datetime = datetime.toISOString().slice(0, 16);
|
||||
itemElem.defaultValue = datetime;
|
||||
break;
|
||||
default:
|
||||
itemElem.defaultValue = eventData[item];
|
||||
}
|
||||
}
|
||||
else console.log("Could not find field " + item);
|
||||
}
|
||||
|
||||
//set section radio button in included
|
||||
if (eventData["section"]) document.getElementById(eventData["section"]).checked = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item on the navigation bar to show the user is editing an event instead of adding one
|
||||
*/
|
||||
function indicateEditing() {
|
||||
document.querySelector(".current-page").classList.remove('current-page');
|
||||
|
||||
//creates html element:
|
||||
//<li class='current-page'><a href='event.html?id=EventID'><span class='link'>Editing</span></a></li>
|
||||
let elem = document.createElement("li");
|
||||
elem.classList.add('current-page');
|
||||
let a = document.createElement('a');
|
||||
a.href = window.location.href;
|
||||
let span = document.createElement('span');
|
||||
span.classList.add('link');
|
||||
span.append('Editing');
|
||||
a.append(span);
|
||||
elem.append(a);
|
||||
document.getElementById("links").append(elem); //add elem to navigation bar
|
||||
|
||||
//creates delete button
|
||||
//<button id="delete-button">Delete</button>
|
||||
let deleteButton = document.createElement("button");
|
||||
deleteButton.id = "delete-button";
|
||||
deleteButton.innerText = "Delete";
|
||||
deleteButton.addEventListener("click", deleteEvent);
|
||||
document.getElementById("body-container").append(deleteButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sents post request to delete current event
|
||||
*/
|
||||
function deleteEvent() {
|
||||
console.log(id);
|
||||
if (confirm("Delete this event?")) {
|
||||
postData("delete-event.json",
|
||||
JSON.stringify({"id":id}),
|
||||
"application/json")
|
||||
.then(res => {
|
||||
if (!res || !res.ok) alert("delete failed");
|
||||
else window.location.replace("./index.html");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", editEvent);
|
||||
73
static/scripts/fetchFile.js
Normal file
73
static/scripts/fetchFile.js
Normal file
@@ -0,0 +1,73 @@
|
||||
let eventServer = new URL("http://" + window.location.host);
|
||||
|
||||
/**
|
||||
* sends the specified GET request to the server and returns the response
|
||||
* @param {string} filePath - path to requested file on server
|
||||
* @param {string} dataType - type of data requested (text, json, blob)
|
||||
* @param {Object} [headers] - request headers if needed
|
||||
* @param {Object} [parameters] - Search Parameters
|
||||
* @returns {Response} response - data returned by the server, decoded as indended
|
||||
*/
|
||||
function fetchFile(filePath, dataType, headers={}, parameters={}) {
|
||||
//setup URL
|
||||
let fileURL = eventServer;
|
||||
fileURL.pathname = `/${filePath}`;
|
||||
for (p in parameters) fileURL.searchParams.append(p, parameters[p]);
|
||||
|
||||
headers["method"] = "GET";
|
||||
return fetch(fileURL, headers)
|
||||
.then(response => {
|
||||
//If server replies with requested file, return it. Else log HTTP error
|
||||
if (response.ok) {
|
||||
//decode the response as indended
|
||||
switch (dataType) {
|
||||
case "text": return response.text().then(data => { return data }); break;
|
||||
case "json": return response.json().then(data => { return data }); break;
|
||||
case "blob": return response.blob().then(data => { return data }); break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log(`HTTP-Error: ${events.status}\n${fileURL}`);
|
||||
return undefined;
|
||||
}
|
||||
})
|
||||
//if request is unable to be sent, log error
|
||||
.catch(error => {
|
||||
console.log(error.message);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sends specified data as a POST request to the server
|
||||
* @param {string} filePath - path to requested file on server
|
||||
* @param {string} data - stringified data to be sent to server
|
||||
* @param {string} contentType - content type header for POST request
|
||||
* @param {Object} [headers] - request headers if needed
|
||||
* @returns {Response} response - server's response to the request
|
||||
*/
|
||||
function postData(filePath, data, contentType, headers={}) {
|
||||
//setup URL
|
||||
let fileURL = eventServer;
|
||||
fileURL.pathname = `/${filePath}`;
|
||||
|
||||
headers["method"] = "POST";
|
||||
headers["headers"] = {"Content-Type" : contentType};
|
||||
headers["body"] = data;
|
||||
|
||||
return fetch(fileURL, headers)
|
||||
.then(response => {
|
||||
//return the server's response, log if there is an HTTP error
|
||||
if (response.ok)
|
||||
return response;
|
||||
else {
|
||||
console.log(`HTTP-Error: ${response.status}\n${fileURL}`);
|
||||
return response;
|
||||
}
|
||||
})
|
||||
//if request is unable to be sent, log error
|
||||
.catch(error => {
|
||||
console.log(error.message);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
98
static/scripts/getDateTime.js
Normal file
98
static/scripts/getDateTime.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* returns string of Date object in format: HH:MM AM/PM
|
||||
* @param {Date} time
|
||||
* @returns {string} time - HH:MM AM/PM
|
||||
*/
|
||||
function getTime(time) {
|
||||
let hours = time.getHours();
|
||||
let meridiem;
|
||||
|
||||
if (hours > 12) {
|
||||
hours -= 12;
|
||||
meridiem = "PM";
|
||||
}
|
||||
else {
|
||||
meridiem = "AM";
|
||||
}
|
||||
|
||||
return `${hours}:${time.getMinutes()} ${meridiem}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns string of Date object in format: DayOfWeek, Month DD
|
||||
* @param {Date} time
|
||||
* @returns {string} date - DayOfWeek, Month DD
|
||||
*/
|
||||
function getDay(time) {
|
||||
let day;
|
||||
switch(time.getDay()) {
|
||||
case 0:
|
||||
day = 'Sunday';
|
||||
break;
|
||||
case 1:
|
||||
day = 'Monday';
|
||||
break;
|
||||
case 2:
|
||||
day = 'Tuesday';
|
||||
break;
|
||||
case 3:
|
||||
day = 'Wednesday';
|
||||
break;
|
||||
case 4:
|
||||
day = 'Thursday';
|
||||
break;
|
||||
case 5:
|
||||
day = 'Friday';
|
||||
break;
|
||||
case 6:
|
||||
day = 'Saturday';
|
||||
break;
|
||||
default:
|
||||
day = 'Invalid';
|
||||
}
|
||||
day = day + ', ';
|
||||
|
||||
switch(time.getMonth()) {
|
||||
case 0:
|
||||
day = day + "January";
|
||||
break;
|
||||
case 1:
|
||||
day = day + "February";
|
||||
break;
|
||||
case 2:
|
||||
day = day + "March";
|
||||
break;
|
||||
case 3:
|
||||
day = day + "April";
|
||||
break;
|
||||
case 4:
|
||||
day = day + "May";
|
||||
break;
|
||||
case 5:
|
||||
day = day + "June";
|
||||
break;
|
||||
case 6:
|
||||
day = day + "July";
|
||||
break;
|
||||
case 7:
|
||||
day = day + "August";
|
||||
break;
|
||||
case 8:
|
||||
day = day + "September";
|
||||
break;
|
||||
case 9:
|
||||
day = day + "October";
|
||||
break;
|
||||
case 10:
|
||||
day = day + "November";
|
||||
break;
|
||||
case 11:
|
||||
day = day + "December";
|
||||
break;
|
||||
default:
|
||||
day = day + "Invalid";
|
||||
}
|
||||
|
||||
day = day + " " + time.getDate();
|
||||
return day;
|
||||
}
|
||||
29
static/scripts/loadEvents.js
Normal file
29
static/scripts/loadEvents.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Retrieves the list of events from the server and adds them respective to their section
|
||||
*/
|
||||
function loadEvents() {
|
||||
fetchFile("events.json", "json").then((events) => {
|
||||
//if server replies with requested data
|
||||
if (events) {
|
||||
for (let header in events) {
|
||||
events[header].forEach((eventData) => {
|
||||
addEvent(eventData, header);
|
||||
});
|
||||
}
|
||||
}
|
||||
else console.log("Could not retrieve event data");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds event to specified header via creating a new instance of EventItem
|
||||
* @param {Object} eventData - contains required information about the event
|
||||
* @param {string} header - specifies under which section to add the new event item
|
||||
*/
|
||||
function addEvent(eventData, header) {
|
||||
let item = new EventItem(eventData);
|
||||
document.getElementById(header).append(item.elem);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", loadEvents);
|
||||
Reference in New Issue
Block a user