se guarda paradero e imagenes

master/frontend^2
Francisco Sandoval 2023-09-07 10:59:19 -03:00
parent cad292e25a
commit 49f8c84bdf
5 changed files with 115 additions and 52 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,13 +1,16 @@
<script> <script>
// imagenes
import IconParada from '$/assets/parada-de-autobus.png' import IconParada from '$/assets/parada-de-autobus.png'
import ImagenParadero from '$/assets/imagen.png' // servicios
import { getParadero } from '$/services/paraderos' import { getParadero, updateParadero, getParaderoImagenes, createParaderoImagen, deleteParaderoImagen } from '$/services/paraderos'
// libs
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let parada = null export let parada = null
let canvas = null let canvas = null
let form = {} let form = {}
let imagenes = []
$: init(!!parada) $: init(!!parada)
@ -19,11 +22,42 @@
try { try {
if (parada) { if (parada) {
form = await getParadero(parada.id_paradero) form = await getParadero(parada.id_paradero)
imagenes = await getParaderoImagenes(parada.id_paradero)
} }
} catch(error) { } catch(error) {
alert(error) alert(error)
} }
} }
async function onSave() {
try {
await updateParadero(form)
alert('Información guardada')
} catch(error) {
alert(error)
}
}
async function onSaveImagen({ target: form }) {
try {
const [ file = null ] = form.file1.files;
await createParaderoImagen(parada.id_paradero, file)
imagenes = await getParaderoImagenes(parada.id_paradero)
form.file1.value = ''
} catch (error) {
alert(error)
}
}
async function onDeleteImagen({ id_paradero_imagen }) {
try {
if (!confirm('Estás seguro de eliminar la imagen?')) return;
await deleteParaderoImagen(id_paradero_imagen)
imagenes = imagenes.filter(imagen => imagen.id_paradero_imagen !== id_paradero_imagen)
} catch (error) {
alert(error)
}
}
</script> </script>
<div class="offcanvas offcanvas-end" tabindex="-1" bind:this={canvas} aria-labelledby="offcanvasParaderoLabel" style="visibility: inherit;"> <div class="offcanvas offcanvas-end" tabindex="-1" bind:this={canvas} aria-labelledby="offcanvasParaderoLabel" style="visibility: inherit;">
@ -46,53 +80,47 @@
</div> </div>
Propiedades: Propiedades:
<div class="input-group mb-3"> <form on:submit|preventDefault={onSave}>
<div class="input-group-text">Nombre</div> <div class="input-group mb-3">
<input type="text" bind:value={form.stop_name} class="form-control"> <div class="input-group-text">Nombre</div>
</div> <input type="text" bind:value={form.stop_name} class="form-control">
<div class="input-group mb-3"> </div>
<div class="input-group-text">Descripción</div> <div class="input-group mb-3">
<input type="text" bind:value={form.stop_desc} class="form-control"> <div class="input-group-text">Descripción</div>
</div> <input type="text" bind:value={form.stop_desc} class="form-control">
<hr> </div>
<div class="text-center"> <hr>
<button class="btn btn-primary"><i class="bi bi-save"></i> Guardar</button> <div class="text-center">
</div> <button type="submit" class="btn btn-primary"><i class="bi bi-save"></i> Guardar</button>
</div>
</form>
<div class="my-3"></div> <div class="my-3"></div>
<!-- imagenes --> <!-- imagenes -->
{#each imagenes as imagen}
<div class="seccion-imagen mb-3"> <div class="seccion-imagen mb-3">
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid"> <img src={imagen.url} alt="imagen paradero" class="img-fluid">
<a href={"#"} class="btn btn-danger"> <a href={"#"} class="btn btn-danger" on:click|preventDefault={() => onDeleteImagen(imagen)}>
<i class="bi bi-trash"></i> Eliminar
</a>
</div>
<div class="seccion-imagen mb-3">
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid">
<a href={"#"} class="btn btn-danger">
<i class="bi bi-trash"></i> Eliminar
</a>
</div>
<div class="seccion-imagen mb-3">
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid">
<a href={"#"} class="btn btn-danger">
<i class="bi bi-trash"></i> Eliminar <i class="bi bi-trash"></i> Eliminar
</a> </a>
</div> </div>
{/each}
<!-- agregar imagen --> <!-- agregar imagen -->
<div class="card"> <form action="" on:submit|preventDefault={onSaveImagen}>
<div class="card-body"> <div class="card">
<div class="form-control" style="overflow: hidden"> <div class="card-body">
<input type="file" accept="*.png,*.jpg,*.jpeg"> <div class="form-control" style="overflow: hidden">
<input type="file" name="file1" accept="*.png,*.jpg,*.jpeg">
</div>
</div>
<div class="card-footer text-center">
<button class="btn btn-primary" type="submit">
<i class="bi bi-plus-lg"></i> Agregar imagen
</button>
</div> </div>
</div> </div>
<div class="card-footer text-center"> </form>
<button class="btn btn-primary">
<i class="bi bi-plus-lg"></i> Agregar imagen
</button>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -3,7 +3,8 @@
import PageTitle from "$/components/PageTitle.svelte"; import PageTitle from "$/components/PageTitle.svelte";
import IconLoading from "$/components/IconLoading.svelte"; import IconLoading from "$/components/IconLoading.svelte";
import imagenParada from '$/assets/parada-de-autobus.png' import imagenPartida from '$/assets/partida.png'
import imagenTermino from '$/assets/termino.png'
import { onMount } from "svelte"; import { onMount } from "svelte";
// servicios // servicios
@ -19,13 +20,20 @@
let id_linea = '' let id_linea = ''
let loading = false let loading = false
let polyline = null let polyline = null
let iconParada = null let iconPartida = null
let iconTermino = null
let L = null let L = null
let marker1 = null let marker1 = null
let marker2 = null let marker2 = null
getOperadores().then(data => operadores = data).catch(error => alert(error)) getOperadores()
getLineas().then(data => lineas = data).catch(error => alert(error)) .then(data => data.sort((a,b) => a.nombre_operador < b.nombre_operador? -1 : 1))
.then(data => operadores = data)
.catch(error => alert(error))
getLineas()
.then(data => data.sort((a,b) => a.nombre_linea < b.nombre_linea? -1 : 1))
.then(data => lineas = data)
.catch(error => alert(error))
$: cargar_coordenadas(id_operador, id_linea) $: cargar_coordenadas(id_operador, id_linea)
@ -36,9 +44,17 @@
function create_map() { function create_map() {
if (!elMap) return; if (!elMap) return;
if (!L) L = globalThis.L; if (!L) L = globalThis.L;
if (!iconParada) { if (!iconPartida) {
iconParada = L.icon({ iconPartida = L.icon({
iconUrl: imagenParada, iconUrl: imagenPartida,
iconSize: [64, 64],
iconAnchor: [32, 64],
popupAnchor: [0, -32]
})
}
if (!iconTermino) {
iconTermino = L.icon({
iconUrl: imagenTermino,
iconSize: [64, 64], iconSize: [64, 64],
iconAnchor: [32, 64], iconAnchor: [32, 64],
popupAnchor: [0, -32] popupAnchor: [0, -32]
@ -78,8 +94,8 @@
myMap.fitBounds(polyline.getBounds()); myMap.fitBounds(polyline.getBounds());
if (coordenadas) { if (coordenadas) {
marker1 = L.marker(coordenadas[0], { icon: iconParada }).addTo(myMap) marker1 = L.marker(coordenadas[0], { icon: iconPartida }).addTo(myMap)
marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconParada }).addTo(myMap) marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconTermino }).addTo(myMap)
} }
} catch (error) { } catch (error) {

View File

@ -2,7 +2,7 @@
import { base, getToken } from './_config' import { base, getToken } from './_config'
export function getUrlImagen(id_paradero) { export function getUrlImagen(id_paradero) {
return `${base}/paraderos/image/${id_paradero}` return `${base}/paraderos-image/${id_paradero}`
} }
export async function getParaderos(params) { export async function getParaderos(params) {
@ -51,15 +51,34 @@ export async function deleteParadero(id) {
return res.json() return res.json()
} }
export async function saveImageParadero(id = null, file) { export async function getParaderoImagenes(id_paradero) {
const form = new FormData() const res = await fetch(`${base}/paraderos-image/?id_paradero=${id_paradero}`, {
form.append('imagen', file) headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
})
if (!res.ok) throw await res.text()
return res.json()
}
const res = await fetch(`${base}/paraderos/image/${id}/`, { export async function createParaderoImagen(id_paradero, file) {
const form = new FormData()
form.append('id_paradero', id_paradero)
form.append('imagen', file)
form.append('content_type', file.type)
const res = await fetch(`${base}/paraderos-image/`, {
method: 'POST', method: 'POST',
body: form, body: form,
headers: { "Authorization": `Bearer ${getToken()}` } headers: { "Authorization": `Bearer ${getToken()}` }
}) })
if (!res.ok) throw await res.text() if (!res.ok) throw await res.text()
return res.json() return res.json()
}
export async function deleteParaderoImagen(id_paradero_imagen) {
const res = await fetch(`${base}/paraderos-image/${id_paradero_imagen}/`, {
method: 'DELETE',
headers: { "Authorization": `Bearer ${getToken()}` }
})
if (!res.ok) throw await res.text()
return res.text()
} }