daily-log_daily-log.js

import LocalStorageRecordsApi from "../backend-storage/records-api.js";
import { Record } from "../backend-storage/record-class.js";
import LocalStorageAccomplishmentsApi from "../backend-storage/accomplishments-api.js";
import { AccomplishmentsObj } from "../backend-storage/accomplishments-class.js";

/**
 * Populates the daily log with the information from the record object
 * @param {Record} record - The record containing either from the record from local storage or new a record
 */
function populateDefaultLog(record) {
    const updateH1 = document.querySelector("h1");
    // no check because title should be there
    updateH1.innerHTML = record.title;
    const updateField1 = document.querySelector("#done-today");

    // check to see if field1 is null
    if (record.field1) {
        updateField1.value = record.field1;
    }
    const updateField2 = document.querySelector("#reflection");
    // check to see if field2 is null
    if (record.field2) {
        updateField2.value = record.field2;
    }
    const updateHours = document.querySelector("#hours");
    // check to see if hours is null
    if (record.hours) {
        updateHours.value = record.hours;
    }

    // if accomplishments exists, populate them on the page
    if (record.hasAccomplishment) {
        // date to search the accomplishment
        const date = new Date(record.date);
        const accomplishmentObj =
            LocalStorageAccomplishmentsApi.getAccomplishmentsObjByDate(date);
        // get the parargraph where the accomplishments would be polated as a list
        const displayParagraph = document.querySelector(
            ".js-accomplishment-list"
        );
        // loop over all content in the accomplishment object, and make each accomplishment list element with buttons
        for (const item of accomplishmentObj.content) {
            let newItem = document.createElement("li");
            //adds the content and buttons to the list element
            newItem = updateContentButtons(newItem, item);
            //append the list object into the paragraph
            displayParagraph.append(newItem);
        }
    }
}

/**
 * Updates the imformation of the record saved in the local storage when the submit button is clicked
 * Jumps to the calendar page
 * @param {Record} record - The record containing either from the record from local storage or new a record
 */
function submitButtonClick(record) {
    // date from record object
    const date = new Date(record.date);
    // If record does not exists in local storage, make a new one.
    if (!LocalStorageRecordsApi.hasRecordByDate(date)) {
        LocalStorageRecordsApi.createRecord(record);
    }
    const updateField1 = document.querySelector("#done-today");
    // check to see if field1 is null and update record if not
    if (updateField1.value) {
        record.field1 = updateField1.value;
    }
    const updateField2 = document.querySelector("#reflection");
    // check to see if field2 is null and update record if not
    if (updateField2.value) {
        record.field2 = updateField2.value;
    }
    const updateHours = document.querySelector("#hours");
    // check to see if hours is null and update record if not
    if (updateHours.value) {
        record.hours = updateHours.value;
    }
    // get the paragraph tag with accomplishments listes in it
    const hasAccomplishments = document.querySelector(
        ".js-accomplishment-list"
    );

    // if accomplishments paragraph is not empty, update the hasAccomplishment variable in the record
    // and store accomplishments in the local storage
    if (hasAccomplishments.textContent !== "") {
        record.hasAccomplishment = true;
        // content array to hold all the accomplishments
        const content = [];
        // gets all the list items from the accomplishment paragraph
        const listItems = hasAccomplishments.querySelectorAll("li");
        // loop over the list items and append the text content of the firstChild into the content array
        for (const item of listItems) {
            content.push(item.firstChild.textContent.trim());
        }
        let accomplishmentObj;
        // if accomplishment exists in local storage, update it; else, make an accomplishment
        if (LocalStorageAccomplishmentsApi.hasAccomplishmentsObjByDate(date)) {
            // get the accomplishment object from local storage
            accomplishmentObj =
                LocalStorageAccomplishmentsApi.getAccomplishmentsObjByDate(
                    date
                );
            // assign the content array to the content of the accomplishment object
            accomplishmentObj.content = content;
            // update the accomplishment object in local storage
            LocalStorageAccomplishmentsApi.updateAccomplishmentsObj(
                accomplishmentObj
            );
        } else {
            // create a new accomplishment object
            accomplishmentObj = new AccomplishmentsObj(content, date);
            // store the acomplishemnt object in the local storage
            LocalStorageAccomplishmentsApi.createAccomplishmentsObj(
                accomplishmentObj
            );
        }
    } else {
        record.hasAccomplishment = false;
        // delete the accomplishment object from local storage
        // as all accomplishment very deleted or none were added
        if (LocalStorageAccomplishmentsApi.hasAccomplishmentsObjByDate(date)) {
            LocalStorageAccomplishmentsApi.deleteAccomplishmentsObj(date);
        }
    }
    // update record in the local storage
    LocalStorageRecordsApi.updateRecord(record);
    // links to the calendar page
    window.location.href = "../calendar/calendar.html";
}

/**
 * Delets record from local storage when the delete button is clicked
 * Has a confirm message, to ask for confirmation
 * Brings to the calendar page
 * @param {Record} record - The record containing either from the record from local storage or new a record
 */
function deleteButtonClick(record) {
    const date = new Date(record.date);
    // if record does exists in local storage, delete it.
    if (LocalStorageRecordsApi.hasRecordByDate(date)) {
        // confirm to see if user wants to delete
        // if ok, call delete function from local storage
        if (window.confirm("Are you sure you want to delete this record?")) {
            LocalStorageRecordsApi.deleteRecord(record.id);
            // if accomplishments for the date exist in the local stoarge, delete them
            if (
                LocalStorageAccomplishmentsApi.hasAccomplishmentsObjByDate(date)
            ) {
                LocalStorageAccomplishmentsApi.deleteAccomplishmentsObj(date);
            }
            // links to the calendar page
            window.location.href = "../calendar/calendar.html";
        }
    }
}

/**
 * Adds a new list item into the accomplishment paragraph
 * Clears the input value for accomplishment input, so that new input can be taken in
 */
function addAccomplishment() {
    // get the input element with new accomplishemnt text
    const newInput = document.querySelector(".js-accomplishment-input");
    // get the accomplishment paragarph
    const displayParagraph = document.querySelector(".js-accomplishment-list");
    // get the text from the input
    const inputValue = newInput.value.trim();
    // if input value not empty, create list element to store new accomplishment
    if (inputValue) {
        let newItem = document.createElement("li");
        // update content and add buttons to the list element
        newItem = updateContentButtons(newItem, inputValue);
        displayParagraph.prepend(newItem);
        // clear the input
        newInput.value = "";
    }
}

/**
 * Updates the content of a specific accomplishment by
 * Creates an input box to get updated accomplishment
 * @param {HTMLLIElement} item - The list element with the content and buttons in it
 */
function editAccomplishment(item) {
    // create an input element that will replace the text for editing
    const input = document.createElement("input");
    input.type = "text";
    // set input value to current text
    input.value = item.firstChild.textContent.trim();
    //allow to tab through
    input.select();

    // Clear the text
    item.firstChild.textContent = "";
    // add input element before the edit/done and delete buttons
    item.insertBefore(input, item.childNodes[1]);

    // get the edit and done buttons to change their classList after done editing
    const editButton = item.querySelector("#edit");
    const doneButton = item.querySelector("#done");
    // with done is clicked, the content is changed and the classList are updated
    doneButton.addEventListener("click", () => {
        editButton.classList.remove("hidden");
        doneButton.classList.add("hidden");
        // if input is not empty, update the text inside list; else delete the list element
        if (input.value.trim() !== "") {
            item.firstChild.textContent = input.value.trim() + " ";
        } else {
            // delete accopmlishment if empty input
            deleteAccomplishment(item);
        }
        // Remove the input field
        input.remove();
    });
}

/**
 * Delete the list element
 * Confirms if the element is to be deleted
 * @param {HTMLLIElement} newItem - The list element with the updated content and buttons
 */
function deleteAccomplishment(item) {
    if (
        confirm(
            "Are you sure you want to remove this accomplishment? This action cannot be undone."
        )
    ) {
        item.remove();
    }
}

/**
 * Updates an accomplishment list element by adding text
 * and buttons for edit, done, and delete actions
 * @param {HTMLLIElement} newItem - The list element
 * @param {string} text - The content to be added to the list item
 * @returns {HTMLLIElement} The list element with the updated content and buttons
 */
function updateContentButtons(newItem, text) {
    // add a class to style the new accomplishment item
    newItem.classList.add("accomplishment-text");
    // set the text content of the new accomplishment list item
    newItem.innerText = text;

    // create a container for the accomplishment buttons
    const accomplishmentButtons = document.createElement("div");
    accomplishmentButtons.classList.add("accomplishment-buttons");
    // create the Edit button
    const editButton = document.createElement("button");
    editButton.textContent = "Edit";
    editButton.setAttribute("id", "edit");
    // create the Done button and hide it initially
    const doneButton = document.createElement("button");
    doneButton.setAttribute("id", "done");
    doneButton.textContent = "Done";
    doneButton.classList.add("hidden");
    // event listener to the Edit button to change to Done button and update accomplishment
    editButton.addEventListener("click", () => {
        editButton.classList.add("hidden");
        doneButton.classList.remove("hidden");
        editAccomplishment(newItem);
    });
    // create the Delete button
    const deleteButton = document.createElement("button");
    deleteButton.textContent = "Delete";
    deleteButton.setAttribute("id", "delete");
    // event listener to the delete accomplishment
    deleteButton.addEventListener("click", () => deleteAccomplishment(newItem));
    // append the buttons to the accomplishment buttons container
    accomplishmentButtons.appendChild(editButton);
    accomplishmentButtons.appendChild(doneButton);
    accomplishmentButtons.appendChild(deleteButton);
    // append the buttons container to the new accomplishment list item
    newItem.appendChild(accomplishmentButtons);
    //returns updated accomplishment
    return newItem;
}

/**
 * Initializes log functionality by setting up the event listeners for the submit and delete buttons
 * @param {string} text - The content to be added to the list item
 */
function logFunctionality(record) {
    //update content of the page
    populateDefaultLog(record);
    const submitButton = document.querySelector(".js-save-button");
    const deleteButton = document.querySelector(".js-delete-button");

    // Event listner for submit button
    submitButton.addEventListener("click", () => {
        submitButtonClick(record);
    });
    // Event listner for delete button
    deleteButton.addEventListener("click", () => {
        deleteButtonClick(record);
    });

    const addAccomplishmentBtn = document.querySelector(
        ".js-add-accomplishment"
    );
    // Event listner for add accomplishment button
    addAccomplishmentBtn.addEventListener("click", addAccomplishment);
}

/**
 * This function is called when the window is loaded.
 * Calls the logFunctionality function with the retrieved or created record.
 * @function
 * @name window.onload
 */
window.onload = function () {
    /**
     * The stringified record retrieved from sessionStorage.
     * @type {string|null}
     */
    const recordString = sessionStorage.getItem("current record");
    /**
     * The record object to be used.
     * @type {Record}
     */
    let record;
    /**
     * A new date object
     * @type {Date}
     */
    let today = new Date();
    today.setHours(0, 0, 0, 0);
    if (!recordString) {
        // if no record is found in sessionStorage, it checks local storage for a record by today's date.
        // if no record is found in local storage, it creates a new Record object.
        if (!LocalStorageRecordsApi.hasRecordByDate(today)) {
            record = new Record("log", { date: today });
        } else {
            record = LocalStorageRecordsApi.getRecordByDate(today);
        }
    } else {
        record = JSON.parse(recordString);
    }
    logFunctionality(record);
};