About & PurposePurpose: As said by the title this is just a simple web application for use of a SINGLE user. It has the features of calculating total hours, clocking in, and clocking out. It also has some functions that helps with the calculations. This is for OFFLINE USE ONLY.This is by no means for commercial use.List of Functions and their PurposeMain Functionsinitialize() - Sole purpose is to make sure that the user is in the proper state. If they already started their shift, then it will lock the CLOCK IN button and enable the CLOCK OUT button and vice-versa. (TL;DR Check session state.)populateTimeCard() - Populates the template with datas in the timeCardDatas (localStorage). This is done using Template-Engine.login() - returns true if the user types in the correct password. This is done by passing the input through the md5(input) function. Afterwards compares it to the MD5 Hash that is hardcoded.reset() - Simply removes the startShift. This is triggered by pressing the Clock Out button.calculateHours(single) - Takes param single. This is for calculating single values instead of an entire array. Ex: (mill1 - mill2) => 50hr. General purpose is to add up all the time and return that.markTime() - Gets the current time and marks it as start or end of shift depending on user session state.Utility Functions: militaryToStandard(time) - Converts military time to standard time.dowToWord(dow) - Turns time.getDay() to word. time.getDay() returns day of the week as int.padZero(number) - As the function names says gives padding zeroes for number less than 9 (1 digit numbers).constructTime(withDOW) - Constructs date in a clear format. (MM / DD / YYYY [DAY_OF_THE_WEEK]). Takes a param that either adds in Day of the Week or not.Codesindex.html<!DOCTYPE html><html>    <head>        <meta charset=utf-8>        <meta name=viewport content=width=device-width, initial-scale=1, shrink-to-fit=no>        <title>Time Card</title>        <link rel=stylesheet type=text/css href=css/main.css/>        <link rel=stylesheet type=text/css href=css/bootstrap.css/>        <style>            html, body {                margin : 0;                height: 100%;            }            .container-fluid {                height: 100%;            }            .row {                height: 100%;            }            .box-header {                background-color: #6C7E8F;                text-align: center;                padding: 8px;                color: #FFF;            }        </style>    </head>    <body style=background-color: #2c3e50;>        <div class=container-fluid>            <div class=row>                <div class=col-sm-8 style=padding: 0; border-right: 1px solid black; height: 100%;>                    <div class=card style=margin: 16px; height: 95%; >                        <h3 class=card-header>Interface</h3>                        <div class=card-block>                            <h4 class=card-title>Instructions</h4>                            <p class=card-text>Press the <b>Clock In</b> button when starting shift. This will get the current time and add it in your <i>Time Card</i>.</p>                            <p class=card-text>Press the <b>Clock Out</b> button when ending shift. This will get the current time and add it in your <i>Time Card</i>.</p>                            <!-- <hr>                            <h4>Datas</h4>                            <p>This is just showing all the datas available. Will be removed after final build. [For development purposes only.]</p>                            <br>                            <b style=color: blue>Date </b> <span id=clockInDate>N/A</span><br>                            <b style=color: green>Clock In </b> <span id=clockInData>N/A</span><br>                            <b style=color: red>Clock Out </b> <span id=clockOutData>N/A</span> -->                            <hr>                            <h4>Password</h4>                            <p>Please enter your password before pressing either <b>Clock In</b> or <b>Clock Out</b>.                            <div class=form-group id=password-group>                                <input class=form-control type=password id=password required/>                            </div>                        </div>                        <div class=card-footer text-muted>                            <button id=clockIn class=btn btn-primary btn-block>Clock In</button>                            <button id=clockOut class=btn btn-danger btn-block>Clock Out</button>                        </div>                    </div>                </div>                <div class=col-sm-4 style=background-color: #34495e; padding: 0;>                    <!-- <div class=header-container>                        <h4 class=box-header>Time Card</h4>                    </div>                    <div class=datas-container>                        <span id=time></span>                    </div> -->                    <div class=card style=margin: 16px; height: 95%; >                        <h3 class=card-header>Time Card</h3>                        <div class=card-block style=padding: 0>                            <div id=accordion role=tablist aria-multiselectable=true>                            </div>                        </div>                        <div class=card-footer>                            <b>Total Hours: </b> <span id=totalHours></span>                        </div>                    </div>                        <!-- <div class=card-footer text-muted>                            <button id=clockIn class=btn btn-primary btn-block>Clock In</button>                            <button id=clockOut class=btn btn-danger btn-block>Clock Out</button>                        </div> -->                </div>            </div>        </div>        <script src=js/jquery.min.js></script>        <script src=js/tether.js></script>        <script src=js/bootstrap.js></script>        <script src=js/en.js></script>        <script src=js/tmpl.min.js></script>        <script src=js/timecard.js></script>        <!-- TEMPLATE -->        <script type=text/x-tmpl id=tmpl-demo>            <div class=card>                <div class=card-header role=tab id=heading{%= o.id %}>                        <h5 class={%= o.id %}>                        <a class=collapsed data-toggle=collapse data-parent=#accordion href=#collapse{%= o.id %} aria-expanded=true aria-controls=collapse{%= o.id %}>                            {%= o.title %}                        </a>                        </h5>                </div>                <div id=collapse{%= o.id %} class=collapse role=tabpanel aria-labelledby=heading{%= o.id %}>                        <div class=card-block>                            <b>Date: </b> {%= o.title %}<br>                            <b style=color: green>Clock In: </b> {%= o.clockIn %}<br>                            <b style=color: red>Clock Out: </b> {%= o.clockOut %}<br>                            <hr>                            <b style=color: blue>Total: </b> {%= o.total %}<br>                        </div>                </div>            </div>        </script>        <script type=text/javascript>            $(document).ready(function(){                if (localStorage.getItem(timeCardDatas) != null) {                    populateTimeCard();                    calculateHours();                }                $(#totalHours).text(localStorage.getItem(totalHours));            });            $(#clockIn).on(click, function(){                if ($(#password).val().length > 0) {                    if (login($(#password).val())) {                        markTime(start);                        $(#password).val();                        toggleClockIn();                    } else {                        triggerFormControl();                    }                } else {                    triggerFormControl();                }            });            $(#clockOut).on(click, function(){                if ($(#password).val().length > 0) {                    if (login($(#password).val())) {                        markTime(end);                        $(#password).val();                        toggleClockOut();                        /*-- Populate Base --*/                        populateTimeCard();                    } else {                        triggerFormControl();                        console.log([DEBUG] Triggered Form Control);                    }                } else {                    triggerFormControl();                    console.log([DEBUG] Triggered Form Control);                }            });        </script>    </body></html>timecard.js/* * Time Card web application. * ------------------------------ * This program is not secure as it's only JS at work. */initialize();function initialize() {    if (localStorage.getItem(startShift) != null) {        toggleClockIn();    } else {        toggleClockOut();    }}function populateTimeCard() {    var tcDatas = JSON.parse(localStorage.getItem(timeCardDatas));    for (var i = tcDatas.length - 1; i >= 0; i--) {        if (i >= 2) {            var datas = {                id: i,                title: tcDatas[i][0][2],                clockIn: tcDatas[i][0][0],                clockOut: tcDatas[i][1][0],                total: calculateHours(tcDatas[i][0][1] - tcDatas[i][1][1])            };            $(#accordion).append(tmpl(tmpl-demo, datas));        }    }}function login(password) {    if (md5(password) == <MD5 Hash Here>) {        return true;    } else {        return false;    }}function reset() {    localStorage.removeItem(startShift);}function calculateHours(single) {    var timeCardDatas = JSON.parse(localStorage.getItem(timeCardDatas)),        totalHour = 0;    single = (typeof single !== 'undefined') ? single : false;    if (!single) {        for (var i = timeCardDatas.length - 1; i >= 0; i--) {            if (i >= 2) {                var curHour = ((timeCardDatas[i][0][1] - timeCardDatas[i][1][1]) / 1000 / 60 / 60).toFixed(2);                if (curHour < 0) {                    totalHour += parseFloat((curHour * -1).toFixed(2));                } else {                    totalHour += parseFloat(curHour).toFixed(2);                }            }        }        localStorage.setItem(totalHours, totalHour.toFixed(2));    } else {        var tHour = ((parseFloat(single)) / 1000 / 60 / 60).toFixed(2);        if (tHour < 0) {            tHour = parseFloat((tHour * -1)).toFixed(2);        } else {            tHour = parseFloat(tHour).toFixed(2);        }        return tHour;    }}function markTime(shift) {    var curTime = new Date();    var h = curTime.getHours();    var m = curTime.getMinutes();    var s = curTime.getSeconds();    m = padZero(m);    s = padZero(s);    var shiftData = [militaryToStandard(h + : + m + : + s), curTime.getTime(), constructTime(true)];    if (shift == start) {        localStorage.setItem(startShift, JSON.stringify(shiftData));    } else if (shift == end) {        var tcDatas = [JSON.parse(localStorage.getItem(startShift)), shiftData];        if (localStorage.getItem(timeCardDatas) == null) {            var fillerDatas = [[FILLER, 0000000000], [FILLER, 0000000000]];            localStorage.setItem(timeCardDatas, JSON.stringify(fillerDatas));            var oldItems = JSON.parse(localStorage.getItem(timeCardDatas));            oldItems.push(tcDatas);            localStorage.setItem(timeCardDatas, JSON.stringify(oldItems));            reset();        } else {            var oldItems = JSON.parse(localStorage.getItem(timeCardDatas));            oldItems.push(tcDatas);            localStorage.setItem(timeCardDatas, JSON.stringify(oldItems));            reset();        }    } else {        console.log([Time Card] An error has occured.);    }}/* * Error Controls */function triggerFormControl() {    $(#password).addClass(form-control-danger);    $(#password-group).addClass(has-danger);}function toggleClockIn() {    $(#clockIn).addClass(disabled);    $(#clockOut).removeClass(disabled);    $('#clockIn').prop('disabled', true);    $('#clockOut').prop('disabled', false);}function toggleClockOut() {    $(#clockOut).addClass(disabled);    $(#clockIn).removeClass(disabled);    $('#clockIn').prop('disabled', false);    $('#clockOut').prop('disabled', true);}/* * Utility */function militaryToStandard(time) {    time = time.split(':');    var hours = Number(time[0]);    var minutes = Number(time[1]);    var seconds = Number(time[2]);    var timeValue;    if (hours > 0 && hours <= 12) {      timeValue=  + hours;    } else if (hours > 12) {      timeValue=  + (hours - 12);    } else if (hours == 0) {      timeValue= 12;    }    timeValue += (minutes < 10) ? :0 + minutes : : + minutes;    timeValue += (seconds < 10) ? :0 + seconds : : + seconds;    timeValue += (hours >= 12) ?  P.M. :  A.M.;    return timeValue;}function dowToWord(dow) {    switch (dow) {        case 0:            return Sunday;            break        case 1:            return Monday;            break;        case 2:            return Tuesday;            break;        case 3:            return Wednesday;            break;        case 4:            return Thursday;            break;        case 5:            return Friday;            break;        case 6:            return Saturday;            break;    }}function padZero(number) {    if (number <= 9) {        number = 0 + number;    }    return number;}function constructTime(withDOW) {    var curTime = new Date();    var construct = padZero((curTime.getMonth() + 1)) + / +                    curTime.getDate() + / +                    curTime.getFullYear();    var a = (typeof withDOW !== 'undefined') ?  true : false;    if (a) {        construct +=   + dowToWord(curTime.getDay());    }    return construct;}JS LibrariesLibraries that I installed.Bootstrap 4Required TetherJQuery 3.2.1 JavaScript-TemplatesJavaScript-MD5Answer(s) I'm Looking ForCode ImprovementsGeneral TipsReferences to Guides (Naming Convention, etc.)AND any other meaningful and useful stuff.If I am missing any other information do let me know what other information you need down in the comments. I will be sure to answer than as fast as I can.
Time Card Web Application Offline
javascript;beginner;jquery;twitter bootstrap
Unnecessary loop cyclesIn this loop in populateTimeCard:for (var i = tcDatas.length - 1; i >= 0; i--) {    if (i >= 2) {        // ...    }}It would be better to change the loop condition and remove the if statement from the loop body, like this:for (var i = tcDatas.length - 1; i >= 2; i--) {Review the other similar loops as well.Use boolean expressions directlyInstead of this:    if (md5(password) == <MD5 Hash Here>) {    return true;} else {    return false;}You can write simply:return md5(password) == <MD5 Hash Here>;Bug or feature?The two branches of this condition look a bit suspicious:if (curHour < 0) {    totalHour += parseFloat((curHour * -1).toFixed(2));} else {    totalHour += parseFloat(curHour).toFixed(2);}Did you misplace the parentheses in the if branch?Perhaps you meant to write this:if (curHour < 0) {    totalHour += parseFloat(-curHour).toFixed(2);} else {    totalHour += parseFloat(curHour).toFixed(2);}In this case I would suggest to not repeat yourself,as totalHour += parseFloat(...).toFixed(2); is the same in both branches.You could write:totalHour += parseFloat(Math.abs(curHour)).toFixed(2);Notice that when duplicate logic is eliminated,it's impossible to misplace parentheses.This is one of the reasons why it's good to eliminate duplications always.Don't repeat yourselfThe parseFloat(...).toFixed(2) snippet appears in many places in the code.It would be good to encapsulate this logic in a helper function and eliminate the duplications.Multiplying by -1Instead of x * -1 you can write simply -x.Returning from case in a switchWhen you return from a case in a switch, you don't need to add a break statement.