sendou.ink/app/components/layout/LogInButtonContainer.tsx
Kalle 3925b73d32 Replace useIsMounted with useHydrated
Strict improvement because we avoid the flash on clientside navigation.
One practical bug was scroll restoration between tournament teams list
and user page. When user pressed back they ended up at the bottom
of the page because the placeholder (smaller height than actual
content) rendered. With useHydrated this placeholder is no longer
rendered for client side navigations.
2026-03-28 07:44:52 +02:00

58 lines
1.4 KiB
TypeScript

import { createPortal } from "react-dom";
import { useTranslation } from "react-i18next";
import { useSearchParams } from "react-router";
import { SendouDialog } from "~/components/elements/Dialog";
import { useHydrated } from "~/hooks/useHydrated";
import { LOG_IN_URL, SENDOU_INK_DISCORD_URL } from "~/utils/urls";
import styles from "./UserItem.module.css";
export function LogInButtonContainer({
children,
}: {
children: React.ReactNode;
}) {
const { t } = useTranslation();
const isHydrated = useHydrated();
const [searchParams] = useSearchParams();
const authError = searchParams.get("authError");
return (
<>
<form action={LOG_IN_URL} method="post" className="stack items-center">
{children}
</form>
{authError != null &&
isHydrated &&
createPortal(
<SendouDialog
isDismissable
onCloseTo="/"
heading={
authError === "aborted"
? t("auth.errors.aborted")
: t("auth.errors.failed")
}
>
<div className={`stack md ${styles.userItem}`}>
{authError === "aborted" ? (
t("auth.errors.discordPermissions")
) : (
<>
{t("auth.errors.unknown")}{" "}
<a
href={SENDOU_INK_DISCORD_URL}
target="_blank"
rel="noreferrer"
>
{SENDOU_INK_DISCORD_URL}
</a>
</>
)}
</div>
</SendouDialog>,
document.body,
)}
</>
);
}