Restore inline password form in SignInPage
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -1,15 +1,28 @@
|
|||||||
|
import { formatError, type GraphQLError } from "@probo/helpers";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import { Button } from "@probo/ui";
|
import { Button, Field, useToast } from "@probo/ui";
|
||||||
import { useLazyLoadQuery } from "react-relay";
|
import type { FormEventHandler } from "react";
|
||||||
import { Link, useLocation } from "react-router";
|
import { useLazyLoadQuery, useMutation } from "react-relay";
|
||||||
|
import { Link, matchPath, useLocation } from "react-router";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
|
|
||||||
|
import type { SignInPageMutation } from "#/__generated__/iam/SignInPageMutation.graphql";
|
||||||
import type { SignInPageQuery } from "#/__generated__/iam/SignInPageQuery.graphql";
|
import type { SignInPageQuery } from "#/__generated__/iam/SignInPageQuery.graphql";
|
||||||
import { useSafeContinueUrl } from "#/hooks/useSafeContinueUrl";
|
import { useSafeContinueUrl } from "#/hooks/useSafeContinueUrl";
|
||||||
|
|
||||||
import { Divider } from "./_components/Divider";
|
import { Divider } from "./_components/Divider";
|
||||||
import { OIDCButtons } from "./_components/OIDCButtons";
|
import { OIDCButtons } from "./_components/OIDCButtons";
|
||||||
|
|
||||||
|
const signInMutation = graphql`
|
||||||
|
mutation SignInPageMutation($input: SignInInput!) {
|
||||||
|
signIn(input: $input) {
|
||||||
|
session {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const signInPageQuery = graphql`
|
const signInPageQuery = graphql`
|
||||||
query SignInPageQuery {
|
query SignInPageQuery {
|
||||||
oidcProviders {
|
oidcProviders {
|
||||||
@@ -20,35 +33,113 @@ const signInPageQuery = graphql`
|
|||||||
|
|
||||||
export default function SignInPage() {
|
export default function SignInPage() {
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
|
const { toast } = useToast();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const safeContinueUrl = useSafeContinueUrl();
|
const safeContinueUrl = useSafeContinueUrl();
|
||||||
|
|
||||||
const data = useLazyLoadQuery<SignInPageQuery>(signInPageQuery, {});
|
const data = useLazyLoadQuery<SignInPageQuery>(signInPageQuery, {});
|
||||||
|
|
||||||
|
const [signIn, isSigningIn]
|
||||||
|
= useMutation<SignInPageMutation>(signInMutation);
|
||||||
|
|
||||||
|
const handleSubmit: FormEventHandler<HTMLFormElement> = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData(e.currentTarget);
|
||||||
|
const email = (formData.get("email") as string) ?? "";
|
||||||
|
const password = (formData.get("password") as string) ?? "";
|
||||||
|
|
||||||
|
if (!email || !password) return;
|
||||||
|
|
||||||
|
const match = matchPath(
|
||||||
|
{
|
||||||
|
path: "/organizations/:organizationId",
|
||||||
|
caseSensitive: false,
|
||||||
|
end: false,
|
||||||
|
},
|
||||||
|
safeContinueUrl.pathname,
|
||||||
|
);
|
||||||
|
|
||||||
|
signIn({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
organizationId: match?.params.organizationId ?? null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, error) => {
|
||||||
|
if (error) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(
|
||||||
|
__("Failed to sign in"),
|
||||||
|
error as GraphQLError,
|
||||||
|
),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = safeContinueUrl.href;
|
||||||
|
},
|
||||||
|
onError: (e) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: e.message,
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-sm mx-auto pt-8">
|
<div className="w-full max-w-sm mx-auto pt-8">
|
||||||
<h1 className="text-2xl font-bold">
|
<h1 className="text-2xl font-bold">
|
||||||
{__("Sign in to your account")}
|
{__("Sign in to your account")}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
<form className="mt-6 space-y-4" onSubmit={handleSubmit}>
|
||||||
|
<Field
|
||||||
|
required
|
||||||
|
name="email"
|
||||||
|
type="email"
|
||||||
|
label={__("Email")}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between mb-1">
|
||||||
|
<label className="text-sm font-medium" htmlFor="password">
|
||||||
|
{__("Password")}
|
||||||
|
</label>
|
||||||
|
<Link
|
||||||
|
to="/auth/forgot-password"
|
||||||
|
className="text-sm text-txt-secondary hover:text-txt-primary"
|
||||||
|
>
|
||||||
|
{__("Forgot your password?")}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<Field
|
||||||
|
required
|
||||||
|
name="password"
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button className="w-full h-10" disabled={isSigningIn}>
|
||||||
|
{isSigningIn ? __("Signing in...") : __("Sign in")}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div className="mt-6 space-y-4">
|
<div className="mt-6 space-y-4">
|
||||||
|
<Divider>{__("Or")}</Divider>
|
||||||
|
|
||||||
<OIDCButtons
|
<OIDCButtons
|
||||||
providers={data.oidcProviders}
|
providers={data.oidcProviders}
|
||||||
safeContinueUrl={safeContinueUrl}
|
safeContinueUrl={safeContinueUrl}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{data.oidcProviders.length > 0 && (
|
|
||||||
<Divider>{__("Or")}</Divider>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
className="w-full h-10"
|
|
||||||
to={{ pathname: "/auth/password-login", search: location.search }}
|
|
||||||
>
|
|
||||||
{__("Sign in with Email")}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="w-full h-10"
|
className="w-full h-10"
|
||||||
|
|||||||
Reference in New Issue
Block a user