60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useState, type CSSProperties, type FC, type ReactNode } from "react";
|
|
import { AuthCard, ResetPasswordForm, type ResetPasswordValues } from "@crema/auth-ui";
|
|
import { ArcadiaError, useArcadiaClient } from "@crema/arcadia-client";
|
|
|
|
export interface PasswordResetConfirmFormProps {
|
|
/** Token from the reset email URL. */
|
|
token: string;
|
|
/** Where to POST. Defaults to "/api/v1/password-reset/confirm". */
|
|
confirmPath?: string;
|
|
onSuccess: () => void | Promise<void>;
|
|
brand?: ReactNode;
|
|
heading?: string;
|
|
subhead?: ReactNode;
|
|
style?: CSSProperties;
|
|
}
|
|
|
|
export const PasswordResetConfirmForm: FC<PasswordResetConfirmFormProps> = ({
|
|
token,
|
|
confirmPath = "/api/v1/password-reset/confirm",
|
|
onSuccess,
|
|
brand,
|
|
heading = "Set a new password",
|
|
subhead,
|
|
style,
|
|
}) => {
|
|
const arcadia = useArcadiaClient();
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
async function handleSubmit({ password }: ResetPasswordValues) {
|
|
setError(null);
|
|
try {
|
|
await arcadia.POST(confirmPath, { body: { token, password } });
|
|
await onSuccess();
|
|
} catch (err) {
|
|
if (err instanceof ArcadiaError) setError(err.message);
|
|
else setError("Something went wrong. Please try again.");
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<AuthCard logo={brand} title={heading} description={subhead}>
|
|
<div data-action="auth-pwreset-confirm" style={style}>
|
|
<ResetPasswordForm onSubmit={handleSubmit} />
|
|
{error ? (
|
|
<div
|
|
role="alert"
|
|
className="mt-3 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive"
|
|
data-action="auth-pwreset-confirm-error"
|
|
>
|
|
{error}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
</AuthCard>
|
|
);
|
|
};
|