Compare commits

..

2 Commits

7 changed files with 270 additions and 0 deletions

View File

@ -0,0 +1,75 @@
import ComponentsAuthForgotForm from '@/components/auth/components-auth-forgot-form';
import IconFacebookCircle from '@/components/icon/icon-facebook-circle';
import IconGoogle from '@/components/icon/icon-google';
import IconInstagram from '@/components/icon/icon-instagram';
import IconTwitter from '@/components/icon/icon-twitter';
import { Metadata } from 'next';
import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = {
title: 'Forgot Password',
};
export default function CoverForgotPassword() {
return (
<div>
<div className="absolute inset-0">
<img src="/assets/images/auth/bg-gradient.png" alt="image" className="h-full w-full object-cover" />
</div>
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.webp)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
<img src="/assets/images/auth/left.webp" alt="image" className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2" />
<img src="/assets/images/auth/top.webp" alt="image" className="absolute left-24 top-0 h-40 md:left-[30%]" />
<img src="/assets/images/auth/top-right.webp" alt="image" className="absolute right-0 top-0 h-[300px]" />
<img src="/assets/images/auth/bottom.webp" alt="image" className="absolute bottom-0 end-[28%]" />
<div className="relative flex w-full max-w-[1502px] flex-col justify-between overflow-hidden rounded-md bg-white/60 backdrop-blur-lg dark:bg-black/50 lg:min-h-[758px] lg:flex-row lg:gap-10 xl:gap-0">
<div className="relative hidden w-full items-center justify-center bg-[linear-gradient(225deg,#333333_35%,#325aa9_100%)] p-5 lg:inline-flex lg:max-w-[835px] xl:-ms-28 ltr:xl:skew-x-[14deg] rtl:xl:skew-x-[-14deg]">
<div className="absolute inset-y-0 w-8 from-primary/10 via-transparent to-transparent ltr:-right-10 ltr:bg-gradient-to-r rtl:-left-10 rtl:bg-gradient-to-l xl:w-16 ltr:xl:-right-20 rtl:xl:-left-20"></div>
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg]">
<Link href="/" className="ms-10 block w-48 lg:w-72">
<img src="/assets/images/white-logo.png" alt="Logo" className="w-full" />
</Link>
<div className="mt-24 hidden w-full max-w-[430px] lg:block">
<img src="/assets/images/auth/register.svg" alt="Cover Image" className="w-full" />
</div>
</div>
</div>
{/* Right side form */}
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-6 sm:px-6 lg:max-w-[667px]">
<div className="flex w-full max-w-[440px] items-center gap-2 lg:absolute lg:end-6 lg:top-6 lg:max-w-full">
<Link href="/" className="block w-8 lg:hidden">
<img src="/assets/images/logo.svg" alt="Logo" className="mx-auto w-10" />
</Link>
</div>
<div className="w-full max-w-[440px] lg:mt-16">
<div className="mb-10">
<h1 className="text-3xl font-extrabold uppercase !leading-snug text-primary md:text-4xl">
Forgot Password
</h1>
<p className="text-base font-bold leading-normal text-white-dark">
Enter your email to receive the reset link
</p>
</div>
{/* forgot form */}
<ComponentsAuthForgotForm />
<div className="text-center mt-8 dark:text-white">
Remember your password?&nbsp;
<Link href="/login" className="uppercase text-primary underline transition hover:text-black dark:hover:text-white">
SIGN IN
</Link>
</div>
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Metatroncube All Rights Reserved.
</p>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,76 @@
import ComponentsAuthForgotForm from '@/components/auth/components-auth-forgot-form';
import ResetPasswordForm from '@/components/auth/components-auth-reset-form';
import IconFacebookCircle from '@/components/icon/icon-facebook-circle';
import IconGoogle from '@/components/icon/icon-google';
import IconInstagram from '@/components/icon/icon-instagram';
import IconTwitter from '@/components/icon/icon-twitter';
import { Metadata } from 'next';
import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = {
title: 'Reset Password',
};
export default function CoverForgotPassword() {
return (
<div>
<div className="absolute inset-0">
<img src="/assets/images/auth/bg-gradient.png" alt="image" className="h-full w-full object-cover" />
</div>
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.webp)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
<img src="/assets/images/auth/left.webp" alt="image" className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2" />
<img src="/assets/images/auth/top.webp" alt="image" className="absolute left-24 top-0 h-40 md:left-[30%]" />
<img src="/assets/images/auth/top-right.webp" alt="image" className="absolute right-0 top-0 h-[300px]" />
<img src="/assets/images/auth/bottom.webp" alt="image" className="absolute bottom-0 end-[28%]" />
<div className="relative flex w-full max-w-[1502px] flex-col justify-between overflow-hidden rounded-md bg-white/60 backdrop-blur-lg dark:bg-black/50 lg:min-h-[758px] lg:flex-row lg:gap-10 xl:gap-0">
<div className="relative hidden w-full items-center justify-center bg-[linear-gradient(225deg,#333333_35%,#325aa9_100%)] p-5 lg:inline-flex lg:max-w-[835px] xl:-ms-28 ltr:xl:skew-x-[14deg] rtl:xl:skew-x-[-14deg]">
<div className="absolute inset-y-0 w-8 from-primary/10 via-transparent to-transparent ltr:-right-10 ltr:bg-gradient-to-r rtl:-left-10 rtl:bg-gradient-to-l xl:w-16 ltr:xl:-right-20 rtl:xl:-left-20"></div>
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg]">
<Link href="/" className="ms-10 block w-48 lg:w-72">
<img src="/assets/images/white-logo.png" alt="Logo" className="w-full" />
</Link>
<div className="mt-24 hidden w-full max-w-[430px] lg:block">
<img src="/assets/images/auth/register.svg" alt="Cover Image" className="w-full" />
</div>
</div>
</div>
{/* Right side form */}
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-6 sm:px-6 lg:max-w-[667px]">
<div className="flex w-full max-w-[440px] items-center gap-2 lg:absolute lg:end-6 lg:top-6 lg:max-w-full">
<Link href="/" className="block w-8 lg:hidden">
<img src="/assets/images/logo.svg" alt="Logo" className="mx-auto w-10" />
</Link>
</div>
<div className="w-full max-w-[440px] lg:mt-16">
<div className="mb-10">
<h1 className="text-3xl font-extrabold uppercase !leading-snug text-primary md:text-4xl">
Reset Password
</h1>
<p className="text-base font-bold leading-normal text-white-dark">
Enter the verification code you received and set your new password
</p>
</div>
{/* forgot form */}
<ResetPasswordForm />
<div className="text-center mt-8 dark:text-white">
Remember your password?&nbsp;
<Link href="/login" className="uppercase text-primary underline transition hover:text-black dark:hover:text-white">
SIGN IN
</Link>
</div>
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Metatroncube All Rights Reserved.
</p>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,51 @@
"use client";
import React, { useState } from "react";
import axios from "axios";
export default function ForgotPasswordForm() {
const [email, setEmail] = useState("");
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState("");
const handleForgot = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setMessage("");
try {
const res = await axios.post("http://localhost:3020/api/auth/forgot-password", { email });
setMessage("✅ Weve emailed you a reset code / link. Enter it below.");
} catch (err: any) {
console.error(err);
setMessage("Something went wrong. Try again.");
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleForgot} className="space-y-5">
<div>
<label className="block text-sm font-medium text-white-dark mb-1">
Email
</label>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="form-input w-full rounded-md border-white-light bg-transparent text-black dark:text-white"
placeholder="you@example.com"
/>
</div>
<button
type="submit"
disabled={loading}
className="btn btn-primary w-full uppercase font-bold"
>
{loading ? "Sending..." : "Send Reset Link"}
</button>
{message && <p className="mt-2 text-center text-sm font-semibold text-primary">{message}</p>}
</form>
);
}

View File

@ -0,0 +1,68 @@
"use client";
import React, { useState } from "react";
import axios from "axios";
import { useSearchParams } from "next/navigation";
export default function ResetPasswordForm() {
const searchParams = useSearchParams();
// ✅ token and email are read from the URL: /reset-password?email=...&token=...
const email = searchParams.get("email") || "";
const token = searchParams.get("token") || "";
const [newPassword, setNewPassword] = useState("");
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState("");
const handleReset = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setMessage("");
try {
await axios.post("http://localhost:3020/api/auth/reset-password", {
email,
token, // ✅ use token from URL
newPassword,
});
setMessage("✅ Your password has been successfully reset.");
} catch (err) {
console.error(err);
setMessage("❌ Reset failed. Check the link or try again.");
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleReset} className="space-y-5">
<div>
<label className="block text-sm font-medium text-white-dark mb-1">
New Password
</label>
<input
type="password"
required
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
className="form-input w-full rounded-md border-white-light bg-transparent text-black dark:text-white"
placeholder="********"
/>
</div>
<button
type="submit"
disabled={loading}
className="btn btn-primary w-full uppercase font-bold"
>
{loading ? "Resetting..." : "Reset Password"}
</button>
{message && (
<p className="mt-2 text-center text-sm font-semibold text-primary">
{message}
</p>
)}
</form>
);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB