diff options
Diffstat (limited to 'js/quest-log/quest.js')
-rw-r--r-- | js/quest-log/quest.js | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/js/quest-log/quest.js b/js/quest-log/quest.js new file mode 100644 index 0000000..0ba5a9d --- /dev/null +++ b/js/quest-log/quest.js @@ -0,0 +1,151 @@ +document.addEventListener("DOMContentLoaded", () => { + loadQuests(); + document.getElementById("new-quest").addEventListener("keypress", handleEnterKey(addQuest)); +}); + +const curry = fn => (...args) => + args.length >= fn.length + ? fn(...args) + : curry(fn.bind(null, ...args)); + +const addQuest = () => { + const questText = getInputValue("new-quest"); + + if (!validateText(questText)) return; + + const quest = createQuestObject(questText); + saveQuest(quest); + clearInput("new-quest")(); + renderQuests(); +}; + +const getInputValue = curry((id) => document.getElementById(id).value); + +const validateText = text => text.trim() !== ""; + +const createQuestObject = text => ({ + id: Date.now(), + text, + status: "new", + dateCreated: new Date().toISOString(), + dateCompleted: null +}); + +const saveQuest = quest => { + const quests = getStoredQuests().concat([quest]); + localStorage.setItem("quests", JSON.stringify(quests)); +}; + +const getStoredQuests = () => + JSON.parse(localStorage.getItem("quests")) || []; + +const clearInput = curry((id) => () => + document.getElementById(id).value = ""); + +const loadQuests = () => renderQuests(); + +const renderQuests = (showCompleted = false) => { + const quests = getStoredQuests(); + const sortedQuests = sortByDateCreated(quests); + const filteredQuests = filterQuests(showCompleted, sortedQuests); + renderQuestList(filteredQuests); +}; + +const sortByDateCreated = quests => + quests.sort((a, b) => new Date(b.dateCreated) - new Date(a.dateCreated)); + +const filterQuests = (showCompleted, quests) => + quests.filter(quest => showCompleted || quest.status !== "complete"); + +const renderQuestList = quests => { + const questList = document.getElementById("quest-list"); + questList.innerHTML = ""; + quests.forEach(renderQuest(questList)); +}; + +const renderQuest = curry((questList, quest) => { + const questDiv = document.createElement("div"); + questDiv.className = `quest ${quest.status}`; + questDiv.innerHTML = ` + <span contenteditable="true" onblur="editQuest(${quest.id}, this.innerText)">${quest.text}</span> + <span> + ${quest.status !== "complete" ? `<button onclick="toggleStatus(${quest.id})">${getStatusButtonText(quest.status)}</button>` : ''} + ${quest.status === "complete" ? `<button onclick="revertQuest(${quest.id})">Revert</button><button onclick="deleteQuest(${quest.id})">Delete</button>` : ''} + </span> + `; + questList.appendChild(questDiv); +}); + +const getStatusButtonText = status => + status === "new" ? "Start Quest" : "Complete Quest"; + +const toggleStatus = id => { + const quests = getStoredQuests(); + const updatedQuests = updateQuestStatus(id, quests); + saveAllQuests(updatedQuests); + renderQuests(); +}; + +const updateQuestStatus = (id, quests) => + quests.map(quest => + quest.id === id ? updateQuest(quest) : quest + ); + +const updateQuest = quest => { + if (quest.status === "new") return { ...quest, status: "in-progress" }; + if (quest.status === "in-progress") + return { ...quest, status: "complete", dateCompleted: new Date().toISOString() }; + return quest; +}; + +const revertQuest = id => { + const quests = getStoredQuests(); + const updatedQuests = revertQuestStatus(id, quests); + saveAllQuests(updatedQuests); + renderQuests(true); +}; + +const revertQuestStatus = (id, quests) => + quests.map(quest => + quest.id === id ? { ...quest, status: "in-progress", dateCompleted: null } : quest + ); + +const deleteQuest = id => { + const quests = getStoredQuests(); + const updatedQuests = removeQuest(id, quests); + saveAllQuests(updatedQuests); + renderQuests(true); +}; + +const removeQuest = (id, quests) => + quests.filter(quest => quest.id !== id); + +const saveAllQuests = quests => + localStorage.setItem("quests", JSON.stringify(quests)); + +const editQuest = (id, newText) => { + const quests = getStoredQuests(); + const updatedQuests = updateQuestText(id, newText, quests); + saveAllQuests(updatedQuests); +}; + +const updateQuestText = (id, newText, quests) => + quests.map(quest => + quest.id === id ? { ...quest, text: newText } : quest + ); + +const handleEnterKey = curry((fn, event) => { + if (event.key === "Enter") fn(); +}); + +const toggleCompleted = () => { + const showCompleted = getShowCompletedState(); + renderQuests(showCompleted); + toggleCompletedButtonText(showCompleted); +}; + +const getShowCompletedState = () => + document.querySelector("button[onclick='toggleCompleted()']").innerText === "View Completed Quests"; + +const toggleCompletedButtonText = showCompleted => + document.querySelector("button[onclick='toggleCompleted()']").innerText = showCompleted ? "Hide Completed Quests" : "View Completed Quests"; |