feat: treemap, skeletons
This commit is contained in:
parent
848eda70e4
commit
330ea7ad79
18 changed files with 1033 additions and 45 deletions
|
|
@ -23,7 +23,8 @@
|
|||
Settings,
|
||||
Gift,
|
||||
Shield,
|
||||
Ticket
|
||||
Ticket,
|
||||
BarChart3
|
||||
} from 'lucide-svelte';
|
||||
import { mode, setMode } from 'mode-watcher';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
{ title: 'Market', url: '/market', icon: Store },
|
||||
{ title: 'Portfolio', url: '/portfolio', icon: BriefcaseBusiness },
|
||||
{ title: 'Leaderboard', url: '/leaderboard', icon: Trophy },
|
||||
{ title: 'Treemap', url: '/treemap', icon: BarChart3 },
|
||||
{ title: 'Create coin', url: '/coin/create', icon: Coins }
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Gift, Clock, CheckCircle, Flame, Loader2 } from 'lucide-svelte';
|
||||
import { Gift, Clock, Loader2, CheckIcon } from 'lucide-svelte';
|
||||
import { USER_DATA } from '$lib/stores/user-data';
|
||||
import { fetchPortfolioData } from '$lib/stores/portfolio-data';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
<Loader2 class="h-4 w-4 animate-spin" />
|
||||
<span>{!rewardStatus ? 'Loading...' : 'Claiming...'}</span>
|
||||
{:else if claimState === 'success'}
|
||||
<CheckCircle class="h-4 w-4" />
|
||||
<CheckIcon class="h-4 w-4" />
|
||||
<span>Claimed!</span>
|
||||
{:else if rewardStatus.canClaim}
|
||||
<Gift class="h-4 w-4" />
|
||||
|
|
|
|||
163
website/src/lib/components/self/skeletons/CoinSkeleton.svelte
Normal file
163
website/src/lib/components/self/skeletons/CoinSkeleton.svelte
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
</script>
|
||||
|
||||
<header class="mb-8">
|
||||
<div class="mb-6 flex items-start justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<Skeleton class="h-16 w-16 rounded-lg" />
|
||||
<div>
|
||||
<Skeleton class="mb-2 h-10 w-48" />
|
||||
<div class="mt-1 flex items-center gap-2">
|
||||
<Skeleton class="h-6 w-16" />
|
||||
<Skeleton class="h-6 w-20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<Skeleton class="mb-2 h-8 w-32" />
|
||||
<div class="mt-2 flex items-center gap-2">
|
||||
<Skeleton class="h-4 w-4" />
|
||||
<Skeleton class="h-6 w-16" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Creator Info Skeleton -->
|
||||
<div class="text-muted-foreground flex items-center gap-2 text-sm">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-4 w-4 rounded-full" />
|
||||
<Skeleton class="h-4 w-40" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="grid gap-6">
|
||||
<!-- Price Chart with Trading Actions -->
|
||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
||||
<!-- Chart (2/3 width) -->
|
||||
<div class="lg:col-span-2">
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Skeleton class="h-5 w-5" />
|
||||
<Skeleton class="h-6 w-32" />
|
||||
</Card.Title>
|
||||
<div class="flex gap-1">
|
||||
{#each Array(6) as _}
|
||||
<Skeleton class="h-8 w-12" />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content class="pt-0">
|
||||
<Skeleton class="h-[500px] w-full" />
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
|
||||
<!-- Right side - Trading Actions + Liquidity Pool (1/3 width) -->
|
||||
<div class="space-y-6 lg:col-span-1">
|
||||
<!-- Trading Actions Skeleton -->
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-4">
|
||||
<Card.Title>
|
||||
<Skeleton class="h-6 w-24" />
|
||||
</Card.Title>
|
||||
<Skeleton class="h-4 w-32" />
|
||||
</Card.Header>
|
||||
<Card.Content class="pt-0">
|
||||
<div class="space-y-3">
|
||||
<Skeleton class="h-11 w-full" />
|
||||
<Skeleton class="h-11 w-full" />
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<!-- Liquidity Pool Skeleton -->
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-4">
|
||||
<Card.Title>
|
||||
<Skeleton class="h-6 w-28" />
|
||||
</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="pt-0">
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<Skeleton class="mb-3 h-5 w-32" />
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Skeleton class="mb-3 h-5 w-20" />
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics Grid Skeleton -->
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
{#each Array(4) as _}
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-2">
|
||||
<Card.Title class="flex items-center gap-2 text-sm font-medium">
|
||||
<Skeleton class="h-4 w-4" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="pt-0">
|
||||
<Skeleton class="mb-1 h-6 w-24" />
|
||||
<Skeleton class="h-3 w-16" />
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Comments Section Skeleton -->
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-4">
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Skeleton class="h-5 w-5" />
|
||||
<Skeleton class="h-6 w-20" />
|
||||
</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="pt-0">
|
||||
<div class="space-y-4">
|
||||
{#each Array(3) as _}
|
||||
<div class="flex gap-3 border-b pb-4 last:border-b-0">
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div class="flex-1">
|
||||
<div class="mb-2 flex items-center gap-2">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="h-3 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-4 w-full" />
|
||||
<Skeleton class="mt-1 h-4 w-3/4" />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto p-6">
|
||||
<!-- Header Skeleton -->
|
||||
<header class="mb-8">
|
||||
<Skeleton class="mb-2 h-9 w-64" />
|
||||
<Skeleton class="h-5 w-96" />
|
||||
</header>
|
||||
|
||||
<!-- Top Coins Grid Skeleton -->
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{#each Array(6) as _}
|
||||
<Card.Root class="h-full">
|
||||
<Card.Header>
|
||||
<Card.Title class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Skeleton class="h-6 w-6 rounded-full" />
|
||||
<Skeleton class="h-6 w-32" />
|
||||
</div>
|
||||
<Skeleton class="h-6 w-16" />
|
||||
</Card.Title>
|
||||
<Card.Description>
|
||||
<Skeleton class="h-4 w-28" />
|
||||
</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<Skeleton class="h-9 w-24" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Market Overview Skeleton -->
|
||||
<div class="mt-12">
|
||||
<Skeleton class="mb-4 h-8 w-40" />
|
||||
<Card.Root>
|
||||
<Card.Content class="p-0">
|
||||
<div class="p-6">
|
||||
{#each Array(10) as _}
|
||||
<div class="flex items-center gap-4 border-b py-4 last:border-b-0">
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div class="flex-1">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="mt-1 h-3 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
</script>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-2">
|
||||
{#each Array(4) as _}
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Skeleton class="h-6 w-6" />
|
||||
<Skeleton class="h-6 w-40" />
|
||||
</Card.Title>
|
||||
<Card.Description>
|
||||
<Skeleton class="h-4 w-64" />
|
||||
</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<div class="space-y-4">
|
||||
{#each Array(5) as _}
|
||||
<div class="flex items-center gap-4 border-b pb-4 last:border-b-0">
|
||||
<Skeleton class="h-6 w-8" />
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div class="flex-1">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="mt-1 h-3 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-5 w-16" />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
import { MediaQuery } from 'svelte/reactivity';
|
||||
|
||||
const isDesktop = new MediaQuery('(min-width: 768px)');
|
||||
let perPage = $derived(isDesktop.current ? 12 : 9);
|
||||
</script>
|
||||
|
||||
<!-- Pagination Info Skeleton -->
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<Skeleton class="h-5 w-48" />
|
||||
<Skeleton class="h-5 w-24" />
|
||||
</div>
|
||||
|
||||
<!-- Market Grid Skeleton -->
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
{#each Array(perPage) as _}
|
||||
<Card.Root class="gap-1">
|
||||
<Card.Header>
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div>
|
||||
<Skeleton class="mb-1 h-5 w-24" />
|
||||
<Skeleton class="h-4 w-16" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<Skeleton class="h-3 w-8" />
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
|
||||
<Card.Content>
|
||||
<div class="space-y-3">
|
||||
<!-- Price -->
|
||||
<div>
|
||||
<Skeleton class="mb-2 h-8 w-24" />
|
||||
<div class="mt-1 flex items-center gap-2">
|
||||
<Skeleton class="h-5 w-12" />
|
||||
<Skeleton class="h-5 w-16" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="space-y-4 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-12" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-4 w-12" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<Skeleton class="h-4 w-12" />
|
||||
<Skeleton class="h-4 w-16" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
128
website/src/lib/components/self/skeletons/ProfileSkeleton.svelte
Normal file
128
website/src/lib/components/self/skeletons/ProfileSkeleton.svelte
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
</script>
|
||||
|
||||
<!-- Profile Header Skeleton -->
|
||||
<Card.Root class="mb-6 py-0">
|
||||
<Card.Content class="p-6">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start">
|
||||
<!-- Avatar Skeleton -->
|
||||
<div class="flex-shrink-0">
|
||||
<Skeleton class="size-20 rounded-full sm:size-24" />
|
||||
</div>
|
||||
|
||||
<!-- Profile Info Skeleton -->
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="mb-3">
|
||||
<div class="mb-1 flex flex-wrap items-center gap-2">
|
||||
<Skeleton class="h-8 w-48 sm:h-9" />
|
||||
<Skeleton class="h-6 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-6 w-32" />
|
||||
</div>
|
||||
|
||||
<Skeleton class="mb-3 h-4 w-full max-w-2xl" />
|
||||
<Skeleton class="mb-6 h-4 w-96" />
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<Skeleton class="h-4 w-4" />
|
||||
<Skeleton class="h-4 w-24" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<!-- Main Portfolio Stats Skeleton -->
|
||||
<div class="mb-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{#each Array(4) as _}
|
||||
<Card.Root class="py-0">
|
||||
<Card.Content class="p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="h-4 w-4" />
|
||||
</div>
|
||||
<Skeleton class="mt-1 h-8 w-32" />
|
||||
<Skeleton class="mt-1 h-3 w-20" />
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Buy & Sell Activity Skeleton -->
|
||||
<div class="mb-6 grid grid-cols-1 gap-4 lg:grid-cols-4">
|
||||
{#each Array(4) as _}
|
||||
<Card.Root class="py-0">
|
||||
<Card.Content class="p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="h-4 w-4" />
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
<Skeleton class="h-8 w-28" />
|
||||
<Skeleton class="mt-1 h-3 w-24" />
|
||||
</div>
|
||||
<div class="border-muted mt-3 border-t pt-3">
|
||||
<Skeleton class="h-6 w-24" />
|
||||
<Skeleton class="mt-1 h-3 w-20" />
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Created Coins Skeleton -->
|
||||
<Card.Root class="mb-6">
|
||||
<Card.Header class="pb-3">
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Skeleton class="h-5 w-5" />
|
||||
<Skeleton class="h-6 w-32" />
|
||||
</Card.Title>
|
||||
<Skeleton class="h-4 w-48" />
|
||||
</Card.Header>
|
||||
<Card.Content class="p-0">
|
||||
<div class="p-6">
|
||||
{#each Array(3) as _}
|
||||
<div class="flex items-center gap-4 border-b py-4 last:border-b-0">
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div class="flex-1">
|
||||
<Skeleton class="h-4 w-24" />
|
||||
<Skeleton class="mt-1 h-3 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="h-4 w-16" />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<!-- Recent Trading Activity Skeleton -->
|
||||
<Card.Root>
|
||||
<Card.Header class="pb-3">
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Skeleton class="h-5 w-5" />
|
||||
<Skeleton class="h-6 w-40" />
|
||||
</Card.Title>
|
||||
<Skeleton class="h-4 w-52" />
|
||||
</Card.Header>
|
||||
<Card.Content class="p-0">
|
||||
<div class="p-6">
|
||||
{#each Array(5) as _}
|
||||
<div class="flex items-center gap-4 border-b py-4 last:border-b-0">
|
||||
<Skeleton class="h-6 w-12" />
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<div class="flex-1">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
<Skeleton class="mt-1 h-3 w-16" />
|
||||
</div>
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-16" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
Reference in a new issue