This repository has been archived on 2023-06-18. You can view files and clone it, but cannot push or open issues or pull requests.
va-project/stockingly-frontend/src/views/Home.vue

108 lines
3.4 KiB
Vue
Raw Normal View History

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">
2023-05-15 09:50:07 +00:00
<div class="d-flex stretch align-center">
<div class="flex-0 pa-3">
<img style="max-height: 36px; min-height: 24px;" :src="company.logoSrc"/>
</div>
<v-card-item style="flex: 1 !important">
<v-card-title>{{ company['short name'] }}</v-card-title>
<v-card-subtitle>{{ company['company name'] }}</v-card-subtitle>
</v-card-item>
</div>
2023-05-10 08:33:40 +00:00
<v-card-text>
<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>
2023-05-15 09:50:07 +00:00
<span class="text-right">{{ m.value(company) }}{{ m.symbol ?? '' }}</span>
</div>
2023-05-15 09:50:07 +00:00
<v-progress-linear :color="m.color" :model-value="m.percentage(company)"></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">
<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';
import { ref, reactive, computed, watch } from 'vue';
2023-05-10 08:33:40 +00:00
const loading = ref(true);
const companies = reactive<Company[]>([]);
interface Metric {
title: string,
color: string,
minValue: number,
maxValue: number,
2023-05-15 09:50:07 +00:00
value: (c: Company) => number // in [0, 100],
symbol?: string
}
const metricsData = reactive<Metric[]>([
{
title: 'Metric 1',
color: 'green',
minValue: 0,
maxValue: 100,
2023-05-15 09:50:07 +00:00
value: _ => 20
},
{
2023-05-15 09:50:07 +00:00
title: 'Length of ticker',
color: 'orange',
minValue: 0,
2023-05-15 09:50:07 +00:00
maxValue: 5,
value: c => c.ticker.length,
symbol: ' chars'
},
]);
2023-05-15 09:50:07 +00:00
const metrics = computed<(Metric & { percentage: (c: Company) => number })[]>(() => metricsData.map(e => ({
...e,
2023-05-15 09:50:07 +00:00
percentage: (c: Company) => (e.value(c) - 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>