about summary refs log blame commit diff stats
path: root/js/quest-log/quest.js
blob: 0ba5a9d480534d35554271b5641edd3a0b00bf6d (plain) (tree)






















































































































































                                                                                                                                                                        
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";