From 6cc0bfd1d79074df790272b8091b1f0226d14283 Mon Sep 17 00:00:00 2001
From: zwlucas <lucas.fariamo08@gmail.com>
Date: Fri, 29 May 2026 15:57:37 -0300
Subject: feat: upload project

Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
---
 frontend/src/lib/components/UptimeTimeline.svelte | 41 +++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 frontend/src/lib/components/UptimeTimeline.svelte

(limited to 'frontend/src/lib/components/UptimeTimeline.svelte')

diff --git a/frontend/src/lib/components/UptimeTimeline.svelte b/frontend/src/lib/components/UptimeTimeline.svelte
new file mode 100644
index 0000000..6cb47df
--- /dev/null
+++ b/frontend/src/lib/components/UptimeTimeline.svelte
@@ -0,0 +1,41 @@
+<script lang="ts">
+	import type { Heartbeat } from '$lib/types';
+
+	let {
+		heartbeats = []
+	}: {
+		heartbeats: Heartbeat[];
+	} = $props();
+
+	let blocks = $derived.by(() => {
+		const all = heartbeats.slice(-30);
+		const filled = all.map((h) => h.is_up);
+		while (filled.length < 30) {
+			filled.unshift(null);
+		}
+		return filled;
+	});
+
+	function blockColor(v: boolean | null): string {
+		if (v === true) return 'var(--green)';
+		if (v === false) return 'var(--red)';
+		return 'var(--border-color)';
+	}
+</script>
+
+<div class="space-y-1.5">
+	<div class="flex gap-[3px]">
+		{#each blocks as block, i}
+			<div
+				class="h-4 flex-1 rounded-sm transition-all duration-300"
+				style="background-color: {blockColor(block)}; opacity: {block !== null ? 0.8 : 1}"
+				title={block === true ? 'UP' : block === false ? 'DOWN' : 'Sem dados'}
+			></div>
+		{/each}
+	</div>
+	<div class="flex justify-between text-[10px] font-medium text-[var(--text-muted)]">
+		<span>{heartbeats.length > 0 ? '-30 min' : ''}</span>
+		<span class="tabular-nums">{heartbeats.length} checks</span>
+		<span>agora</span>
+	</div>
+</div>
-- 
cgit v1.2.3

