Desayunos
diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js
index ff99beb..6713981 100644
--- a/frontend/src/services/api.js
+++ b/frontend/src/services/api.js
@@ -20,3 +20,7 @@ export async function getPrices() {
export async function getCiStatus() {
return getJson('/health');
}
+
+export async function getBuildHistory() {
+ return getJson('/builds');
+}
diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css
index e6aa29d..6866649 100644
--- a/frontend/src/styles/app.css
+++ b/frontend/src/styles/app.css
@@ -477,3 +477,132 @@ li {
.mono {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
+
+.history-card {
+ background: linear-gradient(180deg, #0f172a, #0c1228);
+}
+
+.history-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+}
+
+.history-item {
+ border: 1px solid rgba(255, 255, 255, 0.06);
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.02);
+ overflow: hidden;
+ transition: border-color 160ms ease, box-shadow 160ms ease;
+}
+
+.history-item summary {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.8rem;
+ padding: 0.75rem 0.9rem;
+ list-style: none;
+ cursor: pointer;
+}
+
+.history-item summary::-webkit-details-marker {
+ display: none;
+}
+
+.summary-left {
+ display: flex;
+ align-items: center;
+ gap: 0.55rem;
+ flex-wrap: wrap;
+}
+
+.summary-title {
+ font-weight: 800;
+ color: #f8fafc;
+}
+
+.summary-branch {
+ color: #a5b4fc;
+ font-weight: 700;
+ font-size: 0.95rem;
+}
+
+.summary-meta {
+ display: flex;
+ gap: 0.6rem;
+ flex-wrap: wrap;
+ color: #cbd5f5;
+ font-size: 0.9rem;
+ justify-content: flex-end;
+}
+
+.status-dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ display: inline-block;
+}
+
+.status-dot.success {
+ background: #22c55e;
+ box-shadow: 0 0 8px rgba(34, 197, 94, 0.6);
+}
+
+.status-dot.failed {
+ background: #f87171;
+ box-shadow: 0 0 8px rgba(248, 113, 113, 0.5);
+}
+
+.history-body {
+ padding: 0.75rem 0.9rem 0.9rem;
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+}
+
+.history-row {
+ margin: 0;
+ display: flex;
+ justify-content: space-between;
+ font-weight: 700;
+ color: #e2e8f0;
+}
+
+.history-row span:last-child {
+ color: #cbd5f5;
+}
+
+.history-message {
+ margin: 0.2rem 0 0;
+ background: rgba(248, 113, 113, 0.12);
+ border: 1px dashed rgba(248, 113, 113, 0.5);
+ padding: 0.5rem 0.75rem;
+ border-radius: 10px;
+ color: #fecaca;
+}
+
+.history-message.success {
+ background: rgba(34, 197, 94, 0.12);
+ border-color: rgba(34, 197, 94, 0.4);
+ color: #bbf7d0;
+}
+
+.history-item[open] {
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
+}
+
+.history-item.success {
+ border-color: rgba(34, 197, 94, 0.3);
+}
+
+.history-item.failed {
+ border-color: rgba(248, 113, 113, 0.35);
+}
+
+.chip.danger {
+ background: rgba(248, 113, 113, 0.2);
+ color: #fecdd3;
+ border: 1px solid rgba(248, 113, 113, 0.4);
+}