app/components/dashboard/RunwayCard.vue

59 lines
1.8 KiB
Vue

<template>
<div class="hidden" data-ui="runway_card_v1" />
<UCard class="min-h-[140px] shadow-sm rounded-xl" :class="borderColor">
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<div class="w-2 h-2 rounded-full" :class="statusDotColor" />
<h3 class="font-semibold">Runway</h3>
</div>
<UBadge
:color="operatingMode === 'target' ? 'blue' : 'neutral'"
size="xs">
{{ operatingMode === "target" ? "Target Mode" : "Min Mode" }}
</UBadge>
</div>
</template>
<div class="text-center space-y-6">
<div class="text-2xl font-semibold" :class="statusColor">
{{ displayRunway }}
</div>
<div class="text-sm text-neutral-600">at current spending</div>
</div>
</UCard>
</template>
<script setup lang="ts">
const { runwayMonths, operatingMode } = useCoopBuilder();
const runway = computed(() => runwayMonths());
const displayRunway = computed(() => {
const months = runway.value;
if (!isFinite(months)) return "∞";
if (months < 1) return "<1 month";
return `${Math.round(months)} months`;
});
const statusColor = computed(() => {
const months = runway.value;
if (!isFinite(months) || months >= 6) return "text-green-600";
if (months >= 3) return "text-amber-600";
return "text-red-600";
});
const statusDotColor = computed(() => {
const months = runway.value;
if (!isFinite(months) || months >= 6) return "bg-green-500";
if (months >= 3) return "bg-amber-500";
return "bg-red-500";
});
const borderColor = computed(() => {
const months = runway.value;
if (!isFinite(months) || months >= 6) return "ring-1 ring-green-200";
if (months >= 3) return "ring-1 ring-amber-200";
return "ring-1 ring-red-200";
});
</script>