Skip to content

Commit

Permalink
feat: add icons to price
Browse files Browse the repository at this point in the history
  • Loading branch information
yjl9903 committed Mar 5, 2024
1 parent e74f5e7 commit 7462772
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 21 deletions.
4 changes: 4 additions & 0 deletions components/City.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const currentCity = props.city;
const timestamp = useTimestamp({ interval: 10 * 1000 });
const mode = ref<'simple' | 'full' | 'edit'>('simple');
const store = useLatestLogs();
</script>

Expand Down Expand Up @@ -53,6 +55,7 @@ const store = useLatestLogs();
<TableCell class="border-r"
><Price
:timestamp="timestamp"
:product="getProductInfo(city.name, product.name)!"
:log="store.getLatestLog(city.name, product.name, currentCity.name)"
></Price
></TableCell>
Expand All @@ -61,6 +64,7 @@ const store = useLatestLogs();
:key="target.name"
><Price
:timestamp="timestamp"
:product="getProductInfo(city.name, product.name)!"
:log="store.getLatestLog(city.name, product.name, target.name)"
></Price
></TableCell>
Expand Down
102 changes: 84 additions & 18 deletions components/Price.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,104 @@ import type { Log } from '~/drizzle/schema';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
const props = defineProps<{ timestamp: number; log: Log | undefined }>();
const props = defineProps<{ timestamp: number; product: ProductInfo; log: Log | undefined }>();
const store = useLatestLogs();
const profit = computed(() => {
if (!props.log || props.log?.type === 'buy') return undefined;
const productLog = store.getLatestLog(props.log.name, props.log.sourceCity, props.log.sourceCity);
if (isLogValid(productLog)) {
return (1.04 * props.log.price - 0.92 * productLog.price).toFixed(0);
} else {
return (1.04 * props.log.price - 0.92 * props.product.basePrice).toFixed(0);
}
});
const isOutdated = computed(() => {
if (!props.log) return true;
const uploadedAt = props.log.uploadedAt.getTime();
return props.timestamp - uploadedAt > 3600 * 1000;
props.timestamp;
return isLogValid(props.log);
});
</script>

<template>
<div v-if="log" :class="{ 'line-through': isOutdated, 'op-50': isOutdated }">
<TooltipProvider :delayDuration="300" :skipDelayDuration="100">
<div>
<TooltipProvider v-if="log" :delayDuration="300" :skipDelayDuration="100">
<Tooltip>
<TooltipTrigger as-child>
<div class="flex gap-1 items-center">
<div :class="{ 'text-red': log.percent < 100, 'text-green': log.percent > 100 }">
<div>
<span>{{ log.price }}</span>
</div>
<div>
<span>{{ log.percent }}%</span>
</div>
<div :class="{ 'line-through': isOutdated, 'op-50': isOutdated }">
<div v-if="log.type === 'sell'" class="h-6 flex gap-1 items-center">
<span class="i-icon-park-income-one text-sm"></span><span>{{ profit }}</span>
</div>
<div v-if="!isOutdated" class="text-2xl">
<span v-if="log.trend === 'up'" class="i-carbon-arrow-up text-green"></span>
<span v-else-if="log.trend === 'down'" class="i-carbon-arrow-down text-red"></span>
<span v-else class="w-4"></span>
<!-- <div v-else="log.type === 'buy'" class="h-6">
<span></span><span>{{ log.price }}</span>
</div> -->
<div class="flex gap-1 items-center h-6">
<span class="i-icon-park:dollar text-sm"></span>
<span :class="{ 'text-red': log.percent < 100, 'text-green': log.percent > 100 }"
>{{ log.percent }}%</span
>
<span class="text-xl mt-1"
><span
v-if="log.trend === 'up'"
class="i-material-symbols-trending-up text-green"
></span>
<span
v-else-if="log.trend === 'down'"
class="i-material-symbols-trending-down text-red"
></span>
<span v-else class="i-material-symbols-trending-flat"></span
></span>
</div>
</div>
</TooltipTrigger>
<TooltipContent>
<p>最近更新于 {{ format(log.uploadedAt, { date: 'long', time: 'medium' }) }}</p>
<div v-if="log" class="py-1 space-y-1">
<p class="flex items-center">
<span class="font-bold mr-2">价格</span>
<span
:class="[
{
'text-red': log.percent < 100,
'text-green': log.percent > 100,
'line-through': isOutdated,
'op-50': isOutdated
},
'mr-2'
]"
>{{ log.price }} ({{ log.percent }}%)</span
>
<span
v-if="log.trend === 'up'"
class="i-material-symbols-trending-up text-green text-xl"
></span>
<span
v-else-if="log.trend === 'down'"
class="i-material-symbols-trending-down text-red text-xl"
></span>
<span v-else class="i-material-symbols-trending-flat text-xl"></span>
</p>
<p v-if="log.type === 'sell'">
<span class="font-bold mr-2">单位利润</span>
<span
:class="{
'text-red': log.percent < 100,
'text-green': log.percent > 100,
'line-through': isOutdated,
'op-50': isOutdated
}"
>{{ profit }}</span
>
</p>
<p>
<span class="font-bold mr-2">最近更新于</span>
<span :class="{ 'op-50': isOutdated }">{{
format(log.uploadedAt, { date: 'long', time: 'medium' })
}}</span>
</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
},
"devDependencies": {
"@iconify-json/carbon": "^1.1.31",
"@iconify-json/icon-park": "^1.1.13",
"@iconify-json/logos": "^1.1.42",
"@iconify-json/material-symbols": "^1.1.74",
"@nuxtjs/color-mode": "^3.3.2",
"@nuxtjs/tailwindcss": "^6.11.4",
"@total-typescript/ts-reset": "^0.5.1",
Expand Down
4 changes: 4 additions & 0 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<script setup lang="ts">
const store = useLatestLogs();
await store.fetch();
useIntervalFn(() => {
store.fetch();
}, 10 * 1000);
</script>

<template>
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/utils/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function connectDatabase(
): Promise<
DrizzleD1Database<{ users: typeof users; products: typeof products; logs: typeof logs }>
> {
if (import.meta.dev) {
if (import.meta.dev && false) {
const { database } = await import('~/drizzle/dev/connect');
return database as any;
} else {
Expand Down
8 changes: 7 additions & 1 deletion utils/cities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import type { CityInfo } from './types';
import { groupBy } from './map';
import { products } from './products';

export const cities: CityInfo[] = groupBy(products, (p) => p.city).map((i) => ({
const citiesMap = groupBy(products, (p) => p.city);

export const cities: CityInfo[] = [...citiesMap].map((i) => ({
name: i[0],
products: i[1]
}));

export function getProductInfo(city: string, name: string) {
return citiesMap.get(city)?.find((p) => p.name === name);
}
7 changes: 7 additions & 0 deletions utils/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Log } from '~/drizzle/schema';

export function isLogValid(log: Log | undefined | null): log is Log {
if (!log) return false;
const uploadedAt = log.uploadedAt.getTime();
return new Date().getTime() - uploadedAt > 3600 * 1000;
}
2 changes: 1 addition & 1 deletion utils/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export function groupBy<T>(arr: T[], fn: (item: T) => string) {
map.set(key, [item]);
}
}
return [...map];
return map;
}

0 comments on commit 7462772

Please sign in to comment.