SkateSpots/src/components/SortDropdown.tsx
SkateSpots 0b796440f1 feat(i18n): Spanish batch 2 — nav/chrome, events/shops/tours, crews/DMs, settings/auth, wallet/stash/newsletter/stats
~3,470 new keys (5,770 total, EN=ES), ~115 more files wired.
- nav + chromeUi: header, More menu, burger menu, footer, map toolbar widgets
  (sort/trust/weather), spot-type label helper.
- placesUi: events, shops, tours, food. socialUi: crews, DMs, notifications,
  collectives, crew chat/coordinator. settingsUi: settings, auth/signup,
  onboarding, profile edit, legal. walletUi: wallet/Cashu, stash, mints,
  app shop, newsletter, community stats, leaderboards, profile.
- Fixed 738 usages where an agent dropped the socialUi. prefix (caught by check:i18n).
2026-10-02 10:11:06 +07:00

103 lines
2.9 KiB
TypeScript

import { ArrowUpDown, Clock, TrendingUp, MapPin, Zap, Shield } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { useTranslation } from '@/contexts/language';
export type SortOption =
| 'recent'
| 'trust'
| 'proximity'
| 'popular'
| 'zaps';
interface SortDropdownProps {
value: SortOption;
onChange: (value: SortOption) => void;
className?: string;
showProximity?: boolean; // Only show if geolocation available
contentType?: 'spots' | 'events' | 'coaches' | 'generic';
}
const SORT_OPTIONS = {
recent: {
labelKey: 'chromeUi.sort.recent',
descKey: 'chromeUi.sort.recentDesc',
icon: Clock,
},
trust: {
labelKey: 'chromeUi.sort.trust',
descKey: 'chromeUi.sort.trustDesc',
icon: Shield,
},
proximity: {
labelKey: 'chromeUi.sort.proximity',
descKey: 'chromeUi.sort.proximityDesc',
icon: MapPin,
},
popular: {
labelKey: 'chromeUi.sort.popular',
descKey: 'chromeUi.sort.popularDesc',
icon: TrendingUp,
},
zaps: {
labelKey: 'chromeUi.sort.zaps',
descKey: 'chromeUi.sort.zapsDesc',
icon: Zap,
},
};
export function SortDropdown({
value,
onChange,
className,
showProximity = false,
}: SortDropdownProps) {
const { t } = useTranslation();
const selectedOption = SORT_OPTIONS[value];
const Icon = selectedOption.icon;
// Determine which sort options to show based on content type
const availableOptions: SortOption[] = ['recent', 'trust'];
if (showProximity) {
availableOptions.push('proximity');
}
// Popular sorting available for all content types
availableOptions.push('popular');
// Zaps available for all content
availableOptions.push('zaps');
return (
<Select value={value} onValueChange={(v) => onChange(v as SortOption)}>
<SelectTrigger className={cn("w-[200px] gap-2", className)}>
<ArrowUpDown className="h-4 w-4 text-muted-foreground" />
<SelectValue>
<span className="flex items-center gap-2">
<Icon className="h-4 w-4" />
{t(selectedOption.labelKey)}
</span>
</SelectValue>
</SelectTrigger>
<SelectContent>
{availableOptions.map((option) => {
const opt = SORT_OPTIONS[option];
const OptionIcon = opt.icon;
return (
<SelectItem key={option} value={option}>
<div className="flex items-center gap-2 w-full">
<OptionIcon className="h-4 w-4 text-muted-foreground" />
<div className="flex-1">
<div className="font-medium">{t(opt.labelKey)}</div>
<div className="text-xs text-muted-foreground">{t(opt.descKey)}</div>
</div>
</div>
</SelectItem>
);
})}
</SelectContent>
</Select>
);
}