import { Button, Form, InputGroup, Table } from "react-bootstrap"; import { useTranslation } from "react-i18next"; import { Form as RemixForm, Link, Outlet, useActionData, useRouteLoaderData, } from "@remix-run/react"; import { loader as settingsLoader } from "../settings/route"; import { loader as rootLoader } from "../../root"; import { DateTime } from "luxon"; import { defaultAvatarUrl, idTimestamp } from "~/lib/utils"; import { ExclamationTriangleFill, InfoCircleFill } from "react-bootstrap-icons"; import AvatarImage from "~/components/profile/AvatarImage"; import { ActionFunctionArgs, json } from "@remix-run/node"; import { type ApiError, ErrorCode, firstErrorFor } from "~/lib/api/error"; import serverRequest, { getToken } from "~/lib/request.server"; import { MeUser } from "~/lib/api/user"; import ErrorAlert from "~/components/ErrorAlert"; export const action = async ({ request }: ActionFunctionArgs) => { const data = await request.formData(); const username = data.get("username") as string | null; const token = getToken(request); if (!username) { return json({ error: { status: 403, code: ErrorCode.BadRequest, message: "Invalid username", } as ApiError, user: null, }); } try { const resp = await serverRequest("PATCH", "/users/@me", { body: { username }, token }); return json({ user: resp, error: null }); } catch (e) { return json({ error: e as ApiError, user: null }); } }; export default function SettingsIndex() { const { user } = useRouteLoaderData("routes/settings")!; const actionData = useActionData(); const { meta } = useRouteLoaderData("root")!; const { t } = useTranslation(); const createdAt = idTimestamp(user.id); return ( <>
{t("settings.general.username")}

{t("settings.general.username-change-hint")}

{actionData?.error && }

{t("settings.general.log-out-everywhere")}

{t("settings.general.log-out-everywhere-hint")}

{/* @ts-expect-error as=Link */}

{t("settings.general.table-header")}

{t("settings.general.id")} {user.id}
{t("settings.general.created")} {createdAt.toLocaleString(DateTime.DATETIME_MED)}
{t("settings.general.member-count")} {user.members.length}/{meta.limits.member_count}
{t("settings.general.member-list-hidden")} {user.member_list_hidden ? t("yes") : t("no")}
{t("settings.general.custom-preferences")} {Object.keys(user.custom_preferences).length}/{meta.limits.custom_preferences}
{t("settings.general.role")} {user.role}
); } function UsernameUpdateError({ error }: { error: ApiError }) { const { t } = useTranslation(); const usernameError = firstErrorFor(error, "username"); if (!usernameError) { return ; } return (

{" "} {t("settings.general.username-update-error", { message: usernameError.message })}

); }