embalse individual

This commit is contained in:
Pablo Ferreiro 2024-10-17 19:30:18 +02:00
parent 1e6c9c7fb2
commit 6ca280469d
9 changed files with 144 additions and 13 deletions

View File

@ -7,6 +7,10 @@ export default class Api {
return Api._makeReq('/embalses'); return Api._makeReq('/embalses');
} }
static async embalseById(id: string): Promise<Embalse[]> {
return Api._makeReq(`/embalses/${id}`);
}
static async _makeReq<T>(endpoint: string): Promise<T[]> { static async _makeReq<T>(endpoint: string): Promise<T[]> {
let hasMore = true; let hasMore = true;

View File

@ -2,6 +2,7 @@
import { render } from 'solid-js/web'; import { render } from 'solid-js/web';
import { Router } from "@solidjs/router"; import { Router } from "@solidjs/router";
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import './styles/loader.css';
import './styles/bulma.scss'; import './styles/bulma.scss';
import routes from './routes'; import routes from './routes';

View File

@ -2,6 +2,7 @@ export default interface Embalse {
id: number id: number
ambito_nombre: string ambito_nombre: string
embalse_nombre: string embalse_nombre: string
agua_actual: number
agua_total: number agua_total: number
electrico_flag: number electrico_flag: number
codigo: number codigo: number

31
src/partials/Card.tsx Normal file
View File

@ -0,0 +1,31 @@
import { JSX } from "solid-js";
interface Props {
title: string;
icon: JSX.Element;
children: JSX.Element;
}
function Card(props: Props) {
return (
<div class="card">
<header class="card-header">
<p class="card-header-title">
<span class="icon-text">
<span class="icon">
{props.icon}
</span>
<span>{props.title}</span>
</span>
</p>
</header>
<div class="card-content">
<div class="content">
{props.children}
</div>
</div>
</div>
);
}
export default Card;

View File

@ -0,0 +1,7 @@
function Loader() {
return (
<span class="loader"></span>
)
}
export default Loader;

View File

@ -2,6 +2,7 @@ import { RouteDefinition } from "@solidjs/router";
import Home from "./views/Home"; import Home from "./views/Home";
import Finder from "./views/Finder"; import Finder from "./views/Finder";
import Viewer from "./views/Viewer"; import Viewer from "./views/Viewer";
import Embalse from "./views/Embalse";
const routes: RouteDefinition[] = [ const routes: RouteDefinition[] = [
{ {
@ -9,12 +10,16 @@ const routes: RouteDefinition[] = [
component: Home component: Home
}, },
{ {
path: '/finder', path: '/embalses',
component: Viewer
},
{
path: '/embalses/nearby',
component: Finder component: Finder
}, },
{ {
path: '/viewer', path: '/embalses/:id',
component: Viewer component: Embalse
} }
]; ];

20
src/styles/loader.css Normal file
View File

@ -0,0 +1,20 @@
.loader {
width: 48px;
height: 48px;
border: 5px solid #FFF;
border-bottom-color: #FF3D00;
border-radius: 50%;
display: inline-block;
box-sizing: border-box;
animation: rotation 1s linear infinite;
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -1,16 +1,77 @@
import { createSignal } from "solid-js"; import { createSignal, onMount, Show } from "solid-js";
import { Params, useParams } from "@solidjs/router";
import EmbalseType from "../interfaces/Embalse"; import EmbalseType from "../interfaces/Embalse";
import Navbar from "../partials/Navbar"; import Navbar from "../partials/Navbar";
import Loader from "../partials/Loader";
import Api from "../helpers/Api";
import Card from "../partials/Card";
import { FaSolidLocationDot, FaSolidLocationPin, FaSolidMapLocationDot, FaSolidWater } from "solid-icons/fa";
interface CustomParams extends Params {
id: string;
}
function Embalse() { function Embalse() {
const [embalse, setEmbalse] = createSignal<EmbalseType | null>(null);
const params = useParams<CustomParams>();
const [embalse, setEmbalse] = createSignal<EmbalseType>();
onMount(() => {
getEmbalse();
});
const getEmbalse = async () => {
const res = await Api.embalseById(params.id);
setEmbalse(res[0]);
}
return ( return (
<> <>
<Navbar /> <Navbar />
<section class="section"> <Show when={embalse() !== undefined} fallback={<Loader />}>
<section class="hero is-fullheight">
</section> <div class="hero-body">
<div class="container has-text-centered">
<div class="columns is-centered">
<div class="column is-half">
<p class="title">{embalse()!.nombre}</p>
<p class="subtitle">
<span class="icon-text">
<span class="icon">
<FaSolidMapLocationDot />
</span>
<span>{embalse()!.provincia}, {embalse()!.ccaa}</span>
</span>
</p>
<div class="columns is-centered is-vcentered is-multiline">
<div class="column is-narrow">
{/* Ubicación */}
<Card title="Ubicación" icon={<FaSolidLocationDot />}>
<>
<p><b>Latitud</b>: {embalse()!.x}</p>
<p><b>Longitud</b>: {embalse()!.y}</p>
</>
</Card>
</div>
<div class="column is-narrow">
<Card title="Caudal" icon={<FaSolidWater />}>
<>
<p><b>Actual</b>: {embalse()!.agua_actual} l/m2</p>
<p><b>Total</b>: {embalse()!.agua_total} l/m2</p>
<p><b>Porcentaje</b>: {embalse()!.agua_actual / embalse()!.agua_total * 100}%</p>
</>
</Card>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</Show>
</> </>
) )
} }
export default Embalse;

View File

@ -1,16 +1,14 @@
import { FaSolidGlassWaterDroplet } from "solid-icons/fa" import { FaSolidGlassWaterDroplet } from "solid-icons/fa"
import Navbar from "../partials/Navbar"
import { createSignal } from "solid-js"
import Photo from "../helpers/Photo" import Photo from "../helpers/Photo"
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
function Home() { function Home() {
const [photo, setPhoto] = createSignal(Photo.random()); const photo = Photo.random();
return ( return (
<> <>
<section class="hero is-fullheight" style={{ <section class="hero is-fullheight" style={{
"background-image": `url('${photo()}')`, "background-image": `url('${photo}')`,
"background-position": 'center center', "background-position": 'center center',
"background-size": 'cover', "background-size": 'cover',
}}> }}>
@ -35,7 +33,10 @@ function Home() {
<span>Malackathon</span> <span>Malackathon</span>
</span> </span>
</p> </p>
<A class="button is-primary" href="/finder">Buscar</A> <div class="buttons">
<A class="button is-primary" href="/embalses">Todos los embalses</A>
<A class="button is-primary" href="/embalses/nearby">Buscar</A>
</div>
</div> </div>
</div> </div>
</div> </div>