se avanza con login usando jwt

master/frontend-google-map
Francisco Sandoval 2023-06-25 22:41:51 -04:00
parent 5b0d8f51be
commit 495de145ee
19 changed files with 212 additions and 21 deletions

View File

@ -10,7 +10,7 @@ services:
- 3000:3000
environment:
- VITE_PORT=3000
- VITE_BACKEND="http://localhost:4000/api"
- VITE_BACKEND=http://localhost:4000/api
working_dir: /app
command: sh -c "
[ ! -d node_modules ] && npm install ;

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte</title>
<title>Gestión de Transporte</title>
</head>
<body>
<div id="app"></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,19 @@
.sidebar, .sidebar-content {
background: steelblue;
}
.sidebar-item.active .sidebar-link:hover, .sidebar-item.active>.sidebar-link {
background: linear-gradient(90deg,rgba(45, 94, 167, 0.5),rgba(59,125,221,.088) 50%,transparent);
border-left-color: orange;
color: #e9ecef;
}
.sidebar-link, a.sidebar-link {
background: steelblue;
}
a.sidebar-link:hover {
background: steelblue;
}

View File

@ -13,7 +13,7 @@
<div class="d-table-cell align-middle">
<div class="text-center mt-4">
<h1 class="h2">Sistema xxxx</h1>
<h1 class="h2">Gestión de Transporte</h1>
<p class="lead">
Acceda a su cuenta para continuar
</p>

View File

@ -3,6 +3,7 @@
import '@adminkit/core/dist/css/app.css'
import '@adminkit/core/dist/js/app.js'
import 'bootstrap-icons/font/bootstrap-icons.css'
import '../assets/colors.css'
import Navbar from './Navbar.svelte'
import Sidebar from './Sidebar.svelte'
import Footer from './Footer.svelte'
@ -11,6 +12,8 @@
import { Router, Route, createHistory } from 'svelte-navigator'
import hashHistory from './hashHistory'
import { onMount } from 'svelte'
import { getInfoToken } from '$/services/login'
import { storeSession } from '$/stores/session'
let triggerEvent = false;
@ -19,6 +22,15 @@
onMount(() => {
triggerEvent && document.dispatchEvent(new Event('DOMContentLoaded'));
})
async function begin() {
try {
$storeSession = await getInfoToken()
} catch (error) {
alert(error.message || error)
}
}
begin()
</script>
<div class="wrapper">

View File

@ -3,7 +3,10 @@
import { Link } from 'svelte-navigator'
let avatar = null;
$: avatar = $storeSession?.avatar_img || '/img/avatar.jpg';
let persona = {}
$: persona = $storeSession
$: avatar = $storeSession?.avatar_img || '/avatars/avatar1.jpg';
function onLogout() {
sessionStorage.clear();
@ -17,11 +20,11 @@
</a>
<a class="nav-link dropdown-toggle d-none d-sm-inline-block" href={"#"} data-bs-toggle="dropdown">
<img src={avatar} class="avatar img-fluid rounded me-1" alt={$storeSession?.nombre_completo} />
<span class="text-dark">{$storeSession?.alias}</span>
<img src={avatar} class="avatar img-fluid rounded me-1" alt={persona.nombres} />
<span class="text-dark">{$storeSession.login}</span>
</a>
<div class="dropdown-menu dropdown-menu-end">
<Link class="dropdown-item" to="/profile">
<Link class="dropdown-item" to="/perfil">
<i class="align-middle me-1" data-feather="user"></i> Perfil
</Link>
<div class="dropdown-divider"></div>

View File

@ -6,6 +6,7 @@
<nav id="sidebar" class="sidebar js-sidebar">
<div class="sidebar-content js-simplebar">
<Link class="sidebar-brand" to="/">
<span class="fs-1">🚌</span>
<span class="align-middle">
Transporte
</span>
@ -19,7 +20,7 @@
<span class="align-middle">Inicio</span>
</SideLink>
<SideLink to="/profile">
<SideLink to="/perfil">
<i class="align-middle bi bi-person-lines-fill fs-4"></i>
<span class="align-middle">Perfil</span>
</SideLink>

View File

@ -1,6 +1,6 @@
<script>
import { Link } from 'svelte-navigator'
import { getToken } from '$/services/login'
import { createToken } from '$/services/login'
let form = { username: '', pass: '' }
let message_error = '';
@ -8,11 +8,13 @@
// validar usuario contraseña
async function onIngresar() {
try {
const token = await getToken(form)
message_error = ''
const { token } = await createToken(form)
sessionStorage.setItem('token', token)
document.location.reload();
} catch(error) {
message_error = error.message || error
setTimeout(() => message_error = '', 3000)
}
}
</script>
@ -20,12 +22,10 @@
<div class="card">
<div class="card-body">
<div class="m-sm-4">
<div class="row align-items-center mb-4">
<div class="col-auto">
<img src="/img/avatar.jpg" alt="Avatar"
class="img-fluid rounded-circle" width="132" height="132"
/>
</div>
<div class="text-center mb-4">
<img src="/avatars/avatar1.jpg" alt="Avatar"
class="img-fluid rounded-circle" width="132" height="132"
/>
</div>
<form on:submit|preventDefault={onIngresar}>
<div class="mb-3">
@ -35,7 +35,7 @@
</div>
<div class="mb-3">
<label class="form-label" for={null}>Contraseña</label>
<input class="form-control form-control-lg" type="password" bind:value={form.pass} required
<input class="form-control form-control-lg" type="password" bind:value={form.password} required
placeholder="Ingrese su contraseña">
</div>

View File

@ -0,0 +1,140 @@
<script>
import { storeSession } from "$/stores/session";
let persona = {}
$: persona = $storeSession.persona || {};
</script>
<h1 class="h3 mb-3">Perfil de usuario</h1>
<div class="row">
<div class="col-md-4 col-xl-3">
<div class="card mb-3">
<div class="card-header">
<h5 class="card-title mb-0">Perfil Detallado</h5>
</div>
<div class="card-body text-center">
<img
src="/avatars/avatar1.jpg"
alt="Christina Mason"
class="img-fluid rounded-circle mb-2"
width="128"
height="128"
/>
<h5 class="card-title mb-0">{persona.nombres} {persona.apellido_a} {persona.apellido_b}</h5>
<div class="text-muted mb-2">{persona.rut}-{persona.dv}</div>
<div>
<a class="btn btn-primary btn-sm" href={"#"}>Follow</a>
<a class="btn btn-primary btn-sm" href={"#"}
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-message-square"
><path
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
/></svg
> Message</a
>
</div>
</div>
<hr class="my-0" />
<div class="card-body">
<h5 class="h6 card-title">Skills</h5>
<a href={"#"} class="badge bg-primary me-1 my-1">HTML</a>
<a href={"#"} class="badge bg-primary me-1 my-1">JavaScript</a>
<a href={"#"} class="badge bg-primary me-1 my-1">Sass</a>
<a href={"#"} class="badge bg-primary me-1 my-1">Angular</a>
<a href={"#"} class="badge bg-primary me-1 my-1">Vue</a>
<a href={"#"} class="badge bg-primary me-1 my-1">React</a>
<a href={"#"} class="badge bg-primary me-1 my-1">Redux</a>
<a href={"#"} class="badge bg-primary me-1 my-1">UI</a>
<a href={"#"} class="badge bg-primary me-1 my-1">UX</a>
</div>
<hr class="my-0" />
<div class="card-body">
<h5 class="h6 card-title">About</h5>
<ul class="list-unstyled mb-0">
<li class="mb-1">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-home feather-sm me-1"
><path
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
/><polyline points="9 22 9 12 15 12 15 22" /></svg
>
Lives in <a href={"#"}>San Francisco, SA</a>
</li>
<li class="mb-1">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-briefcase feather-sm me-1"
><rect
x="2"
y="7"
width="20"
height="14"
rx="2"
ry="2"
/><path
d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"
/></svg
>
Works at <a href={"#"}>GitHub</a>
</li>
<li class="mb-1">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-map-pin feather-sm me-1"
><path
d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"
/><circle cx="12" cy="10" r="3" /></svg
>
From <a href={"#"}>Boston</a>
</li>
</ul>
</div>
<hr class="my-0" />
<div class="card-body">
<h5 class="h6 card-title">Elsewhere</h5>
<ul class="list-unstyled mb-0">
<li class="mb-1"><a href={"#"}>staciehall.co</a></li>
<li class="mb-1"><a href={"#"}>Twitter</a></li>
<li class="mb-1"><a href={"#"}>Facebook</a></li>
<li class="mb-1"><a href={"#"}>Instagram</a></li>
<li class="mb-1"><a href={"#"}>LinkedIn</a></li>
</ul>
</div>
</div>
</div>
</div>

View File

@ -1,9 +1,11 @@
import PageHome from '$/pages/site/Home.svelte'
import PagePerfil from '$/pages/usuario/Perfil.svelte'
import PageError from '$/pages/site/Error.svelte'
import PageAplicaciones from '$/pages/aplicaciones/Admin.svelte'
export const routes = [
{ path: '/', component: PageHome },
{ path: '/perfil', component: PagePerfil },
{ path: '/aplicaciones', component: PageAplicaciones },
{ path: '*', component: PageError },
]

View File

@ -1,2 +1,2 @@
export const base = import.meta.env.VITE_BACKEND || origin;
export const base = import.meta.env.VITE_BACKEND || '/api';
export const getToken = () => sessionStorage.getItem('token') || null;

View File

@ -1,5 +1,19 @@
import { base } from "./_config";
import { base, getToken } from "./_config";
export async function getToken({ username, password }) {
return 'token12345'
export async function createToken({ username, password }) {
const res = await fetch(`${base}/auth/`, {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: { "Content-Type": "application/json" }
})
if (!res.ok) throw await res.text()
return res.json()
}
export async function getInfoToken() {
const res = await fetch(`${base}/auth/`, {
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
})
if (!res.ok) throw await res.text()
return res.json()
}