refactor: update app.vue and various components to enhance UI consistency, replace color classes for improved accessibility, and refine layout for better user experience
This commit is contained in:
parent
7b4fb6c2fd
commit
24e8b7a3a8
41 changed files with 2395 additions and 1603 deletions
|
|
@ -3,10 +3,10 @@
|
|||
<template #header>
|
||||
<h4 class="font-medium">Stress Test</h4>
|
||||
</template>
|
||||
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-700 mb-2 block">
|
||||
<label class="text-sm font-medium text-neutral-700 mb-2 block">
|
||||
Revenue Delay: {{ stress.revenueDelay }} months
|
||||
</label>
|
||||
<input
|
||||
|
|
@ -15,13 +15,14 @@
|
|||
min="0"
|
||||
max="6"
|
||||
step="1"
|
||||
class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
|
||||
@input="(e) => updateStress({ revenueDelay: Number(e.target.value) })"
|
||||
/>
|
||||
class="w-full h-2 bg-neutral-200 rounded-lg appearance-none cursor-pointer"
|
||||
@input="
|
||||
(e) => updateStress({ revenueDelay: Number(e.target.value) })
|
||||
" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-700 mb-2 block">
|
||||
<label class="text-sm font-medium text-neutral-700 mb-2 block">
|
||||
Cost Shock: +{{ stress.costShockPct }}%
|
||||
</label>
|
||||
<input
|
||||
|
|
@ -30,29 +31,32 @@
|
|||
min="0"
|
||||
max="30"
|
||||
step="5"
|
||||
class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
|
||||
@input="(e) => updateStress({ costShockPct: Number(e.target.value) })"
|
||||
/>
|
||||
class="w-full h-2 bg-neutral-200 rounded-lg appearance-none cursor-pointer"
|
||||
@input="
|
||||
(e) => updateStress({ costShockPct: Number(e.target.value) })
|
||||
" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UCheckbox
|
||||
:model-value="stress.grantLost"
|
||||
label="Major Grant Lost"
|
||||
@update:model-value="(val) => updateStress({ grantLost: val })"
|
||||
/>
|
||||
@update:model-value="(val) => updateStress({ grantLost: val })" />
|
||||
</div>
|
||||
|
||||
<div v-if="isStressActive" class="p-3 bg-orange-50 border border-orange-200 rounded">
|
||||
<div
|
||||
v-if="isStressActive"
|
||||
class="p-3 bg-orange-50 border border-orange-200 rounded">
|
||||
<div class="text-sm">
|
||||
<div class="flex items-center gap-2 text-orange-800 mb-1">
|
||||
<UIcon name="i-heroicons-exclamation-triangle" class="w-4 h-4" />
|
||||
<span class="font-medium">Stress Test Active</span>
|
||||
</div>
|
||||
<div class="text-orange-700">
|
||||
Projected runway: <span class="font-semibold">{{ displayStressedRunway }}</span>
|
||||
Projected runway:
|
||||
<span class="font-semibold">{{ displayStressedRunway }}</span>
|
||||
<span v-if="runwayChange !== 0" class="ml-2">
|
||||
({{ runwayChange > 0 ? '+' : '' }}{{ runwayChange }} months)
|
||||
({{ runwayChange > 0 ? "+" : "" }}{{ runwayChange }} months)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -62,32 +66,35 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { stress, updateStress, runwayMonths } = useCoopBuilder()
|
||||
const { stress, updateStress, runwayMonths } = useCoopBuilder();
|
||||
|
||||
const isStressActive = computed(() =>
|
||||
stress.value.revenueDelay > 0 ||
|
||||
stress.value.costShockPct > 0 ||
|
||||
stress.value.grantLost
|
||||
)
|
||||
const isStressActive = computed(
|
||||
() =>
|
||||
stress.value.revenueDelay > 0 ||
|
||||
stress.value.costShockPct > 0 ||
|
||||
stress.value.grantLost
|
||||
);
|
||||
|
||||
const stressedRunway = computed(() => runwayMonths(undefined, { useStress: true }))
|
||||
const normalRunway = computed(() => runwayMonths())
|
||||
const stressedRunway = computed(() =>
|
||||
runwayMonths(undefined, { useStress: true })
|
||||
);
|
||||
const normalRunway = computed(() => runwayMonths());
|
||||
|
||||
const displayStressedRunway = computed(() => {
|
||||
const months = stressedRunway.value
|
||||
if (!isFinite(months)) return '∞'
|
||||
if (months < 1) return '<1 month'
|
||||
return `${Math.round(months)} months`
|
||||
})
|
||||
const months = stressedRunway.value;
|
||||
if (!isFinite(months)) return "∞";
|
||||
if (months < 1) return "<1 month";
|
||||
return `${Math.round(months)} months`;
|
||||
});
|
||||
|
||||
const runwayChange = computed(() => {
|
||||
const normal = normalRunway.value
|
||||
const stressed = stressedRunway.value
|
||||
|
||||
if (!isFinite(normal) && !isFinite(stressed)) return 0
|
||||
if (!isFinite(normal)) return -99 // Very large negative change
|
||||
if (!isFinite(stressed)) return 0
|
||||
|
||||
return Math.round(stressed - normal)
|
||||
})
|
||||
</script>
|
||||
const normal = normalRunway.value;
|
||||
const stressed = stressedRunway.value;
|
||||
|
||||
if (!isFinite(normal) && !isFinite(stressed)) return 0;
|
||||
if (!isFinite(normal)) return -99; // Very large negative change
|
||||
if (!isFinite(stressed)) return 0;
|
||||
|
||||
return Math.round(stressed - normal);
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue