core/apps/webapp/app/hooks/useUser.ts
Harshith Mullapudi bcc0560cf0
Feat: Space (#93)
* Feat: change space assignment from statement to episode

* feat: add default spaces and improve integration, space tools discovery in MCP

* feat: change spaces to episode based

* Feat: take multiple spaceIds while ingesting

* Feat: modify mcp tool descriptions, add spaceId in mcp url

* feat: add copy

* bump: new version 0.1.24

---------

Co-authored-by: Manoj <saimanoj58@gmail.com>
2025-10-09 12:38:42 +05:30

57 lines
1.5 KiB
TypeScript

import { type UIMatch } from "@remix-run/react";
import type { User } from "~/models/user.server";
import { type loader } from "~/root";
import { useChanged } from "./useChanged";
import { useTypedMatchesData } from "./useTypedMatchData";
export interface ExtendedUser extends User {
availableCredits: number;
totalCredits: number;
}
export function useIsImpersonating(matches?: UIMatch[]) {
const data = useTypedMatchesData({
id: "routes/_app.workspace.$workspaceSlug",
matches,
});
return data?.isImpersonating === true;
}
export function useOptionalUser(matches?: UIMatch[]): ExtendedUser | undefined {
const routeMatch = useTypedMatchesData<typeof loader>({
id: "root",
matches,
});
return routeMatch?.user
? {
...routeMatch?.user,
availableCredits: routeMatch?.availableCredits,
totalCredits: routeMatch?.totalCredits,
}
: undefined;
}
export function useUser(matches?: UIMatch[]): ExtendedUser {
const maybeUser = useOptionalUser(matches);
if (!maybeUser) {
throw new Error(
"No user found in root loader, but user is required by useUser. If user is optional, try useOptionalUser instead.",
);
}
return maybeUser;
}
export function useUserChanged(
callback: (user: ExtendedUser | undefined) => void,
) {
useChanged(useOptionalUser, callback);
}
export function useHasAdminAccess(matches?: UIMatch[]): boolean {
const user = useOptionalUser(matches);
const isImpersonating = useIsImpersonating(matches);
return Boolean(user?.admin) || isImpersonating;
}