diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/README.md b/README.md
index 435afd5..2c4e80c 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,10 @@ Launch application in development environment.
 ```
 $ php -S 0.0.0.0:9090 -t .
 ```
+
+Enable CORS on server side
+```
+header('Access-Control-Allow-Origin: *');
+header("Access-Control-Allow-Headers: *");
+if($_SERVER['REQUEST_METHOD'] == "OPTIONS") die();
+```
diff --git a/clockIn.html b/clockIn.html
new file mode 100644
index 0000000..d1351d5
--- /dev/null
+++ b/clockIn.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>FichApp</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <link href="css/style.css" rel="stylesheet" type="text/css"/>
+        <script src="node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
+        <script src="node_modules/fastclick/lib/fastclick.js" type="text/javascript"></script>
+    </head>
+    <body class="pinLogin">
+
+        <header>
+
+            <div class="btnSalir">Cerrar</div>
+            <h2 id="txtNombre"></h2>
+
+        </header>
+
+        <div class="paneles">
+            <div class="planPanel">
+                <div class="container">
+                    <h2>Tus fichadas</h2>
+                    <h3>Situación de los ultimos 7 días</h3> 
+                    <div class="total">Total: 7.7h</div>
+                    <ul class="listHorario">
+                    </ul>
+                </div>
+            </div>
+
+        </div>
+
+        <div class="footer">
+            <div class="in">Inicio jornada</div>
+            <div class="inMiddle">Inicio descanso</div>
+            <div class="outMiddle">Fin descanso</div>
+            <div class="out">Fin jornanda</div>
+        </div> 
+
+        <p></p>
+    
+        <div class="loading">
+            <div class="loadingcontent">
+                <div class="sk-cube-grid">
+                    <div class="sk-cube sk-cube1"></div>
+                    <div class="sk-cube sk-cube2"></div>
+                    <div class="sk-cube sk-cube3"></div>
+                    <div class="sk-cube sk-cube4"></div>
+                    <div class="sk-cube sk-cube5"></div>
+                    <div class="sk-cube sk-cube6"></div>
+                    <div class="sk-cube sk-cube7"></div>
+                    <div class="sk-cube sk-cube8"></div>
+                    <div class="sk-cube sk-cube9"></div>
+                </div>
+            </div>
+        </div>
+
+        <div class="confirm">
+            <div class="contConfirm">
+                <h4 class="txtConfirm"></h4>
+            </div>
+        </div>
+        <script src="config.js" type="text/javascript"></script>
+        <script src="js/main.js" type="text/javascript"></script>
+        <script src="js/clock.js" type="text/javascript"></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/config.js b/config.js
new file mode 100644
index 0000000..7c7ab08
--- /dev/null
+++ b/config.js
@@ -0,0 +1,13 @@
+
+var process = {
+    env: {NODE_ENV: 'development'}
+};
+
+var config = {
+    development: {
+        urlBase: 'http://localhost:8080'
+    },
+    production: {
+        urlBase: '//app.verdnatura.es'
+    }
+};
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..29f96d8
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,440 @@
+/* 
+    Created on : 29-jul-2019, 11:30:28
+    Author     : enrique blasco blanquer
+*/
+
+*{
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+}
+
+html,body{
+    width: 100%;
+    height: 100%;
+    font-family: sans-serif;
+    background: #000;
+}
+
+
+h1{
+    position: fixed;
+    bottom: 20px;
+    right: 20px;
+    font-size: 1em;
+    color: #fff;
+}
+span{
+    color: #ED4947;
+}
+
+
+.total{
+    float: right;
+    font-weight: bold;
+    font-size: 1.4em;
+    margin-top: -40px;
+}
+
+ul{
+    list-style: none;
+}
+
+.pinLogin{
+        background-image: url(../img/logo.png);
+        background-size: cover;
+        background-position: center;
+        background-repeat: no-repeat;
+}
+
+#logoVerd{
+    width: 200px;
+    margin: 20px;
+}
+
+#logoVerdHeader{
+    width: 50px;
+    margin: 0;
+    position: fixed;
+    top: 12px;
+    left: 20px;
+}
+
+
+
+.pinContainer{
+    width: 350px;
+    height: 460px;
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    margin: auto;
+    text-align: center;
+}
+
+#txtPin{
+    text-align: center;
+    padding: 15px 5px;
+    background: rgba(255,255,255,.90);
+    border: none;
+    font-weight: bold;
+    font-size: 1.5em;
+
+    display: block;
+    width: 250px;
+    margin: auto;
+    margin-bottom: 10px;
+}
+
+.btnPin{
+    float: left;
+    width: calc(100% / 3);
+    height: calc(500px/5);
+    padding: 5px;
+}
+.btnPinNum{
+    width: 100%;
+    height: 100%;
+    font-size: 2.5em;
+    background: rgba(255,255,255,.90);
+    padding-top: 18px;
+}
+
+.btnCancel{
+    width: 100%;
+    height: 100%;
+    font-size: 2.5em;
+    padding-top: 18px;
+    background: rgba(237,73,71,.90);
+    color: #fff;
+}
+
+.btnOk{
+    width: 100%;
+    height: 100%;
+    font-size: 2.5em;
+    padding-top: 18px;
+    background: rgba(163,171,38,.90);
+    color: #fff;
+}
+
+
+#txtNombre{
+    padding-top: 0px;
+    padding-left: 10px;
+    float: left;
+    color: #fff;
+    text-align: right;
+    font-size: 1.8em;
+    font-weight: bold;
+}
+
+.paneles{
+    overflow: hidden;
+    width: 100%;
+}
+
+.planPanel{
+    float: left;
+    width: 100%;
+    padding: 20px 20px 0 20px;
+    height: auto;
+}
+.problemsPanel{
+    float: left;
+    width: 100%;
+    height: auto;
+    padding: 20px;
+}
+.container{
+    width: 100%;
+    height: 100%;
+    background: rgba(255,255,255,.90);
+    padding: 20px;
+    overflow: hidden;
+    box-shadow: 0 0 5px rgba(0,0,0,.2);
+    border-radius: 8px;
+}
+h2{
+    font-size: 1.3em;
+}
+h3{
+    font-size: 1em;
+    color: #9EA7AC;
+    font-weight: normal;
+
+}
+
+.footer{
+    display: none;
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    height: 100px; 
+    text-align: center;
+}
+
+.in,.inMiddle {
+    display: inline;
+    position: static;
+    width: 350px;
+    background: #8DD202;
+    padding: 20px 40px;
+    font-size: 2em;
+    color: #fff;
+    text-align: center;
+    border-radius: 10px;
+}
+
+.out,.outMiddle{
+    display: inline;
+    position: static;
+    width: 350px;
+    background: rgba(237,73,71,.90);
+    padding: 20px 40px;
+    font-size: 2em;
+    color: #fff;
+    text-align: center;
+    border-radius: 10px;
+}
+
+header{
+    overflow: hidden;
+    padding: 20px 20px 0px 20px;
+}
+
+.btnSalir{
+    float: right;
+    background: rgba(237,73,71,.90);
+    padding: 5px 30px;
+    font-size: 1.2em;
+    color: #fff;
+}
+
+#txtIncidencia{
+    color: #ED4947;
+    font-weight: bold;
+    font-size: 1.4em;
+    margin-top: 10px;
+}
+
+
+
+.listHorario{
+    margin-top: 20px;
+    width: 100%;
+    overflow: hidden;
+}
+.listHorario .headerLi{
+    width: 100%;
+    overflow: hidden;
+    border-bottom: 1px solid #9EA7AC;
+    padding-bottom: 10px;
+
+}
+
+.listHorario label{
+    float: left;
+    width: calc(100% / 7);
+    text-align: center;
+    font-weight: bold;
+    padding: 5px 0;
+
+}
+.hoy{
+    background: #9EA7AC;
+    color: #fff;
+}
+
+.listHorario .time{
+    float: left;
+    width: calc(100% / 7);
+    text-align: center;
+    padding: 5px 0;
+    font-size: 1.2em;
+    overflow: hidden;
+
+}
+.listHorario .time img{
+    width: 20px;
+    float: left;
+    margin-right: 5px;
+    margin-left: 15px;
+    margin-top: 7px;
+}
+
+.listHorario .time p{
+    float: left;
+    background: #8DD202;
+    padding: 5px;
+    border-radius: 7px;
+}
+
+.impar{
+    color: rgba(163,171,38,.90);
+    font-weight: bold;
+}
+
+.hide{
+    opacity: 0;
+}
+.show{
+    opacity: 1;
+}
+
+.confirm{
+    display: none;
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: #8DD202;
+    color: #fff;
+}
+.confirmKO{
+    display: inline;
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(237,73,71);
+    color: #fff;
+}
+
+.contConfirm{
+    position: fixed;
+    margin: auto;
+    top:0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    width: 800px;
+    height: 170px;
+    text-align: center;
+}
+
+.contConfirm h4{
+    font-size: 2.5em;
+    margin-bottom: 20px;
+}
+
+.btnconfirmar{
+    float: left;
+    font-size: 1.2em;
+    padding: 18px;
+    background: rgba(163,171,38,.90);
+    color: #fff;
+    margin: 15px;
+}
+
+.btnnoconfirm{
+    float: left;
+    font-size: 1.2em;
+    padding: 18px;
+    background: rgba(237,73,71,.90);
+    color: #fff;
+    margin: 15px;
+}
+
+.botonera{
+    margin: auto;
+    width: 310px;
+    overflow: hidden;
+}
+
+.loading{
+    display: none;
+    top: 0;
+    left: 0;
+    position: fixed;
+    z-index: 999;
+    width: 100%;
+    height: 100%;
+    background: rgba(25,154,166,1);
+    background: -moz-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
+    background: -webkit-gradient(left bottom, right top, color-stop(0%, rgba(25,154,166,1)), color-stop(100%, rgba(39,216,139,1)));
+    background: -webkit-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
+    background: -o-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
+    background: -ms-linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
+    background: linear-gradient(45deg, rgba(25,154,166,1) 0%, rgba(39,216,139,1) 100%);
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#199aa6', endColorstr='#27d88b', GradientType=1 );
+}
+
+
+.loadingcontent{
+    position: fixed;
+    height: 50px;
+    width: 100%;
+    margin: auto;
+    top: 0;
+    bottom: 0;
+    left: 0;
+}
+
+
+
+.sk-cube-grid {
+    width: 40px;
+    height: 40px;
+    margin:  auto;
+}
+
+.sk-cube-grid .sk-cube {
+    width: 33%;
+    height: 33%;
+    background-color: #fff;
+    float: left;
+    -webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
+    animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; 
+}
+.sk-cube-grid .sk-cube1 {
+    -webkit-animation-delay: 0.2s;
+    animation-delay: 0.2s; }
+.sk-cube-grid .sk-cube2 {
+    -webkit-animation-delay: 0.3s;
+    animation-delay: 0.3s; }
+.sk-cube-grid .sk-cube3 {
+    -webkit-animation-delay: 0.4s;
+    animation-delay: 0.4s; }
+.sk-cube-grid .sk-cube4 {
+    -webkit-animation-delay: 0.1s;
+    animation-delay: 0.1s; }
+.sk-cube-grid .sk-cube5 {
+    -webkit-animation-delay: 0.2s;
+    animation-delay: 0.2s; }
+.sk-cube-grid .sk-cube6 {
+    -webkit-animation-delay: 0.3s;
+    animation-delay: 0.3s; }
+.sk-cube-grid .sk-cube7 {
+    -webkit-animation-delay: 0s;
+    animation-delay: 0s; }
+.sk-cube-grid .sk-cube8 {
+    -webkit-animation-delay: 0.1s;
+    animation-delay: 0.1s; }
+.sk-cube-grid .sk-cube9 {
+    -webkit-animation-delay: 0.2s;
+    animation-delay: 0.2s; }
+
+@-webkit-keyframes sk-cubeGridScaleDelay {
+    0%, 70%, 100% {
+        -webkit-transform: scale3D(1, 1, 1);
+        transform: scale3D(1, 1, 1);
+    } 35% {
+        -webkit-transform: scale3D(0, 0, 1);
+        transform: scale3D(0, 0, 1); 
+    }
+}
+
+@keyframes sk-cubeGridScaleDelay {
+    0%, 70%, 100% {
+        -webkit-transform: scale3D(1, 1, 1);
+        transform: scale3D(1, 1, 1);
+    } 35% {
+        -webkit-transform: scale3D(0, 0, 1);
+        transform: scale3D(0, 0, 1);
+    } 
+}
\ No newline at end of file
diff --git a/img/in.png b/img/in.png
new file mode 100644
index 0000000..d9d51b1
Binary files /dev/null and b/img/in.png differ
diff --git a/img/logo.png b/img/logo.png
new file mode 100644
index 0000000..cd8e681
Binary files /dev/null and b/img/logo.png differ
diff --git a/img/out.png b/img/out.png
new file mode 100644
index 0000000..7ffa686
Binary files /dev/null and b/img/out.png differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..507133a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>FichApp</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <link href="css/style.css" rel="stylesheet" type="text/css"/>
+        <script src="node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
+        <script src="node_modules/fastclick/lib/fastclick.js" type="text/javascript"></script>
+    </head>
+    <body class="pinLogin">
+       
+        <div class="pinContainer">
+            <p id="txtPin">USUARIO</p>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    1
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    2
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    3
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    4
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    5
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    6
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    7
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    8
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    9
+                </div>
+            </div>
+            <div class="btnPin">
+                <div class="btnCancel">
+                    x
+                </div>
+            </div>
+            <div class="btnPin btnnum">
+                <div class="btnPinNum">
+                    0
+                </div>
+            </div>
+            <div class="btnPin ">
+                <div class="btnOk">
+                    ok
+                </div>
+            </div>
+        </div>
+        <h1>
+            developed with <span>&hearts;</span> by Verdnatura
+        </h1>
+
+        <div class="loading">
+            <div class="loadingcontent">
+                <div class="sk-cube-grid">
+                    <div class="sk-cube sk-cube1"></div>
+                    <div class="sk-cube sk-cube2"></div>
+                    <div class="sk-cube sk-cube3"></div>
+                    <div class="sk-cube sk-cube4"></div>
+                    <div class="sk-cube sk-cube5"></div>
+                    <div class="sk-cube sk-cube6"></div>
+                    <div class="sk-cube sk-cube7"></div>
+                    <div class="sk-cube sk-cube8"></div>
+                    <div class="sk-cube sk-cube9"></div>
+                </div>
+            </div>
+        </div>
+        
+        <div class="confirm">
+            <div class="contConfirm">
+                <h4 class="txtConfirm"></h4>
+            </div>
+        </div>
+        <script src="config.js" type="text/javascript"></script>
+        <script src="js/main.js" type="text/javascript"></script>
+        <script src="js/index.js" type="text/javascript"></script>
+    </body>
+</html>
diff --git a/js/clockIn.js b/js/clockIn.js
new file mode 100644
index 0000000..092f534
--- /dev/null
+++ b/js/clockIn.js
@@ -0,0 +1,187 @@
+var userData = "";
+
+$(document).ready(function () {
+    userData = $.parseJSON(localStorage.getItem("userData"));
+    FastClick.attach(document.body);
+    setView();
+    setEvents();
+});
+
+function setEvents() {
+
+    $(".btnSalir").on("click", function () {
+        cerrar();
+    });
+
+    $(".in").on("click", function () {
+        fichar('in');
+    });
+    
+    $(".inMiddle").on("click", function () {
+        fichar('middle');
+    });
+
+    $(".outMiddle").on("click", function () {
+        fichar('middle');
+    });
+
+    $(".out").on("click", function () {
+        fichar('out');
+    });
+
+    setTimeout(function () {
+        cerrar();
+    }, 5000);
+}
+
+function setView() {
+    $(".footer").hide();
+    $("#txtNombre").text(userData["name"] + " " + userData["surname"]);
+    getInfo();
+    $("." + userData["button1"]).show();
+    $("." + userData["button2"]).show();
+}
+
+function  fichar(direction) {
+    $.post({
+        urlPath: 'clockIn',
+        jsonData: [userData['userFk'], direction],
+        processData: false,
+        success: function (msg) {
+            if (msg[0].error){
+                printErrores(msg);
+                setTimeout(function () {
+                    cerrar();
+                }, 3000);
+            }else {
+                $(".confirm").fadeIn(200);
+                $(".txtConfirm").append('FICHADA REGISTRADA');
+                setTimeout(function () {
+                    cerrar();
+                }, 1000);
+            }
+        }
+    });
+}    
+
+function setView() {
+    $(".footer").hide();
+    $(".in").hide();
+    $(".inMiddle").hide();
+    $(".outMiddle").hide();
+    $(".out").hide();
+    $("#txtNombre").text(userData["name"] + " " + userData["surname"]);
+    getInfo();
+    $("." + userData["button1"]).show();
+    $("." + userData["button2"]).show();
+}
+
+function getInfo() {
+    $.post({
+        urlPath: 'getClockIn',
+        jsonData: [userData['userFk']],
+        processData: false,
+        success: function (data) {
+            $('.footer').show();
+            printHorario(data);
+        }
+    });
+}
+
+function printHorario(horarios) {
+    var c = "in";
+    for (var i = 0; i < horarios.length; i++) {
+        if (i % 2 !== 0) {
+            c = "out";
+        } else {
+            c = "in";
+        }
+        if (horarios[i]["7_dias_antes"] === "total") {
+            if (horarios.length > (i + 1)) {
+                printTotalHours(horarios[i + 1]);
+            }
+            if (horarios.length > (i + 2)) {
+                $(".total").text('Total: ' + horarios[i + 2]["1_dia_antes"] + 'h');
+            }
+            break;
+        }
+        $(".listHorario").append('<li><div class="time ' + ifIsEmpty(horarios[i]["6_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["6_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["5_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["5_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["4_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["4_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["3_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["3_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["2_dias_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["2_dias_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["1_dia_antes"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["1_dia_antes"]) + '</p></div><div class="time ' + ifIsEmpty(horarios[i]["mismo_dia"]) + '"><img src="img/' + c + '.png" alt=""/><p>' + ifIsEmptyText(horarios[i]["mismo_dia"]) + '</p></div></li>');
+    }
+    var listWeekName = printWeek();
+    $(".listHorario").prepend('<li class="headerLi"><label>' + listWeekName[5] + '</label><label>' + listWeekName[4] + '</label><label>' + listWeekName[3] + '</label><label>' + listWeekName[2] + '</label><label>' + listWeekName[1] + '</label><label>' + listWeekName[0] + '</label><label class="hoy">HOY</label></li>');
+}
+
+function printTotalHours(horarios) {
+    $(".listHorario").append('<li><br><hr></li>');
+    $(".listHorario").append('<li><div class="time">' + ifIsEmptyText(horarios["6_dias_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["5_dias_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["4_dias_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["3_dias_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["2_dias_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["1_dia_antes"])
+            + '</div><div class="time">' + ifIsEmptyText(horarios["mismo_dia"])
+            + '</div></li>');
+}
+
+function printWeek() {
+    var listWeekName = [];
+    var curr = new Date();
+    for (var i = 0; i < 7; i++) {
+        curr.setDate(curr.getDate() - 1);
+        listWeekName.push(weekDays[curr.getDay()]);
+    }
+    return listWeekName;
+}
+
+var weekDays = [
+    'Domingo',
+    'Lunes',
+    'Martes',
+    'Miércoles',
+    'Jueves',
+    'Viernes',
+    'Sábado'
+];
+
+function printError(msg){
+    $(".txtConfirm").empty();
+    $(".txtConfirm").append(msg);
+    $(".txtConfirm").append("<br>");
+    $(".loading").fadeOut(200);
+    $(".confirm").addClass('confirmKO');
+}
+
+function printErrores(errores) {
+    var error ='';
+    $(".txtConfirm").empty();
+    for (var i = 0; i < errores.length; i++) {
+        if (errores[i].error) {
+           error += errores[i].error + "<br>";
+        }
+    }
+    printError(error);
+}
+
+function ifIsEmpty(value) {
+    if (value.trim().length === 0) {
+        return "hide";
+    } else {
+        return "show";
+    }
+}
+
+function ifIsEmptyText(value) {
+    if (value.trim().length === 0) {
+        return "00:00";
+    } else {
+        return value;
+    }
+}
+
+function cerrar(){
+    $(".loading").fadeIn(200); 
+    localStorage.removeItem("userData");
+    setTimeout(function () {
+    window.history.back();
+    }, 200);
+}
\ No newline at end of file
diff --git a/js/index.js b/js/index.js
new file mode 100644
index 0000000..89da24f
--- /dev/null
+++ b/js/index.js
@@ -0,0 +1,45 @@
+var pin = "";
+var datoUsuario = "";
+
+$(document).ready(function () {
+    FastClick.attach(document.body);
+    setEvents();
+});
+
+function setEvents() {
+    $(".btnnum").on("click", function () {
+        pin += parseInt($(this).children().html());
+        $("#txtPin").text(pin);
+    });
+
+    $(".btnCancel").on("click", function () {
+        pin = "";
+        $("#txtPin").text("USUARIO");
+    });
+
+    $(".btnOk").on("click", login);
+
+    $(".btnconfirmar").on("click", function () {
+        localStorage.setItem("userData", JSON.stringify(datoUsuario));
+        setTimeout(function () {
+            window.location = "clockIn.html";
+            }, 200);
+        $(".loading").fadeOut(200);     
+    });
+}
+
+function login() {
+    $.post({
+        urlPath: 'login',
+        jsonData: [pin],
+        processData: false,
+        success: function (data) {
+            localStorage.setItem("userData", JSON.stringify(data));
+            $("#txtPin").text("USUARIO O DNI");
+            pin = "";
+            window.location = "clockIn.html";
+            $(".loading").fadeOut(200);
+        }
+    });
+
+}
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
new file mode 100644
index 0000000..10c2b42
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,66 @@
+var config = config[process.env.NODE_ENV];
+var urlBase = config.urlBase;
+
+
+function printError(msg){
+    $(".txtConfirm").empty();
+    $(".txtConfirm").append(msg);
+    $(".confirm").addClass('confirmKO');
+    pin = "";
+    $("#txtPin").text("USUARIO");
+    setTimeout(function() {
+        $(".confirm").removeClass('confirmKO');
+    }, 1500);
+}
+
+$.ajaxPrefilter(function(xhr) {
+    $(".loading").fadeIn(200);
+    Object.assign(xhr, {
+        url: `${urlBase}/workerTimeControl/${xhr.urlPath}`,
+        headers: {
+            'version': '1',
+            'aplicacion': 'workerTimeControl'
+        },
+        timeout: 1000,
+        contentType: 'application/json; charset=utf-8',
+        dataType: 'json',
+        processData: false,
+        data: JSON.stringify(xhr.jsonData),
+        error: function (xhr, textStatus, err) {
+            var mensaje;
+
+            switch (textStatus){
+                case 'parsererror':
+                    mensaje = 'Requested JSON parse failed';
+                    break;
+                case 'timeout':
+                    mensaje = 'Time out error';
+                    break;
+                case 'abort':
+                    mensaje = 'Ajax request aborted';
+                    break;
+                case 'error':
+                    switch (xhr.status){
+                        case 0:
+                            mensaje = 'Not connect: Verify Network';
+                            break;
+                        case 555:
+                            mensaje = JSON.parse(xhr.statusText).Message;
+                            break;    
+                        default:
+                            if (xhr.status >= 400 && xhr.status < 500)
+                                mensaje = xhr.statusText;
+                            else
+                                mensaje = 'Ha ocurrido un error, consulta con informática';
+                    }
+                    break;
+                default:
+                    mensaje = 'Ha ocurrido un error, consulta con informática';
+            }
+            printError(mensaje);  
+        },
+        complete: function() {
+            $(".loading").fadeOut(200); 
+        }
+    });
+});
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..3e2a737
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,18 @@
+{
+  "name": "es.verdnatura.fichador",
+  "version": "1.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "fastclick": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/fastclick/-/fastclick-1.0.6.tgz",
+      "integrity": "sha1-FhYlsnsaWAZAWTa9qaLBkm0Gvmo="
+    },
+    "jquery": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
+      "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
+    }
+  }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..de17fbe
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+  "name": "es.verdnatura.worker-time-control",
+  "displayName": "Fichador",
+  "version": "1.0.0",
+  "description": "Fichador",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "Verdnatura Levante SL",
+  "license": "GPL-3.0",
+  "dependencies": {
+    "fastclick": "^1.0.6",
+    "jquery": "^3.6.0"
+  }
+}