import copy from "copy-to-clipboard"; import { ExternalLinkIcon, LayoutListIcon, type LucideIcon, MapIcon } from "lucide-react"; import { lazy, Suspense } from "react"; import { toast } from "react-hot-toast"; import { useParams, useSearchParams } from "react-router-dom"; import MemoView from "@/components/MemoView"; import PagedMemoList from "@/components/PagedMemoList"; import UserAvatar from "@/components/UserAvatar"; import { Button } from "@/components/ui/button"; import { useMemoFilters, useMemoSorting } from "@/hooks"; import { useUser } from "@/hooks/useUserQueries"; import { cn } from "@/lib/utils"; import { State } from "@/types/proto/api/v1/common_pb"; import { Memo } from "@/types/proto/api/v1/memo_service_pb"; import { useTranslate } from "@/utils/i18n"; type TabView = "memos" | "map"; const UserMemoMap = lazy(() => import("@/components/UserMemoMap")); const TabButton = ({ icon: Icon, label, isActive, onClick, }: { icon: LucideIcon; label: string; isActive: boolean; onClick: () => void; }) => ( ); interface User { name: string; username: string; displayName: string; avatarUrl?: string; description?: string; } const ProfileHeader = ({ user, onCopyProfileLink, shareLabel }: { user: User; onCopyProfileLink: () => void; shareLabel: string }) => (

{user.displayName || user.username}

{user.displayName &&

@{user.username}

}
{user.description &&

{user.description}

}
); const UserProfile = () => { const t = useTranslate(); const username = useParams().username; const [searchParams, setSearchParams] = useSearchParams(); const activeTab = (searchParams.get("view") === "map" ? "map" : "memos") as TabView; const { data: user, isLoading, error } = useUser(`users/${username}`, { enabled: !!username }); if (error && !isLoading) { toast.error(t("message.user-not-found")); } const memoFilter = useMemoFilters({ creatorName: user?.name, includeShortcuts: false, includePinned: true, }); const { listSort, orderBy } = useMemoSorting({ pinnedFirst: true, state: State.NORMAL, }); const handleCopyProfileLink = () => { if (!user) return; copy(`${window.location.origin}/u/${encodeURIComponent(user.username)}`); toast.success(t("message.copied")); }; const toggleTab = (view: TabView) => { setSearchParams((prev) => { view === "map" ? prev.set("view", "map") : prev.delete("view"); return prev; }); }; if (isLoading) return null; return (
{user ? ( <>
toggleTab("memos")} /> toggleTab("map")} />
{activeTab === "memos" ? ( ( )} listSort={listSort} orderBy={orderBy} filter={memoFilter} /> ) : (
}>
)}
) : (

{t("message.user-not-found")}

)}
); }; export default UserProfile;