Files
AlquilaFacil/Front/src/paginas/Informes.svelte
2025-05-31 01:06:59 -03:00

374 lines
15 KiB
Svelte

<script lang="ts">
import { onMount } from "svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import FChart from "../Componentes/Estadisticas/fChart.svelte";
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import { urlG } from "../stores/urlStore";
import type { ChartData, IngresosDto } from "../types";
let token = sessionStorage.getItem("token") || "";
let y = $state(2025);
let cdata: ChartData | any = $state();
let aldata: { id: number; ubicacion: string; divisa: string }[] = $state(
[],
);
let chartMesesDuracion: ChartData | any = $state();
let tablaMesesDuracion: {
meses: number;
repes: number;
semaforizacion: string;
}[] = $state([]);
let showModoDaltonico: boolean = $state(false);
let modaldata: string = $state("");
onMount(async () => {
await dataAlquileresporAño();
});
async function dataAlquileresporAño(year = 2025) {
try {
const rep = fetch(
$urlG + "/api/stats/alquileresIniciados?year=" + year,
{
method: "GET",
headers: {
Auth: token,
},
},
);
const pre = fetch(
$urlG + "/api/tabla/alquileresIniciados?year=" + year,
{
method: "GET",
headers: {
Auth: token,
},
},
);
let [r, p] = await Promise.all([rep, pre]);
let data = await r.json();
let data2 = await p.json();
cdata = data;
aldata = data2;
return;
} catch {
modaldata = "Fallo al intentar alcanzar el servidor";
}
}
let visibleMesesDuracion: boolean = $state(false);
async function dataMesesDuracion() {
try {
const p1 = fetch($urlG + "/api/stats/duracionContrato", {
method: "GET",
headers: {
Auth: token,
},
});
const p2 = fetch($urlG + "/api/tabla/duracionContrato", {
method: "GET",
headers: {
Auth: token,
},
});
let [r1, r2] = await Promise.all([p1, p2]);
let [d1, d2] = await Promise.all([r1.json(), r2.json()]);
chartMesesDuracion = d1;
tablaMesesDuracion = d2;
} catch {
modaldata = "Fallo al intentar alcanzar el servidor";
}
}
function toggleModoDaltonico() {
if (tablaMesesDuracion == null) return;
tablaMesesDuracion.forEach((item) => {
if (item.semaforizacion === "🟢") {
item.semaforizacion = "🔵";
} else if (item.semaforizacion === "🔵") {
item.semaforizacion = "🟢";
}
});
}
const nombresMeses = [
"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
];
let ingresos: IngresosDto[] = $state([]);
let chartingresos: ChartData | null = $state(null);
let yearr:number = $state(0);
async function getIngresos(year:number) {
try{
const req = await fetch($urlG+"/api/stats/Pagos?year="+year, {
method:"GET",
headers: {
"Auth": token || "",
},
});
const data = await req.json();
if (req.ok){
ingresos = data.tabla.map(item => ({
...item,
mes: nombresMeses[Number(item.mes) - 1]
}));
chartingresos = data.chart;
} else {
modaldata = data.message;
}
}catch{
modaldata="Fallo la req para obtener ingresos";
}
}
</script>
{#if modaldata}
<ModalEstatico payload={modaldata} close={() => !!(modaldata = "")} />
{/if}
<NavBarAutocompletable />
<div class="container-fluid">
<div class="row mt-4">
<BarraHorizontalConTexto text="Estadisticas" />
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header" id="hea1">
<button
class="accordion-button"
type="button"
data-bs-toggle="collapse"
data-bs-target="#c1"
aria-expanded="true"
aria-controls="c1"
>
Alquileres Por Mes
</button>
</h2>
<div
class="accordion-collapse collapse show"
id="c1"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row">
<div class="col">
<div class="d-flex input-group">
<input
class="form-control"
type="number"
bind:value={y}
/>
<button
class="btn btn-primary"
onclick={() => dataAlquileresporAño(y)}
><img
src="/zoom.svg"
alt="lupa"
aria-label="Lupa"
/>Buscar</button
>
</div>
<p class="text-muted">
Todos los Alquileres de un año mostrados por mes
</p>
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>Ubicacion</th>
<th>Divisa</th>
</tr>
</thead>
<tbody>
{#each aldata as al}
<tr>
<td>{al.id}</td>
<td>{al.ubicacion}</td>
<td>{al.divisa}</td>
</tr>
{/each}
</tbody>
</table>
</div>
<div class="col">
{#if cdata}
<FChart chartData={cdata} />
{/if}
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="hea2">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#c2"
aria-expanded="false"
aria-controls="c2"
onclick={() => {
if (visibleMesesDuracion === true) {
visibleMesesDuracion = false;
return;
} else if (visibleMesesDuracion === false) {
visibleMesesDuracion = true;
showModoDaltonico = false;
dataMesesDuracion();
}
}}
>
Meses De Duracion
</button>
</h2>
<div
class="accordion-collapse collapse"
id="c2"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row">
<div class="col">
<p class="text-muted">
Objetivo: <i
>Mide la longitud de los contratos en meses
y cuantos hay por cada longitud. por lo
menos 2.</i
>
</p>
<input
class="form-check-input"
type="checkbox"
onclick={() => {
showModoDaltonico = !showModoDaltonico;
toggleModoDaltonico();
}}
checked={showModoDaltonico}
/>
Activar Modo Daltónico
<table class="table table-hover">
<thead>
<tr>
<th>Cantidad de meses</th>
<th>Repeticiones</th>
<th>Semaforización</th>
</tr>
</thead>
<tbody>
{#each tablaMesesDuracion as mes}
<tr>
<td>{mes.meses}</td>
<td>{mes.repes}</td>
<td>{mes.semaforizacion}</td>
</tr>
{/each}
</tbody>
</table>
</div>
<div class="col-md-4">
{#if chartMesesDuracion}
<FChart
chartData={chartMesesDuracion}
typec="pie"
/>
{/if}
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#c3"
aria-expanded="false"
aria-controls="c3"
onclick={async ()=> {
if (yearr ==0){
yearr = new Date().getFullYear();
getIngresos(yearr);
} else if (yearr != 0){
yearr = 0;
}}}
>
Estado Pagos por Mes
</button>
</h2>
<div class="accordion-collapse collapse" id="c3"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row">
<div class="col">
<div class="d-flex input-group">
<input
class="form-control"
type="number"
bind:value={yearr}
/>
<button
class="btn btn-primary"
onclick={() => getIngresos(yearr)}
><img
src="/zoom.svg"
alt="lupa"
aria-label="Lupa"
/>Buscar</button
>
</div>
<p class="text-muted">
Todos los canones ya sean pagados, Pagados Atrasados o Sin Realizar
</p>
{#if ingresos.length == 0}
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
</div>
{:else}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Mes</th>
<th>Pagos Realizados</th>
<th>Pagos Atrasados</th>
<th>Pagos Sin Realizar</th>
</tr>
</thead>
<tbody>
{#each ingresos as i }
<tr>
<td>{i.mes}</td>
<td>{i.realizados}</td>
<td>{i.atrasados}</td>
<td>{i.sin_realizar}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
</div>
<div class="col">
{#if chartingresos != null}
<FChart
chartData={chartingresos}
typec="line"
/>
{/if}
</div>
</div>
</div>
</div>
</div>
</div>
</div>