78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
/**
|
|
* Renders a profile's "manage" tab, `/@name/manage`, where those who hold
|
|
* `user:manage` change another user's role and name. The site's own tools are
|
|
* the `/manage` page's.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import { Trans } from "@lingui/react/macro";
|
|
import { userApiUrl } from "../../utils/shared/urls.ts";
|
|
import type { Wire } from "../../../shared/api.ts";
|
|
import type { PublicUser } from "../../../shared/user.ts";
|
|
import { expectOk } from "../../utils/shared/api.ts";
|
|
import { deserializePublicUser } from "../../utils/shared/deserialize.ts";
|
|
import { useAuth } from "../../hooks/auth/useAuth.ts";
|
|
import { homeHost } from "../../utils/auth/home.ts";
|
|
import { ProfileSection } from "./ProfileSection.tsx";
|
|
import { RoleSwitcher } from "./RoleSwitcher.tsx";
|
|
import { SettingRow } from "./SettingRow.tsx";
|
|
import { UsernameField } from "./UsernameField.tsx";
|
|
|
|
/**
|
|
* Passed to {@link ProfileManageTab} by `UserPublicProfile`, which shows the
|
|
* tab on another user's profile to those who hold `user:manage`.
|
|
*/
|
|
export interface ProfileManageTabProps {
|
|
user: PublicUser;
|
|
/** Called with the user as the server left them. */
|
|
onUserSaved: (user: PublicUser) => void;
|
|
}
|
|
|
|
/**
|
|
* Renders the user's role and name. A rename here has no rate limit, and the
|
|
* profile's URL then takes the new name. A user from another instance is
|
|
* named there, so their name is only shown.
|
|
*/
|
|
export function ProfileManageTab(
|
|
{ user, onUserSaved }: ProfileManageTabProps,
|
|
): React.JSX.Element {
|
|
const { authFetch } = useAuth();
|
|
|
|
async function rename(username: string): Promise<string> {
|
|
const renamed = deserializePublicUser(
|
|
await expectOk<Wire<PublicUser>>(
|
|
await authFetch(userApiUrl(user, "username"), {
|
|
method: "PATCH",
|
|
body: JSON.stringify({ username }),
|
|
}),
|
|
),
|
|
);
|
|
onUserSaved(renamed);
|
|
return renamed.username;
|
|
}
|
|
|
|
return (
|
|
<ProfileSection title={<Trans>User management</Trans>}>
|
|
<div className="profile-appearance-grid">
|
|
<RoleSwitcher
|
|
userId={user.id}
|
|
currentRole={user.role}
|
|
onSaved={(role) => onUserSaved({ ...user, role })}
|
|
/>
|
|
<SettingRow label={<Trans>Username</Trans>}>
|
|
{homeHost(user.username)
|
|
? <span className="profile-appearance-value">{user.username}</span>
|
|
: (
|
|
<UsernameField
|
|
key={user.username}
|
|
username={user.username}
|
|
save={rename}
|
|
/>
|
|
)}
|
|
</SettingRow>
|
|
</div>
|
|
</ProfileSection>
|
|
);
|
|
}
|