se agrega mapa paraderos

master/frontend-google-map
Francisco Sandoval 2023-07-24 22:40:57 -04:00
parent 28cac09f12
commit 169c0766de
13 changed files with 138 additions and 51 deletions

15
package-lock.json generated
View File

@ -11,7 +11,6 @@
"@adminkit/core": "^3.4.0",
"bootstrap": "^5.3.0",
"bootstrap-icons": "^1.10.5",
"google-maps": "^4.3.3",
"history": "^5.3.0",
"svelte-navigator": "^3.2.2",
"svelte-pagination": "^0.0.1"
@ -469,12 +468,6 @@
"vite": "^4.0.0"
}
},
"node_modules/@types/googlemaps": {
"version": "3.43.3",
"resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.43.3.tgz",
"integrity": "sha512-ZWNoz/O8MPEpiajvj7QiqCY8tTLFNqNZ/a+s+zTV58wFVNAvvqV4bdGfnsjTb5Cs4V6wEsLrX8XRhmnyYJ2Tdg==",
"deprecated": "Types for the Google Maps browser API have moved to @types/google.maps. Note: these types are not for the googlemaps npm package, which is a Node API."
},
"node_modules/bootstrap": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz",
@ -675,14 +668,6 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/google-maps": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/google-maps/-/google-maps-4.3.3.tgz",
"integrity": "sha512-MQbEgBNQbGyV7mfS2tlFgW4EoGKLia24BvAl4a+kgsYWt4283kyPpaay/yKIsScQLr7nSUONaLNfOdMsCuJDEw==",
"dependencies": {
"@types/googlemaps": "^3.39.1"
}
},
"node_modules/history": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",

View File

@ -17,7 +17,6 @@
"@adminkit/core": "^3.4.0",
"bootstrap": "^5.3.0",
"bootstrap-icons": "^1.10.5",
"google-maps": "^4.3.3",
"history": "^5.3.0",
"svelte-navigator": "^3.2.2",
"svelte-pagination": "^0.0.1"

View File

@ -0,0 +1,54 @@
<script>
import { onMount } from 'svelte'
export let google_api_key = null;
export let center = null;
export let zoom = 4;
export let marks = [];
let mapEl = null;
onMount(() => {
console.log('onMount')
if (!globalThis.google) {
const el = document.createElement('script')
el.src = "https://maps.googleapis.com/maps/api/js?key=" + google_api_key + "&callback=initMap&v=weekly"
el.async = true;
el.onload = globalThis.initMap;
document.body.appendChild(el)
}
globalThis.initMap()
})
globalThis.initMap = function () {
const google = globalThis.google;
if (!google || !mapEl) return;
const map = new google.maps.Map(mapEl, { zoom, center });
const infoWindow = new google.maps.InfoWindow();
for (const mark of marks) {
const { position, title, location } = mark;
const marker = new google.maps.Marker({
position,
map,
title,
});
marker.addListener("click", () => {
infoWindow.close();
const html = `
<h1>${title}</h1>
<p>${location}</p>
`
infoWindow.setContent(html);
infoWindow.open(marker.getMap(), marker);
});
}
google.maps.event.addListener(map, "zoom_changed", function () {
console.log({ zoom: map.zoom });
});
};
</script>
<div bind:this={mapEl} style="height: 800px; max-height: 90vh;">Cargando...</div>

View File

@ -0,0 +1,3 @@
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>

View File

@ -1,2 +1,15 @@
<script>
import IconLoading from "./IconLoading.svelte";
export let loading = false;
</script>
<h3 class="h3 mb-3"><slot/></h3>
<div class="row">
<div class="col-auto">
<h3 class="h3 mb-3"><slot/></h3>
</div>
{#if loading}
<div class="col">
<IconLoading />
</div>
{/if}
</div>

View File

@ -11,17 +11,21 @@
let ordering = 'id_aplicacion'
let aplicaciones = []
let aplicacion = null
let loading = false;
$: onPage(page)
async function onPage(p) {
try {
loading = true
offset = (p - 1) * limit;
const data = await getAplicaciones({ offset, limit, ordering })
aplicaciones = data.results;
count = data.count;
} catch (error) {
alert(error)
} finally {
loading = false;
}
}
@ -39,7 +43,7 @@
}
</script>
<PageTitle>Aplicaciones</PageTitle>
<PageTitle {loading}>Aplicaciones</PageTitle>
<div class="card">
<div class="card-header">

View File

@ -10,16 +10,20 @@
let es_nuevo = true
let comunas = { count: 0, results: [] }
let page = 1
let loading = false;
const limit = 15
$: onPage(page)
async function onPage(page) {
try {
loading = true
const offset = (page - 1) * limit;
comunas = await getComunas({ offset, limit, ordering: 'id_region' })
} catch(error) {
alert(error.detail || error)
} finally {
loading = false
}
}
@ -30,10 +34,13 @@
async function onEditar({ id_comuna }) {
try {
loading = true
comuna = await getComuna(id_comuna)
es_nuevo = false
} catch (error) {
alert(error.detail || error)
} finally {
loading = false
}
}
@ -65,12 +72,12 @@
}
</script>
<PageTitle>Comunas</PageTitle>
<PageTitle {loading}>Comunas</PageTitle>
<div class="card">
<div class="card-header">
<div class="mb-3 d-flex">
<button class="btn btn-primary"
<button class="btn btn-primary me-3"
on:click|preventDefault={onNuevo}>
<i class="bi bi-plus-lg"></i> Nuevo
</button>

View File

@ -1,38 +1,41 @@
<script>
import PageTitle from '$/components/PageTitle.svelte';
import {Loader} from 'google-maps';
import { getMarcasParaderos } from '$/services/mapas';
import PageTitle from "$/components/PageTitle.svelte";
import { getMarcasParaderos } from "$/services/mapas";
import { storeParaderos } from "$/stores/global";
import GoogleMap from '$/components/GoogleMap.svelte'
import IconLoading from "$/components/IconLoading.svelte";
const options = { language: 'es', region: 'CL' };
let my_map = null
$: start()
async function start() {
try {
const { api_key_google, zoom, center, marks } = await getMarcasParaderos()
const loader = new Loader(api_key_google, options);
const google = await loader.load();
const map = new google.maps.Map(my_map, { center, zoom });
let my_map = null;
let data_map = null
for (const mark of marks) {
const { lat, lng, title } = mark;
new google.maps.Marker({
position: { lat, lng },
map,
title
});
}
} catch (error) {
alert(error)
}
$: init_google_map($storeParaderos)
$: console.log({ data_map })
async function init_google_map(data_inicial) {
const paraderos = data_inicial || await getMarcasParaderos()
storeParaderos.set(paraderos);
data_map = paraderos;
}
</script>
<PageTitle>Paraderos</PageTitle>
<div class="card">
<div class="card-header">
<button class="btn btn-outline-secondary" on:click|preventDefault={() => init_google_map(null)}><i class="bi bi-arrow-repeat"></i> Refrescar</button>
</div>
<div class="card-body">
<div bind:this={my_map} style="height: 500px"></div>
{#if data_map}
<GoogleMap
google_api_key={data_map.google_api_key}
center={data_map.center}
zoom={data_map.zoom}
marks={data_map.marks}
/>
{:else}
<IconLoading />
{/if}
</div>
</div>

View File

@ -2,23 +2,28 @@
import { Link } from 'svelte-navigator'
import Paginate from '$/components/Paginate.svelte'
import { getPersonas } from '$/services/personas';
import PageTitle from '$/components/PageTitle.svelte';
let page = 1;
let limit = 15;
let personas = { results: [], count: 0 };
let loading = false;
$: onPage(page)
async function onPage(page) {
try {
loading = true
const offset = (page - 1) * limit;
personas = await getPersonas({ offset, limit })
} catch (error) {
alert(error.detail || error)
} finally {
loading = false;
}
}
</script>
<h2 class="h3 mb-3">Personas</h2>
<PageTitle {loading}>Personas</PageTitle>
<div class="card">
<div class="card-header">

View File

@ -4,6 +4,7 @@
import FormPersona from './Form.svelte'
import { Link, useParams, useNavigate } from 'svelte-navigator';
import { getPersona, createPersona, updatePersona } from '$/services/personas';
import PageTitle from '../../components/PageTitle.svelte';
onMount(() => {
$storeLayout.showSidebar = false;
@ -16,6 +17,7 @@
const navigate = useNavigate()
let es_nuevo = true;
let form = {}
let loading = false;
$: es_nuevo = !$params.rut
$: begin($params)
@ -23,9 +25,12 @@
async function begin({ rut = null }) {
try {
if (!rut) return; // si es nuevo, no busco informacion
loading = true
form = await getPersona(rut)
} catch (error) {
alert(error.detail || error)
} finally {
loading = false
}
}
@ -45,7 +50,7 @@
}
</script>
<h3 class="h3 mb-3">{es_nuevo ? 'Nuevo Persona': 'Editar Persona'}</h3>
<PageTitle {loading}>{es_nuevo ? 'Nuevo Persona': 'Editar Persona'}</PageTitle>
<form action="" on:submit|preventDefault={onSave}>
<div class="card">

View File

@ -7,20 +7,24 @@
let usuarios = { count: 0, results: [] }
let page = 1
const limit = 15
let loading = false
$: onPage(page)
async function onPage(page) {
try {
loading = true
const offset = (page - 1) * limit;
usuarios = await getUsuarios({ offset, limit, ordering: 'login' })
} catch(error) {
alert(error.detail || error)
} finally {
loading = false;
}
}
</script>
<PageTitle>Usuarios</PageTitle>
<PageTitle {loading}>Usuarios</PageTitle>
<div class="card">
<div class="card-header">

View File

@ -1,6 +1,7 @@
<script>
import { onMount } from 'svelte'
import { storeLayout } from '$/stores/global'
import PageTitle from '$/components/PageTitle.svelte';
import FormPersona from '../personas/Form.svelte'
import FormUsuario from './Form.svelte'
import { Link, useParams, useNavigate } from 'svelte-navigator';
@ -20,20 +21,23 @@
let form_persona = {}
let form_usuario = {}
let clave2 = ''
let loading = false;
$: es_nuevo = !$params.login
$: begin($params)
$: console.log({ form_persona })
async function begin({ login = null }) {
try {
if (!login) return; // si es nuevo, no busco informacion
loading = true
const { persona, ...data } = await getUsuario(login)
form_persona = persona;
form_usuario = data;
} catch (error) {
console.error(error)
alert(error.detail || error)
} finally {
loading = false;
}
}
@ -68,7 +72,7 @@
}
</script>
<h3 class="h3 mb-3">{es_nuevo ? 'Nuevo Usuario': 'Editar Usuario'}</h3>
<PageTitle {loading}>{es_nuevo ? 'Nuevo Usuario': 'Editar Usuario'}</PageTitle>
<form action="" on:submit|preventDefault={onSave}>
<div class="card">

View File

@ -1,5 +1,6 @@
import { writable } from 'svelte/store'
export const storeMessages = writable([]);
export const storeParaderos = writable(null);
export const storeSession = writable({});
export const storeLayout = writable({ showSidebar: true });