implement authentication system with login, signup, and user module components and layout structure
This commit is contained in:
parent
350e632db6
commit
1e01ea3568
@ -86,16 +86,7 @@ const CoverLogin = () => {
|
||||
<ComponentsAuthLoginForm />
|
||||
|
||||
|
||||
{/* Sign-up link */}
|
||||
<div className="text-center dark:text-white">
|
||||
Don't have an account?
|
||||
<Link
|
||||
href="/signup"
|
||||
className="uppercase text-primary underline transition hover:text-black dark:hover:text-white"
|
||||
>
|
||||
SIGN UP
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
const AUTH_API_BASE = process.env.AUTH_API_BASE ?? 'https://ebay.backend.vgproducts.com';
|
||||
const AUTH_API_BASE = process.env.AUTH_API_BASE ?? 'http://localhost:3050';
|
||||
const SESSION_MAX_AGE_S = 30 * 60; // 30 minutes in seconds
|
||||
|
||||
// Utility to extract userId from a nested object
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
const AUTH_API_BASE = process.env.AUTH_API_BASE ?? 'https://ebay.backend.vgproducts.com';
|
||||
const AUTH_API_BASE = process.env.AUTH_API_BASE ?? 'http://localhost:3050';
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
|
||||
@ -13,7 +13,7 @@ export default function ForgotPasswordForm() {
|
||||
setLoading(true);
|
||||
setMessage("");
|
||||
try {
|
||||
const res = await axios.post("https://ebay.backend.vgproducts.com/api/auth/forgot-password", { email });
|
||||
const res = await axios.post("http://localhost:3050/api/auth/forgot-password", { email });
|
||||
setMessage("✅ We’ve emailed you a reset code / link. Enter it below.");
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
|
||||
@ -7,7 +7,7 @@ import IconMail from '@/components/icon/icon-mail';
|
||||
const ComponentsAuthLoginForm = () => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const nextUrl = searchParams.get('next') || '/';
|
||||
const nextUrl = searchParams.get('next') || '/user';
|
||||
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
@ -29,7 +29,7 @@ const ComponentsAuthLoginForm = () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// ✅ Call your Next.js API (same origin), which sets d4a_uid, d4a_session, d4a_exp cookies
|
||||
const res = await fetch('https://ebay.backend.vgproducts.com/api/auth/login', {
|
||||
const res = await fetch('http://localhost:3050/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
// credentials not required for same-origin, but harmless:
|
||||
|
||||
@ -7,8 +7,8 @@ import IconUser from '@/components/icon/icon-user';
|
||||
|
||||
const API_BASE =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, '') ||
|
||||
// 'https://ebay.backend.vgproducts.com';
|
||||
'https://ebay.backend.vgproducts.com';
|
||||
// 'http://localhost:3050';
|
||||
'http://localhost:3050';
|
||||
|
||||
|
||||
const ComponentsAuthRegisterForm = () => {
|
||||
|
||||
@ -40,7 +40,7 @@ const ComponentsAuthChangePasswordForm = () => {
|
||||
|
||||
// ✅ Axios call with generic type
|
||||
const res = await axios.post<ChangePasswordResponse>(
|
||||
`https://ebay.backend.vgproducts.com/api/auth/change-password`,
|
||||
`http://localhost:3050/api/auth/change-password`,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
|
||||
@ -54,7 +54,7 @@ const Header = () => {
|
||||
setUser(email);
|
||||
} else {
|
||||
axios
|
||||
.get("https://ebay.backend.vgproducts.com/api/auth/protected", { withCredentials: true })
|
||||
.get("http://localhost:3050/api/auth/protected", { withCredentials: true })
|
||||
.then((res: any) => {
|
||||
const userData = res.data.user;
|
||||
if (userData) {
|
||||
@ -218,9 +218,7 @@ const Header = () => {
|
||||
<IconMenu className="h-5 w-5" />
|
||||
</button>
|
||||
<Link href="/" className="main-logo flex shrink-0 items-center ml-3">
|
||||
<img className="inline w-[164px] h-[40px] ltr:-ml-1 rtl:-mr-1 block dark:hidden" src="/assets/images/logo_dark.png" alt="logo" />
|
||||
<img className="inline w-[164px] h-[40px] ltr:-ml-1 rtl:-mr-1 hidden dark:block" src="/assets/images/logo_light.png" alt="logo" />
|
||||
{/* <span className="hidden align-middle text-2xl font-semibold transition-all duration-300 ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light md:inline">VG Products</span> */}
|
||||
<span className="align-middle text-2xl font-bold transition-all duration-300 ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light md:inline text-[#e8572a]">VG Products</span>
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
|
||||
@ -66,10 +66,8 @@ const Sidebar = () => {
|
||||
>
|
||||
<div className="h-full bg-white dark:bg-black">
|
||||
<div className="flex items-center justify-between px-4 py-3">
|
||||
<Link href="/" className="main-logo flex shrink-0 items-center">
|
||||
<img className="ml-[5px] w-[164px] h-[40px] flex-none block dark:hidden" src="/assets/images/logo_dark.png" alt="logo" />
|
||||
<img className="ml-[5px] w-[164px] h-[40px] flex-none hidden dark:block" src="/assets/images/logo_light.png" alt="logo" />
|
||||
{/* <span className="align-middle text-2xl font-semibold ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light lg:inline">VG Products</span> */}
|
||||
<Link href="/user" className="main-logo flex shrink-0 items-center">
|
||||
<span className="align-middle text-2xl font-bold ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light lg:inline text-[#e8572a]">VG Products</span>
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
@ -96,21 +94,9 @@ const Sidebar = () => {
|
||||
</div>
|
||||
</button>
|
||||
<AnimateHeight duration={300} height={currentMenu === 'dashboard' ? 'auto' : 0}> */}
|
||||
<li className="nav-item">
|
||||
<Link href="/" className="group nav-link">
|
||||
<div className="flex items-center">
|
||||
<span className="shrink-0 group-hover:!text-primary">🏠</span>
|
||||
<span className="text-black ltr:pl-3 rtl:pr-3 dark:text-[#506690] dark:group-hover:text-white-dark">{t('Dashboard')}</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
{/* </AnimateHeight>
|
||||
</li> */}
|
||||
{/* Dashboard removed */}
|
||||
|
||||
<h2 className="-mx-4 mb-1 flex items-center bg-[#0f2444] px-7 py-3 font-extrabold uppercase dark:bg-dark dark:bg-opacity-[0.08]">
|
||||
<IconMinus className="hidden h-5 w-4 flex-none" />
|
||||
<span>{t('settings')}</span>
|
||||
</h2>
|
||||
{/* Settings header removed */}
|
||||
|
||||
<li className="nav-item">
|
||||
<Link href="/user" className="group nav-link">
|
||||
|
||||
@ -14,11 +14,11 @@ const UserModule = () => {
|
||||
const [addUserModal, setAddUserModal] = useState(false);
|
||||
|
||||
const defaultParams = {
|
||||
userid: null,
|
||||
_id: null,
|
||||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
phonenumber: '',
|
||||
mobileNumber: '',
|
||||
role: 'customer',
|
||||
};
|
||||
const [params, setParams] = useState<any>({ ...defaultParams });
|
||||
@ -26,9 +26,10 @@ const UserModule = () => {
|
||||
// ✅ Fetch users
|
||||
const fetchUsers = async () => {
|
||||
try {
|
||||
const res = await axios.get('https://ebay.backend.vgproducts.com/api/auth/users');
|
||||
setUsers(res.data?.users || []);
|
||||
setFilteredUsers(res.data?.users || []);
|
||||
const res = await axios.get('http://localhost:3050/api/users');
|
||||
const usersList = Array.isArray(res.data) ? res.data : (res.data?.users || []);
|
||||
setUsers(usersList);
|
||||
setFilteredUsers(usersList);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
showMessage('Failed to load users', 'error');
|
||||
@ -72,19 +73,19 @@ const UserModule = () => {
|
||||
|
||||
// ✅ Add / Update User
|
||||
const saveUser = async () => {
|
||||
if (!params.name || !params.email || !params.phonenumber || !params.role) {
|
||||
if (!params.name || !params.email || !params.role) {
|
||||
showMessage('Please fill all required fields', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (params.userid) {
|
||||
if (params._id) {
|
||||
// UPDATE
|
||||
await axios.put(`https://ebay.backend.vgproducts.com/api/auth/users/${params.userid}`, params);
|
||||
await axios.put(`http://localhost:3050/api/users/${params._id}`, params);
|
||||
showMessage('User updated successfully');
|
||||
} else {
|
||||
// ADD
|
||||
await axios.post('https://ebay.backend.vgproducts.com/api/auth/users/add', params);
|
||||
await axios.post('http://localhost:3050/api/users/create', params);
|
||||
showMessage('User added successfully');
|
||||
}
|
||||
setAddUserModal(false);
|
||||
@ -113,7 +114,7 @@ const UserModule = () => {
|
||||
}).then(async (result) => {
|
||||
if (result.isConfirmed) {
|
||||
try {
|
||||
await axios.delete(`https://ebay.backend.vgproducts.com/api/auth/users/${user.userid}`);
|
||||
await axios.delete(`http://localhost:3050/api/users/${user._id}`);
|
||||
showMessage('User deleted successfully');
|
||||
fetchUsers();
|
||||
} catch (err) {
|
||||
@ -174,10 +175,10 @@ const UserModule = () => {
|
||||
</thead>
|
||||
<tbody>
|
||||
{filteredUsers.map((user: any) => (
|
||||
<tr key={user.userid}>
|
||||
<tr key={user._id}>
|
||||
<td>{user.name}</td>
|
||||
<td>{user.email}</td>
|
||||
<td>{user.phonenumber}</td>
|
||||
<td>{user.mobileNumber}</td>
|
||||
<td>{user.role}</td>
|
||||
<td className="text-center">
|
||||
<div className="flex justify-center gap-2">
|
||||
@ -241,7 +242,7 @@ const UserModule = () => {
|
||||
<IconX />
|
||||
</button>
|
||||
<div className="bg-[#fbfbfb] py-3 text-lg font-medium ltr:pl-5 rtl:pr-5 dark:bg-[#121c2c]">
|
||||
{params.userid ? 'Edit User' : 'Add User'}
|
||||
{params._id ? 'Edit User' : 'Add User'}
|
||||
</div>
|
||||
<div className="p-5">
|
||||
<form>
|
||||
@ -267,7 +268,7 @@ const UserModule = () => {
|
||||
placeholder="Enter email"
|
||||
/>
|
||||
</div>
|
||||
{!params.userid && (
|
||||
{!params._id && (
|
||||
<div className="mb-4">
|
||||
<label>Password</label>
|
||||
<input
|
||||
@ -283,10 +284,10 @@ const UserModule = () => {
|
||||
<div className="mb-4">
|
||||
<label>Phone Number</label>
|
||||
<input
|
||||
id="phonenumber"
|
||||
id="mobileNumber"
|
||||
type="text"
|
||||
className="form-input"
|
||||
value={params.phonenumber}
|
||||
value={params.mobileNumber || ''}
|
||||
onChange={changeValue}
|
||||
placeholder="Enter phone number"
|
||||
/>
|
||||
@ -316,7 +317,7 @@ const UserModule = () => {
|
||||
className="btn btn-primary ltr:ml-4 rtl:mr-4"
|
||||
onClick={saveUser}
|
||||
>
|
||||
{params.userid ? 'Update' : 'Add'}
|
||||
{params._id ? 'Update' : 'Add'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user