import { useEffect, useRef, useState } from "react"; import { useNavigate, useParams, Link } from "react-router-dom"; import Layout from "@/components/Layout"; import LoadingScreen from "@/components/LoadingScreen"; import PassportSummary from "@/components/passport/PassportSummary"; // API Base URL for fetch requests const API_BASE = import.meta.env.VITE_API_BASE || ""; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { aethexUserService, aethexAchievementService, aethexProjectService, type AethexUserProfile, type AethexAchievement, } from "@/lib/aethex-database-adapter"; import { useAuth } from "@/contexts/AuthContext"; import FourOhFourPage from "@/pages/404"; import { Clock, Rocket, Target, ExternalLink, Award, Music, Copy, CheckCircle2, } from "lucide-react"; import { aethexSocialService } from "@/lib/aethex-social-service"; interface ProjectPreview { id: string; title: string; status: string; description?: string | null; created_at?: string; } const formatDate = (value?: string | null) => { if (!value) return "Recent"; const date = new Date(value); if (Number.isNaN(date.getTime())) return "Recent"; return new Intl.DateTimeFormat(undefined, { dateStyle: "medium", }).format(date); }; const isUuid = (value: string) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test( value, ); const ProfilePassport = () => { const params = useParams<{ username?: string }>(); const navigate = useNavigate(); const { user, linkedProviders, profile: authProfile } = useAuth(); const requestedUsername = params.username?.trim(); const isSelfRoute = !requestedUsername || requestedUsername === "me"; const [profile, setProfile] = useState< (AethexUserProfile & { email?: string | null }) | null >(null); const [achievements, setAchievements] = useState([]); const [followStats, setFollowStats] = useState<{ followers: number; following: number; }>({ followers: 0, following: 0 }); const [degree, setDegree] = useState(""); const [projects, setProjects] = useState([]); const [interests, setInterests] = useState([]); const [loading, setLoading] = useState(true); const [notFound, setNotFound] = useState(false); const [ethosTracks, setEthosTracks] = useState([]); const [ethosProfile, setEthosProfile] = useState(null); const [creatorProfile, setCreatorProfile] = useState(null); const [profileLinkCopied, setProfileLinkCopied] = useState(false); const lastLoadedKeyRef = useRef(null); const activationAttemptedRef = useRef(false); useEffect(() => { if (isSelfRoute && !user) { setLoading(false); setNotFound(false); navigate("/login"); return; } const normalizedUsername = requestedUsername?.toLowerCase() ?? null; const targetKey = isSelfRoute ? user?.id ? `id:${user.id}` : authProfile?.username ? `username:${authProfile.username.toLowerCase()}` : "self" : normalizedUsername ? `username:${normalizedUsername}` : null; if (targetKey && lastLoadedKeyRef.current === targetKey) { setLoading(false); setNotFound(false); return; } if (targetKey && lastLoadedKeyRef.current !== targetKey) { activationAttemptedRef.current = false; } let cancelled = false; if (!targetKey || lastLoadedKeyRef.current !== targetKey) { setLoading(true); } const loadPassport = async () => { try { let resolvedProfile: | (AethexUserProfile & { email?: string | null }) | null = null; let resolvedId: string | null = null; if (isSelfRoute) { const currentUser = await aethexUserService.getCurrentUser(); if (currentUser?.username) { if (!requestedUsername || requestedUsername === "me") { navigate(`/passport/${currentUser.username}`, { replace: true }); return; } if ( normalizedUsername && currentUser.username.toLowerCase() === normalizedUsername && currentUser.username !== requestedUsername ) { navigate(`/passport/${currentUser.username}`, { replace: true }); return; } } if (currentUser) { resolvedProfile = { ...currentUser, email: (currentUser as any)?.email ?? user?.email ?? authProfile?.email ?? null, } as AethexUserProfile & { email?: string | null }; resolvedId = currentUser.id ?? user?.id ?? null; } } else if (requestedUsername) { const fetchedProfile = (await aethexUserService.getProfileByUsername(requestedUsername)) ?? (isUuid(requestedUsername) ? await aethexUserService.getProfileById(requestedUsername) : null); if ( fetchedProfile?.username && fetchedProfile.username.toLowerCase() === normalizedUsername && fetchedProfile.username !== requestedUsername ) { navigate(`/passport/${fetchedProfile.username}`, { replace: true }); return; } if (fetchedProfile) { resolvedProfile = { ...fetchedProfile, email: (fetchedProfile as any)?.email ?? null, } as AethexUserProfile & { email?: string | null }; resolvedId = fetchedProfile.id ?? null; } } if (!resolvedProfile || !resolvedId) { if (!cancelled) { setProfile(null); setAchievements([]); setInterests([]); setProjects([]); setNotFound(true); lastLoadedKeyRef.current = null; } return; } if ( resolvedProfile.username && resolvedProfile.username.toLowerCase() === "mrpiglr" ) { if (!activationAttemptedRef.current) { activationAttemptedRef.current = true; try { await aethexAchievementService.activateCommunityRewards({ email: resolvedProfile.email ?? user?.email ?? authProfile?.email ?? undefined, username: resolvedProfile.username, }); const refreshedProfile = (await aethexUserService.getProfileByUsername( resolvedProfile.username, )) ?? (resolvedId ? await aethexUserService.getProfileById(resolvedId) : null); if (refreshedProfile) { resolvedProfile = { ...refreshedProfile, email: (refreshedProfile as any)?.email ?? resolvedProfile.email ?? null, } as AethexUserProfile & { email?: string | null }; resolvedId = refreshedProfile.id ?? resolvedId; } } catch { activationAttemptedRef.current = false; } } } else { activationAttemptedRef.current = false; } const viewingSelf = isSelfRoute || (!!user?.id && resolvedId === user.id) || (!!authProfile?.username && !!resolvedProfile.username && authProfile.username.toLowerCase() === resolvedProfile.username.toLowerCase()); const [achievementList, interestList, projectList, ethos, creator] = await Promise.all([ aethexAchievementService .getUserAchievements(resolvedId) .catch(() => [] as AethexAchievement[]), aethexUserService .getUserInterests(resolvedId) .catch(() => [] as string[]), aethexProjectService .getUserProjects(resolvedId) .catch(() => [] as ProjectPreview[]), fetch(`${API_BASE}/api/ethos/artists?id=${resolvedId}`) .then((res) => (res.ok ? res.json() : { tracks: [] })) .catch(() => ({ tracks: [] })), fetch(`${API_BASE}/api/creators/user/${resolvedId}`) .then((res) => (res.ok ? res.json() : null)) .catch(() => null), ]); if (cancelled) { return; } setProfile({ ...resolvedProfile, email: resolvedProfile.email ?? (viewingSelf ? (user?.email ?? authProfile?.email ?? null) : null), }); setAchievements(achievementList ?? []); setInterests(interestList ?? []); setProjects( (projectList ?? []).slice(0, 4).map((project: any) => ({ id: project.id, title: project.title, status: project.status, description: project.description, created_at: project.created_at, })), ); // Set Ethos Guild data if user is an artist if (ethos && ethos.tracks) { setEthosTracks(ethos.tracks || []); setEthosProfile({ verified: ethos.verified, skills: ethos.skills, bio: ethos.bio, for_hire: ethos.for_hire, }); } // Set creator profile data if (creator) { setCreatorProfile(creator); } setNotFound(false); try { const [followingIds, followerIds] = await Promise.all([ aethexSocialService.getFollowing(resolvedId), aethexSocialService.getFollowers(resolvedId), ]); if (!cancelled) setFollowStats({ following: followingIds.length, followers: followerIds.length, }); } catch {} try { const me = user?.id || null; if (me && resolvedId && me !== resolvedId) { const myConns = await aethexSocialService.getConnections(me); const first = new Set(myConns.map((c: any) => c.connection_id)); if (first.has(resolvedId)) setDegree("1st"); else { const secondLists = await Promise.all( Array.from(first) .slice(0, 50) .map((id) => aethexSocialService.getConnections(id)), ); const second = new Set( secondLists.flat().map((c: any) => c.connection_id), ); setDegree(second.has(resolvedId) ? "2nd" : "3rd+"); } } else if (me && resolvedId && me === resolvedId) { setDegree("1st"); } else { setDegree(""); } } catch {} lastLoadedKeyRef.current = targetKey ?? (resolvedProfile.username ? `username:${resolvedProfile.username.toLowerCase()}` : resolvedId ? `id:${resolvedId}` : null); } catch { if (!cancelled) { lastLoadedKeyRef.current = null; setProfile(null); setAchievements([]); setInterests([]); setProjects([]); setNotFound(true); } } finally { if (!cancelled) { setLoading(false); } } }; loadPassport(); return () => { cancelled = true; }; }, [ authProfile?.email, authProfile?.username, isSelfRoute, navigate, requestedUsername, user?.email, user?.id, ]); const isSelf = Boolean( profile && ((user?.id && profile.id && user.id === profile.id) || (authProfile?.username && profile.username && authProfile.username.toLowerCase() === profile.username.toLowerCase())), ); const profileUrl = profile?.username ? `https://${profile.username}.aethex.me` : ""; const copyProfileLink = () => { if (profileUrl) { navigator.clipboard.writeText(profileUrl); setProfileLinkCopied(true); setTimeout(() => setProfileLinkCopied(false), 2000); } }; if (loading) { return ; } if (notFound || !profile) { return ; } const passportInterests = interests.length ? interests : ((profile as any)?.interests as string[]) || []; return (
{ethosProfile && (

Ethos Guild

Audio production portfolio & services.

{isSelf && ( )}
{/* Artist Info */}
{ethosProfile.verified && ( ✓ Verified Artist )} {ethosProfile.for_hire && ( Available for hire )}
{ethosProfile.skills && ethosProfile.skills.length > 0 && (

Skills

{ethosProfile.skills .slice(0, 5) .map((skill: string) => ( {skill} ))} {ethosProfile.skills.length > 5 && ( +{ethosProfile.skills.length - 5} more )}
)}
{/* Tracks */} {ethosTracks.length > 0 && (

Published Tracks ({ethosTracks.length})

{ethosTracks.slice(0, 5).map((track: any) => (

{track.title}

{track.genre && track.genre.slice(0, 2).map((g: string) => ( {g} ))}
))}
)}
)} {projects.length > 0 && (

Highlighted missions

A snapshot of what this creator has shipped inside AeThex.

{isSelf && ( )}
{projects.map((project) => (
{project.title} {project.description || "AeThex project"}
{project.status?.replace("_", " ") ?? "active"}
{" "} {formatDate(project.created_at)}
))}
)}

Achievements

Passport stamps earned across AeThex experiences.

{isSelf && ( {achievements.length}{" "} badges )}
{achievements.length === 0 ? ( No achievements yet. Complete onboarding and participate in missions to earn AeThex badges. ) : (
{achievements.map((achievement) => (
{((): string => { const key = String( achievement.icon || achievement.name || "", ).toLowerCase(); if (/founding|founder/.test(key)) return "🎖️"; if (/trophy|award|medal|badge/.test(key)) return "🏆"; if (/welcome/.test(key)) return "🎉"; if (/star/.test(key)) return "⭐"; if (/rocket|launch/.test(key)) return "🚀"; return typeof achievement.icon === "string" && achievement.icon.length <= 3 ? (achievement.icon as string) : "🏅"; })()}

{achievement.name}

{achievement.description || "AeThex honor"}

XP Reward • {achievement.xp_reward ?? 0} Passport stamped
))}
)}

Stay connected

Reach out, collaborate, and shape the next AeThex release together.

{isSelf ? ( ) : profile.email ? ( ) : ( )}
{profileUrl && (
Profile link: {profileUrl}
)} {(profile.arm_affiliations as string[])?.length > 0 && (

Arm Affiliations

{(profile.arm_affiliations as string[]).map((arm: string) => { const armConfig: Record< string, { label: string; color: string } > = { foundation: { label: "Foundation", color: "bg-red-500/20 text-red-200 border-red-500/40", }, gameforge: { label: "GameForge", color: "bg-green-500/20 text-green-200 border-green-500/40", }, labs: { label: "Labs", color: "bg-yellow-500/20 text-yellow-200 border-yellow-500/40", }, corp: { label: "Corp", color: "bg-blue-500/20 text-blue-200 border-blue-500/40", }, devlink: { label: "Dev-Link", color: "bg-cyan-500/20 text-cyan-200 border-cyan-500/40", }, }; const config = armConfig[arm] || { label: arm, color: "bg-slate-500/20 text-slate-200 border-slate-500/40", }; return ( {config.label} ); })}
)}
Followers: {followStats.followers} Following: {followStats.following} {degree && ( {degree} degree )} {profile.github_url && ( )} {profile.linkedin_url && ( )} {profile.twitter_url && ( )} {profile.website_url && ( )} {creatorProfile?.spotify_profile_url && ( )} {profile.bio && ( {profile.bio} )}
); }; export default ProfilePassport;