import { useEffect, useState } from "react"; import { useParams, Link, useNavigate } from "react-router-dom"; import EthosLayout from "@/components/ethos/EthosLayout"; import SEO from "@/components/SEO"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; // API Base URL for fetch requests const API_BASE = import.meta.env.VITE_API_BASE || ""; import { Star, Mail, Music, Zap, Clock } from "lucide-react"; import { resolveIdentifierToUserId, isUUID } from "@/lib/identifier-resolver"; interface Artist { user_id: string; skills: string[]; for_hire: boolean; bio?: string; portfolio_url?: string; sample_price_track?: number; sample_price_sfx?: number; sample_price_score?: number; turnaround_days?: number; verified: boolean; total_downloads: number; created_at: string; user_profiles: { id: string; full_name: string; avatar_url?: string; email?: string; }; tracks: Array<{ id: string; title: string; genre: string[]; download_count: number; }>; } export default function ArtistProfile() { const { userId: identifier } = useParams<{ userId: string }>(); const navigate = useNavigate(); const [artist, setArtist] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchArtist = async () => { if (!identifier) return; try { // Support both username and userId let resolvedUserId = identifier; if (!isUUID(identifier)) { // If not a UUID, try to resolve username to userId const userId = await resolveIdentifierToUserId(identifier); if (userId) { resolvedUserId = userId; } else { // If resolution failed and it's not a UUID, it's an invalid identifier setArtist(null); setLoading(false); return; } } const res = await fetch( `${API_BASE}/api/ethos/artists?id=${resolvedUserId}`, ); const data = await res.json(); setArtist(data); } catch (error) { console.error("Failed to fetch artist:", error); setArtist(null); } finally { setLoading(false); } }; fetchArtist(); }, [identifier]); if (loading) { return (
Loading artist profile...
); } if (!artist) { return (
Artist not found
); } const memberSince = new Date(artist.created_at).toLocaleDateString("en-US", { year: "numeric", month: "short", }); return ( <>
{/* Profile Header */}
{artist.user_profiles.full_name.charAt(0)}

{artist.user_profiles.full_name}

{artist.verified && ( ✓ Verified Artist )}
{artist.bio && (

{artist.bio}

)}

Total Downloads

{artist.total_downloads}

Tracks Published

{artist.tracks.length}

Member Since

{memberSince}

{artist.for_hire && ( )}
{/* Skills & Services */}
{artist.skills.length > 0 && ( Skills
{artist.skills.map((skill) => ( {skill} ))}
)} {artist.for_hire && ( Services {artist.sample_price_track && (
Custom Track ${artist.sample_price_track}
)} {artist.sample_price_sfx && (
SFX Pack ${artist.sample_price_sfx}
)} {artist.sample_price_score && (
Full Score ${artist.sample_price_score}
)} {artist.turnaround_days && (
{artist.turnaround_days} day turnaround
)}
)}
{/* Portfolio */}

Portfolio

{artist.tracks.length === 0 ? ( No tracks published yet ) : (
{artist.tracks.map((track) => (

{track.title}

{track.genre.map((g) => ( {g} ))}
{track.download_count} downloads
))}
)}
); }