basic ui
This commit is contained in:
parent
574b8f4240
commit
b07af64247
25
package-lock.json
generated
25
package-lock.json
generated
@ -10,10 +10,12 @@
|
||||
"dependencies": {
|
||||
"@solidjs/router": "^0.14.9",
|
||||
"bulma": "^1.0.2",
|
||||
"leaflet": "^1.9.4",
|
||||
"solid-icons": "^1.1.0",
|
||||
"solid-js": "^1.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/leaflet": "^1.9.12",
|
||||
"sass": "^1.80.1",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.4.8",
|
||||
@ -1826,6 +1828,23 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
|
||||
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.12.tgz",
|
||||
"integrity": "sha512-BK7XS+NyRI291HIo0HCfE18Lp8oA30H1gpi1tf0mF3TgiCEzanQjOqNZ4x126SXzzi2oNSZhZ5axJp1k0iM6jg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"dev": true,
|
||||
@ -3250,6 +3269,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/leven": {
|
||||
"version": "3.1.0",
|
||||
"dev": true,
|
||||
|
@ -11,10 +11,12 @@
|
||||
"dependencies": {
|
||||
"@solidjs/router": "^0.14.9",
|
||||
"bulma": "^1.0.2",
|
||||
"leaflet": "^1.9.4",
|
||||
"solid-icons": "^1.1.0",
|
||||
"solid-js": "^1.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/leaflet": "^1.9.12",
|
||||
"sass": "^1.80.1",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.4.8",
|
||||
|
6
src/constants/Photos.ts
Normal file
6
src/constants/Photos.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/** Lista de fotos (Licencia CC) */
|
||||
const PHOTOS: string[] = [
|
||||
"https://images.pexels.com/photos/2532003/pexels-photo-2532003.jpeg?cs=srgb&dl=pexels-jamie-patterson-1318696-2532003.jpg&fm=jpg"
|
||||
];
|
||||
|
||||
export default PHOTOS;
|
@ -1,6 +0,0 @@
|
||||
/** Lista de videos (CC) */
|
||||
const VIDEOS: string[] = [
|
||||
"https://www.pexels.com/es-es/download/video/13831212/?fps=60.0&h=720&w=1280"
|
||||
];
|
||||
|
||||
export default VIDEOS;
|
0
src/helpers/Api.ts
Normal file
0
src/helpers/Api.ts
Normal file
@ -1,15 +1,15 @@
|
||||
import VIDEOS from "../constants/Videos";
|
||||
import PHOTOS from "../constants/Photos";
|
||||
|
||||
/**
|
||||
* Clase helper para gestionar los vídeos de fondo
|
||||
* encontrados en views/Home
|
||||
*/
|
||||
export default class Video {
|
||||
export default class Photo {
|
||||
/**
|
||||
* Elige un vídeo aleatoriamente de la lista
|
||||
* @returns Vídeo aleatorio
|
||||
*/
|
||||
static random(): string {
|
||||
return VIDEOS[Math.floor(Math.random()*VIDEOS.length)];
|
||||
return PHOTOS[Math.floor(Math.random()*PHOTOS.length)];
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/* @refresh reload */
|
||||
import { render } from 'solid-js/web';
|
||||
import { Router } from "@solidjs/router";
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import './styles/bulma.scss';
|
||||
import routes from './routes';
|
||||
|
||||
|
27
src/interfaces/Embalse.ts
Normal file
27
src/interfaces/Embalse.ts
Normal file
@ -0,0 +1,27 @@
|
||||
export default interface Embalse {
|
||||
// EMBALSES
|
||||
ID: number;
|
||||
AMBITO_NOMBRE: string;
|
||||
EMBALSE_NOMBRE: string;
|
||||
AGUA_TOTAL: number;
|
||||
ELECTRICO_FLAG: boolean;
|
||||
// LISTADO_EMBALSES
|
||||
CODIGO: number;
|
||||
NOMBRE: string;
|
||||
EMBALSE: string;
|
||||
X: string;
|
||||
Y: string;
|
||||
DEMARC: string;
|
||||
CAUCE: string;
|
||||
GOOGLE: string;
|
||||
OPENSTREETMAP: string;
|
||||
WIKIDATA: string;
|
||||
PROVINCIA: string;
|
||||
CCAA: string;
|
||||
TIPO: string;
|
||||
TITULAR: string;
|
||||
USO: string;
|
||||
COTA_CORON: string;
|
||||
ALT_CIMIEN: string;
|
||||
INFORME: string;
|
||||
}
|
@ -1,10 +1,15 @@
|
||||
import { RouteDefinition } from "@solidjs/router";
|
||||
import Home from "./views/Home";
|
||||
import Finder from "./views/Finder";
|
||||
|
||||
const routes: RouteDefinition[] = [
|
||||
{
|
||||
path: '/',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/finder',
|
||||
component: Finder
|
||||
}
|
||||
];
|
||||
|
||||
|
155
src/views/Finder.tsx
Normal file
155
src/views/Finder.tsx
Normal file
@ -0,0 +1,155 @@
|
||||
import { createSignal, onCleanup, onMount } from "solid-js";
|
||||
import L from 'leaflet';
|
||||
import { FaSolidLocationPin } from "solid-icons/fa";
|
||||
import Navbar from "../partials/Navbar";
|
||||
|
||||
function Finder() {
|
||||
const [pos, setPos] = createSignal<[number, number]>([0, 0]);
|
||||
const [geo, setGeo] = createSignal(true);
|
||||
|
||||
let markers: L.Marker[] = [];
|
||||
|
||||
let first = true;
|
||||
let watchId: number = -1;
|
||||
let map: L.Map;
|
||||
|
||||
let me = L.marker([0, 0]);
|
||||
|
||||
/**
|
||||
* Montar Leafmap
|
||||
*/
|
||||
onMount(() => {
|
||||
map = L.map('map');
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
|
||||
if (geo()) {
|
||||
listenGeolocation();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Limpiar watch de geolocalización si
|
||||
* está activo
|
||||
*/
|
||||
onCleanup(() => {
|
||||
if (watchId !== -1) {
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Activar / Desactivar uso de Geolocalización
|
||||
*/
|
||||
const toggleGeo = () => {
|
||||
if (geo()) {
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
watchId = -1;
|
||||
} else {
|
||||
listenGeolocation();
|
||||
}
|
||||
|
||||
setGeo(!geo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Activar listener de geolocalización en tiempo real
|
||||
*/
|
||||
const listenGeolocation = () => {
|
||||
watchId = navigator.geolocation.watchPosition(
|
||||
(pos) => {
|
||||
setPos([pos.coords.latitude, pos.coords.longitude]);
|
||||
handleLocation();
|
||||
},
|
||||
(err) => {
|
||||
alert(err.message);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Escribe los puntos relevantes
|
||||
* (Mi ubicación y los embalses cercanos)
|
||||
*/
|
||||
const handleLocation = () => {
|
||||
me.setLatLng(pos());
|
||||
if (first) {
|
||||
map.setView(pos(), 9);
|
||||
me.addTo(map);
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if (markers.length > 0) {
|
||||
markers.forEach((m) => {
|
||||
map.removeLayer(m);
|
||||
})
|
||||
|
||||
markers = [];
|
||||
}
|
||||
|
||||
// TODO: Hacer petición y sacar markers
|
||||
}
|
||||
|
||||
/**
|
||||
* Escribe la latitud de la tupla manualmente
|
||||
* @param val Latitud dada por el input
|
||||
*/
|
||||
const setLatitudeManual = (val: string) => {
|
||||
const lat = parseFloat(val);
|
||||
|
||||
setPos([lat, pos()[1]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escribe la longitud de la tupla manualmente
|
||||
* @param val longitud dada por el input
|
||||
*/
|
||||
const setLongitudeManual = (val: string) => {
|
||||
const lon = parseFloat(val);
|
||||
|
||||
setPos([pos()[0], lon]);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="columns is-centered is-vcentered is-multiline">
|
||||
<div class="column is-narrow">
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<div class="control">
|
||||
<input class="input" on:change={(e) => setLatitudeManual(e.target.value)} type="text" disabled={geo()} placeholder="Latitud" value={pos()[0]} />
|
||||
</div>
|
||||
<div class="control">
|
||||
<input class="input" on:change={(e) => setLongitudeManual(e.target.value)} type="text" disabled={geo()} placeholder="Longitud" value={pos()[1]} />
|
||||
</div>
|
||||
<div class="control">
|
||||
<button disabled={geo()} on:click={() => handleLocation()} class="button is-info">
|
||||
Aplicar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<button on:click={() => toggleGeo()} class="button" classList={{ 'is-success': geo(), 'is-danger': !geo() }}>
|
||||
<span class="icon">
|
||||
<FaSolidLocationPin />
|
||||
</span>
|
||||
<span>Geolocalización</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map" style={{
|
||||
height: '70vh'
|
||||
}}></div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Finder;
|
@ -1,11 +1,19 @@
|
||||
import { FaSolidGlassWaterDroplet } from "solid-icons/fa"
|
||||
import Navbar from "../partials/Navbar"
|
||||
import { createSignal } from "solid-js"
|
||||
import Photo from "../helpers/Photo"
|
||||
import { A } from "@solidjs/router";
|
||||
|
||||
function Home() {
|
||||
const [photo, setPhoto] = createSignal(Photo.random());
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
<section class="hero is-fullheight-with-navbar">
|
||||
<section class="hero is-fullheight" style={{
|
||||
"background-image": `url('${photo()}')`,
|
||||
"background-position": 'center center',
|
||||
"background-size": 'cover',
|
||||
}}>
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<div class="columns is-centered">
|
||||
@ -14,6 +22,7 @@ function Home() {
|
||||
<div class="columns is-centered is-vcentered is-mobile">
|
||||
<div class="column is-4">
|
||||
<figure class="image is-128x128">
|
||||
{/* TODO: Agregar icono */}
|
||||
<img src="https://bulma.io/assets/images/placeholders/128x128.png" />
|
||||
</figure>
|
||||
</div>
|
||||
@ -26,6 +35,7 @@ function Home() {
|
||||
<span>Malackathon</span>
|
||||
</span>
|
||||
</p>
|
||||
<A class="button is-primary" href="/finder">Buscar</A>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -35,7 +45,7 @@ function Home() {
|
||||
</div>
|
||||
</section>
|
||||
<section class="section">
|
||||
<video src="https://www.pexels.com/es-es/download/video/13831212/?fps=60.0&h=720&w=1280"></video>
|
||||
<p>TODO: Agregar tarjetitas guapas</p>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user