import { useSeoMeta } from '@unhead/react'; import { useParams, Link, useNavigate } from 'react-router-dom'; import { Layout } from '@/components/Layout'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Skeleton } from '@/components/ui/skeleton'; import { ZapButton } from '@/components/ZapButton'; import { TrustBadge } from '@/components/TrustBadge'; import { useLabProfile } from '@/hooks/useLabProfiles'; import { useAuthor } from '@/hooks/useAuthor'; import { genUserName } from '@/lib/genUserName'; import { COACH_SKILL_LABELS, COACH_SKILL_DESCRIPTIONS, FILMING_SERVICE_LABELS, FILMING_SERVICE_DESCRIPTIONS, FILMING_SKILL_LABELS, FILMING_SKILL_DESCRIPTIONS } from '@/lib/types'; import { sanitizeUrl, sanitizeTel, sanitizeEmail, urlDomain } from '@/lib/sanitizeUrl'; import { OfficialBadge } from '@/components/OfficialBadge'; import NotFound from './NotFound'; import { GraduationCap, MapPin, ArrowLeft, MessageCircle, Mail, Phone, Globe, Instagram, Calendar, Video, } from 'lucide-react'; import { nip19 } from 'nostr-tools'; function CoachDetailSkeleton() { return ( ); } export default function CoachDetailPage() { const { pubkey, identifier } = useParams<{ pubkey: string; identifier: string }>(); const { data: profile, isLoading, error } = useLabProfile(identifier || '', pubkey); const author = useAuthor(profile?.pubkey); const navigate = useNavigate(); const isCoach = profile?.profileType === 'coach'; const isFilmer = profile?.profileType === 'filmer'; useSeoMeta({ title: profile ? `${profile.title} - SkateSpots` : 'Profile - SkateSpots', description: profile?.bio || 'View profile.', }); const metadata = author.data?.metadata; const displayName = metadata?.name ?? genUserName(profile?.pubkey || ''); if (isLoading) { return ; } if (error || !profile) { return ; } const npub = nip19.npubEncode(profile.pubkey); // Get skill labels and descriptions based on profile type const getSkillLabel = (skill: string) => { if (isCoach) return COACH_SKILL_LABELS[skill] || skill; if (isFilmer) return FILMING_SERVICE_LABELS[skill] || FILMING_SKILL_LABELS[skill] || skill; return skill; }; const getSkillDescription = (skill: string) => { if (isCoach) return COACH_SKILL_DESCRIPTIONS[skill]; if (isFilmer) return FILMING_SERVICE_DESCRIPTIONS[skill] || FILMING_SKILL_DESCRIPTIONS[skill]; return undefined; }; return ( Back to The Lab {/* Main Content */} {/* Profile Card */} {profile.title.slice(0, 2).toUpperCase()} {profile.title} {isCoach && } {isFilmer && } Joined {new Date(profile.createdAt * 1000).toLocaleDateString()} {/* Bio */} {profile.bio && ( About {profile.bio} )} {/* Skills */} {profile.skills.length > 0 && ( {isCoach ? 'Skills' : 'Services & Skills'} {profile.skills.map((skill) => ( {getSkillLabel(skill)} {getSkillDescription(skill) && ( {getSkillDescription(skill)} )} ))} )} {/* Experience & Rate */} {profile.experience && ( Experience {profile.experience} years )} {profile.rate && ( Rate {profile.rate} )} {/* Sidebar */} {/* Contact Card */} Contact {/* Direct Message */} navigate(`/messages/${npub}`)} > Send Message {/* Contact Info from Profile */} {sanitizeTel(profile.phone) && ( {profile.phone} )} {sanitizeEmail(profile.email) && ( {profile.email} )} {sanitizeUrl(profile.website) && ( {urlDomain(profile.website!)} )} {isCoach && profile.instagram && ( @{profile.instagram.replace('@', '')} )} {isFilmer && sanitizeUrl(profile.social) && ( {urlDomain(profile.social!)} )} {/* Lightning Address from Nostr Profile */} {metadata?.lud16 && ( {metadata.lud16} )} {/* Zap Button */} {/* Location Card */} {profile.location && ( Location {profile.location} )} ); }
Joined {new Date(profile.createdAt * 1000).toLocaleDateString()}
{profile.bio}
{getSkillDescription(skill)}
{profile.experience} years
{profile.rate}
{profile.location}