···11export { homeLoader } from "./home";
22export { bbsLoader, type BBSLoaderData } from "./bbs";
33+export { profileLoader } from "./profile";
34export { boardLoader, hydrateThreadPage, type ThreadItem } from "./board";
45export { threadLoader, type ThreadObj } from "./thread";
56export { requireAuthLoader } from "./account";
67export type { InboxItem } from "../../lib/inbox";
78export type { PinnedBBS } from "../../lib/pins";
89export type { MyThread } from "../../lib/mythreads";
99-export {
1010- sysopEditLoader,
1111- sysopModerateLoader,
1212- type HiddenInfo,
1313-} from "./sysop";
1010+export { sysopEditLoader, sysopModerateLoader, type HiddenInfo } from "./sysop";
+21
web/src/router/loaders/profile.ts
···11+import type { LoaderFunctionArgs } from "react-router-dom";
22+import { fetchProfile, type Profile } from "../../lib/profile";
33+import { fetchMyThreads, type MyThread } from "../../lib/mythreads";
44+55+export async function profileLoader({ params }: LoaderFunctionArgs) {
66+ const handle = params.handle!;
77+ const profile = await fetchProfile(handle);
88+99+ let threads: Promise<MyThread[]> = Promise.resolve([]);
1010+ if (profile) {
1111+ threads = fetchMyThreads(profile.pdsUrl, profile.did);
1212+ }
1313+1414+ return { handle, profile, threads };
1515+}
1616+1717+export type ProfileLoaderData = {
1818+ handle: string;
1919+ profile: Profile | null;
2020+ threads: Promise<MyThread[]>;
2121+};
+8
web/src/router/routes.tsx
···1111import Home from "../pages/Home";
1212import Login from "../pages/Login";
1313import OAuthCallback from "../pages/OAuthCallback";
1414+import ProfilePage from "../pages/ProfilePage";
1415import BBS from "../pages/BBS";
1516import Board from "../pages/Board";
1617import Thread from "../pages/Thread";
···2425 homeLoader,
2526 bbsLoader,
2627 boardLoader,
2828+ profileLoader,
2729 threadLoader,
2830 requireAuthLoader,
2931 sysopEditLoader,
···8183 element: <News />,
8284 },
8385 ],
8686+ },
8787+ {
8888+ path: "/profile/:handle",
8989+ loader: profileLoader,
9090+ element: <ProfilePage />,
9191+ errorElement: <ErrorPage />,
8492 },
8593 { path: "*", element: <NotFound /> },
8694 ],