about summary refs log tree commit diff stats
path: root/js/quest-log/quest.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/quest-log/quest.js')
-rw-r--r--js/quest-log/quest.js151
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";