diff --git a/README.md b/README.md index b4011107..4633aeaf 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,12 @@ ## [Team Page](/admin/team.md) -Homepage +Dev Journal\ +Documentation + +### Description +cse 110, dev journal, features: +### Team Members + +### Pipeline diff --git a/admin/cipipeline/updated-pipeline.drawio.png b/admin/cipipeline/updated-pipeline.drawio.png new file mode 100644 index 00000000..afcf1412 Binary files /dev/null and b/admin/cipipeline/updated-pipeline.drawio.png differ diff --git a/admin/meetings/052424-sprint-1-review.md b/admin/meetings/052424-sprint-1-review.md index 7ed14f6a..2e7f343e 100644 --- a/admin/meetings/052424-sprint-1-review.md +++ b/admin/meetings/052424-sprint-1-review.md @@ -46,4 +46,7 @@ Opportunities: - more assigning, linked with issues, closing issues, updating project board Threats: -- attendance and tardiness \ No newline at end of file +- attendance and tardiness + +# Retrospective Board +![img](../misc/CSE110-Retrospective1.png) diff --git a/admin/meetings/052424-weekly.md b/admin/meetings/052424-weekly.md index 08446bab..4d187485 100644 --- a/admin/meetings/052424-weekly.md +++ b/admin/meetings/052424-weekly.md @@ -4,7 +4,7 @@ # Weekly Meeting ### Meeting held in 1st floor Geisel West -### Attendance (7/10) +### Attendance (5/10) - Chris - Bobby - Kai diff --git a/admin/meetings/052924-meeting.md b/admin/meetings/052924-meeting.md new file mode 100644 index 00000000..07b38854 --- /dev/null +++ b/admin/meetings/052924-meeting.md @@ -0,0 +1,54 @@ +# Team 25 +## Wednesday, 1:30PM May 29, 2024 + +# Weekly Meeting +### Meeting held in 1st floor Geisel West + +### Attendance (8/10) +- Chris +- Bobby +- Kai +- Nathan +- Justin +- Sahana +- Sonya +- Andrew + +### Absent +- Derek +- Kevin + +## Agenda +1. Standup/General Announcements +2. Testing Prioritization +3. Minimum screen size +4. Reassign Teams +5. Get a Push to Main +6. Bugs + +### Standup/General Announcements +Home page is done except for sizing of rating widget. Calendar only needs slight changes with coloring and sizing. Needs to implement tasks side bar. +Chris met with Smruthi, we should switch focus almost entirely to testing. The last time we can make changes to our product is end of week 10. + +### Testing +Teams will begin to shift focus onto testing. Backend team still working on storage, but other teams will focus on puppeteering and e2e tests. + +### Minimum Screen Size +Need to decide on a minumum screen size to allow users to still use the desktop app. Phone version is a no-go for now. +Could posibly add some sort of implementation but highly unlikely. + +### Reassign Teams +Need to redo the team structure for testing. Sonya, Kai, Kevin most comfortable with pipeline integration. +We need unit tests, puppeteering, and integration into the pipeline. +GitHub Automation: Kai and Sonya +Unit Testing: Andrew and Derek +Home Page Puppeteer Tests: Chris and Nathan +Calendar Puppeteer Tests: Sahana +Backend Storage: Kevin, Bobby, and Justin + +### Push to Main +Add all the updates to task list into the calendar page. Merge homepage-front and calendar-front into main. + +### Bugs +Home Page: Sizing on rating widget. Resizing of task name height +Calendar: Drop down menu for changing month. diff --git a/admin/meetings/053124-meeting.md b/admin/meetings/053124-meeting.md new file mode 100644 index 00000000..2f78b001 --- /dev/null +++ b/admin/meetings/053124-meeting.md @@ -0,0 +1,41 @@ +# Team 25 +## Wednesday, 1:30PM May 29, 2024 + +# Weekly Meeting +### Meeting held in 1st floor Geisel West + +### Attendance (10/10) +- Chris +- Bobby +- Kai +- Nathan +- Justin +- Sahana +- Derek +- Kevin +- Sonya +- Andrew + +### Absent + +## Agenda +1. Puppeteer Tests +2. Calendar Pages +3. Unit Tests +4. To Do + +### Puppeteer Tests +Kai has implemented auto testing into the pipeline. Need to merge all updates into main so that testing can be on the most updates website. +Nathan has written puppeteer tests for entire homepage aside from tasks. + +### Calendar Page +Tasks displayed in each day box. Hover for dates works and is reponsive. Days linked to corresponding homepage date. +Future dates blocked from accessing homepage. Minheight set for the top bar. + +### Unit Tests +Problems with unit tests interacting with the dom. Reached out to TA waiting on response. + +### To Do +Put all of the updates pushed into main. Finish writing tests. Local storage.\ +Homepage & Calendar teams work on finishing frontend, very slight changes. Also writing puppeteer and unit tests.\ +JS team continue adding storage functionality. diff --git a/admin/meetings/06032024-meeting.md b/admin/meetings/06032024-meeting.md new file mode 100644 index 00000000..6c18461a --- /dev/null +++ b/admin/meetings/06032024-meeting.md @@ -0,0 +1,48 @@ +# Team 25 +## Monday, 2:00PM June 3, 2024 + +# Weekly Meeting +### Meeting held in 1st floor Geisel West + +### Attendance (10/10) +- Chris +- Bobby +- Kai +- Nathan +- Justin +- Sahana +- Derek +- Kevin +- Sonya +- Andrew + +### Absent + +## Agenda +1. Standup Meeting by Group +2. Regroup Together +3. Push to Main + + +### Standups +**Testing Team** +Kai: Fixed bug with window size in GitHub actuions. Website icon. Finish up smaller bugs in website\ +Sonya: Written tests for task list in smaller window, editing tasks in task bar\ +Nathan: Tests for rating widget and journal, will write tests for moving task between completed and editing there\ +Andrew: Written calendar tests for resize. Working on tests for moving to next month\ +Sahana: Working on window resizing in calendar\ +Chris: Wrote tests for top bar. Once storage is updated, will test population of elements in calendar and weekly view + +**Storage Team**\ +Kevin: Worked on populating calendar page with stored data and LocalStorage unit tests. Task storage Bug fixing.\ +Justin: Worked on populating homepage calendar week view with stored data. \ +Derek: Worked on Unit testing with DOM for localstorage. \ +Bobby: Worked on Task List functionality and bug fixing and homepage calendar week view. \ + +### Regroup +Testing is making progress. Calendar page is finalized. Will write tests into one file to simulate a whole user experience.\ +Calendar is filling in with completed tasks. Weekly view is almost fully working with some minor errors. +Journal and rating widget has saving and population. local-storage-branch has mainly working storage, will require a few bug fixes and then a main push can happen today. + +### Push to Main +Testing team will spend meeting time pushing all updated tests to main. diff --git a/admin/meetings/06072024-meeting.md b/admin/meetings/06072024-meeting.md new file mode 100644 index 00000000..10d2dffc --- /dev/null +++ b/admin/meetings/06072024-meeting.md @@ -0,0 +1,30 @@ +# Team 25 +## Friday, 12:30PM June 7, 2024 + +# Weekly Meeting +### Meeting held in 1st floor Geisel West + +### Attendance (6/10) +- Chris +- Bobby +- Kai +- Justin +- Derek +- Sonya + +### Absent +- Nathan +- Andrew +- Sahana +- Kevin + +## Agenda +1. Fix on commenting and formatting on css and js files +2. videos reminders +3. swot and retrospective + +### TODO +each person send 30 sec video +- name +- subteam/role +- what you worked on diff --git a/admin/meetings/060724-Final-Sprint-Review.md b/admin/meetings/060724-Final-Sprint-Review.md new file mode 100644 index 00000000..31ae6d0b --- /dev/null +++ b/admin/meetings/060724-Final-Sprint-Review.md @@ -0,0 +1,48 @@ +# Team 25 +# Friday 12:30PM, June 7, 2024 + +# Final Sprint Review & Retrospective +### Meeting held in Geisel 1st Floor West + +### Attendance (6/10) +- Bobby +- Chris +- Derek +- Sonya +- Kai +- Justin + +### Absent +- Nathan +- Sahana +- Kevin +- Andrew + +## SWOT Analysis +### Strengths: +- Planned and designed before we implemented; spent significant time on this part before moving forward +- Splitting up into teams was efficient, more manageable +- Everyone carried their weight and was reliable +- Everyone had input and each opinion was considered +- Github pipeline and actions were done well +- Communication was great, within teams and between teams; utilizing Slack, Github comments, and in-person meetings + +### Weaknesses +- Some unnecessary backtracking; ie implementing something, then refactoring, then re-implementing +- Messy Github repo; too many branches and issues +- Differing code style somewhat +- Pipeline was finalized a little late into the project + +### Opportunities +- More structured pipeline +- Responsiveness of the website at smaller screens isn’t great +- A universal search function for searching for past journal entries, tasks, etc. + +### Threats +- Our storage system is fairly small; performance would slow down with upward scaling +- On slow, low-capability mobile phones, website slows down significantly + +# Retrospective +![img](../misc/Retrospective-Final.png) + + diff --git a/admin/misc/Retrospective-Final.png b/admin/misc/Retrospective-Final.png new file mode 100644 index 00000000..10f83344 Binary files /dev/null and b/admin/misc/Retrospective-Final.png differ diff --git a/js-doc/calendar_calendar.js.html b/js-doc/calendar_calendar.js.html new file mode 100644 index 00000000..d5c74868 --- /dev/null +++ b/js-doc/calendar_calendar.js.html @@ -0,0 +1,708 @@ + + + + + JSDoc: Source: calendar/calendar.js + + + + + + + + + + +
+ +

Source: calendar/calendar.js

+ + + + + + +
+
+
const DISPLAY_TASK_COUNT = 2;
+const RATING_FILES_NAMES = ["1angry.png", "2upset.png", "3neutral.png", "4happy.png", "5overjoyed.png"];
+const PRODUCTIVITY_FILES_NAMES = ["1-icon.svg", "2-icon.svg", "3-icon.svg", "4-icon.svg", "5-icon.svg"];
+
+// Wait for window to load
+window.addEventListener('DOMContentLoaded', init);
+
+// Get current date globals
+var currDate = new Date();
+var month = currDate.getMonth();
+var year = currDate.getFullYear();
+
+// Defines confetti
+const confetti = window.confetti;
+
+/**
+ * Updates the global date variables to the current date.
+ */
+function updateDateGlobals() {
+    month = currDate.getMonth();
+    year = currDate.getFullYear();
+}
+
+/**
+ * Initializes the page when the DOM content is fully loaded.
+ */
+function init() {
+    // Initiaze the jump buttons
+    displayJump(year - 6, year + 5);
+    taskListViewHandler();
+
+    // Initially display the calendar, calendar header, and task colors
+    calendarHeader();
+    displayCalendar();
+
+    // Initialize the buttons 
+    initButtons();
+
+    loadTasks();
+}
+
+/**
+ * Initializes the buttons for adding tasks, navigating months, and other functionalities.
+ */
+function initButtons() {
+
+    const addTaskBtn = document.querySelector(".add-task-btn");
+    addTaskBtn.addEventListener("click", () => {
+        addTask();
+    });
+
+    // Previous month button
+    let prevBtn = document.querySelector(".prev-date-btn");
+    prevBtn.addEventListener('click', prev);
+
+    // Next month button
+    let nextBtn = document.querySelector(".next-date-btn");
+    nextBtn.addEventListener('click', next);
+
+    // Jump header buttons
+    // List of months
+    let monthJumpBtn = document.querySelectorAll(".month-btn");
+    monthJumpBtn.forEach(btn => {
+        btn.addEventListener("click", () => {
+            let monthValue = btn.getAttribute("value");
+            jump(monthValue, year);
+        });
+    });
+    // List of years
+    let yearJumpBtn = document.querySelectorAll(".year-btn");
+    yearJumpBtn.forEach(btn => {
+        btn.addEventListener("click", () => {
+            let yearValue = btn.getAttribute("value");
+            jump(month, yearValue);
+        });
+    });
+
+    // Resize window for responsiveness
+    window.addEventListener('resize', windowWidth);
+
+    // Add left/right arrows to goto prev/next months
+    window.addEventListener('keydown', function(event) {
+        if (event.key === "ArrowLeft") {
+            prev();
+        } else if (event.key === "ArrowRight") {
+            next();
+        }
+    });
+}
+
+/**
+ * Updates the global currDate to the next date and displays the next month.
+ */
+function next(){
+    // Increment the month
+    currDate.setMonth(currDate.getMonth() + 1);
+    updateDateGlobals();
+    displayCalendar();
+}
+
+/**
+ * Updates the global currDate to the previous month and displays the previous month's calendar.
+ */
+function prev() {
+    // Decrement the month
+    currDate.setMonth(currDate.getMonth() - 1);
+    updateDateGlobals();
+    displayCalendar();
+}
+
+/**
+ * Adds a task to the task list upon "Add Task" button click.
+ * 
+ * @param {boolean} [loadTask=false] - Indicates whether the task is being loaded from storage.
+ * @returns {HTMLElement} - The newly created task element.
+ */
+function addTask(loadTask = false) {
+    // Add a task to an element of task container
+    const taskList = document.querySelector(".task-container");
+    const task = document.createElement("li");
+    task.className = "task";
+    
+    // Add it at the first row
+    task.insertAdjacentHTML("beforeend", `
+        <div class="check-input-wrap">
+            <button id="task1" class="task-checkbox" aria-label="Task Checkbox"></button>
+            <div contenteditable="true" class="task-input" placeholder="Add a task..." onkeypress="return this.innerText.length <= 180;"></div>
+        </div>
+        <div class="color-buttons">
+            <button id="purple" class="color-button" aria-label="Purle"></button>
+            <button id="green" class="color-button" aria-label="Green"></button>
+            <button id="blue" class="color-button" aria-label="Blue"></button>
+            <button id="pink" class="color-button" aria-label="Pink"></button>
+            <button id="grey" class="color-button" aria-label="Grey"></button>
+        </div>
+        <img class="trash-icon" src="../icons/trash-icon.svg" alt="Remove">
+    `);
+    task.querySelector(".task-input").addEventListener("input", saveTasks);
+
+
+    taskList.append(task);
+
+    // Listener to stop editing when user presses enter
+    const task_name = task.querySelector(".task-input");
+    task_name.addEventListener('keydown', function (event) {
+        // Shift + Enter pressed, insert a line break
+        if (event.key == 'Enter') {
+            // Enter pressed, end editing
+            if (!event.shiftKey) {
+                // Prevent default behavior of Enter key
+                event.preventDefault(); 
+
+                // Remove focus from the element
+                task_name.blur(); 
+            }
+        }
+    });
+
+    // Auto click into the task name text box
+    if (loadTask == false){
+        setTimeout(() => {
+            task_name.focus();
+            const selection = document.getSelection();
+            if (selection.rangeCount > 0) {
+                selection.collapseToEnd();
+            }
+        }, 0);
+    }  
+
+    // Add functionality to task buttons
+    taskButtonsFunctionality(task);
+
+    return task;
+}
+
+/**
+ * Adds button functionality to a task upon creation.
+ * 
+ * @param {HTMLElement} task - The task element to add functionality to.
+ */
+function taskButtonsFunctionality(task) {
+    // Implement color changing functionality 
+    const colorBtns = task.querySelectorAll(".color-button");
+    colorBtns.forEach(btn => {
+        btn.addEventListener('click', function () {
+            let color;
+            switch (btn.id) {
+                case "purple":
+                    color = "#C380CC";
+                    break;
+                case "green":
+                    color = "#91DC79";
+                    break;
+                case "blue":
+                    color = "#6BB1D9";
+                    break;
+                case "pink":
+                    color = "#EEBAE9";
+                    break;
+                default:
+                    color = "var(--main-color)";
+            }
+            task.style['background-color'] = color;
+            saveTasks();
+        });
+    });
+
+    // Trash icon delete functionality
+    const deleteIcon = task.querySelector(".trash-icon");
+    deleteIcon.addEventListener("click", () => {
+        task.remove();
+        saveTasks();
+    });
+
+    // Checkbox move to completed tasks functionality
+    const checkbox = task.querySelector(".task-checkbox");
+    checkbox.addEventListener('click', function () {
+
+        // Add or remove completed from class name
+        if (task.className.includes('complete')) {
+            task.classList.remove('complete');
+            const taskContainer = document.querySelector('.task-container');
+            taskContainer.appendChild(task);
+            task.addEventListener("blur", saveTasks);
+            saveTasks();
+        }
+        else {
+            task.classList.add('complete');
+            saveCompleted(task);
+            task.remove()
+            saveTasks();
+
+            confetti({
+                particleCount: 100,
+                spread: 70,
+                origin: { y: 0.6 }
+            });
+        }
+    });
+}
+
+/**
+ * Expands task list from collapsed state.
+ */
+function taskListViewHandler() {
+    const taskList = document.querySelector('.task-list');
+    const taskWrap = document.querySelector('.task-wrapper');
+    const outSide = document.querySelector('.full-calendar');
+    taskList.addEventListener('click', function(event) {
+        if (event.target === taskList) {
+            if (window.innerWidth <= 800) { 
+                taskList.classList.toggle('active');
+                taskWrap.classList.toggle('active');
+            }
+        }
+    });
+    outSide.addEventListener('click', function(){
+        if (window.innerWidth <= 800) { 
+            taskList.classList.remove('active');
+            taskWrap.classList.remove('active');
+        }
+    });
+}
+
+/**
+ * Saves the completed tasks for a specific day.
+ * 
+ * @param {HTMLElement} completedTaskElement - The task element that was completed.
+ */
+function saveCompleted(completedTaskElement) {
+    let data = getJournal();
+    let dateText = new Date().toLocaleDateString();
+    let completedTask = loadFromStorage(data, dateText, "completedTasks") || [];
+    let taskName = completedTaskElement.querySelector('.task-input').textContent;
+    let taskColor = completedTaskElement.style['background-color']
+    completedTask.push({
+        text: taskName,
+        color: taskColor,
+    });
+    saveToStorage(data, dateText, "completedTasks", completedTask);
+    localStorage.setItem("journals", JSON.stringify(data));
+    displayCalendar();
+}
+
+/**
+ * Displays the calendar for the current month.
+ */
+function displayCalendar() {
+    // Get body and clear current calendar
+    let tbody = document.getElementById("tbody-calendar");
+    tbody.innerHTML = "";
+
+    // Initialize list of months
+    let allMonths = [
+        "January", "February", "March", "April", "May", "June",
+        "July", "August", "September", "October", "November", "December"
+    ];
+
+    // Get day of the week of first day in given month
+    let currCalendarMonth = new Date(year, month, 1);
+    let today = new Date();
+    let dayOffset = -(currCalendarMonth.getDay());
+
+    // Get month and year header
+    let monthHeader = document.getElementById("month");
+    let yearHeader = document.getElementById("year");
+    monthHeader.textContent = allMonths[parseInt(month, 10)];
+    yearHeader.textContent = year;
+
+    // Build Calendar
+    // Loop through number of rows
+    let currDay;
+    for (let i = 0; i < 6; i++) {
+        // Create rows
+        let row = document.createElement("tr");
+
+        // Loop through number of columns
+        for (let j = 0; j < 7; j++) {
+            // Create data for each table cell in the row
+            let cellData = document.createElement("td");
+
+            // Create span for cell number
+            let cellNum = document.createElement('span');
+
+            // Add offset to first date in calendar
+            if (i === 0 && j === 0) {
+                currCalendarMonth.setDate(currCalendarMonth.getDate() + dayOffset);
+                currDay = currCalendarMonth.getDate();
+            }
+            // Increment date by one
+            else {
+                currCalendarMonth.setDate(currCalendarMonth.getDate() + 1);
+                currDay = currCalendarMonth.getDate();
+            }
+            // Add number and class to cellNum
+            cellNum.textContent = currDay;
+            cellNum.className = "cell-date";
+            let cellDate = new Date(currCalendarMonth);
+
+            // If current month
+            if (currCalendarMonth.getMonth() === currDate.getMonth()) {
+                cellData.classList.add("curr-month-date-num");
+            }
+            // If other month
+            else {
+                cellData.classList.add("other-month-date-num");
+            }
+
+            // If cell is today
+            if (currCalendarMonth.toDateString() === today.toDateString()) {
+                cellData.classList.add("current-date");
+            }
+            // If cell is in the past
+            else if (currCalendarMonth < today) {
+                cellData.classList.add("past-date");
+            }
+            // If cell is in the future
+            else {
+                cellData.classList.add("future-date");
+            }
+
+            // Add cell number to calendar cell
+            cellData.appendChild(cellNum);
+
+            if (cellDate <= today) {
+                loadCellDataTest(cellData, currCalendarMonth);
+            }
+            // Append new cell to row
+            row.appendChild(cellData);
+        }
+        // Append row to table
+        tbody.appendChild(row);
+    }
+    // Change the header if the window size is too small
+    windowWidth();
+
+    // Get the width of month and align the year 
+    let monthWidth = document.getElementById('month-dropdown').offsetWidth;
+    document.getElementById('year-dropdown').style.left = monthWidth + 5 + 'px';
+}
+
+/**
+ * Loads cell data such as rating, productivity, and tasks for a specific date in the calendar.
+ * 
+ * @param {HTMLElement} cellData - The table cell element to populate with data.
+ * @param {Date} currCalendarMonth - The current month being displayed in the calendar.
+ */
+function loadCellDataTest(cellData, currCalendarMonth) {
+    let journals = getJournal();
+    let dateText = currCalendarMonth.toLocaleDateString();
+
+    let rating = loadFromStorage(journals, dateText, "rating");
+    let productivity = loadFromStorage(journals, dateText, "productivity");
+    let tasks = loadFromStorage(journals, dateText, "completedTasks");
+
+    if (rating != null) {
+        // Add sentiment icon
+        let sentimentIcon = document.createElement("img");
+        sentimentIcon.src = `../icons/${RATING_FILES_NAMES[rating - 1]}`;
+        sentimentIcon.alt = "sentiment icon";
+        sentimentIcon.className = "sentiment-icon";
+
+        // Append sentiment icon to new cell
+        cellData.appendChild(sentimentIcon);
+    }
+
+    if (productivity != null) {
+        // Add productivity icon
+        let productivityIcon = document.createElement("img");
+        productivityIcon.src = `../icons/${PRODUCTIVITY_FILES_NAMES[productivity - 1 - 5]}`;
+        productivityIcon.alt = "productivity icon";
+        productivityIcon.className = "productivity-icon";
+
+        // Append sentiment icon to new cell
+        cellData.appendChild(productivityIcon);
+    }
+
+    // Add tasklist in calendar cell
+    // Create tasklist div
+    let taskDiv = document.createElement("div");
+    taskDiv.className = "task-div";
+    
+    // Create unordered list
+    let taskList = document.createElement("ul");
+    taskList.className = "task-ul";
+
+    if (tasks != null) {
+        for (let i = 0; i < tasks.length && i < DISPLAY_TASK_COUNT; i++) {
+            let taskItem = document.createElement("li");
+            taskItem.textContent = tasks[i]["text"];
+            taskItem.className = "task-item";
+            taskItem.style.setProperty('--task-color', tasks[i]["color"]);
+            taskList.appendChild(taskItem);
+        }
+
+        if (tasks.length > DISPLAY_TASK_COUNT) {
+            // Handle extra tasks in calendar view
+            let taskExtra = document.createElement("li");
+            taskExtra.textContent = `${tasks.length - DISPLAY_TASK_COUNT} more tasks`;
+            taskExtra.className = "task-indicator";
+            taskList.appendChild(taskExtra);
+        }
+    }
+
+    // Append taskList to task div;
+    taskDiv.appendChild(taskList);
+
+    // Append tasklist div to new cell
+    cellData.appendChild(taskDiv);
+
+    // Create buttons that link to speciic homepage and extract selected date
+    let aLink = document.createElement("a");
+    let dayLink = currCalendarMonth.getDate();
+    let monthLink = currCalendarMonth.getMonth();
+    let yearLink = currCalendarMonth.getFullYear()
+
+    // Query is in format ?date=month-day-year
+    aLink.href = `../homepage/homepage.html?date=${monthLink}-${dayLink}-${yearLink}`;
+    aLink.className = "a-link";
+    aLink.setAttribute("aria-label", `Link to details for ${monthLink + 1}/${dayLink}/${yearLink}`);
+    cellData.appendChild(aLink);
+}
+
+/**
+ * Generates a dropdown for year and month selection.
+ * 
+ * @param {number} startYear - The start year for the dropdown range.
+ * @param {number} endYear - The end year for the dropdown range.
+ */
+function displayJump(startYear, endYear) {
+    // Years
+    let yearDropdown = document.getElementById("year-dropdown")
+
+    // Loop through year range and append to list
+    for (let yr = startYear; yr < endYear + 1; yr++) {
+        let yearJump = document.createElement("button");
+        yearJump.value = yr;
+        yearJump.textContent = yr;
+        yearJump.className = "year-btn";
+        yearDropdown.appendChild(yearJump);
+
+    }
+
+    // Months
+    let allMonths = [
+        "January", "February", "March", "April", "May", "June",
+        "July", "August", "September", "October", "November", "December"
+    ];
+    
+    // Loop through months and append to list
+    let monthDropdown = document.getElementById("month-dropdown")
+    for (let mnth = 0; mnth < 12; mnth++) {
+        let monthJump = document.createElement("button");
+        monthJump.value = mnth;
+        monthJump.textContent = allMonths[parseInt(mnth, 10)];
+        monthJump.className = "month-btn";
+        monthDropdown.appendChild(monthJump);
+    }
+}
+
+/**
+ * Function to jump to a specific month and year.
+ * 
+ * @param {number} mnth - month to jump to
+ * @param {number} yr - year to jump to
+ */
+function jump(mnth, yr) {
+    currDate = new Date(yr, mnth)
+    updateDateGlobals();
+    displayCalendar();
+}
+
+/**
+ * Creates header of the calendar.
+ */
+function calendarHeader(){
+    // Initialize list of days of the week
+    let allDays = ["Sun", "Mon", "Tue", "Wed","Thu", "Fri", "Sat"];
+
+    // Header of Days of the week
+    let thead = document.getElementById("thead-weekheadings");
+    let headerRow = document.createElement("tr");
+
+    // Loop through allDays list and append day of week to row
+    for (let dow of allDays) {
+        let headerData = document.createElement("th");
+        headerData.textContent = dow;
+        headerRow.appendChild(headerData);
+    }
+    thead.appendChild(headerRow);
+}
+
+/**
+ * Adjusts the month header text based on the window width.
+ */
+function windowWidth() {
+    if (window.innerWidth < 920) {
+        // Initialize list of abbreviated months
+        let allMonths = [
+            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+            "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"
+        ];
+
+        let monthHeader = document.getElementById("month");
+        monthHeader.textContent = allMonths[parseInt(month, 10)];
+    }
+    else {
+        // Initialize list of months
+        let allMonths = [
+            "January", "February", "March", "April", "May", "June",
+            "July", "August", "September", "October", "November", "December"
+        ];
+        let monthHeader = document.getElementById("month");
+        monthHeader.textContent = allMonths[parseInt(month, 10)];
+    }
+
+    // Get the width of month and align the year 
+    let monthWidth = document.getElementById('month-dropdown').offsetWidth;
+    document.getElementById('year-dropdown').style.left = monthWidth + 5 + 'px';
+}
+
+/* ********** Storage and Population ********** */
+
+// Get the all relevent elements from page
+const tasks = document.querySelector(".task-container");
+
+// Save journal entry and tasks to local storage on page unload
+window.onbeforeunload = function () {
+    saveTasks()
+}
+
+/**
+ * Save journal entry to local storage.
+ * 
+ * @param {string} data - Journal entry text in parsed json format.
+ * @param {string} dateText - Date of the journal entry in locale date string format.
+ * @param {string} key - Key to store the value under.
+ * @param {string} value - Value to store.
+ */
+function saveToStorage(data, dateText, key, value) {
+    if (!(dateText in data)) {
+        data[dateText] = {}
+    }
+    data[dateText][key] = value;
+}
+
+/**
+ * Load journal entry from local storage.
+ * 
+ * @param {Object} data - Journal entry text in parsed JSON format.
+ * @param {string} dateText - Date of the journal entry in locale date string format.
+ * @param {string} key - Key to get the value from.
+ * @returns {string|null} - Value of the key in the data or null if not found.
+ */
+function loadFromStorage(data, dateText, key) {
+    if (!(dateText in data)) {
+        return null;
+    }
+    return data[dateText][key];
+}
+
+/**
+ * Get journal entry from local storage.
+ * 
+ * @returns {Object} - Journal entry text in parsed json format.
+ */
+function getJournal() {
+    let data = JSON.parse(localStorage.getItem("journals"))
+    if (data == null) {
+        data = {}
+    }
+    return data;
+}
+
+/**
+ * Save tasks to local storage.
+ */
+function saveTasks() {
+    let tasks = [];
+    document.querySelectorAll('.task-container li').forEach(task => {
+        let taskName = task.querySelector('.task-input').textContent;
+        let taskColor = task.style['background-color']
+        tasks.push({
+            text: taskName,
+            color: taskColor,
+        });
+    });
+    localStorage.setItem("tasks", JSON.stringify(tasks));
+}
+
+/**
+ * Get tasks from local storage.
+ *
+ * @returns {string} - Tasks in parsed json format or empty array if no tasks.
+ */
+function getTasks() {
+    let storedTasks = localStorage.getItem("tasks");
+    return storedTasks ? JSON.parse(storedTasks) : [];
+}
+
+/**
+ * Load tasks from local storage.
+ */
+function loadTasks() {
+    let tasks = getTasks();
+    if (tasks.length > 0) {
+        tasks.forEach(task => {
+            let curLi = addTask(true);
+            curLi.querySelector(".task-input").textContent = task['text']
+            curLi.style['background-color'] = task['color']
+        });
+    }
+
+}
+
+// Save journal entry and tasks to local storage on events.
+tasks.addEventListener("blur", saveTasks)
+tasks.addEventListener("change", saveTasks)
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/js-doc/fonts/OpenSans-Bold-webfont.eot b/js-doc/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 00000000..5d20d916 Binary files /dev/null and b/js-doc/fonts/OpenSans-Bold-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-Bold-webfont.svg b/js-doc/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 00000000..3ed7be4b --- /dev/null +++ b/js-doc/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-Bold-webfont.woff b/js-doc/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 00000000..1205787b Binary files /dev/null and b/js-doc/fonts/OpenSans-Bold-webfont.woff differ diff --git a/js-doc/fonts/OpenSans-BoldItalic-webfont.eot b/js-doc/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 00000000..1f639a15 Binary files /dev/null and b/js-doc/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-BoldItalic-webfont.svg b/js-doc/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 00000000..6a2607b9 --- /dev/null +++ b/js-doc/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-BoldItalic-webfont.woff b/js-doc/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 00000000..ed760c06 Binary files /dev/null and b/js-doc/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/js-doc/fonts/OpenSans-Italic-webfont.eot b/js-doc/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 00000000..0c8a0ae0 Binary files /dev/null and b/js-doc/fonts/OpenSans-Italic-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-Italic-webfont.svg b/js-doc/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 00000000..e1075dcc --- /dev/null +++ b/js-doc/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-Italic-webfont.woff b/js-doc/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 00000000..ff652e64 Binary files /dev/null and b/js-doc/fonts/OpenSans-Italic-webfont.woff differ diff --git a/js-doc/fonts/OpenSans-Light-webfont.eot b/js-doc/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 00000000..14868406 Binary files /dev/null and b/js-doc/fonts/OpenSans-Light-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-Light-webfont.svg b/js-doc/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 00000000..11a472ca --- /dev/null +++ b/js-doc/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-Light-webfont.woff b/js-doc/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 00000000..e7860748 Binary files /dev/null and b/js-doc/fonts/OpenSans-Light-webfont.woff differ diff --git a/js-doc/fonts/OpenSans-LightItalic-webfont.eot b/js-doc/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 00000000..8f445929 Binary files /dev/null and b/js-doc/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-LightItalic-webfont.svg b/js-doc/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 00000000..431d7e35 --- /dev/null +++ b/js-doc/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-LightItalic-webfont.woff b/js-doc/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 00000000..43e8b9e6 Binary files /dev/null and b/js-doc/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/js-doc/fonts/OpenSans-Regular-webfont.eot b/js-doc/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 00000000..6bbc3cf5 Binary files /dev/null and b/js-doc/fonts/OpenSans-Regular-webfont.eot differ diff --git a/js-doc/fonts/OpenSans-Regular-webfont.svg b/js-doc/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 00000000..25a39523 --- /dev/null +++ b/js-doc/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js-doc/fonts/OpenSans-Regular-webfont.woff b/js-doc/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 00000000..e231183d Binary files /dev/null and b/js-doc/fonts/OpenSans-Regular-webfont.woff differ diff --git a/js-doc/global.html b/js-doc/global.html new file mode 100644 index 00000000..c50d8b09 --- /dev/null +++ b/js-doc/global.html @@ -0,0 +1,5864 @@ + + + + + JSDoc: Global + + + + + + + + + + +
+ +

Global

+ + + + + + +
+ +
+ +

+ + +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

addTask(loadTaskopt) → {HTMLElement}

+ + + + + + +
+

Adds a task to the task list upon "Add Task" button click.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
loadTask + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +

Indicates whether the task is being loaded from storage.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+
    +
  • The newly created task element.
  • +
+
+ + + +
+
+ Type +
+
+ +HTMLElement + + +
+
+ + + + + + + + + + + + + +

addTask(loadTaskopt)

+ + + + + + +
+

Adds task to task list upon "Add Task" button click. Initializes buttons within each task

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
loadTask + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

calendarHeader()

+ + + + + + +
+

Creates header of the calendar.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

dateQuery()

+ + + + + + +
+

Links calendar cell to homepage on corresponding date

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

displayCalendar()

+ + + + + + +
+

Displays the calendar for the current month.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

displayDate(date)

+ + + + + + +
+

Updates interface with date

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
date + + +string + + + +

date in string format

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

displayJump(startYear, endYear)

+ + + + + + +
+

Generates a dropdown for year and month selection.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startYear + + +number + + + +

The start year for the dropdown range.

endYear + + +number + + + +

The end year for the dropdown range.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

displayWeek()

+ + + + + + +
+

Updates interface with Past Week view

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

formatDate() → {string}

+ + + + + + +
+

Formats the currDate global variable into proper string display

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+
    +
  • properly formatted string representing the date as "Weekday, Month Day, Year"
  • +
+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

getCompleted() → {string}

+ + + + + + +
+

Fetch completed tasks from storage in proper format

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

tasks data in proper format

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

getJournal() → {Object}

+ + + + + + +
+

Get journal entry from local storage.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+
    +
  • Journal entry text in parsed json format.
  • +
+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

getJournal() → {string}

+ + + + + + +
+

Get journal entry from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

journal entry text in parsed json format

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

getTasks() → {string}

+ + + + + + +
+

Get tasks from local storage.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+
    +
  • Tasks in parsed json format or empty array if no tasks.
  • +
+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

getTasks() → {string}

+ + + + + + +
+

Get tasks from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

tasks in parsed json format or empty array if no tasks

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

init()

+ + + + + + +
+

Initializes the page when the DOM content is fully loaded.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

init()

+ + + + + + +
+

Initializes all necessary components

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

initButtons()

+ + + + + + +
+

Initializes the buttons for adding tasks, navigating months, and other functionalities.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

initButtons()

+ + + + + + +
+

Initializes functionality of buttons

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

jump(mnth, yr)

+ + + + + + +
+

Function to jump to a specific month and year.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
mnth + + +number + + + +

month to jump to

yr + + +number + + + +

year to jump to

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadAll()

+ + + + + + +
+

Load all data from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadCellData(cellData, currWeekDay)

+ + + + + + +
+

Fetches data from local storage and populates Past Week view

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cellData + + +HTMLElement + + + +

Data for specified day

currWeekDay + + +Date + + + +

Date to populate data within

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadCellDataTest(cellData, currCalendarMonth)

+ + + + + + +
+

Loads cell data such as rating, productivity, and tasks for a specific date in the calendar.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cellData + + +HTMLElement + + + +

The table cell element to populate with data.

currCalendarMonth + + +Date + + + +

The current month being displayed in the calendar.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadCompleted()

+ + + + + + +
+

Load and populate completed tasks from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadFromStorage(data, dateText, key) → {string|null}

+ + + + + + +
+

Load journal entry from local storage.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + +

Journal entry text in parsed JSON format.

dateText + + +string + + + +

Date of the journal entry in locale date string format.

key + + +string + + + +

Key to get the value from.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+
    +
  • Value of the key in the data or null if not found.
  • +
+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + + + + +

loadFromStorage(data, dateText, key)

+ + + + + + +
+

Load journal entry from local storage

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +string + + + +

journal entry text in parsed json format

dateText + + +string + + + +

date of the journal entry in locale date string format

key + + +string + + + +

key to get the value from

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadJournal()

+ + + + + + +
+

Load journal entry from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadTasks()

+ + + + + + +
+

Load tasks from local storage.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadTasks()

+ + + + + + +
+

Load tasks from local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

loadWidgets()

+ + + + + + +
+

Load widget ratings from local storage and update interface

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

next()

+ + + + + + +
+

Updates the global currDate to the next date and displays the next month.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

nextDate()

+ + + + + + +
+

Updates the global currDate to the next date and updates interface

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

prev()

+ + + + + + +
+

Updates the global currDate to the previous month and displays the previous month's calendar.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

prevDate()

+ + + + + + +
+

Updates global currDate to the previous date and updates interface

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveCompleted(completedTaskElement)

+ + + + + + +
+

Saves the completed tasks for a specific day.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
completedTaskElement + + +HTMLElement + + + +

The task element that was completed.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveCompleted()

+ + + + + + +
+

Saves the completed tasks and updates Past Week view

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveJournal()

+ + + + + + +
+

Save journal entry to local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveTasks()

+ + + + + + +
+

Save tasks to local storage.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveTasks()

+ + + + + + +
+

Save tasks to local storage

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveToStorage(data, dateText, key, value)

+ + + + + + +
+

Save journal entry to local storage.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +string + + + +

Journal entry text in parsed json format.

dateText + + +string + + + +

Date of the journal entry in locale date string format.

key + + +string + + + +

Key to store the value under.

value + + +string + + + +

Value to store.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveToStorage(data, dateText, key, value)

+ + + + + + +
+

Format journal input to be stored

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +string + + + +

journal entry text in parsed json format

dateText + + +string + + + +

date of the journal entry in locale date string format

key + + +string + + + +

key to store the value under

value + + +string + + + +

value to store

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

saveWidgets(value)

+ + + + + + +
+

Save widgets to local storage and updates Past Week view

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +int + + + +

ID value of the widget selected

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

selectWidget(buttonIndex)

+ + + + + + +
+

Shows that a given button has been selected by adding the active property to its classname

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
buttonIndex + + +int + + + +

the index of the button selected.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

taskButtonsFunctionality(task)

+ + + + + + +
+

Adds button functionality to a task upon creation.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
task + + +HTMLElement + + + +

The task element to add functionality to.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

taskButtonsFunctionality(task)

+ + + + + + +
+

Adds button functionality to task upon creation

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
task + + +HTMLElement + + + +

the task to have functionality

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

taskListViewHandler()

+ + + + + + +
+

Expands task list from collapsed state.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

taskListViewHandler()

+ + + + + + +
+

Expands task list from collapsed state

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

unselectAllCompleted()

+ + + + + + +
+

Remove completed tasks from interface upon changing dates

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

unselectAllWidgets()

+ + + + + + +
+

Unselects all widgets by removing the active property from their classnames

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

updateDateGlobals()

+ + + + + + +
+

Updates the global date variables to the current date.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

windowWidth()

+ + + + + + +
+

Adjusts the month header text based on the window width.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/js-doc/homepage.js.html b/js-doc/homepage.js.html new file mode 100644 index 00000000..cebe7232 --- /dev/null +++ b/js-doc/homepage.js.html @@ -0,0 +1,73 @@ + + + + + JSDoc: Source: homepage.js + + + + + + + + + + +
+ +

Source: homepage.js

+ + + + + + +
+
+
window.addEventListener('DOMContentLoaded', init);
+
+function init() {
+    getDate('current-date')
+}
+
+/**
+ * Displays the current date in a specified HTML container.
+ * The date is formatted in a long format with the day of the week, the month name, the day of the month, and the year.
+ * 
+ * @param {string} container_id - The ID of the HTML container where the date will be displayed.
+ */
+function getDate(container_id) {
+    // Get the current date
+    const currentDate = new Date();
+
+    // Format the date (e.g., "May 8, 2024")
+    const formattedDate = currentDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
+
+    // Display the date in the designated container
+    const dateContainer = document.getElementById(container_id);
+    dateContainer.textContent = formattedDate;
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/js-doc/homepage_homepage.js.html b/js-doc/homepage_homepage.js.html new file mode 100644 index 00000000..18d38675 --- /dev/null +++ b/js-doc/homepage_homepage.js.html @@ -0,0 +1,734 @@ + + + + + JSDoc: Source: homepage/homepage.js + + + + + + + + + + +
+ +

Source: homepage/homepage.js

+ + + + + + +
+
+
const DISPLAY_TASK_COUNT = 2;
+const RATING_FILES_NAMES = ["1angry.png", "2upset.png", "3neutral.png", "4happy.png", "5overjoyed.png"];
+const PRODUCTIVITY_FILES_NAMES = ["1-icon.svg", "2-icon.svg", "3-icon.svg", "4-icon.svg", "5-icon.svg"];
+
+window.addEventListener('DOMContentLoaded', init);
+
+// Get current date global
+var currDate = new Date();
+
+// Defines confetti
+const confetti = window.confetti;
+
+/**
+ * Initializes all necessary components
+ */
+function init() {
+    dateQuery();
+    displayDate(formatDate(currDate));
+    displayWeek();
+    initButtons();
+    taskListViewHandler();
+
+    // Configure going to today's homepage on refresh
+    window.history.replaceState("stateObj", 
+    "new page", "../homepage/homepage.html");
+
+}
+
+/**
+ * Initializes functionality of buttons
+ */
+function initButtons() {
+    const nextBtn = document.querySelector(".next-date-btn");
+    nextBtn.addEventListener("click", nextDate);
+    const prevBtn = document.querySelector(".prev-date-btn");
+    prevBtn.addEventListener("click", prevDate);
+
+    const addTaskBtn = document.querySelector(".add-task-btn");
+    addTaskBtn.addEventListener("click", () => {
+        addTask();
+    });
+
+    const ratingSelBtn = document.querySelectorAll(".rating-select-btn");
+    ratingSelBtn.forEach(btn => {
+        btn.addEventListener("click", () => {
+            var id = btn.getAttribute("id");
+            selectWidget(id.substring(3,5));
+        });
+    });
+
+    // Add keyboard left, rigth arrow for switching dates
+    window.addEventListener('keydown', function(event) {
+        if ((event.target.tagName.toLowerCase() === "textarea") ||
+           (event.target.tagName.toLowerCase() === "div")) {
+            return;
+        }
+        if (event.key === "ArrowLeft") {
+            prevDate();
+        } else if (event.key === "ArrowRight") {
+            nextDate();
+        }
+    });
+    // Save user entry to local storage on any changes
+    journal.addEventListener("blur", saveJournal);
+    tasks.addEventListener("blur", saveTasks);
+    tasks.addEventListener("change", saveTasks);
+    tasks.addEventListener("blur", saveCompleted);
+    tasks.addEventListener("change", saveCompleted);
+    completedTasks.addEventListener("blur", saveCompleted);
+    completedTasks.addEventListener("change", saveCompleted);
+    completedTasks.addEventListener("blur", saveTasks);
+    completedTasks.addEventListener("change", saveTasks);
+}
+
+/**
+ * Updates interface with date
+ * 
+ * @param {string} date - date in string format
+ */
+function displayDate(date) {
+    const dateContainer = document.getElementById('current-date');
+    dateContainer.textContent = date;
+}
+
+/**
+ * Updates the global currDate to the next date and updates interface
+ */
+function nextDate() {
+    saveJournal();
+    let today = new Date();
+    today.setHours(0, 0, 0, 0);
+    if (currDate <= today) {
+        currDate.setDate(currDate.getDate() + 1);
+        displayDate(formatDate(currDate));  
+    }
+    unselectAllWidgets();
+    unselectAllCompleted();
+    loadAll();
+}
+
+/**
+ * Updates global currDate to the previous date and updates interface
+ */
+function prevDate() {
+    saveJournal();
+    currDate.setDate(currDate.getDate() - 1);
+    displayDate(formatDate(currDate));
+    unselectAllWidgets();
+    unselectAllCompleted();
+    loadAll();
+}
+
+/**
+ * Formats the currDate global variable into proper string display
+ * @returns {string} - properly formatted string representing the date as "Weekday, Month Day, Year"
+ */
+function formatDate() {
+    // Formats date as "Weekday, Month Date, Year"
+    const formattedDate = currDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
+    return formattedDate;
+}
+
+/**
+ * Shows that a given button has been selected by adding the active property to its classname
+ * 
+ * @param {int} buttonIndex - the index of the button selected.
+ */
+function selectWidget(buttonIndex) {
+    if (buttonIndex > 5) {
+        // Clear active class from all buttons in row
+        const buttons = document.querySelectorAll('.productiveness img');
+        buttons.forEach(button => {
+            button.classList.remove('active');
+        });
+        // Add active class to selected button
+        const selection = document.querySelector(`.rating-widget .productiveness button:nth-child(${buttonIndex - 5}) img`);
+        selection.classList.add('active');
+        saveWidgets(buttonIndex);
+    }
+    else {
+        const buttons = document.querySelectorAll('.feelings img');
+        buttons.forEach(button => {
+            button.classList.remove('active');
+        });
+        const selection = document.querySelector(`.rating-widget .feelings button:nth-child(${buttonIndex}) img`);
+        selection.classList.add('active');
+        saveWidgets(buttonIndex);
+    }
+}
+
+/**
+ * Adds task to task list upon "Add Task" button click. Initializes buttons within each task
+ * @param {boolean} [loadTask=false] 
+ */
+ function addTask(loadTask = false) {
+    const taskList = document.querySelector(".task-container");
+    const task = document.createElement("li");
+    task.setAttribute("class", "task");
+    task.insertAdjacentHTML("beforeend", `
+        <div class="check-input-wrap">
+            <button id="task1" class="task-checkbox" aria-label="Task Checkbox"></button>
+            <div contenteditable="true" class="task-input" placeholder="Add a task..." onkeypress="return this.innerText.length <= 180;"></div>
+        </div>
+        <div class="color-buttons">
+            <button id="purple" class="color-button" aria-label="Purle"></button>
+            <button id="green" class="color-button" aria-label="Green"></button>
+            <button id="blue" class="color-button" aria-label="Blue"></button>
+            <button id="pink" class="color-button" aria-label="Pink"></button>
+            <button id="grey" class="color-button" aria-label="Grey"></button>
+        </div>
+        <img class="trash-icon" src="../icons/trash-icon.svg" alt="Remove">
+    `);
+    task.querySelector(".task-input").addEventListener("input", saveCompleted)
+    taskList.append(task);
+
+    // Listener to stop editing when user presses enter
+    const task_name = task.querySelector(".task-input");
+    task_name.addEventListener('keydown', function (event) {
+        // Shift+Enter pressed, insert a line break
+        if (event.key == 'Enter') {
+            // Enter pressed, end editing
+            if (!event.shiftKey) {
+                // Prevent default behavior of Enter key
+                event.preventDefault();
+
+                // Remove focus from the element
+                task_name.blur(); 
+            }
+        }
+    });
+
+    // Auto click into the task name text box
+    if (loadTask == false){
+        setTimeout(() => {
+            task_name.focus();
+            const selection = document.getSelection();
+            if (selection.rangeCount > 0) {
+                selection.collapseToEnd();
+            }
+        }, 0);
+    }   
+
+    taskButtonsFunctionality(task);
+    if (loadTask == false){
+        saveTasks();
+    }
+
+    return task;
+}
+
+/**
+ * Adds button functionality to task upon creation
+ * 
+ * @param {HTMLElement} task - the task to have functionality
+ */
+function taskButtonsFunctionality(task) {
+    // Implement color changing functionality
+    const colorBtns = task.querySelectorAll(".color-button");
+    colorBtns.forEach(btn => {
+        btn.addEventListener('click', function() {
+            let color;
+            switch (btn.id) {
+                case "purple":
+                    color = "#C380CC";
+                    break;
+                case "green":
+                    color = "#91DC79";
+                    break;
+                case "blue":
+                    color = "#6BB1D9";
+                    break;
+                case "pink":
+                    color = "#EEBAE9";
+                    break;
+                default:
+                    color = "var(--main-color)";
+            }
+            task.style['background-color'] = color;
+            saveCompleted();
+            saveTasks();
+        });
+    });
+
+    // Trash icon delete functionality
+    const deleteIcon = task.querySelector(".trash-icon");
+    deleteIcon.addEventListener("click", () => {
+        task.remove();
+        saveCompleted();
+        saveTasks();
+    });
+
+    // Checkbox move to Completed Tasks functionality
+    const checkbox = task.querySelector(".task-checkbox");
+    checkbox.addEventListener('click', function() {
+        if (task.className.includes('complete')) {
+            task.classList.remove('complete');
+            const taskContainer = document.querySelector('.task-container');
+            taskContainer.appendChild(task);
+            task.addEventListener("blur", saveTasks);
+            saveCompleted();
+            saveTasks();
+        }
+        else {
+            task.classList.add('complete');
+            const completedTaskContainer = document.querySelector('.completed-task-container');
+            completedTaskContainer.appendChild(task);
+            saveCompleted();
+            saveTasks();
+
+            confetti({
+                particleCount: 100,
+                spread: 70,
+                origin: { y: 0.6 }
+            });
+        }
+    });
+}
+
+/**
+ * Unselects all widgets by removing the active property from their classnames
+ */
+ function unselectAllWidgets() {
+    const buttons = document.querySelectorAll('.feelings img');
+    buttons.forEach(button => {
+        button.classList.remove('active');
+    });
+
+    const buttons2 = document.querySelectorAll('.productiveness img');
+    buttons2.forEach(button => {
+        button.classList.remove('active');
+    });
+}
+
+
+
+/**
+ * Updates interface with Past Week view
+ */
+function displayWeek() {
+    let allDays = ["Sun", "Mon", "Tue", "Wed","Thu", "Fri", "Sat"];
+
+    // Get and clear the table
+    let table = document.getElementById("week-calendar");
+    table.innerHTML = "";
+
+    let currWeekDay = new Date();
+    currWeekDay.setDate(currWeekDay.getDate() + 1);
+
+    let row = document.createElement("tr");
+
+    // Initialize  each past day
+    for (let i = 0; i < 7; i++) {
+        let cellData = document.createElement("td");
+
+        if (i === 0){
+            currWeekDay.setDate(currWeekDay.getDate() + (i-8));
+        }
+        else {
+            currWeekDay.setDate(currWeekDay.getDate() + 1);
+        }
+
+        let cellNum = document.createElement('span'); 
+        cellNum.textContent = allDays[currWeekDay.getDay()] + " " + (currWeekDay.getMonth()+1) + "/" + currWeekDay.getDate();
+        cellNum.className = "cell-date";
+        cellData.appendChild(cellNum);
+        loadCellData(cellData, currWeekDay);
+        row.appendChild(cellData);
+    }
+    table.appendChild(row);
+}
+
+/* ******** Storage and Population ********** */
+
+// Get the all relevent elements from page
+const journal = document.getElementById("textarea");
+const date = document.getElementById("current-date");
+const tasks = document.querySelector(".task-container");
+const completedTasks = document.querySelector(".completed-task-container");
+
+// Load journal entry and tasks from local storage on page load
+window.onload = function () {
+    loadAll();
+    loadTasks();
+}
+
+// Save journal entry and tasks to local storage on page unload
+window.onbeforeunload = function () {
+    saveJournal()
+    saveTasks()
+    saveCompleted()
+}
+
+/**
+ * Load all data from local storage
+ */
+function loadAll() {
+    loadJournal();
+    loadWidgets();
+    loadCompleted();
+}
+
+/**
+ * Format journal input to be stored
+ * 
+ * @param {string} data - journal entry text in parsed json format
+ * @param {string} dateText - date of the journal entry in locale date string format
+ * @param {string} key - key to store the value under
+ * @param {string} value - value to store
+ * 
+ */
+export function saveToStorage(data, dateText, key, value) {
+    if (!(dateText in data)) {
+        data[dateText] = {}
+    }
+    data[dateText][key] = value;
+}
+
+/**
+ * Load journal entry from local storage
+ * 
+ * @param {string} data - journal entry text in parsed json format
+ * @param {string} dateText - date of the journal entry in locale date string format
+ * @param {string} key - key to get the value from
+ */
+export function loadFromStorage(data, dateText, key) {
+    if (!(dateText in data)) {
+        return null;
+    }
+    return data[dateText][key];
+}
+
+/**
+ * Save journal entry to local storage
+ */
+function saveJournal() {
+    let data = getJournal()
+    let dateText = new Date(date.textContent).toLocaleDateString();
+    saveToStorage(data, dateText, "contents", journal.value)
+    localStorage.setItem("journals", JSON.stringify(data))
+}
+
+/**
+ * Get journal entry from local storage
+ * 
+ * @returns {string} journal entry text in parsed json format
+ */
+export function getJournal() {
+    let data = JSON.parse(localStorage.getItem("journals"))
+    if (data == null) {
+        data = {}
+    }
+    return data
+}
+
+/**
+ * Load journal entry from local storage
+ */
+function loadJournal() {
+    let data = getJournal()
+    let dateText = new Date(date.textContent).toLocaleDateString();
+    journal.value = loadFromStorage(data, dateText, "contents") || "";
+}
+
+/**
+ * Save tasks to local storage
+ */
+function saveTasks() {
+    let tasks = [];
+    document.querySelectorAll('.task-container li').forEach(task => {
+        let taskName = task.querySelector('.task-input').textContent;
+        let taskColor = task.style['background-color']
+        tasks.push({
+            text: taskName,
+            color: taskColor,
+        });
+    });
+
+    localStorage.setItem("tasks", JSON.stringify(tasks));
+
+    displayWeek();
+}
+
+/**
+ * Get tasks from local storage
+ *
+ * @returns {string} tasks in parsed json format or empty array if no tasks
+ */
+function getTasks() {
+    let storedTasks = localStorage.getItem("tasks");
+    return storedTasks ? JSON.parse(storedTasks) : [];
+}
+
+/**
+ * Load tasks from local storage
+ */
+function loadTasks() {
+    let tasks = getTasks();
+
+    if (tasks.length > 0) {
+        tasks.forEach(task => {
+            let curLi = addTask(true);
+            curLi.querySelector(".task-input").textContent = task['text']
+            curLi.style['background-color'] = task['color']
+        });
+    }
+
+}
+
+/**
+ * Saves the completed tasks and updates Past Week view
+ */
+function saveCompleted() {
+    let data = getJournal();
+    let completedTask = [];
+    let dateText = new Date(date.textContent).toLocaleDateString();
+
+    document.querySelectorAll('.completed-task-container li').forEach(completedTaskElement => {
+        let taskName = completedTaskElement.querySelector('.task-input').textContent;
+        let taskColor = completedTaskElement.style['background-color']
+        completedTask.push({
+            text: taskName,
+            color: taskColor,
+        });
+    });
+
+    saveToStorage(data, dateText, "completedTasks", completedTask);
+    localStorage.setItem("journals", JSON.stringify(data));
+
+    displayWeek();
+}
+
+/**
+ * Fetch completed tasks from storage in proper format
+ * 
+ * @returns {string} tasks data in proper format
+ */
+function getCompleted() {
+    let data = getJournal();
+    let dateText = new Date(date.textContent).toLocaleDateString();
+    let storedTasks = loadFromStorage(data, dateText, "completedTasks");
+    return storedTasks ? storedTasks : [];
+}
+
+/**
+ * Load and populate completed tasks from local storage
+ */
+function loadCompleted() {
+    let tasks2 = getCompleted();
+    if (tasks2.length > 0) {
+        tasks2.forEach(task => {
+            let curLi = addTask(true);
+            completedTasks.appendChild(curLi);
+            curLi.querySelector(".task-input").textContent = task['text']
+            curLi.style['background-color'] = task['color']
+            curLi.classList.add('complete')
+        });
+    }
+}
+
+/**
+ * Remove completed tasks from interface upon changing dates
+ */
+function unselectAllCompleted() {
+    document.querySelectorAll('.completed-task-container li').forEach(task => {
+        task.remove();
+    });
+}
+
+/**
+ * Save widgets to local storage and updates Past Week view
+ * 
+ * @param {int} value - ID value of the widget selected
+ */
+function saveWidgets(value) {
+    let data = getJournal();
+    let dateText = new Date(date.textContent).toLocaleDateString();
+    if (value < 6) {
+        saveToStorage(data, dateText, "rating", value);
+    }
+    else {
+        saveToStorage(data, dateText, "productivity", value);
+    }
+
+    localStorage.setItem("journals", JSON.stringify(data));
+
+    displayWeek();
+}
+
+/**
+ * Load widget ratings from local storage and update interface
+ */
+function loadWidgets() {
+    let data = getJournal();
+    let dateText = new Date(date.textContent).toLocaleDateString();
+    let rating = loadFromStorage(data, dateText, "rating");
+    let productivity = loadFromStorage(data, dateText, "productivity");
+
+    if (rating != null) {
+        selectWidget(rating);
+    }
+    if (productivity != null) {
+        selectWidget(productivity);
+    }
+}
+
+/**
+ * Fetches data from local storage and populates Past Week view
+ * @param {HTMLElement} cellData - Data for specified day
+ * @param {Date} currWeekDay - Date to populate data within
+ */
+function loadCellData(cellData, currWeekDay) {
+    let journals = getJournal();
+    let dateText = currWeekDay.toLocaleDateString();
+
+    let rating = loadFromStorage(journals, dateText, "rating");
+    let productivity = loadFromStorage(journals, dateText, "productivity");
+    let tasks = loadFromStorage(journals, dateText, "completedTasks");
+
+    if (rating != null) {
+
+        // Add sentiment icon
+        let sentimentIcon = document.createElement("img");
+        sentimentIcon.src = `../icons/${RATING_FILES_NAMES[rating - 1]}`;
+        sentimentIcon.alt = "sentiment icon";
+        sentimentIcon.className = "sentiment-icon";
+
+        // Append sentiment icon to new cell
+        cellData.appendChild(sentimentIcon);
+    }
+
+    if (productivity != null) {
+
+        // Add productivity icon
+        let productivityIcon = document.createElement("img");
+        productivityIcon.src = `../icons/${PRODUCTIVITY_FILES_NAMES[productivity - 1 - 5]}`;
+        productivityIcon.alt = "productivity icon";
+        productivityIcon.className = "productivity-icon";
+
+        // Append sentiment icon to new cell
+        cellData.appendChild(productivityIcon);
+    }
+
+    // Add tasklist in calendar cell
+    let taskDiv = document.createElement("div");
+    taskDiv.className = "task-div";
+    let taskList = document.createElement("ul");
+    taskList.className = "task-ul";
+
+    // Format task
+    if (tasks != null) {
+        for (let i = 0; i < tasks.length && i < DISPLAY_TASK_COUNT; i++) {
+            let taskItem = document.createElement("li");
+            taskItem.textContent = tasks[i]["text"];
+            taskItem.className = "task-item";
+            taskItem.style.setProperty('--task-color', tasks[i]["color"]);
+            taskList.appendChild(taskItem);
+        }
+
+        // Extra tasks are indicated but not displayed
+        if (tasks.length > DISPLAY_TASK_COUNT) {
+            let taskExtra = document.createElement("li");
+            taskExtra.textContent = `${tasks.length - DISPLAY_TASK_COUNT} more tasks`;
+            taskExtra.className = "task-indicator";
+            taskList.appendChild(taskExtra);
+        }
+    }
+
+    // Create buttons that link to speciic homepage and extract selected date
+    let aLink = document.createElement("a");
+    let dayLink = currWeekDay.getDate();
+    let monthLink = currWeekDay.getMonth();
+    let yearLink = currWeekDay.getFullYear()
+
+    // Query is in format ?date=month-day-year
+    aLink.href = `../homepage/homepage.html?date=${monthLink}-${dayLink}-${yearLink}`;
+    aLink.className = "a-link";
+    aLink.setAttribute("aria-label", `Link to details for ${monthLink + 1}/${dayLink}/${yearLink}`);
+    cellData.appendChild(aLink);
+
+    // Append taskList to task div;
+    taskDiv.appendChild(taskList);
+
+    // Append tasklist div to new cell
+    cellData.appendChild(taskDiv);
+}
+
+/**
+ * Links calendar cell to homepage on corresponding date
+ */
+function dateQuery() {
+    // Extract query from the page
+    let params = new URLSearchParams(window.location.search);
+    let date = params.get("date");
+
+    if (date) {
+        let components = date.split('-');
+        currDate = new Date(components[2], components[0], components[1]);
+    }
+}
+
+/**
+ * Expands task list from collapsed state
+ */
+function taskListViewHandler() {
+    const taskList = document.querySelector('.task-list');
+    const taskWrap = document.querySelector('.task-wrapper');
+    const outSide = document.querySelector('.main-wrap');
+
+    taskList.addEventListener('click', function(event) {
+        if (event.target === taskList) {
+            if (window.innerWidth <= 800) { 
+                taskList.classList.toggle('active');
+                taskWrap.classList.toggle('active');
+            }
+        }
+    });
+
+    outSide.addEventListener('click', function(){
+        if (window.innerWidth <= 800) { 
+            taskList.classList.remove('active');
+            taskWrap.classList.remove('active');
+        }
+    });
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/js-doc/index.html b/js-doc/index.html new file mode 100644 index 00000000..6e59439d --- /dev/null +++ b/js-doc/index.html @@ -0,0 +1,71 @@ + + + + + JSDoc: Home + + + + + + + + + + +
+ +

Home

+ + + + + + + + +

+ + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/js-doc/scripts/linenumber.js b/js-doc/scripts/linenumber.js new file mode 100644 index 00000000..4354785c --- /dev/null +++ b/js-doc/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(() => { + const source = document.getElementsByClassName('prettyprint source linenums'); + let i = 0; + let lineNumber = 0; + let lineId; + let lines; + let totalLines; + let anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = `line${lineNumber}`; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/js-doc/scripts/prettify/Apache-License-2.0.txt b/js-doc/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/js-doc/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/js-doc/scripts/prettify/lang-css.js b/js-doc/scripts/prettify/lang-css.js new file mode 100644 index 00000000..041e1f59 --- /dev/null +++ b/js-doc/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/js-doc/scripts/prettify/prettify.js b/js-doc/scripts/prettify/prettify.js new file mode 100644 index 00000000..eef5ad7e --- /dev/null +++ b/js-doc/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.source +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.source code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/js-doc/styles/prettify-jsdoc.css b/js-doc/styles/prettify-jsdoc.css new file mode 100644 index 00000000..5a2526e3 --- /dev/null +++ b/js-doc/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/js-doc/styles/prettify-tomorrow.css b/js-doc/styles/prettify-tomorrow.css new file mode 100644 index 00000000..b6f92a78 --- /dev/null +++ b/js-doc/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/source/.DS_Store b/source/.DS_Store index 5008ddfc..47a6258c 100644 Binary files a/source/.DS_Store and b/source/.DS_Store differ diff --git a/source/calendar/calendar.html b/source/calendar/calendar.html index 3931b654..eef0aad8 100644 --- a/source/calendar/calendar.html +++ b/source/calendar/calendar.html @@ -1,27 +1,26 @@ - - - - Calendar - - - - - - - + + + Dev Calendar + + + + + + + + + + -
- +
- +

Tasks

diff --git a/source/calendar/calendar.js b/source/calendar/calendar.js index 204eb1bc..e660d0f4 100644 --- a/source/calendar/calendar.js +++ b/source/calendar/calendar.js @@ -10,6 +10,9 @@ var currDate = new Date(); var month = currDate.getMonth(); var year = currDate.getFullYear(); +// Defines confetti +const confetti = window.confetti; + /** * Updates the global date variables to the current date. */ @@ -265,6 +268,12 @@ function taskButtonsFunctionality(task) { saveCompleted(task); task.remove() saveTasks(); + + confetti({ + particleCount: 100, + spread: 70, + origin: { y: 0.6 } + }); } }); } diff --git a/source/homepage/homepage.css b/source/homepage/homepage.css index 4975ae43..e6dffad6 100644 --- a/source/homepage/homepage.css +++ b/source/homepage/homepage.css @@ -208,7 +208,6 @@ button:hover { -webkit-box-orient: unset; overflow: unset; text-overflow: unset; - } } /* Set task placeholder */ diff --git a/source/homepage/homepage.html b/source/homepage/homepage.html index 2185a774..2b4017d5 100644 --- a/source/homepage/homepage.html +++ b/source/homepage/homepage.html @@ -1,6 +1,5 @@ - diff --git a/source/homepage/homepage.js b/source/homepage/homepage.js index 5cda08d8..04277ac6 100644 --- a/source/homepage/homepage.js +++ b/source/homepage/homepage.js @@ -7,6 +7,9 @@ window.addEventListener('DOMContentLoaded', init); // Get current date global var currDate = new Date(); +// Defines confetti +const confetti = window.confetti; + /** * Initializes all necessary components */ @@ -197,11 +200,11 @@ function addTask(loadTask = false) {
- - - - - + + + + +
Remove `); @@ -301,6 +304,12 @@ function taskButtonsFunctionality(task) { completedTaskContainer.appendChild(task); saveCompleted(); saveTasks(); + + confetti({ + particleCount: 100, + spread: 70, + origin: { y: 0.6 } + }); } }); } diff --git a/specs/adr/053124-PuppeteerFiles.md b/specs/adr/053124-PuppeteerFiles.md new file mode 100644 index 00000000..490b338d --- /dev/null +++ b/specs/adr/053124-PuppeteerFiles.md @@ -0,0 +1,13 @@ +# Amount of Puppeteer Files for our Tests + +Decision occured during weekly meeting on May 31, Friday + +Decision: How many files should the puppeteer tests belong in +- We are creating tests for the homepage, calendar, and tasklist +- Many of the tests associate with multiple difference facets of the app at once +- The tests should follow the user's path of interaction where the user interacts with many features in a single sitting +- The tests should be able pass even after changes to other facets of the system have been interacted with + +Team decided that the all the puppeteer tests should be in a single file. Our first reason is that it will provide a stronger representation of the user flow. +This is because the user may interact with every feature in a single sitting and so the tests should represent how certain features respond to other feature interactions. +The second reason is that it is easier to integrate multiple difference aspects of the website in a test if there is no problem with a certain file only associating with a certain test. diff --git a/specs/adr/053124-Testing&Settings.md b/specs/adr/053124-Testing&Settings.md new file mode 100644 index 00000000..5c7675d6 --- /dev/null +++ b/specs/adr/053124-Testing&Settings.md @@ -0,0 +1,18 @@ +# Testing and Settings Page + +Decision occured during weekly meeting on May 31, Friday + +Decision #1: What should we do about unit tests vs e2e testing +- We would like to include both unit tests and e2e/frontend interaction testing +- Our JS funcitons mainly interact with the webpage; there is not much computation involved +- Unit tests test individual functions, e2e testing tests user interface interactions + +Team decided that the majority of our testing will be using Puppeteer as e2e testing. Although, we will +also employ unit tests on the individual functions that we're able to test using Jest. + +Decision #2: Do we have time to implement the Settings page we talked about +- We are on track with respect to our timeline, but our timeline did not include extra time for supplementary features +- Our settings page would not consist of much apart from color theme choices and character limit on tasks + +Team decided that given the time constraints and the fact that the settings page is an additional, nonvital +feature, we will not implement a settings page.