|
@@ -1,10 +1,125 @@
|
|
|
<script>
|
|
<script>
|
|
|
import Header from '$lib/layout/Header.svelte';
|
|
import Header from '$lib/layout/Header.svelte';
|
|
|
- import EmptyState from '$lib/components/ui/EmptyState.svelte';
|
|
|
|
|
|
|
+ import Tables from '$lib/components/Tables.svelte';
|
|
|
|
|
+ import BuyPanel from '$lib/components/trading/BuyPanel.svelte';
|
|
|
|
|
+ import SellPanel from '$lib/components/trading/SellPanel.svelte';
|
|
|
|
|
+ import { writable } from 'svelte/store';
|
|
|
|
|
+ import { onMount } from 'svelte';
|
|
|
|
|
+ import { browser } from '$app/environment';
|
|
|
|
|
+
|
|
|
const breadcrumb = [{ label: 'Início' }, { label: 'Trading', active: true }];
|
|
const breadcrumb = [{ label: 'Início' }, { label: 'Trading', active: true }];
|
|
|
|
|
+
|
|
|
|
|
+ const orders = writable([]);
|
|
|
|
|
+
|
|
|
|
|
+ let currentPrice = 125;
|
|
|
|
|
+
|
|
|
|
|
+ onMount(() => {
|
|
|
|
|
+ if (browser) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const saved = localStorage.getItem('tradingOrders');
|
|
|
|
|
+ if (saved) orders.set(JSON.parse(saved));
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ function addOrder(order) {
|
|
|
|
|
+ orders.update((arr) => {
|
|
|
|
|
+ const next = [{ ...order, id: Date.now() }, ...arr];
|
|
|
|
|
+ if (browser) localStorage.setItem('tradingOrders', JSON.stringify(next));
|
|
|
|
|
+ return next;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function formatBRL(n) {
|
|
|
|
|
+ return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(Number(n || 0));
|
|
|
|
|
+ }
|
|
|
|
|
+ function formatEasyCoin(n) {
|
|
|
|
|
+ return new Intl.NumberFormat('pt-BR', { minimumFractionDigits: 6, maximumFractionDigits: 6 }).format(Number(n || 0));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let buyTab = 'market';
|
|
|
|
|
+ let sellTab = 'market';
|
|
|
|
|
+
|
|
|
|
|
+ let buyAmountFiat = '';
|
|
|
|
|
+ let buyLimitPrice = '';
|
|
|
|
|
+ let sellAmountEasyCoin = '';
|
|
|
|
|
+ let sellLimitPrice = '';
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ $: buyComputedEasyCoin = buyTab === 'market'
|
|
|
|
|
+ ? (Number(buyAmountFiat) && currentPrice ? Number(buyAmountFiat) / currentPrice : 0)
|
|
|
|
|
+ : (Number(buyAmountFiat) && Number(buyLimitPrice) ? Number(buyAmountFiat) / Number(buyLimitPrice) : 0);
|
|
|
|
|
+
|
|
|
|
|
+ $: sellComputedFiat = sellTab === 'market'
|
|
|
|
|
+ ? (Number(sellAmountEasyCoin) && currentPrice ? Number(sellAmountEasyCoin) * currentPrice : 0)
|
|
|
|
|
+ : (Number(sellAmountEasyCoin) && Number(sellLimitPrice) ? Number(sellAmountEasyCoin) * Number(sellLimitPrice) : 0);
|
|
|
|
|
+
|
|
|
|
|
+ function confirmBuy() {
|
|
|
|
|
+ const price = buyTab === 'limit' ? Number(buyLimitPrice) : currentPrice;
|
|
|
|
|
+ const valueFiat = Number(buyAmountFiat);
|
|
|
|
|
+ if (!price || !valueFiat) return;
|
|
|
|
|
+ const amount = valueFiat / price;
|
|
|
|
|
+ addOrder({ side: 'Compra', price, amount, total: valueFiat, status: 'Aberta', type: buyTab });
|
|
|
|
|
+ buyAmountFiat = '';
|
|
|
|
|
+ buyLimitPrice = '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function confirmSell() {
|
|
|
|
|
+ const price = sellTab === 'limit' ? Number(sellLimitPrice) : currentPrice;
|
|
|
|
|
+ const amount = Number(sellAmountEasyCoin);
|
|
|
|
|
+ if (!price || !amount) return;
|
|
|
|
|
+ const total = amount * price;
|
|
|
|
|
+ addOrder({ side: 'Venda', price, amount, total, status: 'Aberta', type: sellTab });
|
|
|
|
|
+ sellAmountEasyCoin = '';
|
|
|
|
|
+ sellLimitPrice = '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const orderColumns = [
|
|
|
|
|
+ { key: 'side', label: 'Tipo' },
|
|
|
|
|
+ { key: 'price', label: 'Preço (R$)' },
|
|
|
|
|
+ { key: 'amount', label: 'Quantidade (EasyCoin)' },
|
|
|
|
|
+ { key: 'total', label: 'Total (R$)' },
|
|
|
|
|
+ { key: 'status', label: 'Status' }
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+$: pendingBuys = $orders.filter((o) => o.side === 'Compra' && o.type === 'limit' && o.status === 'Aberta');
|
|
|
|
|
+$: pendingSells = $orders.filter((o) => o.side === 'Venda' && o.type === 'limit' && o.status === 'Aberta');
|
|
|
|
|
+
|
|
|
|
|
+$: displayPendingBuys = pendingBuys.map((o) => ({
|
|
|
|
|
+ side: o.side,
|
|
|
|
|
+ price: formatBRL(o.price),
|
|
|
|
|
+ amount: formatEasyCoin(o.amount),
|
|
|
|
|
+ total: formatBRL(o.total),
|
|
|
|
|
+ status: o.status
|
|
|
|
|
+}));
|
|
|
|
|
+
|
|
|
|
|
+$: displayPendingSells = pendingSells.map((o) => ({
|
|
|
|
|
+ side: o.side,
|
|
|
|
|
+ price: formatBRL(o.price),
|
|
|
|
|
+ amount: formatEasyCoin(o.amount),
|
|
|
|
|
+ total: formatBRL(o.total),
|
|
|
|
|
+ status: o.status
|
|
|
|
|
+}));
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<div>
|
|
|
<Header title="Trading" subtitle="Trading do sistema" breadcrumb={breadcrumb} />
|
|
<Header title="Trading" subtitle="Trading do sistema" breadcrumb={breadcrumb} />
|
|
|
- <EmptyState title="Área em Desenvolvimento" description="Esta funcionalidade estará disponível em breve." />
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <div class="p-4 space-y-4">
|
|
|
|
|
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
|
|
+ <BuyPanel
|
|
|
|
|
+ referencePrice={currentPrice}
|
|
|
|
|
+ on:confirm={(e) => addOrder({ side: 'Compra', price: e.detail.price, amount: e.detail.amount, total: e.detail.total, status: 'Aberta', type: e.detail.type })}
|
|
|
|
|
+ />
|
|
|
|
|
+ <SellPanel
|
|
|
|
|
+ referencePrice={currentPrice}
|
|
|
|
|
+ on:confirm={(e) => addOrder({ side: 'Venda', price: e.detail.price, amount: e.detail.amount, total: e.detail.total, status: 'Aberta', type: e.detail.type })}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
|
|
+ <Tables title="Ordens de Compra (pendentes)" columns={orderColumns} data={displayPendingBuys} showActions={false} showAdd={false}/>
|
|
|
|
|
+ <Tables title="Ordens de Venda (pendentes)" columns={orderColumns} data={displayPendingSells} showActions={false} showAdd={false}/>
|
|
|
|
|
+</div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|