termine el contador de dias

This commit is contained in:
2025-11-01 16:16:58 -03:00
parent 06629cc1c0
commit 2d60fcc9cd
5 changed files with 179 additions and 33 deletions

View File

@@ -1,7 +1,10 @@
<script lang="ts"> <script lang="ts">
import Header from "./componentes/header.svelte";
import CalcularDias from "./componentes/paginas/CalcularDias.svelte";
import Tarjeta from "./componentes/tarjeta.svelte"; import Tarjeta from "./componentes/tarjeta.svelte";
import html2canvas from "html2canvas"; import html2canvas from "html2canvas";
let pagina = $state(0);
let issues: any[] = $state([]); let issues: any[] = $state([]);
$effect(() => { $effect(() => {
obtener_issues(); obtener_issues();
@@ -50,24 +53,30 @@
</script> </script>
<main> <main>
<button onclick={() => exportAllToPNG(issues)} class="btn btn-primary mt-3" <Header bind:pagina></Header>
>Exportar a PNG</button {#if pagina == 0}
> <button
{#if issues.length == 0} onclick={() => exportAllToPNG(issues)}
<p>Cargando...</p> class="btn btn-primary mt-3">Exportar a PNG</button
{:else} >
<div class="d-flex justify-center flex-column align-items-center"> {#if issues.length == 0}
{#each issues as issue} <p>Cargando...</p>
<div class="m-2 w-75"> {:else}
<Tarjeta {issue} /> <div class="d-flex justify-center flex-column align-items-center">
<!-- {#each issues as issue}
<div class="m-2 w-75">
<Tarjeta {issue} />
<!--
<button <button
onclick={() => exportToPNG(issue)} onclick={() => exportToPNG(issue)}
class="btn btn-primary mt-3">Exportar a PNG</button class="btn btn-primary mt-3">Exportar a PNG</button
> >
--> -->
</div> </div>
{/each} {/each}
</div> </div>
{/if}
{:else if pagina === 1}
<CalcularDias {issues} />
{/if} {/if}
</main> </main>

View File

@@ -874,25 +874,6 @@
"updated_on": "2025-10-22T23:05:58Z", "updated_on": "2025-10-22T23:05:58Z",
"closed_on": "2025-10-22T21:24:48Z" "closed_on": "2025-10-22T21:24:48Z"
}, },
{
"id": 7,
"project": { "id": 1, "name": "AlquilaFacil" },
"tracker": { "id": 1, "name": "Caracteristica" },
"status": { "id": 2, "name": "Cerrado", "is_closed": true },
"priority": { "id": 2, "name": "Normal" },
"author": { "id": 5, "name": "Federico Polidoro" },
"subject": "Falta validacion de longitud campo nombre",
"description": "![image.png](/attachments/f1c4250a-b349-49f6-9d01-2db5e750bace)\r\n\r\n\u003cimg width=\"389\" alt=\"image.png\" src=\"attachments/b6ed90ae-e622-4ab6-bbf2-dabd58b94717\"\u003e\r\n\r\n",
"start_date": "2025-05-29",
"due_date": "2025-05-29",
"done_ratio": 100,
"is_private": false,
"estimated_hours": null,
"total_estimated_hours": null,
"created_on": "2025-10-22T20:58:54Z",
"updated_on": "2025-10-22T23:07:19Z",
"closed_on": "2025-10-22T21:24:48Z"
},
{ {
"id": 6, "id": 6,
"project": { "id": 1, "name": "AlquilaFacil" }, "project": { "id": 1, "name": "AlquilaFacil" },

View File

@@ -0,0 +1,29 @@
<script>
let count = $state(0);
let { pagina = $bindable() } = $props();
</script>
<header
style="display: flex; justify-content: space-between; align-items: center; padding: 1rem; "
>
<div>
<button class="btn btn-primary" onclick={() => (pagina = 0)}
>Tarjetas</button
>
<button class="btn btn-primary" onclick={() => (pagina = 1)}
>Dias de duracion</button
>
<button
class="btn"
aria-label="Cambiar tema"
onclick={() =>
document.body.setAttribute(
"data-bs-theme",
document.body.getAttribute("data-bs-theme") === "dark"
? "light"
: "dark",
)}>AAAA me quema los ojos</button
>
</div>
</header>

View File

@@ -0,0 +1,107 @@
<script lang="ts">
import type { Issue } from "../../types";
let { issues }: { issues: Issue[] } = $props();
$effect(() => {
calcularDiasPorIssue();
calcularDiasTotales();
});
let diasCalculados = $state(0);
function calcularDiasTotales() {
if (!issues || issues.length === 0) {
diasCalculados = 0;
return;
}
let totalDias = 0;
let primerIssue = issues.reduce((acc, issue) => {
if (!acc.start_date) return issue;
if (!issue.start_date) return acc;
const accDate = new Date(acc.start_date);
const issueDate = new Date(issue.start_date);
return issueDate < accDate ? issue : acc;
});
let ultimoIssue = issues.reduce((acc, issue) => {
if (!acc.due_date) return issue;
if (!issue.due_date) return acc;
const accDate = new Date(acc.due_date);
const issueDate = new Date(issue.due_date);
return issueDate > accDate ? issue : acc;
});
if (!primerIssue.start_date || !ultimoIssue.due_date) {
diasCalculados = 0;
return;
}
const startDate = new Date(primerIssue.start_date);
const endDate = new Date(ultimoIssue.due_date);
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
diasCalculados = 0;
return;
}
const diffTime = endDate.getTime() - startDate.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
diasCalculados = diffDays > 0 ? diffDays : 0;
}
function calcularDiasPorIssue() {
issues.forEach((issue) => {
if (issue.start_date && issue.due_date) {
const startDate = new Date(issue.start_date);
const dueDate = new Date(issue.due_date);
if (!isNaN(startDate.getTime()) && !isNaN(dueDate.getTime())) {
const diffTime = dueDate.getTime() - startDate.getTime();
const diffDays = Math.ceil(
diffTime / (1000 * 60 * 60 * 24),
);
issue.cantDias = diffDays;
}
}
});
}
</script>
<div class="container mt-4">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">Calculadora de Días</h5>
</div>
<div class="card-body">
{#if diasCalculados > 0}
<div class="alert alert-info">
<strong>Resultado:</strong>
{diasCalculados} días calculados
</div>
{/if}
<div class="mt-3">
<h6>Issues:</h6>
<ul class="list-group">
{#each issues as issue}
<li
class="list-group-item d-flex justify-content-between align-items-center"
>
{`${issue.id} | ${issue.subject}`}
<span class="badge bg-secondary"
>{issue.cantDias || 0} días</span
>
</li>
{/each}
</ul>
</div>
</div>
</div>
</div>

20
src/types.d.ts vendored Normal file
View File

@@ -0,0 +1,20 @@
export interface Issue {
id: number;
project: { id: number; name: string };
tracker: { id: number; name: string };
status: { id: number; name: string; is_closed: boolean };
priority: { id: number; name: string };
author: { id: number; name: string };
subject: string;
description: string;
start_date: string;
due_date: string;
cantDias: number;
done_ratio: number;
is_private: boolean;
estimated_hours: number | null;
total_estimated_hours: number | null;
created_on: string;
updated_on: string;
closed_on: string;
}