-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
265 lines (242 loc) · 9.4 KB
/
Copy pathscript.js
File metadata and controls
265 lines (242 loc) · 9.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
var DEFAULT_TITLE_MESSAGE = "Unnamed Task List";
var DATA_FIELDS = ["title", "dueDate", "label", "details"];
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
/* Upload JSON file and store in data directory */
function getYear(str) {
return parseInt(str.substring(str.indexOf(',') + 2, str.length));
}
function getMonth(str) {
return MONTHS.indexOf(str.substring(0, 3));
}
function getDay(str) {
return parseInt(str.substring(str.indexOf(' ') + 1, str.indexOf(',')));
}
/**
* This method sorts our dates since they are stored as strings
*
* @param list of dates
* @returns sorted list of dates
*/
function sortDates(datas) {
return datas.sort((task1, task2) => {
let date1 = task1.dueDate;
let date2 = task2.dueDate;
//sort by year first
let year1 = getYear(date1);
let year2 = getYear(date2);
if (year1 !== year2) {
return year1 - year2;
}
//then sort by month
let month1 = getMonth(date1);
let month2 = getMonth(date2);
if (month1 < month2) {
return -1;
} else if (month1 > month2) {
return 1;
}
//then sort by day
let day1 = getDay(date1);
let day2 = getDay(date2);
if (day1 !== day2) {
return day1 - day2;
}
return 0; //dates are the same
});
}
function isPlainObject(obj) {
// Check if the object is not null and its type is "object"
if (obj !== null && typeof obj === 'object') {
// Get the object's prototype
const proto = Object.getPrototypeOf(obj);
// Check if the prototype is the default Object.prototype
return proto === Object.prototype || proto === null;
}
return false;
}
function verifyAndSort(data) {
if (Array.isArray(data)) {
for (const element of data) {
if (isPlainObject(element)) {
for (const field of DATA_FIELDS) {
if (!(field in element)) {
console.log("does not have field: " + field);
return null;
}
}
}
else {
console.log("not obj");
return null;
}
}
}
data = sortDates(data);
return data;
}
function importData() {
let input = document.createElement('input');
input.type = 'file';
input.onchange = _ => {
let toDisplay = null;
let file = input.files[0];
// Check if the file type is JSON or if the file name ends with ".json"
// The console logging is temporary and will be replaced with shown text
const errorArea = document.getElementById("error");
errorArea.innerHTML = "";
if (file.type === 'application/json' || file.name.endsWith('.json')) {
// We are given a JSON file and can't save it without some server side code, so I will just verify it and send it to the display function
const reader = new FileReader();
reader.onload = function(event) {
const jsonData = JSON.parse(event.target.result);
if (Array.isArray(jsonData)) {
// Something else will need to be done
console.log("Its an Array");
if (verified(jsonData)) {
// display(jsonData);
}
else {
errorArea.innerHTML = 'Array is not in the correct format.';
}
}
else if (isPlainObject(jsonData)) {
if (!("title" in jsonData)) {
// Add a temporary title
jsonData["title"] = DEFAULT_TITLE_MESSAGE;
}
if (!("data" in jsonData)) {
errorArea.innerHTML = 'JSON has no data field.';
}
else {
datas = verifyAndSort(jsonData["data"]);
if (datas === null) {
errorArea.innerHTML = 'Data field is not in the correct format.';
}
else {
toDisplay = jsonData;
toDisplay["data"] = datas;
display(toDisplay);
}
}
}
else {
// Something is wrong, return error
errorArea.innerHTML = 'JSON file is not an object or Array';
}
};
reader.readAsText(file);
}
else {
errorArea.innerHTML = 'File is not a JSON file.';
}
};
input.click();
}
// Code for Color Mode Switch Display
// Extract elements
let bodyElem = document.body;
const colorBtnImg = document.getElementById("color-mode");
let containerElem = document.getElementsByClassName("container")[0];
let taskIcons = document.getElementsByClassName("task-icon");
// Color change function based on current color mode
function colorChange() {
if(containerElem.classList[1] == "light-mode") {
// change to dark mode
containerElem.style.backgroundColor = "#081236";
containerElem.style.color = "white";
containerElem.classList.replace("light-mode", "dark-mode");
bodyElem.style.backgroundColor = "#0C1121";
bodyElem.classList.replace("light-mode", "dark-mode");
for(let i = 0; i < taskIcons.length; i++) {
taskIcons[i].classList.replace("light-mode-icon", "dark-mode-icon");
if (taskIcons[i].classList[2] == "right-icon") {
taskIcons[i].src = "images/triangle-right-white.svg";
}
else {
taskIcons[i].src = "images/triangle-down-white.svg";
}
}
}
else {
// change to light mode
containerElem.style.backgroundColor = "white";
containerElem.style.color = "black";
containerElem.classList.replace("dark-mode", "light-mode");
bodyElem.style.backgroundColor = "white";
bodyElem.classList.replace("dark-mode", "light-mode");
for(let i = 0; i < taskIcons.length; i++) {
taskIcons[i].classList.replace("dark-mode-icon", "light-mode-icon");
if (taskIcons[i].classList[2] == "right-icon") {
taskIcons[i].src = "images/triangle-right-black.svg";
}
else {
taskIcons[i].src = "images/triangle-down-black.svg";
}
}
}
};
/* Toggle Functionality */
function toggleIcon(el) {
const task = el.parentNode;
const description = task.getElementsByClassName('description')[0];
const image = el.getElementsByTagName('img')[0];
//change from down to right
if (image.classList[2] == 'down-icon') {
image.classList.replace('down-icon', 'right-icon');
description.style.display = 'none';
if (image.classList[1] == 'light-mode-icon') {
image.src = 'images/triangle-right-black.svg';
}
else {
image.src = 'images/triangle-right-white.svg';
}
}
// change from right to down
else {
image.classList.replace('right-icon', 'down-icon')
description.style.display = 'block';
if (image.classList[1] == 'light-mode-icon') {
image.src = 'images/triangle-down-black.svg';
}
else {
image.src = 'images/triangle-down-white.svg';
}
}
}
//updates all checkBoxs to have strikethrough functionality
function strikeName(){
let checkbox = document.querySelectorAll(".checkbox");
let taskName = document.querySelectorAll(".taskName");
checkbox.forEach((current, idx) => {
current.addEventListener("change", () => {
if(current.checked){
taskName[idx].classList.add("strikethrough");
} else{
taskName[idx].classList.remove("strikethrough");
}
});
} );
};
//makes default page have strikethrough functionality
strikeName();
function display(taskData) {
const listTitle=document.getElementsByClassName("title");
listTitle[0].innerHTML=taskData.title;
//populating the list of tasks (?)
const listContainer = document.getElementById("list");
listContainer.innerHTML = ''; // empty list
const arrow = (containerElem.classList[1] == "light-mode")?
'<button class="dropdown-btn" onclick="toggleIcon(this)"><img src="images/triangle-right-black.svg" alt="Task Icon "class="task-icon light-mode-icon right-icon" onclick="toggleIcon(this)"></button>'
: '<button class="dropdown-btn" onclick="toggleIcon(this)"><img src="images/triangle-right-white.svg" alt="Task Icon "class="task-icon dark-mode-icon right-icon" onclick="toggleIcon(this)"></button>';
for(let i=0; i<taskData.data.length; i++){
listContainer.innerHTML += '<li class="task">'
+ arrow
+ '<input class="checkbox" type="checkbox">'
+ '<h3 class="taskName">' + taskData.data[i].title + '</h3>'
+ '<p class="due-date">'+ taskData.data[i].dueDate + '</p>'
+ '<p class="description" style="display: none;">' + taskData.data[i].details + '</p>'
+ '</li>';
}
//updates all new checkboxes with strikethrough functionality
strikeName();
}