remember last used idp in dashboard login form

This commit is contained in:
Fred KISSIE
2026-07-03 21:05:16 +02:00
parent 1bf3d2cdd6
commit bb4deb1ae9

View File

@@ -30,10 +30,7 @@ import Link from "next/link";
import { GenerateOidcUrlResponse } from "@server/routers/idp"; import { GenerateOidcUrlResponse } from "@server/routers/idp";
import { Separator } from "./ui/separator"; import { Separator } from "./ui/separator";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { import { generateOidcUrlProxy, loginProxy } from "@app/actions/server";
generateOidcUrlProxy,
loginProxy
} from "@app/actions/server";
import { redirect as redirectTo } from "next/navigation"; import { redirect as redirectTo } from "next/navigation";
import { useEnvContext } from "@app/hooks/useEnvContext"; import { useEnvContext } from "@app/hooks/useEnvContext";
import IdpTypeIcon from "@app/components/IdpTypeIcon"; import IdpTypeIcon from "@app/components/IdpTypeIcon";
@@ -41,6 +38,7 @@ import IdpTypeIcon from "@app/components/IdpTypeIcon";
import { loadReoScript } from "reodotdev"; import { loadReoScript } from "reodotdev";
import { build } from "@server/build"; import { build } from "@server/build";
import MfaInputForm from "@app/components/MfaInputForm"; import MfaInputForm from "@app/components/MfaInputForm";
import { useLocalStorage } from "@app/hooks/useLocalStorage";
export type LoginFormIDP = { export type LoginFormIDP = {
idpId: number; idpId: number;
@@ -105,7 +103,6 @@ export default function LoginForm({
} }
}, []); }, []);
const formSchema = z.object({ const formSchema = z.object({
email: z.string().email({ message: t("emailInvalid") }), email: z.string().email({ message: t("emailInvalid") }),
password: z.string().min(8, { message: t("passwordRequirementsChars") }) password: z.string().min(8, { message: t("passwordRequirementsChars") })
@@ -130,6 +127,10 @@ export default function LoginForm({
} }
}); });
const [lastUsedIdpId, setLastUsedIdpId] = useLocalStorage<string | null>(
"login:last-used-idp",
null
);
async function onSubmit(values: any) { async function onSubmit(values: any) {
const { email, password } = form.getValues(); const { email, password } = form.getValues();
@@ -179,8 +180,7 @@ export default function LoginForm({
if (data.useSecurityKey) { if (data.useSecurityKey) {
setError( setError(
t("securityKeyRequired", { t("securityKeyRequired", {
defaultValue: defaultValue: "Please use your security key to sign in."
"Please use your security key to sign in."
}) })
); );
return; return;
@@ -242,6 +242,8 @@ export default function LoginForm({
async function loginWithIdp(idpId: number) { async function loginWithIdp(idpId: number) {
let redirectUrl: string | undefined; let redirectUrl: string | undefined;
setLastUsedIdpId(idpId.toString());
try { try {
const data = await generateOidcUrlProxy( const data = await generateOidcUrlProxy(
idpId, idpId,
@@ -356,7 +358,6 @@ export default function LoginForm({
)} )}
<div className="space-y-4"> <div className="space-y-4">
{!mfaRequested && ( {!mfaRequested && (
<> <>
<SecurityKeyAuthButton <SecurityKeyAuthButton
@@ -385,25 +386,41 @@ export default function LoginForm({
idp.variant || idp.name.toLowerCase(); idp.variant || idp.name.toLowerCase();
return ( return (
<div
className="w-full relative"
key={idp.idpId}
>
<Button <Button
key={idp.idpId} key={idp.idpId}
type="button" type="button"
variant="outline" variant="outline"
className="w-full inline-flex items-center space-x-2" className="w-full inline-flex items-center space-x-2 after:absolute after:inset-0 after:z-10"
onClick={() => { onClick={() => {
loginWithIdp(idp.idpId); loginWithIdp(idp.idpId);
}} }}
> >
<IdpTypeIcon type={effectiveType} size={16} /> <IdpTypeIcon
type={effectiveType}
size={16}
/>
<span>{idp.name}</span> <span>{idp.name}</span>
</Button> </Button>
{lastUsedIdpId ===
idp.idpId.toString() && (
<div className="absolute inset-0">
<span className="absolute top-0 right-0 text-xs bg-primary text-primary-foreground rounded-bl-sm rounded-tr-sm px-2 py-0.5">
{t("idpLastUsed")}
</span>
</div>
)}
</div>
); );
})} })}
</> </>
)} )}
</> </>
)} )}
</div> </div>
</div> </div>
); );