import { useState, useMemo } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Slider } from '@/components/ui/slider'; import { Card, CardContent } from '@/components/ui/card'; import { ScrollArea } from '@/components/ui/scroll-area'; import { useToast } from '@/hooks/useToast'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useSkateSpots } from '@/hooks/useSkateSpots'; import { useUserStatus, useSetUserStatus, useClearUserStatus, SKATING_STATUSES, type SkatingStatusId } from '@/hooks/useUserStatus'; import type { SkateSpot } from '@/lib/types'; import { cn } from '@/lib/utils'; import { Loader2, MapPin, Clock, X, Zap, Search } from 'lucide-react'; interface SetStatusDialogProps { open: boolean; onOpenChange: (open: boolean) => void; preselectedSpot?: SkateSpot; } export function SetStatusDialog({ open, onOpenChange, preselectedSpot, }: SetStatusDialogProps) { const { user } = useCurrentUser(); const { toast } = useToast(); const { data: currentStatus } = useUserStatus(user?.pubkey); const setStatus = useSetUserStatus(); const clearStatus = useClearUserStatus(); const [selectedStatusId, setSelectedStatusId] = useState(null); const [customStatus, setCustomStatus] = useState(''); const [linkedSpot, setLinkedSpot] = useState<{ pubkey: string; identifier: string; title?: string } | null>( preselectedSpot ? { pubkey: preselectedSpot.pubkey, identifier: preselectedSpot.identifier, title: preselectedSpot.title } : null ); const [expirationMinutes, setExpirationMinutes] = useState(60); // Default 1 hour const [showSpotPicker, setShowSpotPicker] = useState(false); const [spotSearchQuery, setSpotSearchQuery] = useState(''); // Get spots for picker const { data: allSpots } = useSkateSpots(100); const filteredSpots = useMemo(() => { if (!allSpots) return []; if (!spotSearchQuery) return allSpots.slice(0, 10); const query = spotSearchQuery.toLowerCase(); return allSpots .filter(s => s.title.toLowerCase().includes(query) || s.location?.toLowerCase().includes(query) ) .slice(0, 10); }, [allSpots, spotSearchQuery]); const handleSetStatus = async () => { try { await setStatus.mutateAsync({ statusId: selectedStatusId || undefined, customStatus: !selectedStatusId ? customStatus : undefined, linkedSpot: linkedSpot || undefined, expirationMinutes, }); toast({ title: 'Status updated!', description: 'Your skating status is now visible to others.', }); onOpenChange(false); // Reset form setSelectedStatusId(null); setCustomStatus(''); if (!preselectedSpot) setLinkedSpot(null); } catch (error) { toast({ title: 'Failed to set status', description: error instanceof Error ? error.message : 'Something went wrong', variant: 'destructive', }); } }; const handleClearStatus = async () => { try { await clearStatus.mutateAsync(); toast({ title: 'Status cleared', description: 'Your status has been removed.', }); onOpenChange(false); } catch (error) { toast({ title: 'Failed to clear status', description: error instanceof Error ? error.message : 'Something went wrong', variant: 'destructive', }); } }; const handleSpotSelected = (spot: SkateSpot) => { setLinkedSpot({ pubkey: spot.pubkey, identifier: spot.identifier, title: spot.title }); setShowSpotPicker(false); setSpotSearchQuery(''); }; const formatExpiration = (minutes: number) => { if (minutes < 60) return `${minutes} min`; if (minutes === 60) return '1 hour'; if (minutes < 1440) return `${Math.round(minutes / 60)} hours`; return `${Math.round(minutes / 1440)} day${minutes >= 2880 ? 's' : ''}`; }; if (!user) return null; return ( Set Your Status Let others know what you're up to. Your status will be visible on your profile and at linked spots.
{/* Current Status */} {currentStatus && (
{currentStatus.emoji} {currentStatus.status}
)} {/* Quick Status Options */}
{SKATING_STATUSES.map((status) => ( { setSelectedStatusId(status.id); setCustomStatus(''); }} > {status.emoji}

{status.label}

{selectedStatusId === status.id && (
✓
)}
))}
{/* Custom Status */}
{ setCustomStatus(e.target.value); setSelectedStatusId(null); }} className="bg-black border-gray-700" />
{/* Link to Spot */}
{linkedSpot ? (
{linkedSpot.title || 'Spot selected'}
) : showSpotPicker ? (
setSpotSearchQuery(e.target.value)} className="bg-gray-800 border-gray-700 pl-9 h-9" autoFocus />
{filteredSpots.map((spot) => ( ))} {filteredSpots.length === 0 && (

No spots found.

)}
) : ( )}
{/* Auto-clear Timer */}
setExpirationMinutes(value)} min={15} max={1440} step={15} className="w-full" />
15 min 1 hr 4 hrs 24 hrs
{/* Submit Button */}
); }