build: refs #6859 #23
32
README.md
32
README.md
|
@ -2,15 +2,29 @@
|
||||||
|
|
||||||
Worker Time Control is a project developed by Verdnatura Levante SL, designed to manage time-related functionalities. This application helps in efficient time tracking and management for workers.
|
Worker Time Control is a project developed by Verdnatura Levante SL, designed to manage time-related functionalities. This application helps in efficient time tracking and management for workers.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Required applications.
|
||||||
|
|
||||||
|
* Node.js
|
||||||
|
* Docker
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Clone the repository:
|
1. Clone the repository.
|
||||||
|
```text
|
||||||
|
$ git clone https://gitea.verdnatura.es/verdnatura/worker-time-control
|
||||||
|
```
|
||||||
|
2. Install dependencies using npm.
|
||||||
|
```text
|
||||||
|
$ npm i
|
||||||
|
```
|
||||||
|
3. Duplicate the `.env.example` file and rename it to `.env`. Then, configure it.
|
||||||
|
```
|
||||||
|
$ cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
git clone https://gitea.verdnatura.es/verdnatura/worker-time-control
|
## Launch
|
||||||
3. Install dependencies using npm:
|
```
|
||||||
|
$ npm start
|
||||||
npm install
|
```
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
npm start
|
|
|
@ -26,6 +26,15 @@ h1 {
|
||||||
span {
|
span {
|
||||||
color: #ED4947;
|
color: #ED4947;
|
||||||
}
|
}
|
||||||
|
.device {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 20px;
|
||||||
|
float: left;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 400;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
.total {
|
.total {
|
||||||
float: right;
|
float: right;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -82,6 +82,9 @@ and open the template in the editor.
|
||||||
<h1>
|
<h1>
|
||||||
developed with <span>♥</span> by Verdnatura
|
developed with <span>♥</span> by Verdnatura
|
||||||
</h1>
|
</h1>
|
||||||
|
<span class="device">
|
||||||
|
<p id="deviceLabel"></p>
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div class="confirm">
|
<div class="confirm">
|
||||||
<div class="contConfirm">
|
<div class="contConfirm">
|
||||||
|
|
|
@ -45,7 +45,8 @@ function setView() {
|
||||||
function fichar(direction) {
|
function fichar(direction) {
|
||||||
const data = {
|
const data = {
|
||||||
workerFk: userData['userFk'],
|
workerFk: userData['userFk'],
|
||||||
direction
|
direction,
|
||||||
|
device: localStorage.getItem("device")
|
||||||
}
|
}
|
||||||
|
|
||||||
$.post({
|
$.post({
|
||||||
|
|
25
js/index.js
25
js/index.js
|
@ -7,12 +7,14 @@ $(document).ready(function () {
|
||||||
|
|
||||||
function setEvents() {
|
function setEvents() {
|
||||||
const heartEl = document.querySelector('body > h1 > span');
|
const heartEl = document.querySelector('body > h1 > span');
|
||||||
|
refreshDeviceLabel()
|
||||||
|
|
||||||
heartEl.addEventListener('click', function() {
|
heartEl.addEventListener('click', function() {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Iniciar sesión',
|
title: 'Iniciar sesión',
|
||||||
html:
|
html:
|
||||||
`<input id="user" class="swal2-input" type="text" placeholder="Usuario" value="${localStorage.getItem('user') ?? ''}">
|
`<input id="device" class="swal2-input" type="text" placeholder="Dispositivo" value="${localStorage.getItem('device') ?? ''}">
|
||||||
|
<input id="user" class="swal2-input" type="text" placeholder="Usuario" value="${localStorage.getItem('user') ?? ''}">
|
||||||
<input id="pass" class="swal2-input" type="password" placeholder="Contraseña">`,
|
<input id="pass" class="swal2-input" type="password" placeholder="Contraseña">`,
|
||||||
confirmButtonText: 'Login',
|
confirmButtonText: 'Login',
|
||||||
showCloseButton: true,
|
showCloseButton: true,
|
||||||
|
@ -21,7 +23,8 @@ function setEvents() {
|
||||||
if(result.isConfirmed) {
|
if(result.isConfirmed) {
|
||||||
const user = $('#user').val();
|
const user = $('#user').val();
|
||||||
const pass = $('#pass').val();
|
const pass = $('#pass').val();
|
||||||
signIn(user,pass);
|
const device = $('#device').val();
|
||||||
|
signIn(user, pass, device);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -36,8 +39,11 @@ function setEvents() {
|
||||||
$("#txtPin").text("ID USUARIO");
|
$("#txtPin").text("ID USUARIO");
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".btnOk").on("click", login);
|
$(".btnOk").on("click", function () {
|
||||||
|
if (pin) {
|
||||||
|
login();
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function login() {
|
function login() {
|
||||||
|
@ -56,7 +62,7 @@ function login() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function signIn(user, password) {
|
function signIn(user, password, device) {
|
||||||
$.post({
|
$.post({
|
||||||
urlPath: 'vnUsers/sign-in',
|
urlPath: 'vnUsers/sign-in',
|
||||||
jsonData: {user, password},
|
jsonData: {user, password},
|
||||||
|
@ -65,9 +71,14 @@ function signIn(user, password) {
|
||||||
localStorage.setItem("token", data.token);
|
localStorage.setItem("token", data.token);
|
||||||
localStorage.setItem("ttl", data.ttl);
|
localStorage.setItem("ttl", data.ttl);
|
||||||
localStorage.setItem("user", user);
|
localStorage.setItem("user", user);
|
||||||
localStorage.setItem("password", password);
|
localStorage.setItem("device", device);
|
||||||
localStorage.setItem("created", Date.now());
|
localStorage.setItem("created", Date.now());
|
||||||
getTokenConfig();
|
getTokenConfig();
|
||||||
|
refreshDeviceLabel();
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshDeviceLabel() {
|
||||||
|
$("#deviceLabel").text(localStorage.getItem('device') ?? '')
|
||||||
}
|
}
|
15
js/main.js
15
js/main.js
|
@ -45,7 +45,7 @@ function getTokenConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkValidity() {
|
function checkValidity() {
|
||||||
const created = localStorage.getItem('created');
|
const created = +localStorage.getItem('created');
|
||||||
const ttl = localStorage.getItem('ttl');
|
const ttl = localStorage.getItem('ttl');
|
||||||
|
|
||||||
if (isCheckingToken || !created) return;
|
if (isCheckingToken || !created) return;
|
||||||
|
@ -66,11 +66,11 @@ $.ajaxPrefilter(function(xhr) {
|
||||||
const token = localStorage.getItem('token')
|
const token = localStorage.getItem('token')
|
||||||
|
|
||||||
Object.assign(xhr, {
|
Object.assign(xhr, {
|
||||||
url: `api/${xhr.urlPath}`,
|
url: `/api/${xhr.urlPath}`,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization : token
|
Authorization : token
|
||||||
},
|
},
|
||||||
timeout: 1000,
|
timeout: 2000,
|
||||||
contentType: 'application/json; charset=utf-8',
|
contentType: 'application/json; charset=utf-8',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
processData: false,
|
processData: false,
|
||||||
|
@ -97,13 +97,20 @@ $.ajaxPrefilter(function(xhr) {
|
||||||
mensaje = 'Ajax request aborted';
|
mensaje = 'Ajax request aborted';
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
|
if (xhr?.responseJSON?.error?.name == 'UserError') {
|
||||||
|
mensaje = xhr.responseJSON.error.message;
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch (xhr.status){
|
switch (xhr.status){
|
||||||
case 0:
|
case 0:
|
||||||
mensaje = 'Not connect: Verify Network';
|
mensaje = 'Not connect: Verify Network';
|
||||||
break;
|
break;
|
||||||
|
case 504:
|
||||||
|
mensaje = 'No se ha podido conectar con Salix, consulta con informática';
|
||||||
|
break;
|
||||||
case 555:
|
case 555:
|
||||||
mensaje = JSON.parse(xhr.statusText).Message;
|
mensaje = JSON.parse(xhr.statusText).Message;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (xhr.status >= 400 && xhr.status < 500)
|
if (xhr.status >= 400 && xhr.status < 500)
|
||||||
mensaje = xhr.statusText;
|
mensaje = xhr.statusText;
|
||||||
|
|
15
proxy.js
15
proxy.js
|
@ -3,16 +3,23 @@ const dotenv = require('dotenv');
|
||||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
const env = process.env;
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
if (!env.TARGET || !env.PORT) {
|
||||||
|
console.error(`[ERROR] The '.env' file is not configured`);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
const apiProxy = createProxyMiddleware('/api', {
|
const apiProxy = createProxyMiddleware('/api', {
|
||||||
target: process.env.TARGET,
|
target: env.TARGET,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use('/api', apiProxy);
|
app.use('/api', apiProxy);
|
||||||
app.use('/', express.static(__dirname));
|
app.use('/', express.static(__dirname));
|
||||||
|
|
||||||
const port = process.env.PORT;
|
const port = env.PORT;
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.log(`Server running on port: ${port}`);
|
console.log(`[SERVER] Running on port: ${port}`);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue