135 lines
2.5 KiB
Vue
135 lines
2.5 KiB
Vue
<template>
|
|
<div class="service-card">
|
|
<div class="card-header">
|
|
<div class="service-info">
|
|
<h3 class="service-name">
|
|
{{ name }}
|
|
</h3>
|
|
<span
|
|
class="info-tooltip"
|
|
title="Click for historical uptime metrics"
|
|
>?</span>
|
|
</div>
|
|
<div
|
|
class="current-status-dot"
|
|
:class="status.toLowerCase()"
|
|
/>
|
|
</div>
|
|
|
|
<div class="uptime-graph">
|
|
<div
|
|
v-for="(day, index) in uptimeHistory"
|
|
:key="index"
|
|
class="bar"
|
|
:class="day.status"
|
|
:title="formatTooltip(day)"
|
|
/>
|
|
</div>
|
|
|
|
<div class="card-footer">
|
|
<span class="time-ago">90 days ago</span>
|
|
<span class="uptime-percentage">{{ uptimePercentage }}% uptime</span>
|
|
<span class="time-today">Today</span>
|
|
</div>
|
|
|
|
<div class="status-label">
|
|
{{ status }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" src="../composables/ServiceCard.ts"></script>
|
|
|
|
<style scoped>
|
|
.service-card {
|
|
background-color: #161b22;
|
|
border: 1px solid #30363d;
|
|
border-radius: 6px;
|
|
padding: 20px;
|
|
color: #c9d1d9;
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.service-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.service-name {
|
|
font-size: 1.05rem;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
color: #f0f6fc;
|
|
}
|
|
|
|
.info-tooltip {
|
|
font-size: 0.75rem;
|
|
color: #8b949e;
|
|
background-color: #21262d;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: help;
|
|
}
|
|
|
|
.current-status-dot {
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
}
|
|
.current-status-dot.normal { background-color: #238636; }
|
|
.current-status-dot.degraded { background-color: #d29922; }
|
|
.current-status-dot.outage { background-color: #f85149; }
|
|
|
|
.uptime-graph {
|
|
display: flex;
|
|
gap: 2px;
|
|
height: 34px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.bar {
|
|
flex: 1;
|
|
background-color: #238636;
|
|
border-radius: 1px;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.bar:hover {
|
|
opacity: 0.7;
|
|
transform: scaleY(1.1);
|
|
}
|
|
|
|
.bar.normal { background-color: #238636; }
|
|
.bar.degraded { background-color: #d29922; }
|
|
.bar.outage { background-color: #f85149; }
|
|
|
|
.card-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: 0.75rem;
|
|
color: #8b949e;
|
|
border-bottom: 1px solid #21262d;
|
|
padding-bottom: 8px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.uptime-percentage {
|
|
color: #8b949e;
|
|
}
|
|
|
|
.status-label {
|
|
font-size: 0.85rem;
|
|
color: #8b949e;
|
|
}
|
|
</style>
|