Go-live: live data wiring, auth callback, SEO, legal pages, UI fixes
This commit is contained in:
80
src/components/SpotDetailSheet.tsx
Normal file
80
src/components/SpotDetailSheet.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
'use client';
|
||||
|
||||
import { MapPin, MessageCircle, Star, Users, X } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import type { CruisingSpot } from '@/types';
|
||||
import Link from 'next/link';
|
||||
|
||||
const CATEGORY_LABELS: Record<string, string> = {
|
||||
park: 'Park',
|
||||
beach: 'Beach',
|
||||
gym: 'Gym',
|
||||
restroom: 'Restroom',
|
||||
bookstore: 'Bookstore',
|
||||
club: 'Club',
|
||||
other: 'Other',
|
||||
};
|
||||
|
||||
interface SpotDetailSheetProps {
|
||||
spot: CruisingSpot | null;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function SpotDetailSheet({ spot, open, onClose }: SpotDetailSheetProps) {
|
||||
if (!spot || !open) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute bottom-24 left-3 right-3 z-[1001] md:left-auto md:right-6 md:max-w-sm">
|
||||
<div className="rounded-2xl border border-primary/25 bg-pulse-midnight/98 backdrop-blur-md shadow-pulse-card p-4 space-y-3">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div>
|
||||
<h3 className="font-bold text-white">{spot.name}</h3>
|
||||
<div className="flex flex-wrap gap-1.5 mt-1">
|
||||
<Badge variant="outline" className="text-[10px]">
|
||||
{CATEGORY_LABELS[spot.category] ?? spot.category}
|
||||
</Badge>
|
||||
{spot.is_popular && (
|
||||
<Badge className="text-[10px] bg-primary/20 text-pulse-pink-light">Popular</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className="p-1 text-white/60 hover:text-white"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
{spot.description && (
|
||||
<p className="text-xs text-white/75 leading-relaxed">{spot.description}</p>
|
||||
)}
|
||||
<div className="flex flex-wrap gap-3 text-[10px] text-white/60">
|
||||
<span className="flex items-center gap-1">
|
||||
<MapPin className="h-3 w-3" />
|
||||
{spot.city}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Star className="h-3 w-3 text-yellow-400" />
|
||||
{spot.rating}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Users className="h-3 w-3 text-emerald-400" />
|
||||
{spot.active_count} active
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="horny" size="sm" className="flex-1 gap-1" asChild>
|
||||
<Link href={`/chat?spot=${spot.id}&room=${encodeURIComponent(spot.name)}`}>
|
||||
<MessageCircle className="h-3.5 w-3.5" />
|
||||
Spot Chat
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user