diff --git a/src/app/(auth)/reset-password/page.tsx b/src/app/(auth)/reset-password/page.tsx index 90d139f..12febd6 100644 --- a/src/app/(auth)/reset-password/page.tsx +++ b/src/app/(auth)/reset-password/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { Suspense, useState } from "react"; import { useSignIn } from "@clerk/nextjs"; import { useRouter, useSearchParams } from "next/navigation"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -11,26 +11,11 @@ import { Label } from "@/components/ui/label"; /** * Reset password page — /reset-password * - * Completes Clerk's password reset flow using the Clerk 7 SignInFutureResource API: - * 1. signIn.resetPasswordEmailCode.verifyCode({ code }) — verify the emailed code - * 2. signIn.resetPasswordEmailCode.submitPassword({ password }) — set new password - * 3. signIn.finalize() — create the session and redirect - * - * The reset code comes from the Clerk-generated email link URL params. - * - * UI-SPEC: Auth Screens — Reset Password - * Heading: "Set a new password" - * CTA: "Reset password" - * Error states: - * - "Password must be at least 8 characters." - * - "Passwords don't match." - * - * Deviation note: Clerk 7 uses the new SignInFutureResource API. The old - * useSignIn().attemptFirstFactor() is replaced by resetPasswordEmailCode.verifyCode() - * + resetPasswordEmailCode.submitPassword() + finalize(). + * useSearchParams() must be inside a Suspense boundary for static rendering. + * ResetPasswordContent is the real component; default export wraps it in Suspense. */ -export default function ResetPasswordPage() { - // Clerk 7: useSignIn returns { errors, fetchStatus, signIn: SignInFutureResource } + +function ResetPasswordContent() { const { signIn, fetchStatus } = useSignIn(); const router = useRouter(); const searchParams = useSearchParams(); @@ -43,10 +28,8 @@ export default function ResetPasswordPage() { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - setError(null); - // Client-side validation per UI-SPEC Error States if (password.length < 8) { setError("Password must be at least 8 characters."); return; @@ -57,13 +40,11 @@ export default function ResetPasswordPage() { } try { - // Clerk appends the code to the URL when the user clicks the email reset link const code = searchParams.get("__clerk_ticket") ?? searchParams.get("code") ?? ""; - // Step 1: verify the reset code from the email const verifyResult = await signIn.resetPasswordEmailCode.verifyCode({ code }); if (verifyResult.error) { setError( @@ -73,19 +54,12 @@ export default function ResetPasswordPage() { return; } - // Step 2: submit the new password - const submitResult = await signIn.resetPasswordEmailCode.submitPassword({ - password, - }); + const submitResult = await signIn.resetPasswordEmailCode.submitPassword({ password }); if (submitResult.error) { - setError( - submitResult.error.message ?? - "Could not set new password. Please try again." - ); + setError(submitResult.error.message ?? "Could not set new password. Please try again."); return; } - // Step 3: finalize the session const finalizeResult = await signIn.finalize(); if (finalizeResult.error) { setError( @@ -98,19 +72,14 @@ export default function ResetPasswordPage() { router.push("/pets"); } catch (err: unknown) { const clerkError = err as { errors?: Array<{ message: string }> }; - setError( - clerkError.errors?.[0]?.message ?? - "Something went wrong. Please try again." - ); + setError(clerkError.errors?.[0]?.message ?? "Something went wrong. Please try again."); } }; return ( - - Set a new password - + Set a new password
@@ -157,3 +126,11 @@ export default function ResetPasswordPage() { ); } + +export default function ResetPasswordPage() { + return ( + + + + ); +}