"use client"; /** * /u/me shared layout — auth gate + Instagram-style profile shell. * * • Anonymous visitors trigger the global AuthModal and are bounced * home if they dismiss it (unchanged from before). * • Renders the ProfileHeader + ProfileTabs above every /u/me/* page. * Tabs: Posts / Collections / Bookmarks / Mentions. * * The old left ProfileSidebar is gone. The "Edit profile" affordance on * the header links out to the dedicated /settings/profile editor (which * lives outside this layout so it isn't framed by the header + tabs). */ import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { AtSign, Bookmark, EyeOff, FolderClosed, LayoutGrid, } from "lucide-react"; import { useAuth } from "@/components/auth/auth-provider"; import { useAuthGate } from "@/components/auth/auth-gate"; import { profile } from "@/lib/social"; import { ProfileHeader } from "@/components/profile/profile-header"; import { ProfileTabs, type ProfileTab } from "@/components/profile/profile-tabs"; export default function MeLayout({ children }: { children: React.ReactNode }) { const { user, loading } = useAuth(); const { requireAuth } = useAuthGate(); const router = useRouter(); useEffect(() => { if (loading || user) return; let cancelled = false; (async () => { const ok = await requireAuth(); if (!ok && !cancelled) router.replace("/"); })(); return () => { cancelled = true; }; }, [loading, user, requireAuth, router]); // Own profile counts (posts / followers / following) for the header // stat line. /auth/me doesn't carry these, so we read them from the // public profile endpoint (which returns no relationship for self). const [counts, setCounts] = useState<{ posts: number; followers: number; following: number; hidden: number; } | null>(null); const handle = user?.handle; useEffect(() => { if (!handle) return; let cancelled = false; profile .get(handle) .then((p) => { if (!cancelled) { setCounts({ posts: p.post_count, followers: p.follower_count, following: p.following_count, hidden: p.hidden_count ?? 0, }); } }) .catch(() => { /* counts are non-critical; leave the stat line minimal on error */ }); return () => { cancelled = true; }; }, [handle]); if (loading || !user) { return ( {loading ? "Loading…" : "Sign in to view your library."} ); } const tabs: ProfileTab[] = [ { href: "/u/me", label: "Posts", icon: , activeFor: ["/u/me/posts"], }, { href: "/u/me/collections", label: "Collections", icon: , }, { href: "/u/me/bookmarks", label: "Bookmarks", icon: , }, { href: "/u/me/mentions", label: "Mentions", icon: , }, ]; // Surface the "Hidden" tab only when the user actually has hidden posts. if ((counts?.hidden ?? 0) > 0) { tabs.push({ href: "/u/me/hidden", label: "Hidden", icon: , }); } return ( {children} ); }
{loading ? "Loading…" : "Sign in to view your library."}