minor changes

This commit is contained in:
kishore kumar 2026-01-02 01:38:00 +05:30
parent 3b8b35d70b
commit 339a38b0f7
24 changed files with 1402 additions and 1382 deletions

View File

@ -1,102 +1,76 @@
import React from 'react';
import ComponentsAuthUnlockForm from '@/components/auth/components-auth-unlock-form';
import { Metadata } from 'next';
import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = {
title: 'Unlock Cover',
title: 'Unlock',
};
const CoverLockScreen = () => {
export default function CoverLockScreen() {
return (
<div>
{/* Background */}
<div className="absolute inset-0">
<img
src="/assets/images/auth/bg-gradient.png"
alt="background"
className="h-full w-full object-cover"
/>
</div>
<div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.png)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
{/* Decorative images */}
<img
src="/assets/images/auth/coming-soon-object1.png"
alt="image"
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2"
/>
<img
src="/assets/images/auth/coming-soon-object2.png"
alt="image"
className="absolute left-24 top-0 h-40 md:left-[30%]"
/>
<img
src="/assets/images/auth/coming-soon-object3.png"
alt="image"
className="absolute right-0 top-0 h-[300px]"
/>
<img
src="/assets/images/auth/polygon-object.png"
alt="image"
className="absolute bottom-0 end-[28%]"
/>
{/* ===== Background Glows (SAME AS LOGIN) ===== */}
{/* Main container */}
<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">
{/* Blue */}
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
{/* LEFT SIDE */}
{/* Green left */}
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Pink left */}
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
{/* Pink bottom */}
<div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
{/* Orange */}
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
{/* Green right */}
<div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Purple */}
<div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
{/* Yellow */}
<div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
{/* ===== CARD ===== */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#1E3A8A_40%,#2563EB_80%)]
p-5 lg:inline-flex lg:max-w-[835px]
xl:-ms-28 ltr:xl:skew-x-[14deg] rtl:xl:skew-x-[-14deg]"
className="relative z-10 w-full max-w-[500px] p-8 rounded-3xl
bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl"
>
<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>
{/* Centered Image */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
{/* Logo */}
<div className="flex flex-col items-center mb-6">
<img
src="/assets/images/auth/sign-in.webp"
alt="Login Illustration"
className="max-w-[430px] w-full"
src="/assets/images/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[120px] w-[120px]"
/>
</div>
</div>
{/* RIGHT SIDE */}
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-10 sm:px-6 lg:max-w-[667px]">
{/* ✅ Top-right logo (responsive + transparent) */}
<div className="absolute right-4 top-0 sm:top-2 md:top-3 lg:top-0 z-10">
<Link href="/" className="block">
<img
src="/assets/images/auth/logo_tri.png"
alt="data4autos"
className="h-[100px] sm:h-[120px] lg:h-[140px] w-auto max-w-none object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* User info */}
<div className="flex items-center gap-4 mt-4">
<div>
<h1 className="text-lg text-white font-semibold">
Change password
</h1>
</div>
</div>
</div>
<div className="w-full max-w-[440px] lg:mt-16">
<div className="mb-10 flex items-center">
<div className="flex h-16 w-16 items-end justify-center overflow-hidden rounded-full bg-[#00AB55] ltr:mr-4 rtl:ml-4">
<img src="/assets/images/auth/user.png" className="w-full object-cover" alt="images" />
</div>
<div className="flex-1">
<h4 className="text-2xl dark:text-white">Shaun Park</h4>
<p className="text-white-dark">Enter your password to unlock your ID</p>
</div>
</div>
{/* Unlock Form (UNCHANGED) */}
<ComponentsAuthUnlockForm />
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Data4Autos All Rights Reserved.
</p>
</div>
{/* Footer */}
<div className="mt-6 text-center text-sm text-gray-400">
Not you?{' '}
<Link href="/login" className="text-blue-400 hover:underline">
Switch account
</Link>
</div>
</div>
</div>
);
};
export default CoverLockScreen;
}

View File

@ -1,150 +1,55 @@
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';
import ForgotPasswordForm from '@/components/auth/components-auth-forgot-form';
export const metadata: Metadata = {
title: 'Forgot Password',
};
export default function CoverForgotPassword() {
export default function ForgotPasswordPage() {
return (
<div>
{/* Background */}
<div className="absolute inset-0">
<div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* ===== Background Glows ===== */}
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
<div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
<div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
<div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
<div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
{/* ===== FORGOT PASSWORD CARD ===== */}
<div className="relative z-10 w-full max-w-[460px] p-8 rounded-3xl bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* Logo / Heading */}
<div className="flex flex-col items-center mb-6">
<img
src="/assets/images/auth/bg-gradient.png"
alt="background"
className="h-full w-full object-cover"
src="/assets/images/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[110px] w-[110px]"
/>
</div>
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.png)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
{/* Decorative images */}
<img
src="/assets/images/auth/coming-soon-object1.png"
alt="image"
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2"
/>
<img
src="/assets/images/auth/coming-soon-object2.png"
alt="image"
className="absolute left-24 top-0 h-40 md:left-[30%]"
/>
<img
src="/assets/images/auth/coming-soon-object3.png"
alt="image"
className="absolute right-0 top-0 h-[300px]"
/>
<img
src="/assets/images/auth/polygon-object.png"
alt="image"
className="absolute bottom-0 end-[28%]"
/>
{/* Main container */}
<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">
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#006AE0_0%,#00B4DB_50%,#19D4FB_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>
{/* Centered Image */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
<img
src="/assets/images/auth/sign-in.webp"
alt="Login Illustration"
className="max-w-[430px] w-full"
/>
</div>
</div>
{/* RIGHT SIDE */}
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-10 sm:px-6 lg:max-w-[667px]">
{/* Triple Logos */}
<div
className="absolute top-6 left-1/2 z-10 -translate-x-1/2
flex flex-row flex-nowrap items-center justify-center
gap-3 sm:gap-5 md:gap-6 lg:gap-8
px-2 w-full max-w-[95%] sm:max-w-[90%] md:max-w-[85%] lg:max-w-[70%]
overflow-hidden mb-6 sm:mb-8 ipad-fix"
>
{/* Logo 1 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/turn14_logo.png"
alt="Turn14"
className="h-[16px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 2 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/data.webp"
alt="Data4Autos"
className="h-[20px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 3 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/ebay.webp"
alt="eBay"
className="h-[18px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
</div>
{/* Forgot pwd Form Section */}
<div className="w-full max-w-[440px] mt-8 sm:mt-10 lg:mt-20">
<div className="mb-10">
<h1 className="text-3xl font-extrabold uppercase !leading-snug text-[#19d4fb] md:text-4xl">
Forgot Password
<h1 className="text-xl text-white font-medium mt-3">
Forgot your password?
</h1>
<p className="text-base font-bold leading-normal text-white-dark">
Enter your email to receive the reset link
<p className="text-sm text-gray-300 mt-1 text-center">
Enter your email and well send you a reset link
</p>
</div>
{/* forgot form */}
<ComponentsAuthForgotForm />
{/* Forgot Password Form */}
<ForgotPasswordForm />
<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">
{/* Back to login */}
<div className="text-center text-sm text-gray-400 mt-6">
Remember your password?{' '}
<Link href="/login" className="text-blue-400 hover:underline">
SIGN IN
</Link>
</div>
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Data4Autos All Rights Reserved.
</p>
</div>
</div>
</div>
</div>
);
}

View File

@ -1,211 +1,49 @@
import React from 'react';
import ComponentsAuthLoginForm from '@/components/auth/components-auth-login-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: 'Login',
};
const CoverLogin = () => {
export default function SocialBuddyLogin() {
return (
<div>
{/* Background */}
<div className="absolute inset-0">
<img
src="/assets/images/auth/bg-gradient.png"
alt="background"
className="h-full w-full object-cover"
/>
</div>
<div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.png)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
{/* Decorative images */}
<img
src="/assets/images/auth/coming-soon-object1.png"
alt="image"
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2"
/>
<img
src="/assets/images/auth/coming-soon-object2.png"
alt="image"
className="absolute left-24 top-0 h-40 md:left-[30%]"
/>
<img
src="/assets/images/auth/coming-soon-object3.png"
alt="image"
className="absolute right-0 top-0 h-[300px]"
/>
<img
src="/assets/images/auth/polygon-object.png"
alt="image"
className="absolute bottom-0 end-[28%]"
/>
{/* ===== Background Glows ===== */}
{/* Main container */}
<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">
{/* Blue */}
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#006AE0_0%,#00B4DB_50%,#19D4FB_100%)]
{/* Green left */}
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Pink left */}
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
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>
{/* Pink bottom */}
<div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
{/* Centered Image */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
<img
src="/assets/images/auth/sign-in.webp"
alt="Login Illustration"
className="max-w-[430px] w-full"
/>
</div>
</div>
{/* Orange */}
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
{/* RIGHT SIDE */}
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-10 sm:px-6 lg:max-w-[667px]">
{/* Green right */}
<div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Purple */}
<div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
{/* Triple Logos */}
<div
className="absolute top-6 left-1/2 z-10 -translate-x-1/2
flex flex-row flex-nowrap items-center justify-center
gap-3 sm:gap-5 md:gap-6 lg:gap-8
px-2 w-full max-w-[95%] sm:max-w-[90%] md:max-w-[85%] lg:max-w-[70%]
overflow-hidden mb-6 sm:mb-8 ipad-fix"
>
{/* Logo 1 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/turn14_logo.png"
alt="Turn14"
className="h-[16px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 2 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/data.webp"
alt="Data4Autos"
className="h-[20px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 3 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/ebay.webp"
alt="eBay"
className="h-[18px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
</div>
{/* Yellow */}
<div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
{/* Login Form Section */}
<div className="w-full max-w-[440px] mt-8 sm:mt-10 lg:mt-20">
<div className="mb-10">
<h1 className="text-3xl font-extrabold uppercase !leading-snug text-[#19d4fb] md:text-4xl">
Sign In
</h1>
<p className="text-base font-bold leading-normal text-white-dark">
Enter your email and password to login
</p>
</div>
{/* Login form */}
<ComponentsAuthLoginForm />
{/* Divider */}
<div className="relative my-7 text-center md:mb-9">
<span className="absolute inset-x-0 top-1/2 h-px w-full -translate-y-1/2 bg-white-light dark:bg-white-dark"></span>
<span className="relative bg-white px-2 font-bold uppercase text-white-dark dark:bg-dark dark:text-white-light">
or
</span>
</div>
{/* Social icons */}
<div className="mb-10 md:mb-[60px]">
<ul className="flex justify-center gap-3.5 text-white">
<li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{
background: 'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)'
}}
>
<IconInstagram />
</Link>
</li>
<li>
<Link
href="https://ebay.backend.data4autos.com/api/auth/facebook/"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{ background: 'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)' }}
>
<IconFacebookCircle />
</Link>
</li>
{/* <li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{ background: 'linear-gradient(135deg, #1E3A8A 0%, #2563EB 50%, #00C6FF 100%)' }}
>
<IconTwitter fill={true} />
</Link>
</li> */}
<li>
<Link
href="https://ebay.backend.data4autos.com/api/auth/google/"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{ background: 'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)' }}
>
<IconGoogle />
</Link>
</li>
</ul>
</div>
{/* Sign-up link */}
<div className="text-center dark:text-white">
Don&apos;t have an account?&nbsp;
<Link
href="/signup"
className="uppercase text-primary underline transition hover:text-black dark:hover:text-white"
>
SIGN UP
</Link>
</div>
</div>
{/* Footer */}
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Data4Autos All Rights Reserved.
</p>
</div>
</div>
</div>
</div>
);
};
export default CoverLogin;
}

View File

@ -1,87 +1,72 @@
import React from 'react';
import ComponentsAuthResetPasswordForm from '@/components/auth/components-auth-reset-password-form';
import { Metadata } from 'next';
import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = {
title: 'Recover Id Cover',
title: 'Recover ID',
};
const CoverPasswordReset = () => {
export default function CoverPasswordReset() {
return (
<div>
<div className="absolute inset-0">
<img
src="/assets/images/auth/bg-gradient.png"
alt="background"
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.png)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
{/* Decorative images */}
<img
src="/assets/images/auth/coming-soon-object1.png"
alt="image"
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2"
/>
<img
src="/assets/images/auth/coming-soon-object2.png"
alt="image"
className="absolute left-24 top-0 h-40 md:left-[30%]"
/>
<img
src="/assets/images/auth/coming-soon-object3.png"
alt="image"
className="absolute right-0 top-0 h-[300px]"
/>
<img
src="/assets/images/auth/polygon-object.png"
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">
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#1E3A8A_40%,#2563EB_80%)]
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="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* Centered Image */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
{/* ===== Background Glows (SAME AS LOGIN) ===== */}
{/* Blue */}
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
{/* Green left */}
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Pink left */}
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
{/* Pink bottom */}
<div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
{/* Orange */}
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
{/* Green right */}
<div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
{/* Purple */}
<div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
{/* Yellow */}
<div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
{/* ===== CARD ===== */}
<div className="relative z-10 w-full max-w-[500px] p-8 rounded-3xl
bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* Logo */}
<div className="flex flex-col items-center mb-6">
<img
src="/assets/images/auth/sign-in.webp"
alt="Login Illustration"
className="max-w-[430px] w-full"
src="/assets/images/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[120px] w-[120px]"
/>
<h1 className="text-xl text-white font-medium mt-3">
Recover Your Account
</h1>
<p className="text-gray-400 text-sm mt-1 text-center">
Enter your email to recover your ID
</p>
</div>
</div>
<div className="relative flex w-full flex-col items-center justify-center gap-6 px-4 pb-16 pt-10 sm:px-6 lg:max-w-[667px]">
{/* ✅ Top-right logo (responsive + transparent) */}
<div className="absolute right-4 top-0 sm:top-2 md:top-3 lg:top-0 z-10">
<Link href="/" className="block">
<img
src="/assets/images/auth/logo_tri.png"
alt="data4autos"
className="h-[100px] sm:h-[120px] lg:h-[140px] w-auto max-w-none object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
</div>
<div className="w-full max-w-[440px] lg:mt-16">
<div className="mb-7">
<h1 className="mb-3 text-2xl font-bold !leading-snug dark:text-white">Password Reset</h1>
<p>Enter your email to recover your ID</p>
</div>
{/* Reset Form (UNCHANGED) */}
<ComponentsAuthResetPasswordForm />
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">© {new Date().getFullYear()}.Data4Autos All Rights Reserved.</p>
</div>
{/* Footer */}
<div className="mt-6 text-center text-sm text-gray-400">
Remembered your password?{' '}
<Link href="/login" className="text-blue-400 hover:underline">
SIGN IN
</Link>
</div>
</div>
</div>
);
};
export default CoverPasswordReset;
}

View File

@ -1,218 +1,61 @@
import ComponentsAuthRegisterForm from '@/components/auth/components-auth-register-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: 'Register Cover',
title: 'Sign Up',
};
const CoverRegister = () => {
export default function BoxedSignUp() {
return (
<div>
{/* Background gradient */}
<div className="absolute inset-0">
<img
src="/assets/images/auth/bg-gradient.png"
alt="background"
className="h-full w-full object-cover"
/>
</div>
<div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
<div className="relative flex min-h-screen items-center justify-center bg-[url(/assets/images/auth/bg.png)] bg-cover bg-center bg-no-repeat px-6 py-10 dark:bg-[#060818] sm:px-16">
{/* Decorative images */}
{/* ===== Background Glows ===== */}
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
<div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
<div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
<div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
<div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
{/* ===== SIGN UP CARD ===== */}
<div className="relative z-10 w-full max-w-[540px] p-8 rounded-3xl bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* Logo */}
<div className="flex flex-col items-center justify-center mb-6">
<img
src="/assets/images/auth/coming-soon-object1.png"
alt="image"
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2"
/>
<img
src="/assets/images/auth/coming-soon-object2.png"
alt="image"
className="absolute left-24 top-0 h-40 md:left-[30%]"
/>
<img
src="/assets/images/auth/coming-soon-object3.png"
alt="image"
className="absolute right-0 top-0 h-[300px]"
/>
<img
src="/assets/images/auth/polygon-object.png"
alt="image"
className="absolute bottom-0 end-[28%]"
src="/assets/images/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[120px] w-[120px]
drop-shadow-[0_0_6px_rgba(0,111,171,0.65),
0_0_8px_rgba(243,195,56,0.55),
0_0_10px_rgba(226,50,118,0.50),
0_0_10px_rgba(243,195,56,0.45),
0_0_10px_rgba(20,71,209,0.40)]"
/>
{/* Main container */}
<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">
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#006AE0_0%,#00B4DB_50%,#19D4FB_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>
{/* Centered Image */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
<img
src="/assets/images/auth/sign-up.webp"
alt="Login Illustration"
className="max-w-[430px] w-full"
/>
</div>
</div>
{/* RIGHT SIDE */}
<div className="relative flex flex-col items-center justify-center w-full px-6 sm:px-10 lg:px-14 pt-10 pb-12">
{/* Triple Logos */}
<div
className="absolute top-6 left-1/2 z-10 -translate-x-1/2
flex flex-row flex-nowrap items-center justify-center
gap-3 sm:gap-5 md:gap-6 lg:gap-8
px-2 w-full max-w-[95%] sm:max-w-[90%] md:max-w-[85%] lg:max-w-[70%]
overflow-hidden mb-6 sm:mb-8 ipad-fix"
>
{/* Logo 1 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/turn14_logo.png"
alt="Turn14"
className="h-[16px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 2 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/data.webp"
alt="Data4Autos"
className="h-[20px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
{/* Logo 3 */}
<Link href="/" className="block flex-shrink-0">
<img
src="/assets/images/auth/ebay.webp"
alt="eBay"
className="h-[18px] sm:h-[26px] md:h-[36px] lg:h-[48px] xl:h-[60px]
w-auto object-contain opacity-90 hover:opacity-100 transition-opacity duration-300"
/>
</Link>
</div>
{/* signup Section */}
<div className="w-full max-w-[440px] mt-8 sm:mt-10 lg:mt-20">
<div className="mb-8 sm:mb-10 text-center">
<h1 className="text-3xl font-extrabold uppercase !leading-snug text-[#19d4fb] md:text-4xl">
Sign Up
<h1 className="text-xl text-white font-medium text-center mt-3">
Create Your SocialBuddy Account
</h1>
<p className="text-base font-bold leading-normal text-white-dark">
Enter your email and password to register
</p>
</div>
{/* Register Form */}
<ComponentsAuthRegisterForm />
{/* Divider */}
<div className="relative my-6 text-center md:my-8">
<span className="absolute inset-x-0 top-1/2 h-px w-full -translate-y-1/2 bg-white-light dark:bg-white-dark"></span>
<span className="relative bg-white px-2 font-bold uppercase text-white-dark dark:bg-dark dark:text-white-light">
or
</span>
</div>
{/* Social Icons */}
<div className="mb-10 md:mb-14">
<ul className="flex justify-center gap-3.5 text-white">
<li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{
background:
'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)',
}}
>
<IconInstagram />
</Link>
</li>
<li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{
background:
'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)',
}}
>
<IconFacebookCircle />
</Link>
</li>
<li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{
background:
'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)',
}}
>
<IconTwitter fill={true} />
</Link>
</li>
<li>
<Link
href="#"
className="inline-flex h-8 w-8 items-center justify-center rounded-full p-0 transition hover:scale-110"
style={{
background:
'linear-gradient(135deg, #0EA5E9 0%, #19D4FB 50%, #67E8F9 100%)',
}}
>
<IconGoogle />
</Link>
</li>
</ul>
</div>
{/* Login link */}
<div className="text-center dark:text-white mt-4 mb-6">
Already have an account?&nbsp;
{/* Footer link */}
<div className="text-center text-gray-400 text-sm mt-6">
Already have an account?{' '}
<Link
href="/login"
className="uppercase text-primary underline transition hover:text-black dark:hover:text-white"
className="text-blue-400 hover:underline"
>
SIGN IN
</Link>
</div>
</div>
{/* Footer text */}
<p className="absolute bottom-6 w-full text-center text-xs text-gray-600 dark:text-white">
© {new Date().getFullYear()}. Data4Autos All Rights Reserved.
</p>
</div>
</div>
</div>
</div>
);
};
export default CoverRegister;
}

View File

@ -6,7 +6,76 @@ export const metadata: Metadata = {
};
const Sales = () => {
return <div>starter page</div>;
return (
<div className="relative min-h-screen w-full bg-[#111111] p-6">
{/* ================= BACKGROUND GLOWS (FROM UserModule) ================= */}
<div className="pointer-events-none absolute inset-0">
<div
className="absolute top-[180px] left-52 w-[100px] h-[100px]
bg-[#1d8be0] rounded-full blur-2xl opacity-[1.5] animate-zoomslow"
/>
<div
className="absolute top-10 left-0 w-[60px] h-[60px]
bg-[#6cb655] rounded-full blur-2xl opacity-[1.5] animate-zoomslower"
/>
<div
className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px]
bg-[#db21d9] blur-3xl opacity-1 animate-zoomslow"
/>
<div
className="absolute bottom-20 left-[440px] w-[60px] h-[60px]
bg-[#db21d9] rounded-full blur-xl opacity-80
-translate-x-1/2 translate-y-1/2"
/>
<div
className="absolute top-[100px] right-[260px] w-[100px] h-[100px]
bg-[#f28f50] rounded-full blur-2xl opacity-80 animate-zoomfast"
/>
<div
className="absolute top-10 right-0 w-[60px] h-[60px]
bg-[#6cb655] rounded-full blur-2xl opacity-[1.5] animate-zoomslower"
/>
<div
className="absolute bottom-20 right-[180px] w-[80px] h-[80px]
bg-[#783e8d] rounded-full blur-2xl opacity-80 animate-zoomslow"
/>
<div
className="absolute top-[280px] -right-[20px] w-[160px] h-[160px]
bg-[#f1b74d] rounded-full blur-2xl opacity-1 animate-zoomslower"
/>
</div>
{/* ================= PAGE CONTENT ================= */}
<div className="relative z-10 ">
<div className="max-w-xl mx-auto text-center">
{/* Title */}
<h1 className="text-4xl font-extrabold mb-6 tracking-wide
bg-gradient-to-r from-[#0073C6] via-[#E44DB3] to-[#5BBE5B]
bg-clip-text text-transparent">
Sales Admin
</h1>
</div>
</div>
</div>
);
};
export default Sales;

View File

@ -0,0 +1,48 @@
import { NextResponse } from 'next/server';
const API_BASE = 'https://api.socialbuddy.co/api/users';
const normalizeUser = (u: any) => ({
userid: u._id,
name: u.name,
email: u.email,
mobile: u.mobileNumber,
role: u.role,
createdAt: u.createdAt,
});
// GET by id
export async function GET(
_req: Request,
{ params }: { params: { id: string } }
) {
const res = await fetch(`${API_BASE}/${params.id}`);
const data = await res.json();
return NextResponse.json(normalizeUser(data));
}
// UPDATE (admin)
export async function PUT(
req: Request,
{ params }: { params: { id: string } }
) {
const body = await req.json();
const res = await fetch(`${API_BASE}/${params.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const data = await res.json();
return NextResponse.json(normalizeUser(data));
}
// DELETE (admin)
export async function DELETE(
_req: Request,
{ params }: { params: { id: string } }
) {
await fetch(`${API_BASE}/${params.id}`, { method: 'DELETE' });
return NextResponse.json({ success: true });
}

57
app/api/users/route.ts Normal file
View File

@ -0,0 +1,57 @@
import { NextResponse } from 'next/server';
const API_BASE = 'https://api.socialbuddy.co/api/users';
const normalizeUser = (u: any) => ({
userid: u._id,
name: u.name,
email: u.email,
mobileNumber:
u.mobileNumber ||
u.mobile ||
u.phone ||
u.phonenumber ||
'',
role: u.role,
});
// GET users
export async function GET() {
const res = await fetch(API_BASE, {
credentials: 'include',
});
const data = await res.json();
return NextResponse.json(data.map(normalizeUser));
}
// ✅ ADD USER (ADMIN ONLY)
export async function POST(req: Request) {
const body = await req.json();
const res = await fetch(`${API_BASE}/create`, {
method: 'POST',
// REQUIRED
credentials: 'include',
headers: {
'Content-Type': 'application/json',
// THIS LINE IS WHY ADD USER WAS FAILING
Cookie: req.headers.get('cookie') || '',
},
body: JSON.stringify(body),
});
if (!res.ok) {
const error = await res.text();
return NextResponse.json(
{ error },
{ status: res.status }
);
}
const data = await res.json();
return NextResponse.json(normalizeUser(data));
}

View File

@ -2,6 +2,7 @@
import React, { useState } from "react";
import axios from "axios";
import { Mail } from "lucide-react";
export default function ForgotPasswordForm() {
const [email, setEmail] = useState("");
@ -12,12 +13,16 @@ export default function ForgotPasswordForm() {
e.preventDefault();
setLoading(true);
setMessage("");
try {
const res = await axios.post("https://ebay.backend.data4autos.com/api/auth/forgot-password", { email });
await axios.post(
"https://ebay.backend.data4autos.com/api/auth/forgot-password",
{ email }
);
setMessage("✅ Weve emailed you a reset code / link. Enter it below.");
} catch (err: any) {
} catch (err) {
console.error(err);
setMessage("Something went wrong. Try again.");
setMessage("Something went wrong. Try again.");
} finally {
setLoading(false);
}
@ -25,27 +30,59 @@ export default function ForgotPasswordForm() {
return (
<form onSubmit={handleForgot} className="space-y-5">
{/* Email */}
<div>
<label className="block text-sm font-medium text-white-dark mb-1">
Email
</label>
<div className="relative">
{/* Icon */}
<Mail
className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"
size={18}
/>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="form-input ps-10 placeholder:text-white-dark"
placeholder="you@example.com"
placeholder="Enter your email"
className="
form-input w-full
ps-12
bg-[#0F172A] text-white
placeholder:text-gray-400
border border-white/10
rounded-xl
focus:border-cyan-400
focus:ring-1 focus:ring-cyan-400
"
/>
</div>
</div>
{/* Button */}
<button
type="submit"
disabled={loading}
className="btn w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(25,212,251,0.44)] disabled:cursor-not-allowed disabled:opacity-70 !mt-6 bg-[linear-gradient(135deg,#0EA5E9_0%,#19D4FB_50%,#67E8F9_100%)] text-white hover:bg-[linear-gradient(135deg,#67E8F9_0%,#19D4FB_50%,#0EA5E9_100%)]"
className="
w-full py-3 rounded-xl text-lg font-semibold text-white
bg-gradient-to-r from-blue-600 to-pink-500
shadow-lg transition-all hover:opacity-90 hover:scale-[1.02]
disabled:opacity-60 mb-3
"
>
{loading ? "Sending..." : "Send Reset Link"}
</button>
{message && <p className="mt-2 text-center text-sm font-semibold text-primary">{message}</p>}
{/* Message */}
{message && (
<p className="mt-2 text-center text-sm font-semibold text-primary">
{message}
</p>
)}
</form>
);
}

View File

@ -1,146 +1,215 @@
'use client';
import React, { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import IconLockDots from '@/components/icon/icon-lock-dots';
import IconMail from '@/components/icon/icon-mail';
import Link from 'next/link';
import { Eye, EyeOff } from 'lucide-react';
import { FcGoogle } from 'react-icons/fc';
const ComponentsAuthLoginForm = () => {
const router = useRouter();
const searchParams = useSearchParams();
const nextUrl = searchParams.get('next') || '/';
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [formData, setFormData] = useState({
email: '',
password: '',
});
const [loading, setLoading] = useState(false);
const [err, setErr] = useState<string | null>(null);
const [msg, setMsg] = useState<string | null>(null);
const [showPassword, setShowPassword] = useState(false);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};
const submitForm = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setErr(null);
setMsg(null);
if (!email || !password) {
if (!formData.email || !formData.password) {
setErr('Please enter email and password.');
return;
}
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.data4autos.com/api/auth/login', {
// ✅ SAME backend logic as your old working code
const res = await fetch(
'https://ebay.backend.data4autos.com/api/auth/login',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
// credentials not required for same-origin, but harmless:
credentials: 'same-origin',
body: JSON.stringify({ email, password }),
});
body: JSON.stringify(formData),
}
);
const contentType = res.headers.get('content-type') || '';
const data = contentType.includes('application/json') ? await res.json() : await res.text();
console.log("data data", data)
try {
console.log('data:', data.store);
sessionStorage.setItem('USERID', data.userid);
sessionStorage.setItem('EBAYSTOREID', data.store.urlPath);
localStorage.setItem('data4auto_uid', data.userid);
localStorage.setItem('d4a_email', data.email);
data?.payment?.stripeSessionId && localStorage.setItem('payment_session', data?.payment?.stripeSessionId);
console.log('set sessionStorage USERID');
} catch {
console.log('no sessionStorage');
}
const data =
contentType.includes('application/json')
? await res.json()
: await res.text();
if (!res.ok) {
throw new Error((typeof data === 'object' && (data?.message || data?.error)) || `Login failed (${res.status})`);
throw new Error(
(typeof data === 'object' &&
(data?.message || data?.error)) ||
`Login failed (${res.status})`
);
}
// (DEV ONLY) quick check that cookies were set:
if (process.env.NODE_ENV !== 'production') {
// ✅ Preserve existing storage behavior
try {
const who = await fetch('/api/debug/whoami', { cache: 'no-store' }).then((r) => r.json());
console.log('whoami:', who);
sessionStorage.setItem('USERID', data.userid);
sessionStorage.setItem('EBAYSTOREID', data.store?.urlPath);
localStorage.setItem('data4auto_uid', data.userid);
localStorage.setItem('d4a_email', data.email);
} catch { }
}
data?.payment?.stripeSessionId &&
localStorage.setItem(
'payment_session',
data.payment.stripeSessionId
);
} catch {}
setMsg('Login successful!');
setTimeout(() => router.push(nextUrl), 500);
} catch (e: any) {
setErr(e?.message || 'Something went wrong. Please try again.');
setErr(e?.message || 'Login failed');
} finally {
setLoading(false);
}
};
return (
<form className="space-y-5 dark:text-white" onSubmit={submitForm}>
<form onSubmit={submitForm} className="dark:text-white">
{/* Alerts */}
{err && <div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">{err}</div>}
{msg && <div className="rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">{msg}</div>}
{err && (
<div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{err}
</div>
)}
{msg && (
<div className="mb-4 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">
{msg}
</div>
)}
<div className="relative w-full min-w-[500px] p-8 rounded-3xl bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* Logo */}
<div className="flex flex-col items-center mb-6">
<img
src="/assets/images/logo_sb.png"
alt="Logo"
className="h-[120px] w-[120px]"
/>
<h1 className="text-xl text-white font-medium mt-3">
Sign in to SocialBuddy
</h1>
</div>
{/* Email */}
<div>
<label htmlFor="Email">Email</label>
<div className="relative text-white-dark">
<div className="mb-4 relative">
<input
id="Email"
name="email"
type="email"
placeholder="Enter Email"
className="form-input ps-10 placeholder:text-white-dark"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email Address"
className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg text-white
focus:outline-none focus:border-white/30"
value={formData.email}
onChange={handleChange}
autoComplete="email"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconMail fill={true} />
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconMail fill />
</span>
</div>
</div>
{/* Password */}
<div>
<label htmlFor="Password">Password</label>
<div className="relative text-white-dark">
<div className="mb-2 relative">
<input
id="Password"
type="password"
placeholder="Enter Password"
className="form-input ps-10 placeholder:text-white-dark"
value={password}
onChange={(e) => setPassword(e.target.value)}
name="password"
type={showPassword ? 'text' : 'password'}
placeholder="Password"
className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg text-white
focus:outline-none focus:border-white/30"
value={formData.password}
onChange={handleChange}
autoComplete="current-password"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconLockDots fill={true} />
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconLockDots fill />
</span>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400"
>
{showPassword ? <EyeOff size={20} /> : <Eye size={20} />}
</button>
</div>
{/* Forgot password */}
<div className="flex justify-end mb-6">
<Link
href="/forgot-password"
className="text-sm text-blue-400 hover:underline"
>
Forgot Password?
</Link>
</div>
{/* Login button */}
<button
disabled={loading}
className="w-full py-3 rounded-xl text-lg font-semibold text-white
bg-gradient-to-r from-blue-600 to-pink-500
shadow-lg transition-all hover:opacity-90 hover:scale-[1.02]
disabled:opacity-60 mb-3"
>
{loading ? 'Logging in…' : 'LOG IN'}
</button>
{/* Divider */}
<div className="relative text-center my-3">
<span className="absolute inset-x-0 top-1/2 h-px bg-white/20" />
<span className="relative bg-[#0b0d1c] px-3 text-xs uppercase text-gray-300">
or
</span>
</div>
{/* Google Sign-in */}
<div className="flex justify-center px-8 mb-4">
<Link
href="https://ebay.backend.data4autos.com/api/auth/google/"
className="flex items-center gap-3 px-8 py-3 rounded-lg
border border-white/20 text-white
hover:bg-white/10 transition active:scale-[0.98]"
>
<FcGoogle size={20} />
<span className="text-sm">Continue with Google</span>
</Link>
</div>
{/* Optional newsletter */}
<div>
<label className="flex cursor-pointer items-center">
<input type="checkbox" className="form-checkbox bg-white dark:bg-black" />
<span className="text-white-dark">Subscribe to weekly newsletter</span>
</label>
{/* Footer */}
<div className="text-center text-sm text-gray-400">
Don&rsquo;t have an account?{' '}
<Link href="/signup" className="text-blue-400 hover:underline">
SIGN UP
</Link>
</div>
</div>
{/* <button
type="submit"
disabled={loading}
className="btn btn-gradient !mt-6 w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(67,97,238,0.44)] disabled:cursor-not-allowed disabled:opacity-70"
>
{loading ? 'Signing in…' : 'Sign in'}
</button> */}
<button
type="submit"
disabled={loading}
className="btn w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(25,212,251,0.44)] disabled:cursor-not-allowed disabled:opacity-70 !mt-6 bg-[linear-gradient(135deg,#0EA5E9_0%,#19D4FB_50%,#67E8F9_100%)] text-white hover:bg-[linear-gradient(135deg,#67E8F9_0%,#19D4FB_50%,#0EA5E9_100%)]"
>
{loading ? 'Signing in…' : 'Sign in'}
</button>
</form>
);
};

View File

@ -7,10 +7,8 @@ import IconUser from '@/components/icon/icon-user';
const API_BASE =
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, '') ||
// 'https://ebay.backend.data4autos.com';
'https://ebay.backend.data4autos.com';
const ComponentsAuthRegisterForm = () => {
const router = useRouter();
@ -18,7 +16,6 @@ const ComponentsAuthRegisterForm = () => {
const [phonenumber, setPhonenumber] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [subscribe, setSubscribe] = useState(false);
const [loading, setLoading] = useState(false);
const [err, setErr] = useState<string | null>(null);
@ -39,157 +36,127 @@ const ComponentsAuthRegisterForm = () => {
const res = await fetch(`${API_BASE}/api/auth/signup`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
// If your API sets cookies, uncomment:
// credentials: 'include',
body: JSON.stringify({
name,
email,
password,
phonenumber,
// You can also send `subscribe` if your API supports it
// subscribe,
}),
});
const contentType = res.headers.get('content-type') || '';
let data: any = null;
if (contentType.includes('application/json')) {
data = await res.json();
} else {
data = await res.text();
}
const data = await res.json();
if (!res.ok) throw new Error(data?.message || 'Signup failed');
if (!res.ok) {
const message =
(typeof data === 'object' && (data?.message || data?.error)) ||
`Signup failed (${res.status})`;
throw new Error(message);
}
setMsg(
(typeof data === 'object' && (data?.message || 'Signup successful!')) ||
'Signup successful!'
);
// Redirect to login (or wherever you like)
setMsg('Signup successful!');
setTimeout(() => router.push('/login'), 1000);
} catch (e: any) {
setErr(e?.message || 'Something went wrong. Please try again.');
setErr(e?.message || 'Something went wrong.');
} finally {
setLoading(false);
}
};
return (
<form className="space-y-3 p-4 dark:text-white" onSubmit={submitForm}>
{/* Name */}
<div>
<label htmlFor="Name">Name</label>
<div className="relative text-white-dark">
<input
id="Name"
type="text"
placeholder="Enter Name"
className="form-input ps-10 placeholder:text-white-dark"
value={name}
onChange={(e) => setName(e.target.value)}
autoComplete="name"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconUser fill={true} />
</span>
</div>
</div>
{/* Email */}
<div>
<label htmlFor="Email">Email</label>
<div className="relative text-white-dark">
<input
id="Email"
type="email"
placeholder="Enter Email"
className="form-input ps-10 placeholder:text-white-dark"
value={email}
onChange={(e) => setEmail(e.target.value)}
autoComplete="email"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconMail fill={true} />
</span>
</div>
</div>
{/* Password */}
<div>
<label htmlFor="Password">Password</label>
<div className="relative text-white-dark">
<input
id="Password"
type="password"
placeholder="Enter Password"
className="form-input ps-10 placeholder:text-white-dark"
value={password}
onChange={(e) => setPassword(e.target.value)}
autoComplete="new-password"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconLockDots fill={true} />
</span>
</div>
</div>
{/* Phone Number */}
<div>
<label htmlFor="PhoneNumber">Phone Number</label>
<div className="relative text-white-dark">
<input
id="PhoneNumber"
type="tel"
placeholder="Enter Phone Number"
className="form-input ps-10 placeholder:text-white-dark"
value={phonenumber}
onChange={(e) => setPhonenumber(e.target.value)}
autoComplete="tel"
/>
{/* Simple emoji icon to match the padded layout without adding a new component */}
<span className="absolute start-4 top-1/2 -translate-y-1/2">📞</span>
</div>
</div>
{/* Subscribe */}
{/* <div>
<label className="flex cursor-pointer items-center">
<input
type="checkbox"
className="form-checkbox bg-white dark:bg-black"
checked={subscribe}
onChange={(e) => setSubscribe(e.target.checked)}
/>
<span className="text-white-dark">Subscribe to weekly newsletter</span>
</label>
</div> */}
<form onSubmit={submitForm} className="dark:text-white">
{/* Alerts */}
{err && (
<div className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
<div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{err}
</div>
)}
{msg && (
<div className="rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">
<div className="mb-4 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">
{msg}
</div>
)}
<div className="space-y-4">
{/* Name */}
<div className="relative">
<input
type="text"
placeholder="Full Name"
value={name}
onChange={(e) => setName(e.target.value)}
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconUser fill />
</span>
</div>
{/* Email */}
<div className="relative">
<input
type="email"
placeholder="Email Address"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconMail fill />
</span>
</div>
{/* Password */}
<div className="relative">
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconLockDots fill />
</span>
</div>
{/* Phone */}
<div className="relative">
<input
type="tel"
placeholder="Phone Number"
value={phonenumber}
onChange={(e) => setPhonenumber(e.target.value)}
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
📞
</span>
</div>
{/* Submit */}
<button
type="submit"
disabled={loading}
className="btn w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(25,212,251,0.44)] disabled:cursor-not-allowed disabled:opacity-70 !mt-6 bg-[linear-gradient(135deg,#0EA5E9_0%,#19D4FB_50%,#67E8F9_100%)] text-white hover:bg-[linear-gradient(135deg,#67E8F9_0%,#19D4FB_50%,#0EA5E9_100%)]"
className="w-full py-3 rounded-xl text-lg font-semibold text-white
bg-gradient-to-r from-blue-600 to-pink-500
shadow-lg transition-all hover:opacity-90 hover:scale-[1.02]
disabled:opacity-60"
>
{loading ? 'Creating account…' : 'Sign Up'}
{loading ? 'Creating account…' : 'SIGN UP'}
</button>
</div>
</form>
);
};

View File

@ -10,22 +10,48 @@ const ComponentsAuthResetPasswordForm = () => {
e.preventDefault();
router.push('/');
};
return (
<form className="space-y-5" onSubmit={submitForm}>
<div>
<label htmlFor="Email" className="dark:text-white">
<form onSubmit={submitForm} className="dark:text-white">
<div className="space-y-4">
{/* Email */}
<div className="relative">
<label
htmlFor="Email"
className="block mb-1 text-sm text-gray-300"
>
Email
</label>
<div className="relative text-white-dark">
<input id="Email" type="email" placeholder="Enter Email" className="form-input ps-10 placeholder:text-white-dark" />
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconMail fill={true} />
<input
id="Email"
type="email"
placeholder="Email Address"
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-[42px] -translate-y-1/2 text-white">
<IconMail fill />
</span>
</div>
</div>
<button type="submit" className="btn w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(67,97,238,0.44)] disabled:cursor-not-allowed disabled:opacity-70 !mt-6 bg-[linear-gradient(135deg,#1E3A8A_0%,#2563EB_50%,#00C6FF_100%)] text-white hover:bg-[linear-gradient(135deg,#00C6FF_0%,#2563EB_50%,#1E3A8A_100%)]">
{/* Submit */}
<button
type="submit"
className="w-full py-3 rounded-xl text-lg font-semibold text-white
bg-gradient-to-r from-blue-600 to-pink-500
shadow-lg transition-all hover:opacity-90 hover:scale-[1.02]"
>
RECOVER
</button>
</div>
</form>
);
};

View File

@ -33,27 +33,21 @@ const ComponentsAuthChangePasswordForm = () => {
return;
}
// ✅ Create FormData and append fields
const formData = new FormData();
formData.append('currentPassword', currentPassword);
formData.append('newPassword', newPassword);
// ✅ Axios call with generic type
const res = await axios.post<ChangePasswordResponse>(
`https://ebay.backend.data4autos.com/api/auth/change-password`,
formData,
{
headers: {
Authorization: `Bearer ${token}`,
// If you're sending FormData, remove JSON content-type
// Axios will automatically set multipart/form-data
},
}
);
setSuccess(res.data.message || 'Password updated successfully!');
// Optional: force re-login after password change
localStorage.removeItem('token');
router.push('/login');
} catch (err: any) {
@ -65,59 +59,91 @@ const ComponentsAuthChangePasswordForm = () => {
};
return (
<form className="space-y-5" onSubmit={submitForm}>
{/* Current password */}
<div>
<label htmlFor="currentPassword" className="dark:text-white">
<form onSubmit={submitForm} className="dark:text-white">
{/* Alerts */}
{error && (
<div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{error}
</div>
)}
{success && (
<div className="mb-4 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700">
{success}
</div>
)}
<div className="space-y-4">
{/* Current Password */}
<div className="relative">
<label
htmlFor="currentPassword"
className="block mb-1 text-sm text-gray-300"
>
Current Password
</label>
<div className="relative text-white-dark">
<input
id="currentPassword"
type="password"
placeholder="Enter Current Password"
className="form-input ps-10 placeholder:text-white-dark"
placeholder="Current Password"
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
required
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconLockDots fill={true} />
<span className="absolute start-4 top-[42px] -translate-y-1/2 text-white">
<IconLockDots fill />
</span>
</div>
</div>
{/* New password */}
<div>
<label htmlFor="newPassword" className="dark:text-white">
{/* New Password */}
<div className="relative">
<label
htmlFor="newPassword"
className="block mb-1 text-sm text-gray-300"
>
New Password
</label>
<div className="relative text-white-dark">
<input
id="newPassword"
type="password"
placeholder="Enter New Password"
className="form-input ps-10 placeholder:text-white-dark"
placeholder="New Password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
required
className="w-full ps-10 py-3
bg-[rgba(7,13,30,0.7)]
border border-white/15 rounded-lg
text-white placeholder:text-gray-400
focus:outline-none focus:border-white/30"
/>
<span className="absolute start-4 top-1/2 -translate-y-1/2">
<IconLockDots fill={true} />
<span className="absolute start-4 top-[42px] -translate-y-1/2 text-white">
<IconLockDots fill />
</span>
</div>
</div>
{error && <p className="text-red-500 text-sm">{error}</p>}
{success && <p className="text-green-500 text-sm">{success}</p>}
{/* Submit */}
<button
type="submit"
disabled={loading}
className="btn w-full border-0 uppercase shadow-[0_10px_20px_-10px_rgba(67,97,238,0.44)] disabled:cursor-not-allowed disabled:opacity-70 !mt-6 bg-[linear-gradient(135deg,#1E3A8A_0%,#2563EB_50%,#00C6FF_100%)] text-white hover:bg-[linear-gradient(135deg,#00C6FF_0%,#2563EB_50%,#1E3A8A_100%)]"
className="w-full py-3 rounded-xl text-lg font-semibold text-white
bg-gradient-to-r from-blue-600 to-pink-500
shadow-lg transition-all hover:opacity-90 hover:scale-[1.02]
disabled:opacity-60"
>
{loading ? 'UPDATING…' : 'CHANGE PASSWORD'}
</button>
</div>
</form>
);
};

View File

@ -1,4 +1,5 @@
'use client';
import { IRootState } from '@/store';
import { usePathname } from 'next/navigation';
import React, { useEffect, useState } from 'react';
@ -18,11 +19,21 @@ const ContentAnimation = ({ children }: { children: React.ReactNode }) => {
setTimeout(() => {
setAnimation('');
}, 1100);
}, [pathname]);
}, [pathname, themeConfig.animation]);
return (
<>
{/* BEGIN CONTENT AREA */}
<div className={`${animation} animate__animated p-6`}>{children}</div>
<div
className={`
${animation} animate__animated
p-6
bg-[#111111]
min-h-screen
`}
>
{children}
</div>
{/* END CONTENT AREA */}
</>
);

View File

@ -1,6 +1,23 @@
const Footer = () => {
return (
<div className="p-6 pt-0 mt-auto text-center dark:text-white-dark ltr:sm:text-left rtl:sm:text-right">© {new Date().getFullYear()}. Vristo All rights reserved.</div>
<div className="mt-auto w-full text-center ltr:sm:text-left rtl:sm:text-right">
<div className="
px-6 py-4
bg-[#242424]
text-white
border-t border-[#000]/60
">
© {new Date().getFullYear()}. SocialBuddy All rights reserved. Powered By{' '}
<a
href="https://metatroncubesolutions.com/"
target="_blank"
className="underline hover:text-white/80"
>
MetatronCube
</a>
</div>
</div>
);
};

View File

@ -208,8 +208,17 @@ const Header = () => {
return (
<header className={`z-40 ${themeConfig.semidark && themeConfig.menu === 'horizontal' ? 'dark' : ''}`}>
<div className="shadow-sm">
<div className="relative flex w-full items-center bg-white px-5 py-2.5 dark:bg-black">
<div className="horizontal-logo flex items-center justify-between ltr:mr-2 rtl:ml-2 lg:hidden">
<div
className="
relative flex w-full items-center
bg-[#242424]
px-5 py-2.5
text-white
"
>
<div className="horizontal-logo flex items-center justify-between ltr:mr- rtl:ml-2 lg:hidden">
<button
type="button"
className="collapse-icon flex flex-none rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary ltr:ml-2 rtl:mr-2 dark:bg-dark/40 dark:text-[#d0d2d6] dark:hover:bg-dark/60 dark:hover:text-primary lg:hidden"
@ -218,8 +227,19 @@ 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" />
<img
className="block w-[184px] h-[70px] ltr:-ml-1 rtl:-mr-1 dark:hidden"
src="/assets/images/logo_socialbuddy.png"
alt="logo"
/>
<img
className="hidden w-[184px] h-[70px] ltr:-ml-1 rtl:-mr-1 dark:block"
src="/assets/images/logo_socialbuddy.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">Data4Autos</span> */}
</Link>
@ -244,7 +264,7 @@ const Header = () => {
</li>
</ul>
</div> */}
<div className="flex items-center justify-end space-x-1.5 ltr:ml-auto rtl:mr-auto rtl:space-x-reverse dark:text-[#d0d2d6] sm:flex-1 ltr:sm:ml-0 sm:rtl:mr-0 lg:space-x-2">
<div className="flex items-center justify-end space-x-1.5 ltr:ml-auto rtl:mr-auto rtl:space-x-reverse dark:text-[#ffffff] sm:flex-1 ltr:sm:ml-0 sm:rtl:mr-0 lg:space-x-2">
{/* <div className="sm:ltr:mr-auto sm:rtl:ml-auto">
<form
className={`${search && '!block'} absolute inset-x-0 top-1/2 z-10 mx-4 hidden -translate-y-1/2 sm:relative sm:top-0 sm:mx-0 sm:block sm:translate-y-0`}
@ -472,48 +492,48 @@ const Header = () => {
placement={`${isRtl ? 'bottom-start' : 'bottom-end'}`}
btnClassName="relative group block"
button={<div className="flex items-center justify-center">
<button className="flex items-center justify-center w-8 h-8 rounded-full bg-[rgb(0,209,255)] shadow-md hover:shadow-lg transition-transform duration-300 hover:scale-105">
<div className="flex items-center justify-center w-8 h-8 rounded-full bg-[rgb(0,209,255)] shadow-md hover:shadow-lg transition-transform duration-300 hover:scale-105">
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-6 h-6 text-white fill-white"
className="w-6 h-6 text-white"
viewBox="0 0 24 24"
>
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
</svg>
</button>
</div>
</div>}
>
<ul className="w-[300px] !py-0 font-semibold text-dark dark:text-white-dark dark:text-white-light/90">
<li>
<div className="flex items-center px-4 py-4">
<div className="flex items-center bg-black px-4 py-4">
<button className="flex items-center justify-center w-8 h-8 rounded-full bg-[rgb(0,209,255)] shadow-md hover:shadow-lg transition-transform duration-300 hover:scale-105">
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-6 h-6 text-white fill-white"
className="w-6 h-6 text-white "
viewBox="0 0 24 24"
>
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
</svg>
</button> <div className="truncate ltr:pl-4 rtl:pr-4">
<h4 className="text-base">
Data4Autos
<h4 className="text-base text-white">
socialbuddy
{/* <span className="rounded bg-success-light px-1 text-xs text-success ltr:ml-2 rtl:ml-2">Pro</span> */}
</h4>
<button type="button" className="text-black/60 hover:text-primary dark:text-dark-light/60 dark:hover:text-white">
<button type="button" className="text-white/60 hover:text-primary dark:text-dark-light/60 dark:hover:text-white">
{user && user}
</button>
</div>
</div>
</li>
{/* <li>
<Link href="/users/profile" className="dark:hover:text-white">
<li className="bg-black dark:border-white-light/10">
<Link href="/users/profile" className="text-white bg-black">
<IconUser className="h-4.5 w-4.5 shrink-0 ltr:mr-2 rtl:ml-2" />
Profile
</Link>
</li>
<li>
{/* <li>
<Link href="/apps/mailbox" className="dark:hover:text-white">
<IconMail className="h-4.5 w-4.5 shrink-0 ltr:mr-2 rtl:ml-2" />
Inbox
@ -525,7 +545,7 @@ const Header = () => {
Lock Screen
</Link>
</li> */}
<li className="border-t border-white-light dark:border-white-light/10">
<li className="border-t border-white-light bg-black dark:border-white-light/10">
<button
onClick={handleSignOut}
className="!py-3 text-danger flex items-center"

View File

@ -1,4 +1,5 @@
'use client';
import React, { useEffect, useState } from 'react';
const ScrollToTop = () => {
@ -20,26 +21,37 @@ const ScrollToTop = () => {
useEffect(() => {
window.addEventListener('scroll', onScrollHandler);
return () => {
window.removeEventListener('onscroll', onScrollHandler);
window.removeEventListener('scroll', onScrollHandler);
};
});
return (
<div className="fixed bottom-6 z-50 ltr:right-6 rtl:left-6">
{showTopButton && (
<button type="button" className="btn btn-outline-primary animate-pulse rounded-full bg-[#fafafa] p-2 dark:bg-[#060818] dark:hover:bg-primary" onClick={goToTop}>
<svg width="24" height="24" className="h-4 w-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<button
type="button"
onClick={goToTop}
className="btn btn-outline-primary animate-pulse rounded-full bg-[#fafafa] p-2 dark:bg-[#060818] dark:hover:bg-primary"
>
<svg
width="24"
height="24"
className="h-4 w-4"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
opacity="0.5"
fillRule="evenodd"
clipRule="evenodd"
d="M12 20.75C12.4142 20.75 12.75 20.4142 12.75 20L12.75 10.75L11.25 10.75L11.25 20C11.25 20.4142 11.5858 20.75 12 20.75Z"
fill="currentColor"
></path>
/>
<path
d="M6.00002 10.75C5.69667 10.75 5.4232 10.5673 5.30711 10.287C5.19103 10.0068 5.25519 9.68417 5.46969 9.46967L11.4697 3.46967C11.6103 3.32902 11.8011 3.25 12 3.25C12.1989 3.25 12.3897 3.32902 12.5304 3.46967L18.5304 9.46967C18.7449 9.68417 18.809 10.0068 18.6929 10.287C18.5768 10.5673 18.3034 10.75 18 10.75L6.00002 10.75Z"
fill="currentColor"
></path>
/>
</svg>
</button>
)}

View File

@ -1,75 +1,177 @@
'use client';
/* ======================================================
IMPORTS
====================================================== */
import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { IRootState } from '@/store';
import { toggleAnimation, toggleLayout, toggleMenu, toggleNavbar, toggleRTL, toggleTheme, toggleSemidark, resetToggleSidebar } from '@/store/themeConfigSlice';
import {
toggleAnimation,
toggleLayout,
toggleMenu,
toggleNavbar,
toggleRTL,
toggleTheme,
toggleSemidark,
resetToggleSidebar,
} from '@/store/themeConfigSlice';
// Icons
import IconSettings from '@/components/icon/icon-settings';
import IconX from '@/components/icon/icon-x';
import IconSun from '@/components/icon/icon-sun';
import IconMoon from '@/components/icon/icon-moon';
import IconLaptop from '@/components/icon/icon-laptop';
/* ======================================================
COMPONENT
====================================================== */
const Setting = () => {
const themeConfig = useSelector((state: IRootState) => state.themeConfig);
const dispatch = useDispatch();
const [showCustomizer, setShowCustomizer] = useState(false);
return (
<div>
<div className={`${(showCustomizer && '!block') || ''} fixed inset-0 z-[51] hidden bg-[black]/60 px-4 transition-[display]`} onClick={() => setShowCustomizer(false)}></div>
{/* ==================================================
OVERLAY (Background blur when drawer opens)
================================================== */}
<div
className={`fixed inset-0 z-[51] bg-black/70 backdrop-blur-sm ${
showCustomizer ? 'block' : 'hidden'
}`}
onClick={() => setShowCustomizer(false)}
/>
{/* ==================================================
CUSTOMIZER DRAWER
Footer-style dark background applied
================================================== */}
<nav
className={`${
(showCustomizer && 'ltr:!right-0 rtl:!left-0') || ''
} fixed bottom-0 top-0 z-[51] w-full max-w-[400px] bg-white p-4 shadow-[5px_0_25px_0_rgba(94,92,154,0.1)] transition-[right] duration-300 ltr:-right-[400px] rtl:-left-[400px] dark:bg-black`}
className={`
fixed top-0 bottom-0 z-[52]
w-full max-w-[400px]
transition-all duration-300
border-l border-white/10
shadow-2xl
${showCustomizer ? 'ltr:right-0 rtl:left-0' : 'ltr:-right-[400px] rtl:-left-[400px]'}
`}
>
{/* ==================================================
FOOTER-STYLE BACKGROUND LAYER
================================================== */}
<div className="absolute inset-0 bg-[#0b0d1c]">
{/* Blue glow */}
<div className="absolute top-24 left-6 w-24 h-24 bg-blue-500/40 blur-3xl rounded-full" />
{/* Purple glow */}
<div className="absolute bottom-32 -left-10 w-40 h-40 bg-purple-600/40 blur-3xl rounded-full" />
{/* Cyan glow */}
<div className="absolute top-1/2 -right-10 w-32 h-32 bg-cyan-400/30 blur-3xl rounded-full" />
</div>
{/* ==================================================
TOGGLE BUTTON
================================================== */}
<button
type="button"
className="absolute bottom-0 top-0 my-auto flex h-10 w-12 cursor-pointer items-center justify-center bg-primary text-white ltr:-left-12 ltr:rounded-bl-full ltr:rounded-tl-full rtl:-right-12 rtl:rounded-br-full rtl:rounded-tr-full"
className="
absolute inset-y-0 my-auto
flex h-12 w-12 items-center justify-center
bg-gradient-to-br from-blue-600 to-cyan-400
text-white shadow-lg
ltr:-left-12 rtl:-right-12
rounded-full
z-10
"
onClick={() => setShowCustomizer(!showCustomizer)}
>
<IconSettings className="h-5 w-5 animate-[spin_3s_linear_infinite]" />
<IconSettings className="h-5 w-5 animate-[spin_6s_linear_infinite]" />
</button>
<div className="perfect-scrollbar h-full overflow-y-auto overflow-x-hidden">
<div className="relative pb-5 text-center">
<button type="button" className="absolute top-0 opacity-30 hover:opacity-100 ltr:right-0 rtl:left-0 dark:text-white" onClick={() => setShowCustomizer(false)}>
{/* ==================================================
CONTENT (Glass effect over footer bg)
================================================== */}
<div className="relative h-full overflow-y-auto px-5 py-6 text-white backdrop-blur-xl bg-black/40">
{/* HEADER */}
<div className="relative mb-6 text-center">
<button
type="button"
className="absolute right-0 top-0 text-gray-400 hover:text-white"
onClick={() => setShowCustomizer(false)}
>
<IconX className="h-5 w-5" />
</button>
<h4 className="mb-1 dark:text-white">TEMPLATE CUSTOMIZER</h4>
<p className="text-white-dark">Set preferences that will be cookied for your live preview demonstration.</p>
<h4 className="text-lg font-semibold">
Template Customizer
</h4>
<p className="text-sm text-gray-400">
UI preferences (saved automatically)
</p>
</div>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Color Scheme</h5>
<p className="text-xs text-white-dark">Overall light or dark presentation.</p>
<div className="mt-3 grid grid-cols-3 gap-2">
<button type="button" className={`${themeConfig.theme === 'light' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('light'))}>
<IconSun className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2" />
Light
</button>
{/* ==================================================
SETTINGS SECTIONS
================================================== */}
<div className="space-y-5">
<button type="button" className={`${themeConfig.theme === 'dark' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('dark'))}>
<IconMoon className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2" />
Dark
</button>
{/* COLOR SCHEME */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-2">Color Scheme</h5>
<button type="button" className={`${themeConfig.theme === 'system' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('system'))}>
<IconLaptop className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2" />
System
</button>
</div>
</div>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Navigation Position</h5>
<p className="text-xs text-white-dark">Select the primary navigation paradigm for your app.</p>
<div className="mt-3 grid grid-cols-3 gap-2">
<div className="grid grid-cols-3 gap-2">
<button
type="button"
className={`${themeConfig.menu === 'horizontal' ? 'btn-primary' : 'btn-outline-primary'} btn`}
className={`btn ${
themeConfig.theme === 'light'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleTheme('light'))}
>
<IconSun className="w-4 h-4 mr-1" /> Light
</button>
<button
className={`btn ${
themeConfig.theme === 'dark'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleTheme('dark'))}
>
<IconMoon className="w-4 h-4 mr-1" /> Dark
</button>
<button
className={`btn ${
themeConfig.theme === 'system'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleTheme('system'))}
>
<IconLaptop className="w-4 h-4 mr-1" /> System
</button>
</div>
</section>
{/* NAVIGATION */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-2">Navigation</h5>
<div className="grid grid-cols-3 gap-2">
<button
className={`btn ${
themeConfig.menu === 'horizontal'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => {
dispatch(toggleMenu('horizontal'));
dispatch(resetToggleSidebar());
@ -79,8 +181,11 @@ const Setting = () => {
</button>
<button
type="button"
className={`${themeConfig.menu === 'vertical' ? 'btn-primary' : 'btn-outline-primary'} btn`}
className={`btn ${
themeConfig.menu === 'vertical'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => {
dispatch(toggleMenu('vertical'));
dispatch(resetToggleSidebar());
@ -90,8 +195,11 @@ const Setting = () => {
</button>
<button
type="button"
className={`${themeConfig.menu === 'collapsible-vertical' ? 'btn-primary' : 'btn-outline-primary'} btn`}
className={`btn ${
themeConfig.menu === 'collapsible-vertical'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => {
dispatch(toggleMenu('collapsible-vertical'));
dispatch(resetToggleSidebar());
@ -100,100 +208,124 @@ const Setting = () => {
Collapsible
</button>
</div>
<div className="mt-5 text-primary">
<label className="mb-0 inline-flex">
<input type="checkbox" className="form-checkbox" checked={themeConfig.semidark} onChange={(e) => dispatch(toggleSemidark(e.target.checked))} />
<span>Semi Dark (Sidebar & Header)</span>
</label>
</div>
</div>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Layout Style</h5>
<p className="text-xs text-white-dark">Select the primary layout style for your app.</p>
<div className="mt-3 flex gap-2">
<label className="mt-4 flex items-center gap-2 text-sm text-gray-300">
<input
type="checkbox"
className="form-checkbox"
checked={themeConfig.semidark}
onChange={(e) =>
dispatch(toggleSemidark(e.target.checked))
}
/>
Semi-dark Header & Sidebar
</label>
</section>
{/* LAYOUT */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-3">Layout</h5>
<div className="flex gap-2">
<button
type="button"
className={`${themeConfig.layout === 'boxed-layout' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`}
onClick={() => dispatch(toggleLayout('boxed-layout'))}
className={`btn flex-1 ${
themeConfig.layout === 'boxed-layout'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() =>
dispatch(toggleLayout('boxed-layout'))
}
>
Box
Boxed
</button>
<button type="button" className={`${themeConfig.layout === 'full' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleLayout('full'))}>
<button
className={`btn flex-1 ${
themeConfig.layout === 'full'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() =>
dispatch(toggleLayout('full'))
}
>
Full
</button>
</div>
</div>
</section>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Direction</h5>
<p className="text-xs text-white-dark">Select the direction for your app.</p>
<div className="mt-3 flex gap-2">
<button type="button" className={`${themeConfig.rtlClass === 'ltr' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleRTL('ltr'))}>
{/* DIRECTION */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-3">Direction</h5>
<div className="flex gap-2">
<button
className={`btn flex-1 ${
themeConfig.rtlClass === 'ltr'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleRTL('ltr'))}
>
LTR
</button>
<button type="button" className={`${themeConfig.rtlClass === 'rtl' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleRTL('rtl'))}>
<button
className={`btn flex-1 ${
themeConfig.rtlClass === 'rtl'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleRTL('rtl'))}
>
RTL
</button>
</div>
</div>
</section>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Navbar Type</h5>
<p className="text-xs text-white-dark">Sticky or Floating.</p>
<div className="mt-3 flex items-center gap-3 text-primary">
<label className="mb-0 inline-flex">
<input
type="radio"
checked={themeConfig.navbar === 'navbar-sticky'}
value="navbar-sticky"
className="form-radio"
onChange={() => dispatch(toggleNavbar('navbar-sticky'))}
/>
<span>Sticky</span>
</label>
<label className="mb-0 inline-flex">
<input
type="radio"
checked={themeConfig.navbar === 'navbar-floating'}
value="navbar-floating"
className="form-radio"
onChange={() => dispatch(toggleNavbar('navbar-floating'))}
/>
<span>Floating</span>
</label>
<label className="mb-0 inline-flex">
<input
type="radio"
checked={themeConfig.navbar === 'navbar-static'}
value="navbar-static"
className="form-radio"
onChange={() => dispatch(toggleNavbar('navbar-static'))}
/>
<span>Static</span>
</label>
</div>
</div>
{/* NAVBAR */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-2">Navbar</h5>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]">
<h5 className="mb-1 text-base leading-none dark:text-white">Router Transition</h5>
<p className="text-xs text-white-dark">Animation of main content.</p>
<div className="mt-3">
<select className="form-select border-primary text-primary" value={themeConfig.animation} onChange={(e) => dispatch(toggleAnimation(e.target.value))}>
<div className="flex gap-3 text-sm text-gray-300">
{['navbar-sticky', 'navbar-floating', 'navbar-static'].map(
(val) => (
<label key={val} className="flex items-center gap-1">
<input
type="radio"
className="form-radio"
checked={themeConfig.navbar === val}
onChange={() => dispatch(toggleNavbar(val))}
/>
{val.replace('navbar-', '')}
</label>
)
)}
</div>
</section>
{/* PAGE ANIMATION */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-2">Page Transition</h5>
<select
className="w-full rounded-lg bg-black/40 border border-white/15 text-white px-3 py-2"
value={themeConfig.animation}
onChange={(e) =>
dispatch(toggleAnimation(e.target.value))
}
>
<option value=" ">None</option>
<option value="animate__fadeIn">Fade</option>
<option value="animate__fadeInDown">Fade Down</option>
<option value="animate__fadeInUp">Fade Up</option>
<option value="animate__fadeInDown">Fade Down</option>
<option value="animate__fadeInLeft">Fade Left</option>
<option value="animate__fadeInRight">Fade Right</option>
<option value="animate__slideInDown">Slide Down</option>
<option value="animate__slideInLeft">Slide Left</option>
<option value="animate__slideInRight">Slide Right</option>
<option value="animate__zoomIn">Zoom In</option>
<option value="animate__zoomIn">Zoom</option>
</select>
</div>
</section>
</div>
</div>
</nav>

View File

@ -40,14 +40,14 @@ const Sidebar = () => {
}
}
}
}, [pathname]);
}, [dispatch, themeConfig.sidebar]);
useEffect(() => {
setActiveRoute();
if (window.innerWidth < 1024 && themeConfig.sidebar) {
dispatch(toggleSidebar());
}
}, [pathname]);
}, [dispatch, themeConfig.sidebar]);
const setActiveRoute = () => {
let allLinks = document.querySelectorAll('.sidebar ul a.active');
@ -60,15 +60,13 @@ const Sidebar = () => {
};
return (
<div className={semidark ? 'dark' : ''}>
<nav
className={`sidebar fixed bottom-0 top-0 z-50 h-full min-h-screen w-[260px] shadow-[5px_0_25px_0_rgba(94,92,154,0.1)] transition-all duration-300 ${semidark ? 'text-white-dark' : ''}`}
>
<div className="h-full bg-white dark:bg-black">
<div className="dark">
<nav className="sidebar fixed bottom-0 top-0 z-50 h-full min-h-screen w-[260px] bg-[#242424] text-white transition-all duration-300">
<div className="h-full bg-[#242424]">
<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" />
<img className="ml-[5px] w-[184px] h-[70px] flex-none block dark:hidden" src="/assets/images/logo_socialbuddy.png" alt="logo" />
<img className="ml-[5px] w-[184px] h-[70px] flex-none hidden dark:block" src="/assets/images/logo_socialbuddy.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">Data4Autos</span> */}
</Link>
<button

View File

@ -1,6 +1,6 @@
'use client';
import React, { Fragment, useEffect, useState } from 'react';
import { Dialog, Transition, TransitionChild, DialogPanel } from '@headlessui/react';
import { Dialog, Transition } from '@headlessui/react';
import IconX from '@/components/icon/icon-x';
import IconUserPlus from '@/components/icon/icon-user-plus';
import IconSearch from '@/components/icon/icon-search';
@ -13,56 +13,58 @@ const UserModule = () => {
const [search, setSearch] = useState('');
const [addUserModal, setAddUserModal] = useState(false);
// ✅ NEW: delete modal state (UI only)
const [deleteUserModal, setDeleteUserModal] = useState(false);
const [userToDelete, setUserToDelete] = useState<any>(null);
const isAdminUser = true;
const defaultParams = {
userid: null,
name: '',
email: '',
mobileNumber: '',
password: '',
phonenumber: '',
role: 'customer',
};
const [params, setParams] = useState<any>({ ...defaultParams });
// ✅ Fetch users
/* ================= LOGIC ================= */
const fetchUsers = async () => {
try {
const res = await axios.get('https://ebay.backend.data4autos.com/api/auth/users');
setUsers(res.data?.users || []);
setFilteredUsers(res.data?.users || []);
} catch (err) {
console.error(err);
const res = await axios.get('/api/users');
setUsers(res.data || []);
setFilteredUsers(res.data || []);
} catch {
showMessage('Failed to load users', 'error');
}
};
useEffect(() => {
fetchUsers();
}, []);
},);
// ✅ Search filter
useEffect(() => {
if (!search) {
setFilteredUsers(users);
} else {
setFilteredUsers(
users.filter((u) => u.name.toLowerCase().includes(search.toLowerCase()))
search
? users.filter((u) =>
(u.name || '').toLowerCase().includes(search.toLowerCase())
)
: users
);
}
}, [search, users]);
const showMessage = (msg = '', type = 'success') => {
const toast: any = Swal.mixin({
Swal.mixin({
toast: true,
position: 'top',
showConfirmButton: false,
timer: 2500,
customClass: { container: 'toast' },
});
toast.fire({
icon: type,
title: msg,
padding: '10px 20px',
});
}).fire({ icon: type as any, title: msg });
};
const changeValue = (e: any) => {
@ -70,126 +72,132 @@ const UserModule = () => {
setParams({ ...params, [id]: value });
};
// ✅ Add / Update User
const saveUser = async () => {
if (!params.name || !params.email || !params.phonenumber || !params.role) {
showMessage('Please fill all required fields', 'error');
if (!params.name || !params.email || !params.mobileNumber) {
showMessage('Name, email and mobile number are required', 'error');
return;
}
const payload = {
name: params.name,
email: params.email,
mobileNumber: params.mobileNumber,
password: params.password,
role: params.role,
};
try {
if (params.userid) {
// UPDATE
await axios.put(`https://ebay.backend.data4autos.com/api/auth/users/${params.userid}`, params);
await axios.put(`/api/users/${params.userid}`, payload);
showMessage('User updated successfully');
} else {
// ADD
await axios.post('https://ebay.backend.data4autos.com/api/auth/users/add', params);
showMessage('User added successfully');
await axios.post('/api/users', payload);
showMessage('User created successfully');
}
setAddUserModal(false);
setParams(defaultParams);
fetchUsers();
} catch (err: any) {
console.error(err);
showMessage('Error saving user', 'error');
} catch {
showMessage('Failed to save user', 'error');
}
};
// ✅ Edit User
const editUser = (user: any) => {
setParams({ ...user, password: '' }); // dont show password in edit
setParams({
userid: user.userid,
name: user.name,
email: user.email,
mobileNumber: user.mobileNumber || '',
role: user.role,
});
setAddUserModal(true);
};
// ✅ Delete User
const deleteUser = async (user: any) => {
Swal.fire({
title: 'Are you sure?',
text: `Delete user ${user.name}?`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Cancel',
}).then(async (result) => {
if (result.isConfirmed) {
try {
await axios.delete(`https://ebay.backend.data4autos.com/api/auth/users/${user.userid}`);
showMessage('User deleted successfully');
fetchUsers();
} catch (err) {
console.error(err);
showMessage('Failed to delete user', 'error');
}
}
});
};
return (
<div>
{/* Header */}
<div className="flex flex-wrap items-center justify-between gap-4">
<div className="relative min-h-screen w-full bg-[#111111] p-6">
{/* BACKGROUND GLOWS */}
<div className="pointer-events-none absolute inset-0">
<div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-[1.5]" />
<div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-[1.5]" />
<div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-1" />
<div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
</div>
{/* CONTENT */}
<div className="relative z-10 text-white w-full min-h-screen">
{/* HEADER */}
<div className="flex justify-between items-center mb-6">
<h2 className="text-xl font-semibold">Users</h2>
<div className="flex gap-3 items-center">
<div className="flex gap-3">
<button
type="button"
className="btn btn-primary"
className="btn btn-primary text-white bg-gradient-to-r from-blue-600 to-pink-500"
disabled={!isAdminUser}
onClick={() => {
setParams(defaultParams);
setAddUserModal(true);
}}
>
<IconUserPlus className="ltr:mr-2 rtl:ml-2" /> Add User
<IconUserPlus className="mr-2" />
Add User
</button>
<div className="relative">
<input
type="text"
placeholder="Search User"
className="form-input py-2 ltr:pr-10 rtl:pl-10"
placeholder="Search user"
value={search}
onChange={(e) => setSearch(e.target.value)}
className="px-3 py-2 rounded-lg bg-[rgba(7,13,30,0.7)] border border-white/15 text-white"
/>
<button
type="button"
className="absolute top-1/2 -translate-y-1/2 ltr:right-[11px] rtl:left-[11px]"
>
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400">
<IconSearch />
</button>
</span>
</div>
</div>
</div>
{/* ✅ Table */}
<div className="panel mt-5 overflow-hidden border-0 p-0">
<div className="table-responsive">
<table className="table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Role</th>
<th className="!text-center">Actions</th>
{/* TABLE */}
<div className="rounded-2xl overflow-hidden border border-white/10 backdrop-blur-xl">
<table className="w-full text-sm text-white">
<thead className="bg-gray text-white">
<tr className='bg-gray'>
<th className="px-5 py-3 text-left bg-[#242424]">Name</th>
<th className='bg-[#242424]'>Email</th>
<th className='bg-[#242424]'>Mobile Number</th>
<th className='bg-[#242424]'>Role</th>
<th className="text-center bg-[#242424]">Actions</th>
</tr>
</thead>
<tbody>
{filteredUsers.map((user: any) => (
<tr key={user.userid}>
<td>{user.name}</td>
{filteredUsers.map((user) => (
<tr key={user.userid} className="border-t border-white/10 hover:bg-white/5">
<td className="px-5 py-4">{user.name}</td>
<td>{user.email}</td>
<td>{user.phonenumber}</td>
<td>{user.role}</td>
<td>{user.mobileNumber}</td>
<td>
<span className="px-3 py-1 rounded-full text-xs bg-blue-500/20 text-blue-400 capitalize">
{user.role}
</span>
</td>
<td className="text-center">
<div className="flex justify-center gap-2">
<button
className="btn btn-sm btn-outline-primary"
onClick={() => editUser(user)}
className="btn btn-sm btn-outline-primary"
>
Edit
</button>
<button
onClick={() => {
setUserToDelete(user);
setDeleteUserModal(true);
}}
className="btn btn-sm btn-outline-danger"
onClick={() => deleteUser(user)}
>
Delete
</button>
@ -202,129 +210,85 @@ const UserModule = () => {
</div>
</div>
{/* ✅ Add / Edit Popup */}
{/* ADD / EDIT MODAL */}
<Transition appear show={addUserModal} as={Fragment}>
<Dialog
as="div"
open={addUserModal}
onClose={() => setAddUserModal(false)}
className="relative z-50"
>
<TransitionChild
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-[black]/60" />
</TransitionChild>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center px-4 py-8">
<TransitionChild
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<DialogPanel className="panel w-full max-w-lg overflow-hidden rounded-lg border-0 p-0 text-black dark:text-white-dark">
<button
type="button"
onClick={() => setAddUserModal(false)}
className="absolute top-4 text-gray-400 hover:text-gray-800 ltr:right-4 rtl:left-4"
>
<Dialog as="div" open={addUserModal} onClose={() => setAddUserModal(false)} className="relative z-50">
<div className="fixed inset-0 bg-black/70" />
<div className="fixed inset-0 flex items-center justify-center px-4">
<Dialog.Panel className="w-full max-w-lg rounded-xl bg-[#0b0d1c] p-6 border border-white/20 text-white">
<button onClick={() => setAddUserModal(false)} className="absolute top-4 right-4 text-gray-400">
<IconX />
</button>
<div className="bg-[#fbfbfb] py-3 text-lg font-medium ltr:pl-5 rtl:pr-5 dark:bg-[#121c2c]">
<h3 className="mb-4 text-lg font-semibold">
{params.userid ? 'Edit User' : 'Add User'}
</div>
<div className="p-5">
<form>
<div className="mb-4">
<label>Name</label>
<input
id="name"
type="text"
className="form-input"
value={params.name}
onChange={changeValue}
placeholder="Enter name"
/>
</div>
<div className="mb-4">
<label>Email</label>
<input
id="email"
type="email"
className="form-input"
value={params.email}
onChange={changeValue}
placeholder="Enter email"
/>
</div>
</h3>
<div className="space-y-3">
<input id="name" value={params.name} onChange={changeValue} placeholder="Name"
className="w-full px-3 py-2 rounded-lg bg-black/40 border border-white/15 text-white" />
<input id="email" value={params.email} onChange={changeValue} placeholder="Email"
className="w-full px-3 py-2 rounded-lg bg-black/40 border border-white/15 text-white" />
<input id="mobileNumber" value={params.mobileNumber} onChange={changeValue} placeholder="Mobile"
className="w-full px-3 py-2 rounded-lg bg-black/40 border border-white/15 text-white" />
{!params.userid && (
<div className="mb-4">
<label>Password</label>
<input
id="password"
type="password"
className="form-input"
value={params.password}
onChange={changeValue}
placeholder="Enter password"
/>
</div>
<input id="password" type="password" value={params.password} onChange={changeValue}
placeholder="Password"
className="w-full px-3 py-2 rounded-lg bg-black/40 border border-white/15 text-white" />
)}
<div className="mb-4">
<label>Phone Number</label>
<input
id="phonenumber"
type="text"
className="form-input"
value={params.phonenumber}
onChange={changeValue}
placeholder="Enter phone number"
/>
</div>
<div className="mb-4">
<label>Role</label>
<select
id="role"
className="form-select"
value={params.role}
onChange={changeValue}
>
<select id="role" value={params.role} onChange={changeValue}
className="w-full px-3 py-2 rounded-lg bg-black/40 border border-white/15 text-white">
<option value="admin">Admin</option>
<option value="partner">Partner</option>
<option value="customer">Customer</option>
</select>
</div>
<div className="mt-6 flex justify-end">
<button
type="button"
className="btn btn-outline-danger"
onClick={() => setAddUserModal(false)}
>
<div className="flex justify-end gap-3 pt-4">
<button className="btn btn-outline-danger" onClick={() => setAddUserModal(false)}>
Cancel
</button>
<button
type="button"
className="btn btn-primary ltr:ml-4 rtl:mr-4"
onClick={saveUser}
>
<button className="btn btn-primary bg-gradient-to-r from-blue-600 to-pink-500" onClick={saveUser}>
{params.userid ? 'Update' : 'Add'}
</button>
</div>
</form>
</div>
</DialogPanel>
</TransitionChild>
</Dialog.Panel>
</div>
</Dialog>
</Transition>
{/* DELETE MODAL SAME CARD UI */}
<Transition appear show={deleteUserModal} as={Fragment}>
<Dialog as="div" open={deleteUserModal} onClose={() => setDeleteUserModal(false)} className="relative z-50">
<div className="fixed inset-0 bg-black/70" />
<div className="fixed inset-0 flex items-center justify-center px-4">
<Dialog.Panel className="w-full max-w-lg rounded-xl bg-[#0b0d1c] p-6 border border-white/20 text-white">
<button onClick={() => setDeleteUserModal(false)} className="absolute top-4 right-4 text-gray-400">
<IconX />
</button>
<h3 className="mb-2 text-lg font-semibold">Delete User</h3>
<p className="text-sm text-gray-400 mb-6">
Are you sure you want to delete <span className="text-white">{userToDelete?.email}</span>?
</p>
<div className="flex justify-end gap-3">
<button className="btn btn-outline-danger" onClick={() => setDeleteUserModal(false)}>
Cancel
</button>
<button
className="btn btn-primary bg-gradient-to-r from-blue-600 to-pink-500"
onClick={async () => {
await axios.delete(`/api/users/${userToDelete.userid}`);
showMessage('User deleted');
setDeleteUserModal(false);
fetchUsers();
}}
>
Delete
</button>
</div>
</Dialog.Panel>
</div>
</Dialog>
</Transition>

20
package-lock.json generated
View File

@ -20,12 +20,14 @@
"eslint-config-next": "14.2.13",
"i18next": "^23.13.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.562.0",
"next": "14.2.13",
"ni18n": "^1.0.5",
"react": "18.3.1",
"react-animate-height": "^3.1.0",
"react-dom": "18.3.1",
"react-i18next": "^15.0.2",
"react-icons": "^5.5.0",
"react-perfect-scrollbar": "^1.5.8",
"react-popper": "^2.3.0",
"react-redux": "^9.1.2",
@ -4323,6 +4325,15 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"node_modules/lucide-react": {
"version": "0.562.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz",
"integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==",
"license": "ISC",
"peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -5289,6 +5300,15 @@
}
}
},
"node_modules/react-icons": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",

View File

@ -21,12 +21,14 @@
"eslint-config-next": "14.2.13",
"i18next": "^23.13.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.562.0",
"next": "14.2.13",
"ni18n": "^1.0.5",
"react": "18.3.1",
"react-animate-height": "^3.1.0",
"react-dom": "18.3.1",
"react-i18next": "^15.0.2",
"react-icons": "^5.5.0",
"react-perfect-scrollbar": "^1.5.8",
"react-popper": "^2.3.0",
"react-redux": "^9.1.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB