import React, { useState, useEffect } from "react"; import { useParams } from "react-router-dom"; import { getUserTargetItems } from "../../api/client"; import type { AnnotationItem, UserProfile } from "../../types"; import Card from "../../components/common/Card"; import { PenTool, Highlighter, Search, AlertTriangle, ExternalLink, } from "lucide-react"; import { clsx } from "clsx"; import { getAvatarUrl } from "../../api/client"; export default function UserUrlPage() { const params = useParams(); const handle = params.handle; const urlPath = params["*"]; const targetUrl = urlPath || ""; const [profile, setProfile] = useState(null); const [annotations, setAnnotations] = useState([]); const [highlights, setHighlights] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState< "all" | "annotations" | "highlights" >("all"); useEffect(() => { async function fetchData() { if (!targetUrl || !handle) { setLoading(false); return; } try { setLoading(true); setError(null); const profileRes = await fetch( `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${encodeURIComponent(handle)}`, ); let did = handle; if (profileRes.ok) { const profileData = await profileRes.json(); setProfile(profileData); did = profileData.did; } const decodedUrl = decodeURIComponent(targetUrl); const data = await getUserTargetItems(did, decodedUrl); setAnnotations(data.annotations || []); setHighlights(data.highlights || []); } catch (err) { setError(err instanceof Error ? err.message : "Unknown error"); } finally { setLoading(false); } } fetchData(); }, [handle, targetUrl]); const displayName = profile?.displayName || profile?.handle || handle; const displayHandle = profile?.handle || (handle?.startsWith("did:") ? null : handle); const avatarUrl = getAvatarUrl(profile?.did, profile?.avatar); const getInitial = () => { return (displayName || displayHandle || "??") ?.substring(0, 2) .toUpperCase(); }; const totalItems = annotations.length + highlights.length; const bskyProfileUrl = displayHandle ? `https://bsky.app/profile/${displayHandle}` : `https://bsky.app/profile/${handle}`; const renderResults = () => { if (activeTab === "annotations" && annotations.length === 0) { return (

No annotations

); } if (activeTab === "highlights" && highlights.length === 0) { return (

No highlights

); } return (
{(activeTab === "all" || activeTab === "annotations") && annotations.map((a) => )} {(activeTab === "all" || activeTab === "highlights") && highlights.map((h) => )}
); }; if (!targetUrl) { return (

No URL specified

Please provide a URL to view annotations.

); } return (
{avatarUrl ? ( {displayName} ) : (
{getInitial()}
)}

{displayName}

{displayHandle && ( @{displayHandle} )}
{loading && (
)} {error && (

{error}

)} {!loading && !error && totalItems === 0 && (

No items found

{displayName} hasn't annotated this page yet.

)} {!loading && !error && totalItems > 0 && (

{totalItems} item{totalItems !== 1 ? "s" : ""}

{renderResults()}
)}
); }