send / received transactions in live trades
This commit is contained in:
parent
e4ba0c71ca
commit
6539eb2f4f
4 changed files with 82 additions and 27 deletions
|
|
@ -28,9 +28,7 @@
|
||||||
TrendingUpDown,
|
TrendingUpDown,
|
||||||
Scale,
|
Scale,
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
|
|
||||||
Hammer
|
Hammer
|
||||||
|
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
import { mode, setMode } from 'mode-watcher';
|
import { mode, setMode } from 'mode-watcher';
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
@ -249,7 +247,15 @@
|
||||||
class="hover:bg-muted/50 flex w-full cursor-pointer items-center gap-2 rounded px-1 py-1 text-left text-xs transition-colors"
|
class="hover:bg-muted/50 flex w-full cursor-pointer items-center gap-2 rounded px-1 py-1 text-left text-xs transition-colors"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
{#if trade.type === 'BUY'}
|
{#if trade.type === 'TRANSFER_IN' || trade.type === 'TRANSFER_OUT'}
|
||||||
|
<Activity class="h-3 w-3 text-blue-500" />
|
||||||
|
<Badge
|
||||||
|
variant="outline"
|
||||||
|
class="h-4 border-blue-500 px-1 py-0 text-[10px] text-blue-500"
|
||||||
|
>
|
||||||
|
{trade.type === 'TRANSFER_IN' ? 'REC' : 'SENT'}
|
||||||
|
</Badge>
|
||||||
|
{:else if trade.type === 'BUY'}
|
||||||
<TrendingUp class="h-3 w-3 text-green-500" />
|
<TrendingUp class="h-3 w-3 text-green-500" />
|
||||||
<Badge
|
<Badge
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
@ -272,8 +278,17 @@
|
||||||
<span class="text-foreground font-medium">
|
<span class="text-foreground font-medium">
|
||||||
{formatValue(trade.totalValue)}
|
{formatValue(trade.totalValue)}
|
||||||
</span>
|
</span>
|
||||||
|
{#if trade.type === 'TRANSFER_IN' || trade.type === 'TRANSFER_OUT'}
|
||||||
|
{#if trade.amount > 0}
|
||||||
|
<span class="text-muted-foreground">*{trade.coinSymbol}</span>
|
||||||
|
{/if}
|
||||||
|
<span class="text-muted-foreground">
|
||||||
|
{trade.type === 'TRANSFER_IN' ? 'to' : 'from'}
|
||||||
|
</span>
|
||||||
|
{:else}
|
||||||
<span class="text-muted-foreground">*{trade.coinSymbol}</span>
|
<span class="text-muted-foreground">*{trade.coinSymbol}</span>
|
||||||
<span class="text-muted-foreground">by</span>
|
<span class="text-muted-foreground">by</span>
|
||||||
|
{/if}
|
||||||
<span class="text-muted-foreground">@{trade.username}</span>
|
<span class="text-muted-foreground">@{trade.username}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { browser } from '$app/environment';
|
||||||
import { PUBLIC_WEBSOCKET_URL } from '$env/static/public';
|
import { PUBLIC_WEBSOCKET_URL } from '$env/static/public';
|
||||||
|
|
||||||
export interface LiveTrade {
|
export interface LiveTrade {
|
||||||
type: 'BUY' | 'SELL';
|
type: 'BUY' | 'SELL' | 'TRANSFER_IN' | 'TRANSFER_OUT';
|
||||||
username: string;
|
username: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
coinSymbol: string;
|
coinSymbol: string;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export async function GET({ url }) {
|
||||||
.limit(limit);
|
.limit(limit);
|
||||||
|
|
||||||
const formattedTrades = trades.map(trade => ({
|
const formattedTrades = trades.map(trade => ({
|
||||||
type: trade.type as 'BUY' | 'SELL',
|
type: trade.type as 'BUY' | 'SELL' | 'TRANSFER_IN' | 'TRANSFER_OUT',
|
||||||
username: trade.username,
|
username: trade.username,
|
||||||
userImage: trade.userImage,
|
userImage: trade.userImage,
|
||||||
amount: Number(trade.amount),
|
amount: Number(trade.amount),
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,35 @@
|
||||||
<div class="flex items-center gap-3 sm:gap-4">
|
<div class="flex items-center gap-3 sm:gap-4">
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<div class="flex flex-wrap items-center gap-1 sm:gap-2">
|
<div class="flex flex-wrap items-center gap-1 sm:gap-2">
|
||||||
|
{#if trade.type === 'TRANSFER_IN' || trade.type === 'TRANSFER_OUT'}
|
||||||
|
{#if trade.amount > 0}
|
||||||
|
<button
|
||||||
|
onclick={() => handleCoinClick(trade.coinSymbol)}
|
||||||
|
class="flex cursor-pointer items-center gap-1.5 transition-opacity hover:underline hover:opacity-80"
|
||||||
|
>
|
||||||
|
<CoinIcon
|
||||||
|
icon={trade.coinIcon}
|
||||||
|
symbol={trade.coinSymbol}
|
||||||
|
name={trade.coinName || trade.coinSymbol}
|
||||||
|
size={5}
|
||||||
|
class="sm:size-6"
|
||||||
|
/>
|
||||||
|
<span class="font-mono text-sm font-medium sm:text-base">
|
||||||
|
{formatQuantity(trade.amount)} *{trade.coinSymbol}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<span class="text-muted-foreground text-xs sm:text-sm">
|
||||||
|
{trade.type === 'TRANSFER_IN' ? 'received by' : 'sent by'}
|
||||||
|
</span>
|
||||||
|
{:else}
|
||||||
|
<span class="font-mono text-sm font-medium sm:text-base">
|
||||||
|
{formatValue(trade.totalValue)}
|
||||||
|
</span>
|
||||||
|
<span class="text-muted-foreground text-xs sm:text-sm">
|
||||||
|
{trade.type === 'TRANSFER_IN' ? 'received by' : 'sent by'}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
<button
|
<button
|
||||||
onclick={() => handleCoinClick(trade.coinSymbol)}
|
onclick={() => handleCoinClick(trade.coinSymbol)}
|
||||||
class="flex cursor-pointer items-center gap-1.5 transition-opacity hover:underline hover:opacity-80"
|
class="flex cursor-pointer items-center gap-1.5 transition-opacity hover:underline hover:opacity-80"
|
||||||
|
|
@ -94,6 +123,8 @@
|
||||||
<span class="text-muted-foreground text-xs sm:text-sm">
|
<span class="text-muted-foreground text-xs sm:text-sm">
|
||||||
{trade.type === 'BUY' ? 'bought by' : 'sold by'}
|
{trade.type === 'BUY' ? 'bought by' : 'sold by'}
|
||||||
</span>
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<HoverCard.Root>
|
<HoverCard.Root>
|
||||||
<HoverCard.Trigger
|
<HoverCard.Trigger
|
||||||
class="cursor-pointer font-medium underline-offset-4 hover:underline"
|
class="cursor-pointer font-medium underline-offset-4 hover:underline"
|
||||||
|
|
@ -124,15 +155,24 @@
|
||||||
|
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<div class="flex items-center gap-2 font-mono text-xs sm:text-sm">
|
<div class="flex items-center gap-2 font-mono text-xs sm:text-sm">
|
||||||
{#if trade.type === 'BUY'}
|
{#if trade.type === 'TRANSFER_IN' || trade.type === 'TRANSFER_OUT'}
|
||||||
|
<Activity class="h-3.5 w-3.5 text-blue-500 sm:h-4 sm:w-4" />
|
||||||
|
<span class="text-blue-500">
|
||||||
|
{trade.type === 'TRANSFER_IN' ? 'RECEIVED' : 'SENT'}
|
||||||
|
</span>
|
||||||
|
<span class="text-muted-foreground">|</span>
|
||||||
|
<span>{formatValue(trade.totalValue)}</span>
|
||||||
|
{:else if trade.type === 'BUY'}
|
||||||
<TrendingUp class="h-3.5 w-3.5 text-green-500 sm:h-4 sm:w-4" />
|
<TrendingUp class="h-3.5 w-3.5 text-green-500 sm:h-4 sm:w-4" />
|
||||||
<span class="text-green-500">BUY</span>
|
<span class="text-green-500">BUY</span>
|
||||||
|
<span class="text-muted-foreground">|</span>
|
||||||
|
<span>{formatValue(trade.totalValue)}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<TrendingDown class="h-3.5 w-3.5 text-red-500 sm:h-4 sm:w-4" />
|
<TrendingDown class="h-3.5 w-3.5 text-red-500 sm:h-4 sm:w-4" />
|
||||||
<span class="text-red-500">SELL</span>
|
<span class="text-red-500">SELL</span>
|
||||||
{/if}
|
|
||||||
<span class="text-muted-foreground">|</span>
|
<span class="text-muted-foreground">|</span>
|
||||||
<span>{formatValue(trade.totalValue)}</span>
|
<span>{formatValue(trade.totalValue)}</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
Reference in a new issue