mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-18 21:44:06 +01:00
feat: add email confirmation after signup
This commit is contained in:
parent
0e35ebf33d
commit
e1b6ba450c
43
src/app/verify/page.tsx
Normal file
43
src/app/verify/page.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { useSearchParams } from "next/navigation";
|
||||||
|
import { Mail } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
const VerifyPage = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const email = searchParams.get("email");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!email) {
|
||||||
|
router.push("/");
|
||||||
|
}
|
||||||
|
}, [email, router]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center min-h-screen bg-gray-100 dark:bg-gray-900">
|
||||||
|
<div className="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-lg max-w-md w-full">
|
||||||
|
<div className="flex justify-center mb-4">
|
||||||
|
<Mail className="text-blue-600 dark:text-blue-400 w-10 h-10" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-2xl font-semibold text-center text-blue-600 dark:text-blue-400 mb-4">Check Your Email</h2>
|
||||||
|
<p className="text-gray-600 dark:text-gray-300 text-center mb-4">
|
||||||
|
We have sent a verification link to <strong>{email}</strong>. Please check your inbox (and spam folder) to
|
||||||
|
confirm your email address.
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-center text-gray-500 dark:text-gray-400">
|
||||||
|
If you did not receive the email, click below to contact support.
|
||||||
|
</p>
|
||||||
|
<Link href="mailto:b2d.ventures.contact@gmail.com">
|
||||||
|
<Button className="w-full mt-4">Contact Support</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VerifyPage;
|
||||||
@ -33,6 +33,7 @@ export async function signup(formData: FormData) {
|
|||||||
password: formData.get("password") as string,
|
password: formData.get("password") as string,
|
||||||
options: {
|
options: {
|
||||||
captchaToken: formData.get("captchaToken") as string,
|
captchaToken: formData.get("captchaToken") as string,
|
||||||
|
emailRedirectTo: "http://localhost:3000/auth",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ export function SignupForm() {
|
|||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [confirmPassword, setConfirmPassword] = useState("");
|
const [confirmPassword, setConfirmPassword] = useState("");
|
||||||
const [captchaToken, setCaptchaToken] = useState<string | undefined>(undefined);
|
const [captchaToken, setCaptchaToken] = useState<string | undefined>(undefined);
|
||||||
|
const [isSendingForm, setIsSendingForm] = useState(false);
|
||||||
const captcha = useRef<HCaptcha | null>(null);
|
const captcha = useRef<HCaptcha | null>(null);
|
||||||
|
|
||||||
const handleSignup = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSignup = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
@ -42,13 +43,16 @@ export function SignupForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
setIsSendingForm(true);
|
||||||
await signup(formData);
|
await signup(formData);
|
||||||
captcha.current?.resetCaptcha();
|
captcha.current?.resetCaptcha();
|
||||||
toast.success("Account created successfully!");
|
toast.success("Account created successfully!");
|
||||||
router.push("/");
|
router.push(`/verify?email=${formData.get("email") as string}`);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
captcha.current?.resetCaptcha();
|
captcha.current?.resetCaptcha();
|
||||||
setError(error.message);
|
setError(error.message);
|
||||||
|
} finally {
|
||||||
|
setIsSendingForm(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,8 +90,8 @@ export function SignupForm() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{error && <p className="text-red-600">{error}</p>}
|
{error && <p className="text-red-600">{error}</p>}
|
||||||
<Button id="signup" type="submit">
|
<Button id="signup" type="submit" disabled={isSendingForm}>
|
||||||
Sign Up
|
{isSendingForm ? "Sending" : "Sign Up"}
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -14,6 +14,6 @@ export const config = {
|
|||||||
* - favicon.ico (favicon file)
|
* - favicon.ico (favicon file)
|
||||||
* Feel free to modify this pattern to include more paths.
|
* Feel free to modify this pattern to include more paths.
|
||||||
*/
|
*/
|
||||||
"/((?!_next/static|_next/image|$|favicon.ico|payment-success|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
"/((?!_next/static|_next/image|$|favicon.ico|payment-success|verify|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user