Compare commits

..

No commits in common. "4d394338eff40178f4d0f23b10fcb5dcd82c71f1" and "a30437941fee5a9afe181ae4ec08f5971f08d6fb" have entirely different histories.

76 changed files with 11898 additions and 15105 deletions

View File

@ -1,27 +0,0 @@
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore
# Node.js dependencies:
node_modules/
# Archivos de desarrollo
src/
public/
# Archivos de JetBrains
.idea/
# Archivos de TypeScript
*.ts

27
.gitignore vendored
View File

@ -1,24 +1,3 @@
.DS_Store /node_modules
node_modules /idea
/dist **.map
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# Archivos js (ya que estoy usando ts)
/Backend/*.js

19
.htaccess Normal file
View File

@ -0,0 +1,19 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /ihc/index.php [L]
</IfModule>
## Desabilitar cache de Apache
<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<IfModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 12 Jan 1980 05:00:00 GMT"
</IfModule>
</FilesMatch>

View File

@ -1,47 +0,0 @@
const obtenerPedidosActuales = (req:any, res:any) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
const USER_ID = req.body.USER_ID;
const storedUserId = req.session.USER_ID.toString();
console.log(`La comparacion: ${USER_ID} === ${storedUserId}. ${typeof USER_ID} y ${typeof storedUserId}`);
if (USER_ID === storedUserId) {
const SQL_CONNECT_DATA = require('../VARIABLES').sqlConnectData;
const con = require('mysql').createConnection(SQL_CONNECT_DATA);
con.connect((err:any) => {
if (err) {
console.log(`Error al conectarse a la base de datos en obtenerPedidosActuales.ts 13.\n${err}`);
res.send(`{"error": "Error al conectarse a la base de datos."}`);
return;
}
con.query(
`SELECT BOLETA_ID, transacciones, horaEntrega FROM boletas WHERE USER_ID='${USER_ID}'
ORDER BY BOLETA_ID DESC `,
(err:any, response:any) => {
if (err) {
console.log(`Error al obtener las boletas del usuario ${USER_ID} en obtenerPedidosActuales.ts \
23.\n${err}`);
res.send("");
return;
}
res.send(JSON.stringify(response));
res.end();
}
);
});
} else {
res.send(`{"error": "El usuario que envia la peticion y el usuario logeado no coinciden."}`);
}
};
module.exports.obtenerPedido = obtenerPedidosActuales;

View File

@ -1,8 +0,0 @@
const SQL_CONNECT_DATA:object = {
host: '35.193.16.64',
user: 'Araozu',
password: 'xsakah4b',
database: 'Usuarios_DB'
};
module.exports.sqlConnectData = SQL_CONNECT_DATA;

View File

@ -1,16 +0,0 @@
declare var module:any;
declare var require:any;
const {OAuth2Client} = require('google-auth-library');
const CLIENT_ID:string = "443321715214-9joe4c9l00osc6qcc4l0i2k3420jvb7q.apps.googleusercontent.com";
const client = new OAuth2Client(CLIENT_ID);
async function verify(token:string) {
const ticket = await client.verifyIdToken({
idToken: token,
audience: CLIENT_ID
});
return ticket.getPayload();
}
module.exports.validator = verify;

View File

@ -1,89 +0,0 @@
const exec = (nombre:string, email:string, pass:string, sesion:any) =>
new Promise((resolve, reject) => {
const mysql = require('mysql');
const SQL_CONNECT_DATA = require('./VARIABLES').sqlConnectData;
const con = mysql.createConnection(SQL_CONNECT_DATA);
con.connect((err:any) => {
if (err) reject("Error al conectarse a la BBDD. registrarUsuarios.ts 10.\n" + err);
con.query(
`SELECT email FROM usuarios WHERE email='${email}'`,
(err:any, respuesta:any) => {
const data = JSON.stringify(respuesta);
if (data === "[]") {
con.query(
`INSERT INTO usuarios (GOOGLE_ID, nombre, email, img, carritoActual, contrasena, ROL)
VALUES ('0','${nombre}', '${email}', '/img/usuario.png', '{}', '${pass}', 'user' )`,
(err:any, respuesta:any) => {
if (err) reject ('Error al ejecutar SQL. registrarUsuario.ts 21\n' + err);
/* El servidor me obligo a hacer esto en vez de usar SELECT LAST_INSERT_ID() */
con.query(
`SELECT USER_ID FROM usuarios WHERE email='${email}'`,
(err:any, respuesta:any) => {
if (err) reject ('Error al ejecutar SQL. registrarUsuario.ts 27\n' + err);
/* Crea la variable de sesion */
sesion.nombre = nombre;
sesion.email = email;
sesion.img = '/img/usuario.png';
sesion.carritoActual = '{}';
sesion.USER_ID = respuesta[0]["USER_ID"];
sesion.ROL = 'user';
sesion.save((err:any) => {
if (err) console.log(`Error :c\n${err}`);
console.log("En teoria ya guarde la sesion....");
});
const datos = {
nombre,
email,
img: '/img/usuario.png',
carritoActual: '{}',
'USER_ID': respuesta[0]["USER_ID"],
ROL: 'user',
logged: true
};
resolve(`{ "existe": false, "creado": true, "data": ${JSON.stringify(datos)} }`);
}
);
}
);
} else {
resolve(`{ "existe": true }`);
}
}
);
});
});
const registrar = (req:any, res:any) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
const sesion = req.session;
const nombre:string = req.body.nombre;
const email:string = req.body.email;
const pass:string = req.body.pass;
if (nombre && email && pass) {
exec(nombre, email, pass, sesion)
.then(respuesta => {
res.send(respuesta);
})
.catch(reason => console.log("Ups. Un error.\n" + reason));
} else {
res.send("Error, datos insuficientes.");
}
};
module.exports.registrar = registrar;

View File

@ -1,117 +0,0 @@
const validator = require('./google_validation.js').validator;
const crearUsuario = (con:any, data:object) =>
new Promise((resolve, reject) => {
con.query (
`INSERT INTO usuarios (nombre, email, img, carritoActual, GOOGLE_ID, ROL)\
VALUES ('${(data as any)["nombreUsuario"]}', '${(data as any)["emailUsuario"]}',
'${(data as any)["imagenUsuario"]}', '{}', '${(data as any)["googleID"]}', 'user')`,
(err:any, res:string) => {
if (err) {
reject("Error al ejecutar query SQL (revisarUsuarioG.ts fila 11))...\n" + err);
}
/* Luego de insertar el usuario, como GET_LAST_INDEX no funciona, otra query obtiene el num de usuario */
con.query(
`SELECT USER_ID FROM usuarios WHERE GOOGLE_ID='${(data as any)["googleID"]}'`,
(err:any, res:any) => {
if (err) reject(`Error al ejecutar query SQL en revisarUsuarios.ts 18.\n${err}`);
resolve(res[0]["USER_ID"]);
}
);
}
);
});
const revisarUsuarioG = (usuario:object, sesion:any) => {
return new Promise((resolve, reject) => {
const mysql = require('mysql');
const SQL_CONNECT_DATA = require('./VARIABLES').sqlConnectData;
const con = mysql.createConnection(SQL_CONNECT_DATA);
con.connect( (err:any) => {
if (err) {
reject("Error al conectarse a la BBDD.");
}
const nombreUsuario:string = (usuario as any)["name"];
const emailUsuario:string = (usuario as any)["email"];
const imagenUsuario:string = (usuario as any)["picture"];
const googleID:number = (usuario as any)["sub"];
con.query (`SELECT nombre, email, img, carritoActual, USER_ID, ROL FROM usuarios WHERE GOOGLE_ID='${googleID}'`,
(err:any, response:any) => {
if (err) {
reject("Error al ejecutar query SQL");
}
const respuestaBD:string = JSON.stringify(response);
if (respuestaBD === '[]') {
/* El usuario no existe :D */
crearUsuario(con, {nombreUsuario, emailUsuario, imagenUsuario, googleID})
.then( (res:any) => {
/* Almacenar la sesion :c */
sesion.nombre = nombreUsuario;
sesion.email = emailUsuario;
sesion.img = imagenUsuario;
sesion.USER_ID = res[0]["USER_ID"];
sesion.ROL = "user";
sesion.carritoActual = "{}";
sesion.save((err:any) => {
if (err)
console.log(`Error al guardar sesion :c\n${err}`)
});
resolve(`{ "nombre": "${nombreUsuario}", "email": "${emailUsuario}", "img": "${imagenUsuario}",
"carrito": {}, "rol": "user", "USER_ID": "${res}"}`);
})
.catch((msg:string) => {
reject("Error al crear el usuario...\n" + msg);
})
} else {
/* Almacenar la sesion :c */
sesion.nombre = nombreUsuario;
sesion.email = emailUsuario;
sesion.img = imagenUsuario;
sesion.USER_ID = response[0]["USER_ID"];
sesion.ROL = response[0]["ROL"];
sesion.carritoActual = response[0]["carritoActual"];
sesion.save((err:any) => {
if (err)
console.log(`Error :c\n${err}`)
});
console.log(`Respuesta servidor:\n${respuestaBD}`);
resolve(JSON.stringify(response[0]));
}
});
});
});
};
const revisarUsuario = (req:any, res:any) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
const token:string = req.body.idtoken;
validator(token)
.then( (usuario:object) => {
revisarUsuarioG(usuario, req.session)
.then(response => res.send(response.toString()))
.catch(err => res.send(err))
})
.catch(console.error);
};
module.exports.revisarUsuarioG = revisarUsuario;

View File

@ -1,35 +0,0 @@
function revisarSesion(req:any, res:any) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
const sesion = req.session;
const USER_ID = sesion.USER_ID;
if (USER_ID) {
console.log("Recorde el usuario :3");
const nombre = sesion.nombre;
const email = sesion.email;
const img = sesion.img;
const carritoActual = sesion.carritoActual;
const ROL = sesion.ROL;
const data = {
nombre,
email,
img,
carritoActual: JSON.parse(carritoActual),
ROL,
USER_ID,
logged: true
};
res.send(JSON.stringify(data));
} else {
console.log("Hmmph, no hay nadie logeado....");
res.send(`{ "logged": false }`);
}
}
module.exports.revisarSesion = revisarSesion;

View File

@ -1,41 +0,0 @@
/* Metodo que obtiene los usuarios que existen. */
const obtenerUsuarios = () => {
return new Promise((resolve, reject) => {
const con = require('mysql').createConnection({
host: '35.193.16.64',
user: 'Araozu',
password: 'xsakah4b',
database: 'Usuarios_DB'
});
con.connect( (err:any) => {
if (err) {
console.log("Error en usuarios.ts 13.\n" + err);
reject("Error :c");
}
con.query(
`SELECT USER_ID, GOOGLE_ID, nombre, ROL FROM usuarios WHERE ROL='user'`,
(err:any, response:any) => {
if (err) {
console.log("Error en usuarios.ts 21.\n" + err);
reject("Error :c");
}
resolve(response);
}
);
});
});
};
const procesar = (req:any, res:any) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
obtenerUsuarios()
.then((resultado:object) => res.send(JSON.stringify(resultado)))
.catch(reason => res.send(reason));
};
module.exports.usuarios = procesar;

View File

@ -1,26 +0,0 @@
# ihc-router
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```

28
app.ts
View File

@ -1,28 +0,0 @@
require('@google-cloud/debug-agent').start();
const expressr = require('express');
const apuri = expressr();
const session = require('express-session');
apuri.use(expressr.json());
apuri.use(expressr.urlencoded());
apuri.use(expressr.static('dist'));
apuri.use(session({
secret: 'azopotamadre we v:',
resave: false,
saveUninitialized: false
}));
/* PUERTO NECESARIO PARA DEPLOYAR EN GOOGLE CLOUD!!! */
const puerto = 8080;
apuri.post('/log-inG', require('./Backend/revisarUsuarioG.js').revisarUsuarioG);
apuri.post('/usuarios', require('./Backend/usuarios.js').usuarios);
apuri.post('/registro', require('./Backend/registrarUsuario.js').registrar);
apuri.post('/sesion', require('./Backend/usuarioLogueado').revisarSesion);
apuri.post('/pedidos/actual', require('./Backend/Pedidos/obtenerPedidosActuales').obtenerPedido);
apuri.get('/');
apuri.listen(puerto, () => console.log(`Estoy escuchando el puerto ${puerto} we v:`));

View File

@ -1,6 +0,0 @@
runtime: nodejs8
instance_class: F2
env_variables:
BUCKET_NAME: "example-gcs-bucket"

View File

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/app'
]
};

1
dist/css/base.css vendored Normal file

File diff suppressed because one or more lines are too long

10947
dist/dependencias/vue.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
dist/dependencias/vuerouter.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/app.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/base.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/topbar.min.js vendored Normal file
View File

@ -0,0 +1 @@
const topBar=document.createElement("div");topBar.style.position="fixed",topBar.style.minHeight="3px",topBar.style.backgroundColor="red",topBar.style.zIndex="1";const transitionD=500;topBar.style.transition="min-width 500ms, opacity 250ms",topBar.style.minWidth="0";let promesaActual,widthDestino=0;document.body.appendChild(topBar);const cambiarProgreso=t=>(widthDestino=t,promesaActual=new Promise((o,i)=>{topBar.style.minWidth=`${t}%`,setTimeout(()=>o(),500)})),cancelarTransicion=()=>{const t=topBar.style.transition;topBar.style.transition="",topBar.style.minWidth=`${widthDestino}%`,topBar.style.transition=t},ocultarTopBar=()=>{topBar.style.opacity="0",setTimeout(()=>{topBar.style.minWidth="0%"},250)},reiniciarTopBar=()=>{const t=topBar.style.transition;topBar.style.transition="",topBar.style.minWidth="0",topBar.style.opacity="1",topBar.style.transition=t};

129
index.php Normal file
View File

@ -0,0 +1,129 @@
<!DOCTYPE HTML>
<html lang="es">
<head>
<title>Cocina Francesa</title>
<link rel="stylesheet" href="/ihc/dist/css/base.css?v=2" type="text/css"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="/ihc/dist/js/topbar.min.js"></script>
<div id="vueApp">
<router-view></router-view>
</div>
<!-- Vue y Vuerouter -->
<!--<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="/ihc/dist/dependencias/vuerouter.min.js"></script>
<script src="/ihc/dist/dependencias/vue.js"></script>
<script>
Vue.use(VueRouter);
const carritoUsuario = [];
const footer = {
template: `<?php include "./src/componentes/mi-footer.vue" ?>`
};
const navBar = {
template: `<?php include "./src/componentes/navBar.vue" ?>`
};
const headerMin = {
template: `<?php include "./src/componentes/headerMin.vue" ?>`
};
const inicio = {
template: `<?php include "./src/componentes/inicio.vue" ?>`,
components: {
'mi-footer': footer,
'header-min': headerMin,
'nav-bar': navBar
}
};
const carrito = {
template: `<?php include "./src/componentes/carrito.vue"?>`,
components: {
'mi-footer': footer,
'header-min': headerMin,
'nav-bar': navBar
},
data: function () {
return {
item: carritoUsuario,
descuento: 0
};
},
computed: {
cantidadItems: function () {
let items = 0;
for (const i in this.item)
items++;
return items;
},
subTotal: function () {
let subT = 0;
for (const itemI in this.item ) {
if (this.item.hasOwnProperty(itemI)){
const item = this.item[itemI];
subT += (item["precio"] * item["cantidad"]);
}
}
return subT;
},
total: function () {
return this.subTotal - this.descuento;
},
noEstaVacio: function () {
for (const i in this.item) {
return true;
}
return false;
},
},
methods: {
restarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad > 0)
elem.cantidad = cantidad -1;
},
aumentarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad >= 0)
elem.cantidad = cantidad+1;
}
}
};
const routes = [
{path: '/ihc/',component: inicio},
{path: '/ihc/carrito/', component: carrito}
];
const router = new VueRouter({
mode: 'history',
routes: routes
});
const vm = new Vue({
el: '#vueApp',
router: router
})
.$mount('#vueApp');
</script>
<!-- Logica principal -->
<!--<script src="./dist/js/base.min.js?v=2"></script>-->
</body>
</html>

67
iniciar-sesion.php Normal file
View File

@ -0,0 +1,67 @@
<div class="contenedor inicio_registro">
<div class="center">
Inicia Sesión.
</div>
<br />
<br />
<br />
<div class="row">
<div class="col-7 center">
<br>
<br>
<br>
<br>
<br>
<br>
<img src="https://www.sbs.com.au/food/sites/sbs.com.au.food/files/styles/full/public/nicoise-salad.jpg?itok=MK0Y7QKN&mtime=1499834368"
alt="plato de comida" class="image">
</div>
<div class="col-5 center">
<br />
<br />
<button type="button" class="google-button" style="width: 213px">
<span class="google-button__icon">
<svg viewBox="0 0 366 372" xmlns="http://www.w3.org/2000/svg">
<path d="M125.9 10.2c40.2-13.9 85.3-13.6 125.3 1.1 22.2 8.2 42.5 21 59.9 37.1-5.8 6.3-12.1 12.2-18.1 18.3l-34.2 34.2c-11.3-10.8-25.1-19-40.1-23.6-17.6-5.3-36.6-6.1-54.6-2.2-21 4.5-40.5 15.5-55.6 30.9-12.2 12.3-21.4 27.5-27 43.9-20.3-15.8-40.6-31.5-61-47.3 21.5-43 60.1-76.9 105.4-92.4z" id="Shape" fill="#EA4335"/><path d="M20.6 102.4c20.3 15.8 40.6 31.5 61 47.3-8 23.3-8 49.2 0 72.4-20.3 15.8-40.6 31.6-60.9 47.3C1.9 232.7-3.8 189.6 4.4 149.2c3.3-16.2 8.7-32 16.2-46.8z" id="Shape" fill="#FBBC05"/><path d="M361.7 151.1c5.8 32.7 4.5 66.8-4.7 98.8-8.5 29.3-24.6 56.5-47.1 77.2l-59.1-45.9c19.5-13.1 33.3-34.3 37.2-57.5H186.6c.1-24.2.1-48.4.1-72.6h175z" id="Shape" fill="#4285F4"/><path d="M81.4 222.2c7.8 22.9 22.8 43.2 42.6 57.1 12.4 8.7 26.6 14.9 41.4 17.9 14.6 3 29.7 2.6 44.4.1 14.6-2.6 28.7-7.9 41-16.2l59.1 45.9c-21.3 19.7-48 33.1-76.2 39.6-31.2 7.1-64.2 7.3-95.2-1-24.6-6.5-47.7-18.2-67.6-34.1-20.9-16.6-38.3-38-50.4-62 20.3-15.7 40.6-31.5 60.9-47.3z" fill="#34A853"/>
</svg>
</span>
<span class="google-button__text">Iniciar con Google</span>
</button>
<br />
<br />
<button style="background-color: #4064ad; height: 40px; border: none; box-shadow: 1px 1px 2px black;
border-radius: 3px">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="Capa_1" x="0px" y="0px" width="20px" viewBox="0 0 96.124 96.123"
style="max-height: 18px" xml:space="preserve">
<g>
<path d="M72.089,0.02L59.624,0C45.62,0,36.57,9.285,36.57,23.656v10.907H24.037c-1.083,0-1.96,0.878-1.96,1.961v15.803 c0,1.083,0.878,1.96,1.96,1.96h12.533v39.876c0,1.083,0.877,1.96,1.96,1.96h16.352c1.083,0,1.96-0.878,1.96-1.96V54.287h14.654 c1.083,0,1.96-0.877,1.96-1.96l0.006-15.803c0-0.52-0.207-1.018-0.574-1.386c-0.367-0.368-0.867-0.575-1.387-0.575H56.842v-9.246 c0-4.444,1.059-6.7,6.848-6.7l8.397-0.003c1.082,0,1.959-0.878,1.959-1.96V1.98C74.046,0.899,73.17,0.022,72.089,0.02z" style="fill: rgb(255, 255, 255);"></path>
</g>
</svg>
<span class="google-button__text" style="color: white; padding: 0 13px">Iniciar con Facebook</span>
</button>
<br />
<br />
O inicia sesión con tu correo:<br />
<br />
<br />
<form method="post" onsubmit="return false">
Correo Electrónico:<br />
<input type="text" placeholder="Tu correo Electrónico"><br />
<br />
Contraseña:<br />
<input type="password" placeholder="Contraseña"><br />
<br />
<input class="botonEnviarForm" type="submit" value="Iniciar Sesión">
</form>
<br />
<br />
¿No tienes una cuenta?<br />
<a href="./#registro" id="botonRegistro" class="boton">
Regístrate
</a>
</div>
</div>
<br />
<br />
</div>

12864
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,25 @@
{ {
"name": "ihc-router", "name": "ihc",
"version": "0.1.0", "version": "1.0.0",
"private": true, "description": "A simple meb application for a 'French Restaurant'",
"main": "index.php",
"scripts": { "scripts": {
"serve": "vue-cli-service serve --port 8081", "uglify": "uglifyjs src/js/*.js -m -c -o dist/js/app.js",
"build": "vue-cli-service build", "sass": "sass -s compressed src/sass:dist/css"
"start": "node app.js"
}, },
"dependencies": { "repository": {
"@google-cloud/debug-agent": "^3.0.0", "type": "git",
"@types/express": "^4.16.0", "url": "git+https://gitlab.com/Araozu/ihc-proyect.git"
"@types/mysql": "^2.15.5",
"@types/node": "^10.12.1",
"express": "^4.16.3",
"express-session": "^1.15.6",
"google-auth-library": "^2.0.0",
"mysql": "^2.16.0",
"vue": "^2.5.17",
"vue-router": "^3.0.1"
}, },
"devDependencies": { "keywords": [
"@vue/cli-plugin-babel": "^3.0.5", "ihc",
"@vue/cli-service": "^3.0.5", "unsa",
"node-sass": "^4.9.0", "2018"
"sass-loader": "^7.0.1", ],
"vue-template-compiler": "^2.5.17" "author": "Fernando Araoz Morales",
"license": "MIT",
"bugs": {
"url": "https://gitlab.com/Araozu/ihc-proyect/issues"
}, },
"postcss": { "homepage": "https://gitlab.com/Araozu/ihc-proyect#readme"
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="443321715214-9joe4c9l00osc6qcc4l0i2k3420jvb7q.apps.googleusercontent.com">
<title>L'Assiete</title>
</head>
<body>
<noscript>
<strong>Ups. La página de L'Assiete no se puede mostrar si tienes el JavaScript desactivado :c <br>
Actívalo y recarga la página.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

69
registro.php Normal file
View File

@ -0,0 +1,69 @@
<div class="contenedor inicio_registro">
<div class="center">
Registrate para tener lo mejor de la cocina francesa en la comodida de tu casa.<br />
</div>
<br />
<br />
<div class="row">
<div class="col-7 center">
<br />
<button type="button" class="google-button" style="width: 213px">
<span class="google-button__icon">
<svg viewBox="0 0 366 372" xmlns="http://www.w3.org/2000/svg">
<path d="M125.9 10.2c40.2-13.9 85.3-13.6 125.3 1.1 22.2 8.2 42.5 21 59.9 37.1-5.8 6.3-12.1 12.2-18.1 18.3l-34.2 34.2c-11.3-10.8-25.1-19-40.1-23.6-17.6-5.3-36.6-6.1-54.6-2.2-21 4.5-40.5 15.5-55.6 30.9-12.2 12.3-21.4 27.5-27 43.9-20.3-15.8-40.6-31.5-61-47.3 21.5-43 60.1-76.9 105.4-92.4z" id="Shape" fill="#EA4335"/><path d="M20.6 102.4c20.3 15.8 40.6 31.5 61 47.3-8 23.3-8 49.2 0 72.4-20.3 15.8-40.6 31.6-60.9 47.3C1.9 232.7-3.8 189.6 4.4 149.2c3.3-16.2 8.7-32 16.2-46.8z" id="Shape" fill="#FBBC05"/><path d="M361.7 151.1c5.8 32.7 4.5 66.8-4.7 98.8-8.5 29.3-24.6 56.5-47.1 77.2l-59.1-45.9c19.5-13.1 33.3-34.3 37.2-57.5H186.6c.1-24.2.1-48.4.1-72.6h175z" id="Shape" fill="#4285F4"/><path d="M81.4 222.2c7.8 22.9 22.8 43.2 42.6 57.1 12.4 8.7 26.6 14.9 41.4 17.9 14.6 3 29.7 2.6 44.4.1 14.6-2.6 28.7-7.9 41-16.2l59.1 45.9c-21.3 19.7-48 33.1-76.2 39.6-31.2 7.1-64.2 7.3-95.2-1-24.6-6.5-47.7-18.2-67.6-34.1-20.9-16.6-38.3-38-50.4-62 20.3-15.7 40.6-31.5 60.9-47.3z" fill="#34A853"/>
</svg>
</span>
<span class="google-button__text">Regístrate con Google</span>
</button>
<br />
<br />
<button style="background-color: #4064ad; height: 40px; border: none; box-shadow: 1px 1px 2px black;
border-radius: 3px">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="Capa_1" x="0px" y="0px" width="20px" viewBox="0 0 96.124 96.123"
style="max-height: 18px" xml:space="preserve">
<g>
<path d="M72.089,0.02L59.624,0C45.62,0,36.57,9.285,36.57,23.656v10.907H24.037c-1.083,0-1.96,0.878-1.96,1.961v15.803 c0,1.083,0.878,1.96,1.96,1.96h12.533v39.876c0,1.083,0.877,1.96,1.96,1.96h16.352c1.083,0,1.96-0.878,1.96-1.96V54.287h14.654 c1.083,0,1.96-0.877,1.96-1.96l0.006-15.803c0-0.52-0.207-1.018-0.574-1.386c-0.367-0.368-0.867-0.575-1.387-0.575H56.842v-9.246 c0-4.444,1.059-6.7,6.848-6.7l8.397-0.003c1.082,0,1.959-0.878,1.959-1.96V1.98C74.046,0.899,73.17,0.022,72.089,0.02z" style="fill: rgb(255, 255, 255);"></path>
</g>
</svg>
<span class="google-button__text" style="color: white; padding: 0 13px">Regístrate con Facebook</span>
</button>
<br />
<br />
<br />
O crea tu cuenta con tu correo electrónico:
<br />
<br />
<br />
<form method="post" onsubmit="return false">
Nombre:<br />
<input placeholder="Tu nombre" name="userName"><br />
<br />
Correo Electrónico:<br />
<input placeholder="Tu correo Electrónico" name="userEmail"><br />
<br />
Contraseña<br />
<input type="password" placeholder="Contraseña" name="userPass"><br />
<br />
<input class="botonEnviarForm" type="submit" value="¡Crear mi cuenta!">
</form>
<br />
<br />
¿Ya tienes una cuenta?<br />
<a href="./#iniciar-sesion" id="botonInicioSesion" class="boton">
Inicia Sesion
</a>
</div>
<div class="col-5 center">
<br>
<br>
<img class="image" alt="Torre Eiffel" src="https://kids.nationalgeographic.com/content/dam/kids/photos/Countries/A-G/france-eiffel-tower.ngsversion.1396531559251.adapt.1900.1.jpg">
<br>
<br>
<img class="image" src="https://www.slh.com/globalassets/country-pages/hero-images/france3.jpg" alt="Vista de francia">
</div>
</div>
<br />
<br />
</div>

View File

@ -1,30 +0,0 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
import conexion from './variables'
export default {
name: 'App',
// Revisa si existe una variable de sesion con el usuario
created: function () {
const xhr = new XMLHttpRequest();
xhr.open("POST",`${conexion}/sesion`);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onload = () => {
const data = JSON.parse(xhr.responseText);
if (data["logged"]) {
window.usuarioActual.pop();
window.usuarioActual.push(data);
}
};
xhr.send();
}
}
</script>
<style>
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,94 @@
<div>
<header-min></header-min>
<nav-bar></nav-bar>
<section id="sectionCarrito" class="contenedor mySeccion" data-collapsed="false">
<br/>
<br/>
<div class="center">
<div id="carrito--tituloprincipal">
Carrito de compras
</div>
<br/>
<a id="carrito--boton--seguircomprando" href="./#usuarios/">Seguir comprando</a>
<br/>
<br/>
<div id="carrito" class="row carrito">
<div id="carrito--elementos" class="col-8">
<div id="carrito--elementos--contenido" class="caja">
<template v-if="noEstaVacio">
<template v-for="producto in item">
<div class="carritoElem">
<img class="carritoElem--img" v-bind:src="producto.imgUrl">
<div class="plato--Titulo">{{ producto.nombre }}</div>
<br>
<div class="plato--Precio">{{ producto.precio }}</div>
<div class="plato--Cantidad">Cantidad:
<i class="material-icons plato--Cantidad--Icon" v-on:click="restarCantidad(producto)">remove</i>
<span>{{ producto.cantidad }}</span>
<i class="material-icons plato--Cantidad--Icon" v-on:click="aumentarCantidad(producto)">add</i>
</div>
<br>
<div class="carrito--subTotal">{{ producto.precio * producto.cantidad }}</div>
<hr>
</div>
</template>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
<div id="carrito--precio" class="col-4">
<div id="carrito--precio--contenido" class="caja">
<template v-if="noEstaVacio">
<div id="pagos">
<div style="display: inline-block;">
{{ cantidadItems }} Producto{{ (cantidadItems>1 || cantidadItems === 0) ? 's': '' }}
</div>
<div style="display: inline-block; float: right; clear: both">
{{ subTotal }} S/.
</div>
</div>
<div>
<div style="display: inline-block;">
Descuentos:
</div>
<div style="display: inline-block; float: right; clear: both">
{{ descuento }} S/.
</div>
</div>
<br>
<br>
<div>
<div class="carrito--precio--contenido--titulo" style="display: inline-block;">
Total:
</div>
<div class="carrito--precio--contenido--titulo"
style="display: inline-block; float: right; clear: both">
{{ total }} S/.
</div>
</div>
<br>
<br>
<a class="carrito--precio--contenido--botonPagar">
Completar Transaccion
</a>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
</div>
</div>
<br/>
<br/>
</section>
<mi-footer></mi-footer>
</div>

View File

@ -0,0 +1,10 @@
<header id="header">
<div class="contenedor">
<div id="tituloP" class="center">
<a href="./#" style="color: white; text-decoration: none">Le goût</a>
<div id="tituloP--descripcion">
Descubre un nuevo sabor
</div>
</div>
</div>
</header>

View File

@ -0,0 +1,23 @@
<header id="header">
<div class="contenedor">
<div id="tituloP" class="center">
<a href="./#" style="color: white; text-decoration: none">L'Assiette</a>
<div id="tituloP--descripcion">
Descubre un nuevo sabor
</div>
</div>
</div>
<div id="contenedorInicio-Registro" class="center mySeccion" data-collapsed="false">
<a href="./#registro" id="botonRegistro" class="boton">
Registrarse
</a>
<a href="./#iniciar-sesion" id="botonInicioSesion" class="boton">
Iniciar Sesion
</a>
<br/>
<br/>
<br/>
</div>
<div id="inicio_registro" class="mySeccion" data-collapsed="true" style="height: 0"></div>
</header>

View File

@ -0,0 +1,44 @@
<div>
<header-min></header-min>
<nav-bar></nav-bar>
<section id="sectionP" class="contenedor mySeccion" data-collapsed="false">
<div class="row contenido">
<div class="col-5">
<img class="image" src="http://www.saintjacquesfrenchcuisine.com/images/MenuSlide5.jpg"
alt="Plato Francés"/>
</div>
<div class="col-7">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col-7 center">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Congue quisque egestas diam in arcu cursus euismod quis. Mi tempus imperdiet nulla
malesuada pellentesque elit eget gravida. Tempus imperdiet nulla malesuada pellentesque elit eget
gravida
cum. Commodo elit at imperdiet dui accumsan sit amet. In nulla posuere sollicitudin aliquam ultrices
sagittis.
</div>
</div>
<div class="col-5">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/6a/Jacques_Lameloise%2C_escab%C3%A8che_d%27%C3%A9crevisses_sur_gaspacho_d%27asperge_et_cresson.jpg"
alt="Plato Francés" class="image">
</div>
</div>
<br/>
</section>
<mi-footer></mi-footer>
</div>

View File

@ -0,0 +1,11 @@
<div>
<footer id="footer">
<div class="contenedor">
Cocina Francesa.<br/>
Una Single Page Application para el curso de IHC, UNSA, 2018.<br/>
Se utilizaron: Vue.js, BEM, Sass, npm, y PHP.<br>
<br/>
Desarrollado por Fernando Araoz, 20173373.
</div>
</footer>
</div>

View File

@ -0,0 +1,10 @@
<div>
<nav id="navBar" class="mySeccion" data-collapsed="true">
<ul class="linksNavBar">
<li><router-link to="/ihc/">Inicio</router-link></li>
<li><router-link to="/ihc/usuarios/">Comprar</router-link></li>
<li><router-link to="/ihc/usuarios/mi-cuenta">Mi cuenta</router-link></li>
<li><router-link to="/ihc/carrito/">Carrito</router-link></li>
</ul>
</nav>
</div>

View File

@ -1,15 +0,0 @@
<template>
<div>
Mirame we, soy un empleado :3
</div>
</template>
<script>
export default {
name: "Empleados"
}
</script>
<style scoped>
</style>

View File

@ -1,53 +0,0 @@
<template>
<div class="usuarios">
<div class="usuarios--titulos">
Usuarios <br>
</div>
<usuario v-for="user in usuarios" :key="user['USER_ID']"
:nombre="user['nombre']"
:rol="user['ROL']"
:googleId="user['GOOGLE_ID']"
:userId="user['USER_ID']"
/>
</div>
</template>
<script>
// const conexion = require('../../variables').conexion;
import conexion from '../../variables';
export default {
name: "Usuarios",
components: {
'usuario': () => import('./Usuarios/Usuario')
},
data: function () {
return {
usuarios: []
}
},
created: function () {
let vm = this;
let xhr = new XMLHttpRequest();
xhr.onload = () => {
console.log("Ya cargué we v':\n" + xhr.responseText);
vm.usuarios = JSON.parse(xhr.responseText);
};
xhr.open("POST",`${conexion}/usuarios`);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send();
}
}
</script>
<style scoped lang="sass">
.usuarios
margin: 20px 0
.usuarios--titulos
text-align: center
font:
size: x-large
</style>

View File

@ -1,27 +0,0 @@
<template>
<div class="usuario hoverable">
Nombre: {{ nombre }}<br>
rol: {{ rol }}<br>
ID de Google: {{ googleId }}<br>
ID de usuario: {{ (99999999999 - userId).toString(16).toUpperCase() }} ({{ userId }})
</div>
</template>
<script>
export default {
name: "Usuario",
props: {
nombre: String,
rol: String,
googleId: String,
userId: Number
}
}
</script>
<style scoped lang="sass">
.usuario
margin: 10px
padding: 10px
border-radius: 3px
</style>

View File

@ -1,62 +0,0 @@
<template>
<div>
<header-min></header-min>
<nav-bar></nav-bar>
<section id="sectionP" class="contenedor mySeccion" data-collapsed="false">
<div class="row contenido">
<div class="col-5">
<img class="image" src="http://www.saintjacquesfrenchcuisine.com/images/MenuSlide5.jpg"
alt="Plato Francés"/>
</div>
<div class="col-7">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col-7 center">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Congue quisque egestas diam in arcu cursus euismod quis. Mi tempus imperdiet nulla
malesuada pellentesque elit eget gravida. Tempus imperdiet nulla malesuada pellentesque elit eget
gravida
cum. Commodo elit at imperdiet dui accumsan sit amet. In nulla posuere sollicitudin aliquam ultrices
sagittis.
</div>
</div>
<div class="col-5">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/6a/Jacques_Lameloise%2C_escab%C3%A8che_d%27%C3%A9crevisses_sur_gaspacho_d%27asperge_et_cresson.jpg"
alt="Plato Francés" class="image">
</div>
</div>
<br/>
</section>
<mi-footer></mi-footer>
</div>
</template>
<script>
import HeaderMin from './headerMin'
import NavBar from './navBar'
import MiFooter from './mi-footer'
export default {
name: 'Inicio',
components: {
'header-min': HeaderMin,
'nav-bar': NavBar,
'mi-footer': MiFooter
}
}
</script>
<style>
</style>

View File

@ -1,33 +0,0 @@
<template>
<a v-on:click.prevent="cerrarSesion" title="Cerrar Sesion">Cerrar Sesion</a>
</template>
<script>
export default {
name: "botonCerrarSesion",
methods: {
cerrarSesion: function () {
const scriptGAPI = document.getElementById("googleGAPI");
try {
gapi.auth2.getAuthInstance().signOut()
.then(() =>
console.log('User signed out.')
);
} catch (e) {
let scr = document.createElement("script");
scr.src = "https://apis.google.com/js/platform.js";
scr.onload = renderButton;
scr.defer = true;
document.head.appendChild(scr);
this.cerrarSesion();
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,57 +0,0 @@
<template>
<header>
<div>
<div id="tituloP" class="center">
<router-link to="/"><h1 class="titulo--link">L'Assiette</h1></router-link>
<div id="tituloP--descripcion">
Descubre un nuevo sabor
</div>
</div>
</div>
<div v-if="musuarioNoLogeado" id="contenedorInicio-Registro" class="center mySeccion" data-collapsed="false">
<router-link to="/iniciar-sesion/" id="botonRegistro" class="boton">
Registrarse
</router-link>
<router-link to="/iniciar-sesion/" id="botonInicioSesion" class="boton">
Iniciar Sesion
</router-link>
<br/>
<br/>
<br/>
</div>
<div v-else class="inicio--usuario-registrado">
Bienvenido, {{ nombreDeUsuario }}<br/>
<router-link v-if="esAdmin" to="/a/" class="inicio--usuario-registrado--link">Ir a la zona administrativa.</router-link>
<br>
<br>
</div>
</header>
</template>
<script>
export default {
name: 'HeaderMin',
data: function () {
return {
usuario: window.usuarioActual
}
},
computed: {
musuarioNoLogeado: function () {
return !this.usuario[0].logged;
},
nombreDeUsuario: function () {
return this.usuario[0].nombre;
},
esAdmin: function () {
return this.usuario[0].ROL === "admin"
}
}
}
</script>
<style scoped lang="sass">
.inicio--usuario-registrado--link
color: white
text-decoration: underline
</style>

View File

@ -1,18 +0,0 @@
<template>
<header id="header">
<div>
<div id="tituloP" class="center tituloP--mini">
<router-link to="/" class="titulo--link">L'Assiette</router-link>
</div>
</div>
</header>
</template>
<script>
export default {
name: 'HeaderMini'
}
</script>
<style>
</style>

View File

@ -1,29 +0,0 @@
<template>
<footer id="footer">
<div class="container row mi-footer transparent">
<div class="col l6 m6">
Cocina Francesa.<br/>
Una Single Page Application para el curso de IHC, UNSA, 2018.<br/>
Con lo último en tecnología: Vue.js, BEM, Sass, TypeScript, y nodejs.<br>
<br/>
Desarrollado por Fernando Araoz, 20173373.
</div>
<div class="col l6 m6">
<div class="hide-on-med-and-up"><hr></div>
Contacto: <br>
<br>
<i class="material-icons white-text">local_phone</i>&nbsp;&nbsp;&nbsp;999 - 888 - 777 <br>
<i class="material-icons white-text">email</i>&nbsp;&nbsp;&nbsp;soporte@l-assiete.com
</div>
</div>
</footer>
</template>
<script>
export default {
name: 'MiFooter'
}
</script>
<style>
</style>

View File

@ -1,32 +0,0 @@
<template>
<nav id="navBar" class="mySeccion">
<ul class="linksNavBar">
<li><router-link to="/">Inicio</router-link></li>
<li><router-link to="/platos/">Platos</router-link></li>
<li>|</li>
<li><router-link to="/mi-cuenta/">Mi cuenta</router-link></li>
<li><router-link to="/carrito/">Mi carrito</router-link></li>
<li><router-link to="/mi-pedido/">Mis pedidos</router-link></li>
<li class="right" v-if="usuarioLogeado"><boton-cerrar-sesion /></li>
</ul>
</nav>
</template>
<script>
import BotonCerrarSesion from './botonCerrarSesion'
export default {
name: 'HeaderMini',
components: {
'boton-cerrar-sesion': BotonCerrarSesion
},
computed: {
usuarioLogeado: function () {
return window.usuarioActual[0]["logged"];
}
}
}
</script>
<style>
</style>

View File

@ -1,26 +0,0 @@
<template>
<nav v-if="usuarioNoLogeado" class="mi-nav-bar">
<ul class="linksNavBar">
<li><router-link to="/iniciar-sesion/">Inicia Sesion</router-link></li>
<li><router-link to="/iniciar-sesion/">Regístrate</router-link></li>
</ul>
</nav>
</template>
<script>
export default {
name: "navBarInicioSesion",
computed: {
usuarioNoLogeado: function () {
return !window.usuarioActual[0].logged;
}
}
}
</script>
<style scoped lang="sass">
.mi-nav-bar ul li
background-color: #3d3d7b
height: auto
</style>

View File

@ -1,16 +0,0 @@
<template>
<div class="pedido">
Este es un pedido we v:
</div>
</template>
<script>
export default {
name: "pedido"
}
</script>
<style scoped lang="sass">
.pedido
padding: 20px
</style>

137
src/js/base.js Normal file
View File

@ -0,0 +1,137 @@
const carritoUsuario = [];
/* Height Transition by CSS Tricks. Returns a Promise */
const collapseSection = element => {
return new Promise((resolve, reject) => {
// get the height of the element's inner content, regardless of its actual size
let sectionHeight = element.scrollHeight;
// temporarily disable all css transitions
let elementTransition = element.style.transition;
element.style.transition = '';
// on the next frame (as soon as the previous style change has taken effect),
// explicitly set the element's height to its current pixel height, so we
// aren't transitioning out of 'auto'
requestAnimationFrame(function () {
element.style.height = sectionHeight + 'px';
element.style.transition = elementTransition;
// on the next frame (as soon as the previous style change has taken effect),
// have the element transition to height: 0
requestAnimationFrame(function () {
element.style.height = 0 + 'px';
setTimeout(() => {
resolve("Termine de ocultar we v':");
}, 160);
});
});
// mark the section as "currently collapsed"
element.setAttribute('data-collapsed', 'true');
});
};
const expandSection = element => {
return new Promise((resolve, reject) => {
// get the height of the element's inner content, regardless of its actual size
let sectionHeight = element.scrollHeight;
// have the element transition to the height of its inner content
element.style.height = sectionHeight + 'px';
// when the next css transition finishes (which should be the one we just triggered)
element.addEventListener('transitionend', function (e) {
// remove this event listener so it only gets triggered once
element.removeEventListener('transitionend', arguments.callee);
// remove "height" from the element's inline styles, so it can return to its initial value
element.style.height = null;
setTimeout(() => {
resolve("Termine de ampliar we v':");
}, 0);
});
// mark the section as "currently not collapsed"
element.setAttribute('data-collapsed', 'false');
});
};
const abrirElemF = (element, midF, postF) => {
if (element.getAttribute("data-collapsed") === "true") {
if (midF !== undefined)
midF();
expandSection(element).then(() => {
if (postF !== undefined)
postF();
});
} else {
collapseSection(element).then(() => {
if (midF !== undefined)
midF();
expandSection(element).then(() => {
if (postF !== undefined)
postF();
});
});
}
};
const cerrarElemF = (element, postF) => {
if (element.getAttribute("data-collapsed") === "false") {
collapseSection(element).then(() => {
if (postF !== undefined)
postF();
});
}
};
const carrito = new Vue({
el: "#carrito",
data: {
item: carritoUsuario,
descuento: 0
},
computed: {
cantidadItems: function () {
let items = 0;
for (const i in this.item)
items++;
return items;
},
subTotal: function () {
let subT = 0;
for (const itemI in this.item ) {
if (this.item.hasOwnProperty(itemI)){
const item = this.item[itemI];
subT += (item["precio"] * item["cantidad"]);
}
}
return subT;
},
total: function () {
return this.subTotal - this.descuento;
},
noEstaVacio: function () {
for (const i in this.item) {
return true;
}
return false;
},
},
methods: {
restarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad > 0)
elem.cantidad = cantidad -1;
},
aumentarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad >= 0)
elem.cantidad = cantidad+1;
}
}
});

46
src/js/topbar.js Normal file
View File

@ -0,0 +1,46 @@
const topBar = document.createElement("div");
topBar.style.position = "fixed";
topBar.style.minHeight = "3px";
topBar.style.backgroundColor = "red";
topBar.style.zIndex = "1";
const transitionD = 500;
topBar.style.transition = `min-width ${transitionD}ms, opacity 250ms`;
topBar.style.minWidth = "0";
let widthDestino = 0;
document.body.appendChild(topBar);
let promesaActual;
const cambiarProgreso = progreso => {
widthDestino = progreso;
promesaActual = new Promise((resolve, reject) => {
topBar.style.minWidth = `${progreso}%`;
setTimeout(() => resolve(),transitionD);
});
return promesaActual;
};
const cancelarTransicion = () => {
const transiciones = topBar.style.transition;
topBar.style.transition = "";
topBar.style.minWidth = `${widthDestino}%`;
topBar.style.transition = transiciones;
};
const ocultarTopBar = () => {
topBar.style.opacity = "0";
setTimeout(() => {
topBar.style.minWidth = "0%";
},250);
};
const reiniciarTopBar = () => {
const transiciones = topBar.style.transition;
topBar.style.transition = "";
topBar.style.minWidth = `0`;
topBar.style.opacity = "1";
topBar.style.transition = transiciones;
};

View File

@ -1,32 +0,0 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
require('@/materialize/css/materialize.min.css');
require('@/sass/base.sass');
require('@/material-icons/material-icons.css');
require('@/materialize/js/materialize.min.js');
require('./typescript/main.js');
(() => {
window.carritoUsuario = [];
window.usuarioActual = [
{
nombre: 'Usuario',
email: 'ejemplo@l-assiete.com',
historial: {},
logged: false
}
];
window.elRouter = router
})();
new Vue({
data: {
carritoUsuario: []
},
router,
render: h => h(App)
}).$mount('#app')

View File

@ -1,36 +0,0 @@
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
src: local('Material Icons'),
local('MaterialIcons-Regular'),
url(MaterialIcons-Regular.woff2) format('woff2'),
url(MaterialIcons-Regular.woff) format('woff'),
url(MaterialIcons-Regular.ttf) format('truetype');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,54 +0,0 @@
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/platos/',
name: 'Platos',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ './views/Platos.vue')
},
{
path: '/carrito/',
name: 'Carrito',
component: () => import('./views/carrito')
},
{
path: '/iniciar-sesion/',
name: 'IniciarSesion',
component: () => import('./views/Login-Registro')
},
{
path: '/mi-cuenta/',
name: 'MiCuenta',
component: () => import('./views/MiCuenta')
},
{
path: '/mi-pedido/',
name: 'MiPedido',
component: () => import('./views/MiPedido')
},
{
path: '/a/',
name: 'Administracion',
component: () => import('./views/Administracion/Inicio'),
children: [
{ path: 'usuarios', component: () => import('./components/Admin/Usuarios') },
{ path: 'empleados', component: () => import('./components/Admin/Empleados') }
]
}
]
})

View File

@ -3,18 +3,13 @@
$fuenteTitulos: 'Muli' $fuenteTitulos: 'Muli'
$fuentePrincipal: 'Open Sans' $fuentePrincipal: 'Open Sans'
$colorPrincipalOscuro: #3d3d7c
* *
box-sizing: border-box box-sizing: border-box
html, body html, body
margin: 0 margin: 0
padding: 0 padding: 0
background-color: #F5F5F5 font-family: $fuentePrincipal, sans-serif
font:
family: $fuentePrincipal, sans-serif
size: large
header header
background-color: #44A background-color: #44A
@ -35,13 +30,57 @@ footer
box-shadow: inset 0 5px 5px #999999 box-shadow: inset 0 5px 5px #999999
padding: 40px padding: 40px
.container .contenedor
margin-top: 10px max-width: 1200px
margin-bottom: 10px width: 80%
padding: 10px margin: auto
.fondoBlanco .col-1
background-color: white width: 8.33%
.col-2
width: 16.66%
.col-3
width: 25%
.col-4
width: 33.33%
.col-5
width: 41.66%
.col-6
width: 50%
.col-7
width: 58.33%
.col-8
width: 66.66%
.col-9
width: 75%
.col-10
width: 83.33%
.col-11
width: 91.66%
.col-12
width: 100%
[class*="col-"]
float: left
.row::after
content: ""
clear: both
display: table
.center
text-align: center
#tituloP #tituloP
padding: 30px padding: 30px
@ -56,17 +95,6 @@ footer
size: large size: large
family: $fuentePrincipal family: $fuentePrincipal
.tituloP--mini
padding: 10px !important
font:
size: 40px !important
.titulo--link
color: white
text-decoration: none
font-size: 50px
margin: 0
.center .center
text-align: center text-align: center
@ -96,7 +124,6 @@ footer
#botonInicioSesion #botonInicioSesion
background-color: white background-color: white
font-size: large
transition: transform 200ms, box-shadow 200ms transition: transform 200ms, box-shadow 200ms
#botonInicioSesion:hover #botonInicioSesion:hover
@ -223,11 +250,10 @@ input
list-style: none list-style: none
float: left float: left
transition: background-color 250ms transition: background-color 250ms
line-height: 50px
a a
cursor: pointer cursor: pointer
display: inline-block display: inline-block
padding: 0 15px padding: 15px
color: white color: white
text-decoration: none text-decoration: none
&:after &:after
@ -337,78 +363,4 @@ input
weight: 900 weight: 900
margin: 10px 0 margin: 10px 0
.responsive-image
padding: 0 20px
width: 100%
height: auto
.tienda--titulo
text-align: center
font:
family: $fuenteTitulos, sans-serif
size: xx-large
weight: 900
margin: 10px 0
.tienda--tarjeta
padding: 10px
margin: 20px 5px
border-radius: 3px
.tienda--tarjeta--titulo
font:
size: x-large
family: $fuenteTitulos, sans-serif
color: $colorPrincipalOscuro
.tienda--tarjeta--descripcion
.tienda--tarjeta--precio
&:before
content: "Precio unitario: "
color: green
&:after
content: " S/."
.tienda--tarjeta--cantidad
&:before
content: "Cantidad "
.tienda--tarjeta--botonComprar
background-color: white
color: $colorPrincipalOscuro
padding: 10px
cursor: pointer
border-radius: 3px
transition: color 100ms, background-color 100ms
font:
size: large
weight: bold
family: $fuenteTitulos
&:hover
background-color: $colorPrincipalOscuro
color: white
&:focus
background-color: white
color: $colorPrincipalOscuro
.img-inicio
height: 90px
margin: 0 20px
.mi-cuenta--usuario-no-logeado
text-align: center
margin: 20px 0
font:
size: x-large
.inicio--usuario-registrado
text-align: center
color: white
font-size: large
.irAlCarrito
text-decoration: underline
color: white
cursor: pointer

View File

@ -1,18 +0,0 @@
function onSignIn(googleUser:any) {
console.log("Mirame we, estoy iniciando sesion v:");
let id_token = googleUser.getAuthResponse().id_token;
let xhr = new XMLHttpRequest();
xhr.open('POST', 'https://yourbackend.example.com/tokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
}
// @ts-ignore
window.irAlCarro = () => {
// @ts-ignore
window.elRouter.push('/carrito/');
};

View File

@ -1,8 +0,0 @@
const conexion_backend = "http://localhost:8080";
const conexion_gcloud = "https://lassiete-unsa.appspot.com/";
/* De este estilo porque por alguna razon a babel no le agrado module.exports en este archivo. */
export default conexion_gcloud;
// module.exports.conexion = conexion_backend;

View File

@ -1,64 +0,0 @@
<template>
<div style="background-color: #f5f5f5">
<header-mini />
<div class="container caja inicio">
<div class="inicio--titulo">
Administración de recursos
</div>
<div class="inicio--desc">
Selecciona un campo para empezar: <br>
<router-link to="/a/usuarios" class="inicio--desc--boton hoverable">Usuarios</router-link>
<router-link to="/a/empleados" class="inicio--desc--boton hoverable">Empleados</router-link>
</div>
<hr>
<router-view />
</div>
</div>
</template>
<script>
import Header from '../../components/headerMini'
import Usuarios from '../../components/Admin/Usuarios'
import Empleados from '../../components/Admin/Empleados'
export default {
name: "Inicio",
data: function () {
return {
componenteAct: 'header-mini'
}
},
components: {
'header-mini': Header,
'usuarios-comp': Usuarios,
'empleados-comp': Empleados
}
}
</script>
<style scoped lang="sass">
.inicio
background-color: white
.inicio--titulo
text-align: center
font:
family: Muli, "Open Sans", sans-serif
weight: bold
size: x-large
.inicio--desc
text-align: center
font:
family: Muli, "Open Sans", sans-serif
size: large
.inicio--desc--boton
display: inline-block
margin: 10px 20px
background-color: #4444aa
color: white
padding: 10px
border-radius: 3px
</style>

View File

@ -1,83 +0,0 @@
<template>
<div>
<header-min></header-min>
<nav-bar></nav-bar>
<section id="sectionP" class="container mySeccion" data-collapsed="false">
<div class="row contenido">
<div class="col l5">
<img class="image" src="http://www.saintjacquesfrenchcuisine.com/images/MenuSlide5.jpg"
alt="Plato Francés"/>
</div>
<div class="col l7">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
</div>
</div>
</div>
<br/>
<div class="row">
<div class="col l7 center">
<div class="descripcionComida">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Congue quisque egestas diam in arcu cursus euismod quis. Mi tempus imperdiet nulla
malesuada pellentesque elit eget gravida. Tempus imperdiet nulla malesuada pellentesque elit eget
gravida
cum. Commodo elit at imperdiet dui accumsan sit amet. In nulla posuere sollicitudin aliquam ultrices
sagittis.
</div>
</div>
<div class="col l5">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/6a/Jacques_Lameloise%2C_escab%C3%A8che_d%27%C3%A9crevisses_sur_gaspacho_d%27asperge_et_cresson.jpg"
alt="Plato Francés" class="image">
</div>
</div>
<br/>
Implementado con lo último en tecnología <br>
<br>
<br>
<div style="text-align: center">
<a href="https://vuejs.org/" title="Vuejs" target="_blank">
<img src="https://vuejs.org/images/logo.png" alt="vuejs" class="img-inicio hoverable">
</a>
<a href="http://getbem.com/" title="BEM" target="_blank">
<img src="http://getbem.com/assets/b_.svg" alt="bem" class="img-inicio hoverable" style="background-color: black">
</a>
<a href="https://sass-lang.com/" title="Sass" target="_blank">
<img src="https://sass-lang.com/assets/img/logos/logo-b6e1ef6e.svg" class="img-inicio hoverable" alt="sass">
</a>
<a href="https://www.typescriptlang.org/" title="TypeScript" target="_blank">
<img src="https://cdn-images-1.medium.com/max/1187/1*JsyV8lXMuTbRVLQ2FPYWAg.png" class="img-inicio hoverable" alt="typescript">
</a>
<a href="https://nodejs.org/es/" title="nodejs" target="_blank">
<img src="https://pluralsight.imgix.net/paths/path-icons/nodejs-601628d09d.png" alt="nodejs" class="img-inicio hoverable">
</a>
</div>
</section>
<mi-footer></mi-footer>
</div>
</template>
<script>
import HeaderMin from '@/components/headerMin'
import NavBar from '@/components/navBar'
import MiFooter from '@/components/mi-footer'
export default {
name: 'home',
components: {
'header-min': HeaderMin,
'nav-bar': NavBar,
'mi-footer': MiFooter
}
}
</script>
<style>
</style>

View File

@ -1,326 +0,0 @@
<template>
<div>
<header>
<div>
<div id="tituloP" class="center">
<router-link to="/"><h1 class="titulo--link">L'Assiette</h1></router-link>
<div id="tituloP--descripcion">
Descubre un nuevo sabor
</div>
</div>
</div>
<div class="container">
<div class="login--google">
Ingresa con Google: <br>
<br>
<div id="my-signin2"></div>
</div>
<br>
<br>
<div class="row login">
<div class="col l6 m6 s12 login--descripcion center-align">
Inicia sesión con tu email: <br>
<br>
<div class="center">
<form name="form-inicio-sesion" class="login--form"
v-on:submit.prevent="iniciarSesion('form-inicio-sesion')">
<label class="login--form--label">Email:</label>
<input class="login--form--input" type="email" placeholder="Tu email" name="email"
required><br>
<br>
<label class="login--form--label">Contraseña</label>
<input class="login--form--input" type="password" placeholder="Contraseña" required><br>
<br>
<button class="btn waves-effect waves-light" type="submit" name="action">Inicia Sesión
</button>
</form>
</div>
<br>
</div>
<div class="col l6 m6 s12 login--registro center-align" id="bordeIzq">
Regístrate con tu email: <br>
<br>
<div class="center">
<form name="form-registro" class="login--form"
v-on:submit.prevent="registrar('form-registro')">
<label class="login--form--label">Nombre</label>
<input class="login--form--input" type="text" placeholder="Tu nombre" name="nombre"
required><br>
<br>
<label class="login--form--label">Email:</label>
<input class="login--form--input" type="email" placeholder="Tu email" name="email"
required><br>
<br>
<label class="login--form--label">Contraseña</label>
<input class="login--form--input" type="password" placeholder="Contraseña" name="pass"
required><br>
<br>
<button class="btn waves-effect waves-light" type="submit" name="action">Regístrame
</button>
</form>
</div>
</div>
</div>
<br>
</div>
<div id="pantalla-carga" pantalla-activa="false">
Iniciando Sesión...<br>
<br>
<div class="preloader-wrapper active center" id="esfera-carga">
<div class="spinner-layer spinner-blue">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-red">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-yellow">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-green">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
<br>
</header>
</div>
</template>
<script>
import MiFooter from '@/components/mi-footer.vue'
/* Cambiado porque a Babel no le gusto es sistema con module.exports/require */
// const conex_backend = require('../variables.js').conexion;
import conex_backend from '../variables';
const procesarUsuario = data => {
try {
const obj = JSON.parse(data);
obj["logged"] = true;
console.log(JSON.stringify(obj));
window.usuarioActual.pop();
window.usuarioActual.push(obj);
window.elRouter.push('/platos/');
} catch (e) {
cambiarPantallaCarga();
}
};
function onSuccess(googleUser) {
cambiarPantallaCarga();
let id_token = googleUser.getAuthResponse().id_token;
let xhr = new XMLHttpRequest();
console.log(`Conexion backend es ${conex_backend}`);
xhr.open('POST', `${conex_backend}/log-inG`);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
console.log('Sesión iniciada. Servidor:\n' + xhr.responseText);
procesarUsuario(xhr.responseText);
};
xhr.send('idtoken=' + id_token);
}
function onFailure(error) {
console.log(error);
}
function renderButton() {
gapi.signin2.render('my-signin2', {
'scope': 'profile email',
'width': 240,
'height': 50,
'longtitle': true,
'theme': 'dark',
'onsuccess': onSuccess,
'onfailure': onFailure
});
}
const crearUsuario = data =>
new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("POST", `${conex_backend}/registro`);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = () => {
const resultado = JSON.parse(xhr.responseText);
if (!resultado["existe"] && resultado["creado"]) {
resolve(JSON.stringify(resultado["data"]));
} else {
reject();
}
};
xhr.send(`nombre=${data['nombreUsuario']}&email=${data['emailUsuario']}&pass=${data['passUsuario']}`);
});
const cambiarPantallaCarga = () => {
const elem = document.getElementById("pantalla-carga");
const pantallaActiva = elem.getAttribute("pantalla-activa") === "true";
// La pantalla de carga es visible y hay que ocultarla
if (pantallaActiva) {
elem.setAttribute("pantalla-activa", "false");
elem.style.opacity = "0";
setTimeout(() => {
elem.style.display = "none";
}, 250);
} else {
// Aqui activamos la pantalla
elem.setAttribute("pantalla-activa", "true");
elem.style.display = "inline-table";
setTimeout(() => {
elem.style.opacity = "0.7";
}, 10);
}
};
/* Inserta el script para el inicio de sesion de gugel */
(() => {
let scr = document.createElement("script");
scr.src = "https://apis.google.com/js/platform.js";
scr.onload = renderButton;
scr.defer = true;
document.head.appendChild(scr);
})();
export default {
name: 'IniciarSesion',
components: {
'mi-footer': MiFooter
},
methods: {
registrar: function (nombre) {
cambiarPantallaCarga();
const nombreUsuario = document.forms[nombre]['nombre'].value;
const emailUsuario = document.forms[nombre]['email'].value;
const passUsuario = document.forms[nombre]['pass'].value;
crearUsuario({nombreUsuario, emailUsuario, passUsuario})
.then(respuesta => procesarUsuario(respuesta))
.catch(() => {
alert("Ya existe un usuario con este email");
});
},
iniciarSesion: function (nombre) {
const emailUsuario = document.forms[nombre]['email'].value;
const nombreUsuario = emailUsuario.substring(0, emailUsuario.search("@"));
window.usuarioActual[0].nombre = nombreUsuario;
window.usuarioActual[0].email = emailUsuario;
window.usuarioActual[0].logged = true;
window.elRouter.push("/");
}
}
}
</script>
<style scoped lang="sass">
#my-signin2
display: inline-block
#bordeIzq
border-left: solid 1px white
.login
color: white
.login--google
text-align: center
color: white
.login--boton
border: none
padding: 10px 50px
cursor: pointer
border-radius: 3px
.login--botonGoogle
background-color: white
.login--botonFacebook
background-color: #3b5998
color: white
.login--form
width: 80%
display: inline-block
.login--form--input
color: white
font-size: large !important
text-shadow: 1px 1px 2px black
.login--form--label
color: white
#pantalla-carga
background-color: black
opacity: 0
z-index: 2
position: fixed
top: 0
width: 100%
height: 100%
transition: opacity 250ms
display: none
text-align: center
padding-top: 20%
color: white
#esfera-carga
text-align: center
width: 100px
height: 100px
@media only screen and (max-width: 800px)
#pantalla-carga
padding-top: 40%
@media only screen and (max-width: 450px)
#pantalla-carga
padding-top: 70%
.lol
</style>

View File

@ -1,114 +0,0 @@
<template>
<div>
<header-mini />
<nav-bar-inicio-sesion />
<nav-bar />
<section>
<div class="container fondoBlanco">
<h2 class="tienda--titulo">Mi cuenta</h2>
<br>
<div v-if="usuarioNoLogeado" class="mi-cuenta--usuario-no-logeado">
¡Ups! Parece que no iniciaste sesión.<br>
Obtén acceso a más de 7 platos
gourmet en la comodida de tu hogar:
<br>
<br>
<div id="contenedorInicio-Registro" class="center mySeccion" data-collapsed="false">
<router-link to="/iniciar-sesion/" id="botonRegistro" class="boton">
Registrarse
</router-link>
<router-link to="/iniciar-sesion/" id="botonInicioSesion" class="boton">
Iniciar Sesion
</router-link>
<br/>
<br/>
<br/>
</div>
</div>
<div v-else class="row">
<div class="col l6 m6">
<div class="datos-usuario">
<img :src="usuario.img" alt="Imagen del Usuario" class="left datos-usuario--imagen">
<div class="datos-usuario--descr">
{{ usuario.nombre }}, desde aquí puedes acceder a todos tus datos, y modificarlos
si deseas.
</div>
<div style="clear: left;"></div>
</div>
<br>
<div class="datos-editar">
<form action="">
<label for="nombre-usuario">Tu nombre</label>
<input id="nombre-usuario" placeholder="Tu nombre" :value="usuario.nombre"/><br>
<label for="email-usuario">Tu email</label>
<input id="email-usuario" placeholder="Tu email" :value="usuario.email"/><br>
<label for="id-usuario">Tu ID de usuario</label>
<input id="id-usuario" disabled :value="(99999999999 - parseInt(usuario['USER_ID'])).toString(16).toUpperCase()">
</form>
</div>
</div>
<div class="col l6 m6">
Tu historial de Compras <br>
<br>
<div v-if="historialVacio">
Tu historial de compras está vacio. ¡Compra algo y lo verás aquí!
</div>
<div v-else>
<template v-for="(plato, key) in usuario.historial">
</template>
</div>
</div>
</div>
</div>
</section>
<mi-footer></mi-footer>
</div>
</template>
<script>
import HeaderMini from '@/components/headerMini'
import NavBar from '@/components/navBar'
import MiFooter from '@/components/mi-footer'
import NavBarInicioSesion from '../components/navBarInicioSesion.vue';
export default {
name: "MiCuenta",
components: {
NavBarInicioSesion,
'header-mini': HeaderMini,
'nav-bar': NavBar,
'mi-footer': MiFooter,
'nav-bar-inicio-sesion': NavBarInicioSesion
},
data: function () {
return {
usuario: window.usuarioActual[0]
}
},
computed: {
historialVacio: function () {
for (let i in this.usuario.historial) {
return false
}
return true
},
usuarioNoLogeado: function () {
return !this.usuario.logged;
}
}
}
</script>
<style scoped lang="sass">
.datos-usuario--imagen
margin: 10px
.datos-usuario--descr
padding: 5px
.datos-editar
</style>

View File

@ -1,116 +0,0 @@
<template>
<div>
<header-mini />
<login-bar v-if="usuarioNoLogeado" />
<nav-bar />
<div class="container fondoBlanco pedidos">
<h2 class="pedidos__titulo">Mis pedidos</h2>
<br>
<br>
<div v-if="usuarioNoLogeado" class="pedidos__usuario-no-logeado">
¡Ups! Parece que no iniciaste sesión.<br>
Inicia sesión y controla fácilmente tus pedidos y entregas a domicilio. <br>
<br>
<div id="contenedorInicio-Registro" class="center mySeccion" data-collapsed="false">
<router-link to="/iniciar-sesion/" id="botonRegistro" class="boton">
Registrarse
</router-link>
<router-link to="/iniciar-sesion/" id="botonInicioSesion" class="boton">
Iniciar Sesion
</router-link>
<br/>
<br/>
<br/>
</div>
</div>
<div v-else>
<pedido v-for="pedido in pedidos"/>
</div>
</div>
<mi-footer />
</div>
</template>
<script>
import HeaderMini from '../components/headerMini'
import NavBar from '../components/navBar'
import LoginBar from '../components/navBarInicioSesion'
import MiFooter from '../components/mi-footer'
import Pedido from '../components/pedido'
import conexion from '../variables';
export default {
name: "MiPedido",
data: function () {
return {
usuario: window.usuarioActual[0],
pedidos: []
}
},
components: {
'header-mini': HeaderMini,
'nav-bar': NavBar,
'login-bar': LoginBar,
'mi-footer': MiFooter,
'pedido': Pedido
},
computed: {
usuarioNoLogeado: function () {
return !this.usuario.logged;
}
},
methods: {
obtenerPedidos: function () {
let vm = this;
const usuarioLogueado = !this.usuario.logged;
return new Promise((resolve, reject) => {
if ( usuarioLogueado ) {
reject("Usuario no logeado.");
return;
}
const xhr = new XMLHttpRequest();
xhr.open("POST",`${conexion}/pedidos/actual`);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onload = () => {
console.log(`Esta es mi respuesta we :3\n${xhr.responseText}`);
resolve(xhr.responseText);
};
xhr.send(`USER_ID=${vm.usuario["USER_ID"]}`);
});
}
},
created: function () {
let vm = this;
this.obtenerPedidos()
.then(response => {
while (vm.pedidos.pop() !== 0);
const data = JSON.parse(response);
for (item of data) {
vm.pedidos.push(item);
}
})
.catch(reason => console.log(`Obtener pedidos desde el servidor rechazado. Razón: ${reason}`));
}
}
</script>
<style scoped lang="sass">
.pedidos__titulo
text-align: center
font:
size: xx-large
weight: bold
family: Muli, "Open Sans", sans-serif
margin: 10px 0
.pedidos__usuario-no-logeado
font-size: x-large
text-align: center
.pedidos
</style>

View File

@ -1,151 +0,0 @@
<template>
<div>
<header-mini />
<nav-bar-inicio-sesion />
<nav-bar />
<section class="tienda container mySeccion fondoBlanco" data-collapsed="false">
<h2 class="tienda--titulo">Platos</h2>
<br>
<template v-for="(item,key) in platos">
<div v-bind:key="key" class="row tienda--tarjeta hoverable">
<div class="col l4">
<img class="responsive-image" :src="item.imgUrl"/>
</div>
<div class="col l8">
<div class="tienda--tarjeta--titulo">
{{ item.nombre }}
</div>
<br>
<div class="tienda--tarjeta--descripcion">
{{ item.descripcion }}
</div>
<br>
<div class="tienda--tarjeta--precio">
{{ item.precio }}
</div>
<br>
<div class="tienda--tarjeta--cantidad">
<i class='material-icons plato--Cantidad--Icon' v-on:click="disminuirCantidad('itemNum' + key)">
remove
</i>
<span :id=" 'itemNum' + key ">1</span>
<i class='material-icons plato--Cantidad--Icon' v-on:click="aumentarCantidad('itemNum' + key)">
add
</i>
</div>
<br/>
<button class="tienda--tarjeta--botonComprar" v-on:click="addAlCarro(item, 'itemNum' + key)">
<i class='material-icons'>add_shopping_cart</i> Añadir al carrito
</button>
</div>
</div>
</template>
</section>
<mi-footer />
</div>
</template>
<script>
import MiFooter from "../components/mi-footer.vue";
import HeaderMini from '../components/headerMini.vue';
import NavBar from '../components/navBar.vue';
import NavBarInicioSesion from '../components/navBarInicioSesion.vue';
export default {
name: 'Platos',
components: {
'mi-footer': MiFooter,
'header-mini': HeaderMini,
'nav-bar': NavBar,
'nav-bar-inicio-sesion': NavBarInicioSesion
},
data: function () {
return {
platos: [
{
"nombre": "Soupe à l'oignon",
"descripcion": "Sopa tradicional hecha con cebolla y carne.",
"imgUrl": "https://www.expatica.com/media/upload/714571.jpg",
"precio": 20
},
{
"nombre": "Coq au vin",
"descripcion": "Pollo cocinado con vino, hongos, carne de cerdo y ajo",
"imgUrl": "https://www.expatica.com/media/upload/714572.jpg",
"precio": 50
},
{
"nombre": "Beef bourguignon",
"descripcion": "Filete cocinado en vino, sasonado con especias",
"imgUrl": "https://www.expatica.com/media/upload/714573.jpg",
"precio": 30
},
{
"nombre": "Cassoulet",
"descripcion": "Guiso parecido a las habichuelas típicas españolas que se hace con alubias blancas o frijoles acompañadas de carne de diferentes animales",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Cassoulet-570x320.jpg",
"precio": 22
},
{
"nombre": "Fondue de queso",
"descripcion": "Crema que se puede tomar bien como acompañante de otros ingredientes o bien mojando trozos de pan en él.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Fondue-570x321.jpg",
"precio": 5
},
{
"nombre": "Ratatouille",
"descripcion": "Elaborado con diversas hortalizas, es un plato natural de Niza y la región de Provenza, al sureste de Francia.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Ratatouille-570x320.jpg",
"precio": 35
},
{
"nombre": "Magret de canard",
"descripcion": "Un filete de carne magra, que suele provenir de un ganso o pato cebado",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Magret-de-Canard-570x320.jpg",
"precio": 17
},
{
"nombre": "Merluza al beurre blanc",
"descripcion": "Este plato consiste en troncos o lomos de merluza que se sirven en salsa beurre blanc.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Merluza-a-la-beurre-blanc-570x320.jpg",
"precio": 22
}
]
};
},
methods: {
addAlCarro: function (plato, id) {
const cantidad = parseInt(document.getElementById(id).innerText);
const obj = JSON.parse(JSON.stringify(plato));
obj["cantidad"] = cantidad;
carritoUsuario.push(obj);
M.toast({html: `Añadido al carrito.&nbsp;&nbsp;<span onclick="window.irAlCarro()" class="irAlCarrito">Ir al carrito</span>`})
},
aumentarCantidad: function (id) {
const elem = document.getElementById(id);
const valorActual = parseInt(elem.innerText);
if (valorActual > 0) {
elem.innerText = valorActual + 1;
} else {
elem.innerText = 1;
}
},
disminuirCantidad: function (id) {
const elem = document.getElementById(id);
const valorActual = parseInt(elem.innerText);
if (valorActual > 1) {
elem.innerText = valorActual - 1;
} else {
elem.innerText = 1;
}
}
}
}
</script>
<style scoped lang="sass">
</style>

View File

@ -1,174 +0,0 @@
<template>
<div>
<header-mini />
<nav-bar-inicio-sesion />
<nav-bar />
<section id="sectionCarrito" class="container mySeccion fondoBlanco">
<div class="center">
<div id="carrito--tituloprincipal">
Carrito de compras
</div>
<br/>
<router-link id="carrito--boton--seguircomprando" to="/platos/" class="hoverable">Seguir comprando</router-link>
<br/>
<br/>
<div id="carrito" class="row carrito">
<div id="carrito--elementos" class="col l8">
<div id="carrito--elementos--contenido" class="caja">
<template v-if="noEstaVacio">
<template v-for="(producto,key) in carrito">
<div v-bind:key="key" class="carritoElem">
<img class="carritoElem--img" v-bind:src="producto.imgUrl">
<div class="plato--Titulo">{{ producto.nombre }}</div>
<br>
<div class="plato--Precio">{{ producto.precio }}</div>
<div class="plato--Cantidad">Cantidad:
<i class="material-icons plato--Cantidad--Icon" v-on:click="restarCantidad(producto)">remove</i>
<span>{{ producto.cantidad }}</span>
<i class="material-icons plato--Cantidad--Icon" v-on:click="aumentarCantidad(producto)">add</i>
</div>
<br>
<div class="carrito--subTotal">{{ producto.precio * producto.cantidad }}</div>
<hr>
</div>
</template>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
<div id="carrito--precio" class="col l4">
<div id="carrito--precio--contenido" class="caja">
<template v-if="noEstaVacio">
<div id="pagos">
<div style="display: inline-block;">
{{ cantidadItems }} Producto{{ (cantidadItems>1 || cantidadItems === 0) ? 's': '' }}
</div>
<div style="display: inline-block; float: right; clear: both">
{{ subTotal }} S/.
</div>
</div>
<div>
<div style="display: inline-block;">
Descuentos:
</div>
<div style="display: inline-block; float: right; clear: both">
{{ descuento }} S/.
</div>
</div>
<br>
<br>
<div>
<div class="carrito--precio--contenido--titulo" style="display: inline-block;">
Total:
</div>
<div class="carrito--precio--contenido--titulo"
style="display: inline-block; float: right; clear: both">
{{ total }} S/.
</div>
</div>
<br>
<br>
<div style="text-align: center">
<a class="carrito--precio--contenido--botonPagar" v-if="usuarioLogeado">
Completar Transaccion
</a>
<router-link to="/iniciar-sesion/" v-else class="carrito__precio__usuarioNoLogeado hoverable">
Inicia Sesion o Regístrate para continuar.
</router-link>
</div>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
</div>
</div>
<br/>
<br/>
</section>
<mi-footer></mi-footer>
</div>
</template>
<script>
import HeaderMini from '@/components/headerMini'
import NavBar from '@/components/navBar'
import MiFooter from '@/components/mi-footer'
import NavBarInicioSesion from '../components/navBarInicioSesion.vue';
export default {
name: 'Carrito',
components: {
'header-mini': HeaderMini,
'nav-bar': NavBar,
'mi-footer': MiFooter,
'nav-bar-inicio-sesion': NavBarInicioSesion
},
data: function () {
return {
carrito: window.carritoUsuario,
descuento: 0
}
},
computed: {
cantidadItems: function () {
let items = 0;
for (const i in this.item)
items++;
return items;
},
subTotal: function () {
let subT = 0;
for (const itemI in this.carrito ) {
if (this.carrito.hasOwnProperty(itemI)){
const item = this.carrito[itemI];
subT += (item["precio"] * item["cantidad"]);
}
}
return subT;
},
total: function () {
return this.subTotal - this.descuento;
},
noEstaVacio: function () {
for (const i in this.carrito) {
return true;
}
return false;
},
usuarioLogeado: function () {
return window.usuarioActual[0]["logged"];
}
},
methods: {
restarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad > 0)
elem.cantidad = cantidad -1;
},
aumentarCantidad: function (elem) {
const cantidad = parseInt(elem.cantidad);
if (cantidad >= 0)
elem.cantidad = cantidad+1;
}
}
}
</script>
<style scoped lang="sass">
.carrito__precio__usuarioNoLogeado
display: inline-block
background-color: green
color: white
border-radius: 3px
padding: 10px
</style>

View File

13
staff/index.php Normal file
View File

@ -0,0 +1,13 @@
<br />
<br />
<div class="center">
Personal<br />
<br />
<br />
<a href="./#usuarios/">Volver a la carta</a>
<br />
<br />
</div>
<br />
<br />

View File

@ -1,17 +0,0 @@
{
"compilerOptions": {
// this aligns with Vue's browser support
"target": "es6",
// this enables stricter inference for data properties on `this`
"strict": true,
// if using webpack 2+ or rollup, to leverage tree shaking:
"module": "es2015",
"moduleResolution": "node",
"types": [
"node"
],
"typeRoots": [
"node_modules/@types"
]
}
}

13
usuarios/index.php Normal file
View File

@ -0,0 +1,13 @@
<br />
<br />
<div class="center">
Pedidos<br />
<br />
<a href="./#usuarios/mi-cuenta">Ver mi cuenta</a><br />
<br />
<br />
<div id="productos">
</div>
</div>
<br />
<br />

53
usuarios/mi-cuenta.php Normal file
View File

@ -0,0 +1,53 @@
<br/>
<br/>
<div class="center" style="font-size: large">
Mi cuenta<br/>
<br/>
<a href="./#usuarios/">Seguir comprando</a>
<br/>
<br/>
<div class="row">
<div class="col-6">
Mis datos:<br/>
<br/>
<div style="text-align: left">
Nombre: {{ userName }}<br/>
Correo electrónico: {{ userEmail }}<br/>
Métodos de pago: {{ userPaymentMethods }}<br/>
</div>
</div>
<div class="col-6">
Historial de compras:<br/>
<br/>
<div class="row">
<div class="col-3 unseen">.</div>
<div class="col-6">
<img class="image" src="https://www.expatica.com/media/upload/714571.jpg">
<div>Soupe à l'oignon</div>
<br>
<div>Sopa tradicional hecha con cebolla y carne.</div>
<div class="center">20 S/.</div>
<div>Fecha de compra: 17/09/18</div>
<br>
</div>
<div class="col-3 unseen">.</div>
</div>
<br />
<div class="row">
<div class="col-3 unseen">.</div>
<div class="col-6">
<img class="image" src="https://www.expatica.com/media/upload/714573.jpg">
<div>Cassoulet</div>
<br>
<div>Plato de habas con carne y especies.</div>
<div class="center">5 S/.</div>
<div>Fecha de compra: 15/09/18</div>
<br>
</div>
<div class="col-3 unseen">.</div>
</div>
</div>
</div>
</div>
<br/>
<br/>

84
usuarios/pagos.php Normal file
View File

@ -0,0 +1,84 @@
<br/>
<br/>
<div class="center">
<div id="carrito--tituloprincipal">
Carrito de compras
</div>
<br/>
<a id="carrito--boton--seguircomprando" href="./#usuarios/">Seguir comprando</a>
<br/>
<br/>
<div id="carrito" class="row carrito">
<div id="carrito--elementos" class="col-8">
<div id="carrito--elementos--contenido" class="caja">
<template v-if="noEstaVacio">
<template v-for="producto in item">
<div class="carritoElem">
<img class="carritoElem--img" v-bind:src="producto.imgUrl">
<div class="plato--Titulo">{{ producto.nombre }}</div>
<br>
<div class="plato--Precio">{{ producto.precio }}</div>
<div class="plato--Cantidad">Cantidad:
<i class="material-icons plato--Cantidad--Icon" v-on:click="restarCantidad(producto)">remove</i>
<span>{{ producto.cantidad }}</span>
<i class="material-icons plato--Cantidad--Icon" v-on:click="aumentarCantidad(producto)">add</i>
</div>
<br>
<div class="carrito--subTotal">{{ producto.precio * producto.cantidad }}</div>
<hr>
</div>
</template>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
<div id="carrito--precio" class="col-4">
<div id="carrito--precio--contenido" class="caja">
<template v-if="noEstaVacio">
<div id="pagos">
<div style="display: inline-block;">
{{ cantidadItems }} Producto{{ (cantidadItems>1 || cantidadItems === 0) ? 's': '' }}
</div>
<div style="display: inline-block; float: right; clear: both">
{{ subTotal }} S/.
</div>
</div>
<div>
<div style="display: inline-block;">
Descuentos:
</div>
<div style="display: inline-block; float: right; clear: both">
{{ descuento }} S/.
</div>
</div>
<br>
<br>
<div>
<div class="carrito--precio--contenido--titulo" style="display: inline-block;">
Total:
</div>
<div class="carrito--precio--contenido--titulo"
style="display: inline-block; float: right; clear: both">
{{ total }} S/.
</div>
</div>
<br>
<br>
<a class="carrito--precio--contenido--botonPagar">
Completar Transaccion
</a>
</template>
<template v-else>
No hay nada en tu carrito de compras :c
</template>
</div>
</div>
</div>
</div>
<br/>
<br/>

50
usuarios/platos.json Normal file
View File

@ -0,0 +1,50 @@
[
{
"nombre": "Soupe à l'oignon",
"descripcion": "Sopa tradicional hecha con cebolla y carne.",
"imgUrl": "https://www.expatica.com/media/upload/714571.jpg",
"precio": 20
},
{
"nombre": "Coq au vin",
"descripcion": "Pollo cocinado con vino, hongos, carne de cerdo y ajo",
"imgUrl": "https://www.expatica.com/media/upload/714572.jpg",
"precio": 50
},
{
"nombre": "Beef bourguignon",
"descripcion": "Filete cocinado en vino, sasonado con especias",
"imgUrl": "https://www.expatica.com/media/upload/714573.jpg",
"precio": 30
},
{
"nombre": "Cassoulet",
"descripcion": "Guiso parecido a las habichuelas típicas españolas que se hace con alubias blancas o frijoles acompañadas de carne de diferentes animales",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Cassoulet-570x320.jpg",
"precio": 22
},
{
"nombre": "Fondue de queso",
"descripcion": "Crema que se puede tomar bien como acompañante de otros ingredientes o bien mojando trozos de pan en él.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Fondue-570x321.jpg",
"precio": 5
},
{
"nombre": "Ratatouille",
"descripcion": "Elaborado con diversas hortalizas, es un plato natural de Niza y la región de Provenza, al sureste de Francia.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Ratatouille-570x320.jpg",
"precio": 35
},
{
"nombre": "Magret de canard",
"descripcion": "Un filete de carne magra, que suele provenir de un ganso o pato cebado",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Magret-de-Canard-570x320.jpg",
"precio": 17
},
{
"nombre": "Merluza al beurre blanc",
"descripcion": "Este plato consiste en troncos o lomos de merluza que se sirven en salsa beurre blanc.",
"imgUrl": "https://www.viajejet.com/wp-content/viajes/Merluza-a-la-beurre-blanc-570x320.jpg",
"precio": 22
}
]

View File

@ -1,8 +0,0 @@
module.exports = {
pluginOptions: {
express: {
shouldServeApp: true,
serverDir: './srv'
}
}
}