Законченный MVP
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type Direction = 'bull' | 'bear' | 'flat';
|
||||
|
||||
type Signal = {
|
||||
sym: string;
|
||||
dir: Direction;
|
||||
conf: string;
|
||||
entry: string;
|
||||
tp: string;
|
||||
sl: string;
|
||||
};
|
||||
|
||||
type Level = { label: string; val: string; color: string };
|
||||
|
||||
const signals: Signal[] = [
|
||||
{ sym: 'BTCUSDT', dir: 'bull', conf: '73%', entry: '103.4k', tp: '104.2k', sl: '102.8k' },
|
||||
{ sym: 'ETHUSDT', dir: 'bear', conf: '68%', entry: '3.21k', tp: '3.08k', sl: '3.28k' },
|
||||
{ sym: 'SOLUSDT', dir: 'bull', conf: '81%', entry: '178.2', tp: '183.5', sl: '175.0' },
|
||||
{ sym: 'BNBUSDT', dir: 'flat', conf: '52%', entry: '612.4', tp: '618.0', sl: '608.0' },
|
||||
{ sym: 'XRPUSDT', dir: 'bull', conf: '76%', entry: '0.614', tp: '0.641', sl: '0.598' },
|
||||
{ sym: 'ADAUSDT', dir: 'bear', conf: '61%', entry: '0.482', tp: '0.461', sl: '0.494' }
|
||||
];
|
||||
|
||||
const paths: Record<Direction, string> = {
|
||||
bull: 'M 0 32 L 20 28 L 40 30 L 60 22 L 80 24 L 100 16 L 120 12 L 140 8 L 160 4',
|
||||
bear: 'M 0 8 L 20 12 L 40 10 L 60 18 L 80 16 L 100 24 L 120 28 L 140 32 L 160 36',
|
||||
flat: 'M 0 20 L 40 18 L 80 22 L 120 20 L 160 19'
|
||||
};
|
||||
|
||||
const dirColor: Record<Direction, string> = {
|
||||
bull: 'text-emerald-400',
|
||||
bear: 'text-red-400',
|
||||
flat: 'text-zinc-500'
|
||||
};
|
||||
|
||||
const dirStroke: Record<Direction, string> = {
|
||||
bull: '#34d399',
|
||||
bear: '#f87171',
|
||||
flat: '#71717a'
|
||||
};
|
||||
|
||||
const dirBorder: Record<Direction, string> = {
|
||||
bull: 'border-l-emerald-400',
|
||||
bear: 'border-l-red-400',
|
||||
flat: 'border-l-zinc-500'
|
||||
};
|
||||
|
||||
const dirLabel: Record<Direction, string> = {
|
||||
bull: '▲ LONG',
|
||||
bear: '▼ SHORT',
|
||||
flat: '— FLAT'
|
||||
};
|
||||
|
||||
function getLevels(signal: Signal): Level[] {
|
||||
return [
|
||||
{ label: 'E', val: signal.entry, color: 'text-orange-400' },
|
||||
{ label: 'TP', val: signal.tp, color: 'text-emerald-400' },
|
||||
{ label: 'SL', val: signal.sl, color: 'text-red-400' }
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full max-w-170 z-20 mx-auto xl:mx-0" style="perspective: 1000px;">
|
||||
<div
|
||||
class="overflow-hidden rounded-2xl border border-white/10 bg-zinc-950 shadow-[0_40px_100px_rgba(0,0,0,0.7),0_0_0_1px_rgba(255,255,255,0.04)] will-change-transform"
|
||||
style="transform: perspective(1000px) rotateY(-6deg) rotateX(3deg); transform-style: preserve-3d;"
|
||||
>
|
||||
<!-- Title bar -->
|
||||
<div class="flex items-center justify-between border-b border-white/6 bg-white/2 px-4 py-2.5">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#ff5f57]"></div>
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#febc2e]"></div>
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-[#28c840]"></div>
|
||||
</div>
|
||||
<span class="font-mono text-[0.6rem] tracking-widest text-zinc-500">FLAMY TRADE</span>
|
||||
</div>
|
||||
|
||||
<!-- Signal grid -->
|
||||
<div class="grid grid-cols-2">
|
||||
{#each signals as signal, i (signal.sym)}
|
||||
<div
|
||||
class={cn(
|
||||
'border-l-[3px] p-3',
|
||||
dirBorder[signal.dir],
|
||||
i % 2 === 0 && 'border-r border-r-white/6',
|
||||
i < 4 && 'border-b border-b-white/6'
|
||||
)}
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="font-display text-[0.6875rem] font-black tracking-tight text-zinc-100">
|
||||
{signal.sym}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class={cn('font-mono text-[0.5625rem]', dirColor[signal.dir])}>
|
||||
{dirLabel[signal.dir]}
|
||||
</span>
|
||||
<span class="font-mono text-[0.5625rem] text-zinc-400">{signal.conf}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mini chart -->
|
||||
<div class="relative mb-2 h-10 overflow-hidden rounded bg-white/2">
|
||||
<svg
|
||||
width="100%"
|
||||
height="40"
|
||||
viewBox="0 0 160 40"
|
||||
preserveAspectRatio="none"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d={paths[signal.dir]}
|
||||
stroke={dirStroke[signal.dir]}
|
||||
stroke-width="1.2"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Levels -->
|
||||
<div class="flex gap-3">
|
||||
{#each getLevels(signal) as level (level.label)}
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="font-mono text-[0.5rem] tracking-widest text-zinc-600"
|
||||
>{level.label}</span
|
||||
>
|
||||
<span class={cn('font-mono text-[0.5625rem]', level.color)}>{level.val}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user