summaryrefslogblamecommitdiffstats
path: root/assets/js/meals.js
blob: e9b3af8559cf373f395146f8481c6c6e1a6e5f2a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                                                    
 
                             











                                                              
 
 
                            




                                                
 
 
                                                        
























                                                                 
                                                            


















                                                                                                     
 
 
                                                                  
























                                                                   
                                                          

































                                                                                                               
 

 
                            
                                           
 
 
                              













































































                                                                                                                                                                                                                        

 
                       



                                                               

 


                         

 
                          


                                                    

 
                               











































                                                                                                 
 
 
                                                                                                                         
 














































                                                                                                         
 
                                    


                                           
 
 










                                    

                                                           
                 


                          































                                                                   
   
const API_ENDPOINT = "https://lopolis-api.gimb.tk/";

async function checkLogin() {
    localforage.getItem("logged_in_lopolis").then((value) => {
        if (value != true) {
            $("#meals-container").hide();
            $("#meals-login").show();
        } else {
            $("#meals-container").show();
            $("#meals-login").hide();
            loadMeals();
        }
    }).catch((err) => {
        console.log(err);
    });
}

function setLoading(state) {
    if (state) {
        $("#loading-bar").removeClass("hidden");
    } else {
        $("#loading-bar").addClass("hidden");
    }
}

async function getToken(callback, callbackparams = []) {
    setLoading(true);
    let promises_to_run = [
        localforage.getItem("lopolis_username").then((value) => {
            username = value;
        }),
        localforage.getItem("lopolis_password").then((value) => {
            password = value;
        })
    ];
    await Promise.all(promises_to_run);

    $.ajax({
        url: API_ENDPOINT + "gettoken",
        crossDomain: true,
        contentType: "application/json",
        data: JSON.stringify({
            "username": username,
            "password": password
        }),

        dataType: "json",
        cache: false,
        type: "POST",

        success: (dataauth) => {
            if(dataauth == null || dataauth.error == true) {
                UIAlert(D("authenticationError"), "getToken(): response error or null");
                localforage.setItem("logged_in_lopolis", false).then( function(){
                    checkLogin();
                });
            } else if (dataauth.error == false) {
                let empty = {};
                empty.token = dataauth.data;
                let argumentsToCallback = [empty].concat(callbackparams);
                callback(...argumentsToCallback); // poslje token v {token: xxx}
            } else {
                UIAlert( D("authenticationError"), "getToken(): invalid response, no condition met");
            }
            setLoading(false);
        },
        error: () => {
            UIAlert( D("lopolisAPIConnectionError"), "getToken(): AJAX error");
            setLoading(false);
        }
    });
}

async function getMenus(dataauth, callback, callbackparams = []) {
    setLoading(true);
    let current_date = new Date();
    // naloži za dva meseca vnaprej (če so zadnji dnevi v mesecu)
    let mealsgathered = {};
    let promises_to_wait_for = [];
    for (let iteration = 1; iteration <= 2; iteration++) {

        promises_to_wait_for[iteration] = $.ajax({
            url: API_ENDPOINT+"getmenus",
            crossDomain: true,
            contentType: "application/json",
            data: JSON.stringify({
                "month": current_date.getMonth() + iteration,
                "year": current_date.getFullYear()
            }),

            headers: {
                "Authorization": `Bearer ${dataauth.token}`
            },

            dataType: "json",
            cache: false,
            type: "POST",

            success: (meals) => {
                if(meals == null || meals.error == true) {
                    UIAlert( D("errorGettingMenus"), "getMenus(): response error or null");
                    setLoading(false);
                    localforage.setItem("logged_in_lopolis", false).then( () => {
                        checkLogin();
                    });
                } else if (meals.error == false) {
                    setLoading(false);
                    mealsgathered[iteration] = meals;
                    } else {
                    setLoading(false);
                    UIAlert( D("errorUnexpectedResponse") , "getMenus(): invalid response, no condition met");
                }
            },

            error: () => {
                setLoading(false);
                UIAlert( D("lopolisAPIConnectionError"), "getMenus(): AJAX error");
            }
        });
    }

    await Promise.all(promises_to_wait_for); // javascript is ducking amazing

    let allmeals = {};
    let passtocallback = {};

    for (const [index, monthmeals] of Object.entries(mealsgathered)) { // although this is not very javascripty
        allmeals = mergeDeep(allmeals, monthmeals.data);
    }

    passtocallback.data = allmeals;
    passtocallback.token = dataauth.token;
    let toBePassed = [passtocallback].concat(callbackparams);
    callback(...toBePassed);

}

async function loadMeals() {
    getToken(getMenus, [displayMeals, []]);
}

function displayMeals(meals) {
    // console.log(JSON.stringify(meals)); // debug // dela!

    let root_element = document.getElementById("meals-collapsible");
    for (const [date, mealzz] of Object.entries(meals.data)) {
        let unabletochoosequestionmark = "";
        let readonly = mealzz.readonly;
        var datum = new Date(date);

        // Create root element for a date entry
        let subject_entry = document.createElement("li");

        // Create subject collapsible header
        let subject_header = document.createElement("div");
        subject_header.classList.add("collapsible-header");
        subject_header.classList.add("collapsible-header-root");

        // Create header text element
        let subject_header_text = document.createElement("span");

        if(mealzz.readonly) {
            unabletochoosequestionmark = `*${S("readOnly")}*`;
        }

        // Use ES6 templates
        subject_header_text = `${dateString.day(datum.getDay())}, ${datum.getDate()}. ${dateString.month(datum.getMonth())} ${datum.getFullYear()} (${mealzz.meal} @ ${mealzz.location}) ${unabletochoosequestionmark}`;

        // Create collection for displaying individuals meals
        let subject_body = document.createElement("div");
        subject_body.className = "collapsible-body";
        let subject_body_root = document.createElement("ul");
        subject_body_root.className = "collection";

        for(const [dindex, dmil] of Object.entries(mealzz.menu_options)) {
            // Create element for individual meal
            let meal_node = document.createElement("li");
            meal_node.className = "collection-item";
            meal_node.classList.add("collection-item")
            meal_node.classList.add("meal-node");
            meal_node.dataset["index"] = dindex;

            if (!readonly) {
                meal_node.onclick = () => {
                    setMenu(date, dmil.value);
                }
            }

            let meal_node_div = document.createElement("div");
            // Node for left text
            let meal_lefttext = document.createElement("span");
            // Node for the right text
            let meal_righttext = document.createElement("div");
            meal_righttext.className = "secondary-content";
            // Apply different style, if the meal is selected
            if (dmil.selected) {
                // Text
                meal_lefttext.innerHTML = `<i>${dmil.text}</i>`;
                // Number
                meal_righttext.innerText = S("selected");
            } else {
                // Text
                meal_lefttext.innerText = dmil.text;
                // Number
                meal_righttext.innerText = "";
            }
            meal_node_div.appendChild(meal_lefttext);
            meal_node_div.appendChild(meal_righttext);
            meal_node.appendChild(meal_node_div);
            subject_body_root.appendChild(meal_node);
        }

        subject_header.appendChild(subject_header_text);
        subject_body.append(subject_body_root);
        subject_entry.append(subject_header);
        subject_entry.append(subject_body);
        root_element.append(subject_entry);
    }
    $("#meals-collapsible").append(root_element);
    // refreshClickHandlers();
}

function clearMeals() {
    const table = document.getElementById("meals-collapsible");
    while (table.firstChild) {
        table.removeChild(table.firstChild);
    }
}

function refreshMeals() {
    clearMeals();
    loadMeals();
}

function lopolisLogout() {
    localforage.setItem("logged_in_lopolis", false);
    $("#meals-collapsible").html("");
    checkLogin();
}

async function lopolisLogin() {
    setLoading(true);
    var usernameEl = $("#meals_username");
    var passwordEl = $("#meals_password");
    $.ajax({
        url: API_ENDPOINT+"gettoken",
        crossDomain: true,
        contentType: "application/json",
        data: JSON.stringify({
            "username": usernameEl.val(),
            "password": passwordEl.val()
        }),

        dataType: "json",
        cache: false,
        type: "POST",

        success: async function(data) {
            if(data == null) {
                UIAlert( S("requestForAuthenticationFailed"), "lopolisLogin(): date is is null");
                setLoading(false);
                usernameEl.val("");
                passwordEl.val("");
            } else if(data.error == true) {
                UIAlert( S("loginFailed"), "lopolisLogin(): login failed. data.error is true");
                usernameEl.val("");
                passwordEl.val("");
                setLoading(false);
            } else {
                let promises_to_run = [
                    localforage.setItem("logged_in_lopolis", true),
                    localforage.setItem("lopolis_username", usernameEl.val()),
                    localforage.setItem("lopolis_password", passwordEl.val())
                ];
                await Promise.all(promises_to_run);
                checkLogin();
                UIAlert("Credential match!");
            }
        },

        error: () => {
            UIAlert( D("loginError"), "lopolisLogin(): ajax.error");
            setLoading(false);
        }
    });
}

async function setMenus(currentmeals = 69, toBeSentChoices) { // currentmeals je getMenus response in vsebuje tudi token.

    if (currentmeals === 69) {
        getToken(getMenus, [setMenus, toBeSentChoices]);
        return;
    }

    for(const [mealzzdate, mealzz] of Object.entries(currentmeals.data)) {
        if (mealzzdate in toBeSentChoices === false) {
            for (const [mealid, mealdata] of Object.entries(mealzz.menu_options)) {
                console.log(mealdata);
                if(mealdata.selected == true || mealzz.readonly == true) {
                    toBeSentChoices[mealzzdate] = mealdata.value;
                    break;
                }
            }
        }
    }

    setLoading(true);

    $.ajax({
        url: API_ENDPOINT + "setmenus",
        crossDomain: true,
        contentType: "application/json",
        data: JSON.stringify( { "choices": toBeSentChoices } ),
        headers: {
            "Authorization": "Bearer " + currentmeals.token
        },
        dataType: "json",
        cache: false,
        type: "POST",

        success: (response) => {
            if(response === null || response.error == true) {
                UIAlert( D("errorSettingMeals"), "setMenus(): response error or null");
            } else if (response.error == false) {
                UIAlert( D("mealSet"), "setMenus(): meni nastavljen");
            } else {
                UIAlert( D("errorUnexpectedResponse"), "setMenus(): invalid response, no condition met");
            }
            setLoading(false);
        },

        error: () => {
            setLoading(false);
            UIAlert( D("lopolisAPIConnectionError"), "setMenus(): AJAX error");
        }
    });
}
async function setMenu(date, menu) {
    let choice = {};
    choice[date] = menu;
    getToken(getMenus, [setMenus, choice]);
}


function setupEventListeners() {
    $("#meals-login").click(() => {
        lopolisLogin();
    });

    $("#meals-logout").click(() => {
        lopolisLogout();
    });
}

// Initialization code
document.addEventListener("DOMContentLoaded", async () => {
    checkLogin();

    setupEventListeners();

    let coll_elem = document.querySelectorAll('.collapsible');
    M.Collapsible.init(coll_elem, {});

    // Setup refresh handler
    $("#refresh-icon").click(function () {
        refreshMeals();
    });

    let elems = document.querySelectorAll('.modal');
    M.Modal.init(elems, {});
    // Setup side menu
    const menus = document.querySelectorAll('.side-menu');
    M.Sidenav.init(menus, { edge: 'right', draggable: true });

    // Setup side modal
    const modals = document.querySelectorAll('.side-modal');
    M.Sidenav.init(modals, { edge: 'left', draggable: false });

    var elemsx = document.querySelectorAll('select');
    M.FormSelect.init(elemsx);

    var datepickerelems = document.querySelectorAll('.datepicker');
    var today = new Date();
    M.Datepicker.init(datepickerelems, {
        firstDay: 1,
        minDate: today,
        showDaysInNextAndPreviousMonths: true,
        showClearBtn: true,
        format: "dddd, dd. mmmm yyyy"
    });

    refreshMeals();
});