2023-05-03 08:07:34 +00:00
|
|
|
<template>
|
2023-05-10 08:33:40 +00:00
|
|
|
<v-container class="fill-height">
|
|
|
|
<v-row>
|
|
|
|
<template v-if="loading" v-for="i in Array.from({ length: 10 }, (_, i) => i)" :key="i">
|
|
|
|
<v-col cols="12" md="6" lg="4">
|
|
|
|
<v-skeleton-loader class="mx-auto" type="card"></v-skeleton-loader>
|
|
|
|
</v-col>
|
|
|
|
</template>
|
|
|
|
<template v-else v-for="company in companies" :key="company.ticker">
|
|
|
|
<v-col cols="12" md="6" lg="4">
|
|
|
|
<v-card class="ma-1 fill-height">
|
|
|
|
<v-card-item>
|
|
|
|
<v-card-title>{{ company['short name'] }}</v-card-title>
|
|
|
|
<v-card-subtitle>{{ company['company name'] }}</v-card-subtitle>
|
|
|
|
</v-card-item>
|
|
|
|
|
|
|
|
<v-card-text>
|
2023-05-15 09:12:43 +00:00
|
|
|
<p class="text--primary">
|
|
|
|
{{ company.description }}
|
|
|
|
</p>
|
|
|
|
<div class="pt-2 pb-2" v-for="m in metrics" :key="m.title">
|
|
|
|
<div class="d-inline-flex justify-space-between" style="width: 100%">
|
|
|
|
<strong>{{ m.title }}</strong>
|
|
|
|
<span class="text-right">{{ m.value }}{{ m.symbol ?? '' }}</span>
|
|
|
|
</div>
|
|
|
|
<v-progress-linear :color="m.color" v-model="m.percentage"></v-progress-linear>
|
|
|
|
</div>
|
2023-05-10 08:33:40 +00:00
|
|
|
</v-card-text>
|
|
|
|
|
|
|
|
<div class="px-4">
|
|
|
|
<v-chip label color="pink" class="ma-1">
|
|
|
|
<v-icon start icon="mdi-chart-timeline-variant"></v-icon>
|
|
|
|
{{ company.ticker }}
|
|
|
|
</v-chip>
|
|
|
|
<v-chip label color="green" class="ma-1">
|
|
|
|
<v-icon start icon="mdi-currency-usd"></v-icon>
|
|
|
|
{{ formatCurrency(company['market cap']) }}
|
|
|
|
</v-chip>
|
|
|
|
<template v-for="tag in company.tags" :key="tag">
|
2023-05-15 09:12:43 +00:00
|
|
|
<v-chip label class="ma-1">{{ tag }}</v-chip>
|
2023-05-10 08:33:40 +00:00
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
</v-card>
|
|
|
|
</v-col>
|
|
|
|
</template>
|
|
|
|
</v-row>
|
|
|
|
</v-container>
|
2023-05-03 08:07:34 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2023-05-10 08:33:40 +00:00
|
|
|
import { getCompanies, Company } from '@/api';
|
2023-05-15 09:12:43 +00:00
|
|
|
import { ref, reactive, computed, watch } from 'vue';
|
2023-05-10 08:33:40 +00:00
|
|
|
|
|
|
|
const loading = ref(true);
|
|
|
|
const companies = reactive<Company[]>([]);
|
|
|
|
|
2023-05-15 09:12:43 +00:00
|
|
|
interface Metric {
|
|
|
|
title: string,
|
|
|
|
color: string,
|
|
|
|
minValue: number,
|
|
|
|
maxValue: number,
|
|
|
|
value: number // in [0, 100],
|
|
|
|
symbol?: string
|
|
|
|
}
|
|
|
|
|
|
|
|
const metricsData = reactive<Metric[]>([
|
|
|
|
{
|
|
|
|
title: 'Metric 1',
|
|
|
|
color: 'green',
|
|
|
|
minValue: 0,
|
|
|
|
maxValue: 100,
|
|
|
|
value: 20
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'Metric 2',
|
|
|
|
color: 'orange',
|
|
|
|
minValue: 0,
|
|
|
|
maxValue: 100,
|
|
|
|
value: 60,
|
|
|
|
symbol: '%'
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const metrics = computed<(Metric & { percentage: number })[]>(() => metricsData.map(e => ({
|
|
|
|
...e,
|
|
|
|
percentage: (e.value - e.minValue) * 100 / (e.maxValue - e.minValue)
|
|
|
|
})));
|
|
|
|
|
|
|
|
|
2023-05-10 08:33:40 +00:00
|
|
|
getCompanies().then(cs => {
|
|
|
|
loading.value = false;
|
|
|
|
companies.push(...cs);
|
|
|
|
});
|
|
|
|
|
|
|
|
const formatCurrency = (d: number) => {
|
|
|
|
if (d < 1000) return `${d}`;
|
|
|
|
if (d < 1_000_000) return `${Math.round(d / 1000)} K`;
|
|
|
|
if (d < 1_000_000_000) return `${Math.round(d / 1_000_000)} M`
|
|
|
|
return `${Math.round(d / 1_000_000_000)} B`
|
|
|
|
}
|
2023-05-03 08:07:34 +00:00
|
|
|
</script>
|