feat: comments

fix: use select instead of dropdown for filter on /market
This commit is contained in:
Face 2025-05-24 19:28:38 +03:00
parent 800b5d1a09
commit bd05b269fe
22 changed files with 2715 additions and 97 deletions

View file

@ -2,7 +2,7 @@
import * as Card from '$lib/components/ui/card';
import * as Popover from '$lib/components/ui/popover';
import * as Pagination from '$lib/components/ui/pagination';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Select from '$lib/components/ui/select';
import { Input } from '$lib/components/ui/input';
import { Button } from '$lib/components/ui/button';
import { Badge } from '$lib/components/ui/badge';
@ -18,11 +18,11 @@
SlidersHorizontal,
ChevronLeft,
ChevronRight,
ChevronDown,
DollarSign,
TrendingUp,
ArrowUpDown
} from 'lucide-svelte'; import { formatPrice, formatMarketCap, debounce, formatRelativeTime } from '$lib/utils';
} from 'lucide-svelte';
import { formatPrice, formatMarketCap, debounce, formatRelativeTime } from '$lib/utils';
import { MediaQuery } from 'svelte/reactivity';
import type { CoinData, FilterOption, VolatilityBadge, MarketResponse } from '$lib/types/market';
@ -165,8 +165,19 @@
fetchMarketData();
}
function handleSortOrderChange(newSortOrder: string) {
sortOrder = newSortOrder;
function handleSortOrderChange() {
currentPage = 1;
updateURL();
fetchMarketData();
}
function handlePriceFilterChange() {
currentPage = 1;
updateURL();
fetchMarketData();
}
function handleChangeFilterChange() {
currentPage = 1;
updateURL();
fetchMarketData();
@ -199,20 +210,6 @@
return null;
}
function handlePriceFilterChange(value: string) {
priceFilter = value;
currentPage = 1;
updateURL();
fetchMarketData();
}
function handleChangeFilterChange(value: string) {
changeFilter = value;
currentPage = 1;
updateURL();
fetchMarketData();
}
let hasActiveFilters = $derived(
searchQuery !== '' ||
priceFilter !== 'all' ||
@ -316,89 +313,68 @@
<div class="space-y-2">
<Label class="text-sm font-medium">Sort Order</Label>
<DropdownMenu.Root>
<DropdownMenu.Trigger
class="border-input bg-background ring-offset-background focus-visible:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
>
<div class="flex items-center gap-2">
<ArrowUpDown class="h-4 w-4" />
<span>{currentSortOrderLabel}</span>
</div>
<ChevronDown class="h-4 w-4 opacity-50" />
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56">
{#each sortOrderOptions as option}
<DropdownMenu.Item
onclick={() => handleSortOrderChange(option.value)}
class="cursor-pointer"
>
<ArrowUpDown class="h-4 w-4" />
<span>{option.label}</span>
{#if sortOrder === option.value}
<div class="bg-primary ml-auto h-2 w-2 rounded-full"></div>
{/if}
</DropdownMenu.Item>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>
<Select.Root
type="single"
bind:value={sortOrder}
onValueChange={handleSortOrderChange}
>
<Select.Trigger class="w-full">
{currentSortOrderLabel}
</Select.Trigger>
<Select.Content>
<Select.Group>
{#each sortOrderOptions as option}
<Select.Item value={option.value} label={option.label}>
{option.label}
</Select.Item>
{/each}
</Select.Group>
</Select.Content>
</Select.Root>
</div>
<div class="space-y-2">
<Label class="text-sm font-medium">Price Range</Label>
<DropdownMenu.Root>
<DropdownMenu.Trigger
class="border-input bg-background ring-offset-background focus-visible:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
>
<div class="flex items-center gap-2">
<DollarSign class="h-4 w-4" />
<span>{currentPriceFilterLabel}</span>
</div>
<ChevronDown class="h-4 w-4 opacity-50" />
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56">
{#each priceFilterOptions as option}
<DropdownMenu.Item
onclick={() => handlePriceFilterChange(option.value)}
class="cursor-pointer"
>
<DollarSign class="h-4 w-4" />
<span>{option.label}</span>
{#if priceFilter === option.value}
<div class="bg-primary ml-auto h-2 w-2 rounded-full"></div>
{/if}
</DropdownMenu.Item>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>
<Select.Root
type="single"
bind:value={priceFilter}
onValueChange={handlePriceFilterChange}
>
<Select.Trigger class="w-full">
{currentPriceFilterLabel}
</Select.Trigger>
<Select.Content>
<Select.Group>
{#each priceFilterOptions as option}
<Select.Item value={option.value} label={option.label}>
{option.label}
</Select.Item>
{/each}
</Select.Group>
</Select.Content>
</Select.Root>
</div>
<div class="space-y-2">
<Label class="text-sm font-medium">24h Change</Label>
<DropdownMenu.Root>
<DropdownMenu.Trigger
class="border-input bg-background ring-offset-background focus-visible:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
>
<div class="flex items-center gap-2">
<TrendingUp class="h-4 w-4" />
<span>{currentChangeFilterLabel}</span>
</div>
<ChevronDown class="h-4 w-4 opacity-50" />
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56">
{#each changeFilterOptions as option}
<DropdownMenu.Item
onclick={() => handleChangeFilterChange(option.value)}
class="cursor-pointer"
>
<TrendingUp class="h-4 w-4" />
<span>{option.label}</span>
{#if changeFilter === option.value}
<div class="bg-primary ml-auto h-2 w-2 rounded-full"></div>
{/if}
</DropdownMenu.Item>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>
<Select.Root
type="single"
bind:value={changeFilter}
onValueChange={handleChangeFilterChange}
>
<Select.Trigger class="w-full">
{currentChangeFilterLabel}
</Select.Trigger>
<Select.Content>
<Select.Group>
{#each changeFilterOptions as option}
<Select.Item value={option.value} label={option.label}>
{option.label}
</Select.Item>
{/each}
</Select.Group>
</Select.Content>
</Select.Root>
</div>
<div class="flex gap-2 pt-2">