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 ComponentsAuthUnlockForm from '@/components/auth/components-auth-unlock-form';
import { Metadata } from 'next'; import { Metadata } from 'next';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Unlock Cover', title: 'Unlock',
}; };
const CoverLockScreen = () => { export default function CoverLockScreen() {
return ( return (
<div> <div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* 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 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"> {/* ===== Background Glows (SAME AS LOGIN) ===== */}
{/* 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 */} {/* Blue */}
<div className="relative flex w-full max-w-[1502px] flex-col justify-between overflow-hidden rounded-md bg-white/60 backdrop-blur-lg dark:bg-black/50 lg:min-h-[758px] lg:flex-row lg:gap-10 xl:gap-0"> <div className="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,#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>
{/* Centered Image */} {/* Green left */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full"> <div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
<img
src="/assets/images/auth/sign-in.webp" {/* Pink left */}
alt="Login Illustration" <div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
className="max-w-[430px] w-full"
/> {/* 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/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[120px] w-[120px]"
/>
{/* 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>
{/* RIGHT SIDE */} </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]">
{/* Unlock Form (UNCHANGED) */}
{/* ✅ Top-right logo (responsive + transparent) */} <ComponentsAuthUnlockForm />
<div className="absolute right-4 top-0 sm:top-2 md:top-3 lg:top-0 z-10">
<Link href="/" className="block"> {/* Footer */}
<img <div className="mt-6 text-center text-sm text-gray-400">
src="/assets/images/auth/logo_tri.png" Not you?{' '}
alt="data4autos" <Link href="/login" className="text-blue-400 hover:underline">
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" Switch account
/> </Link>
</Link>
</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>
<ComponentsAuthUnlockForm />
</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> </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 { Metadata } from 'next';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react'; import React from 'react';
import ForgotPasswordForm from '@/components/auth/components-auth-forgot-form';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Forgot Password', title: 'Forgot Password',
}; };
export default function CoverForgotPassword() { export default function ForgotPasswordPage() {
return ( return (
<div> <div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* 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 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"> {/* ===== Background Glows ===== */}
{/* Decorative images */} <div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
<img <div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
src="/assets/images/auth/coming-soon-object1.png" <div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
alt="image" <div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2" <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" />
<img <div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
src="/assets/images/auth/coming-soon-object2.png" <div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
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 */} {/* ===== FORGOT PASSWORD CARD ===== */}
<div className="relative flex w-full max-w-[1502px] flex-col justify-between overflow-hidden rounded-md bg-white/60 backdrop-blur-lg dark:bg-black/50 lg:min-h-[758px] lg:flex-row lg:gap-10 xl:gap-0"> <div className="relative z-10 w-full max-w-[460px] p-8 rounded-3xl bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#006AE0_0%,#00B4DB_50%,#19D4FB_100%)]
{/* Logo / Heading */}
<div className="flex flex-col items-center mb-6">
<img
src="/assets/images/logo_sb.png"
alt="SocialBuddy Logo"
className="h-[110px] w-[110px]"
/>
<h1 className="text-xl text-white font-medium mt-3">
Forgot your password?
</h1>
<p className="text-sm text-gray-300 mt-1 text-center">
Enter your email and well send you a reset link
</p>
</div>
p-5 lg:inline-flex lg:max-w-[835px] {/* Forgot Password Form */}
xl:-ms-28 ltr:xl:skew-x-[14deg] rtl:xl:skew-x-[-14deg]" <ForgotPasswordForm />
>
<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 */} {/* Back to login */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full"> <div className="text-center text-sm text-gray-400 mt-6">
<img Remember your password?{' '}
src="/assets/images/auth/sign-in.webp" <Link href="/login" className="text-blue-400 hover:underline">
alt="Login Illustration" SIGN IN
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> </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>
<p className="text-base font-bold leading-normal text-white-dark">
Enter your email to receive the reset link
</p>
</div>
{/* forgot form */}
<ComponentsAuthForgotForm />
<div className="text-center mt-8 dark:text-white">
Remember your password?&nbsp;
<Link href="/login" className="uppercase text-primary underline transition hover:text-black dark:hover:text-white">
SIGN IN
</Link>
</div>
</div>
<p className="absolute bottom-6 w-full text-center dark:text-white">
© {new Date().getFullYear()}. Data4Autos All Rights Reserved.
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
); );
} }

View File

@ -1,211 +1,49 @@
import React from 'react';
import ComponentsAuthLoginForm from '@/components/auth/components-auth-login-form'; 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 { Metadata } from 'next';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Login', title: 'Login',
}; };
const CoverLogin = () => { export default function SocialBuddyLogin() {
return ( return (
<div> <div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* Background */}
<div className="absolute inset-0"> {/* ===== Background Glows ===== */}
<img
src="/assets/images/auth/bg-gradient.png" {/* Blue */}
alt="background" <div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
className="h-full w-full object-cover"
/> {/* 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" />
<ComponentsAuthLoginForm />
</div> </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>
{/* 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 ComponentsAuthResetPasswordForm from '@/components/auth/components-auth-reset-password-form';
import { Metadata } from 'next'; import { Metadata } from 'next';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Recover Id Cover', title: 'Recover ID',
}; };
const CoverPasswordReset = () => { export default function CoverPasswordReset() {
return ( return (
<div> <div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
<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>
{/* Centered Image */} {/* ===== Background Glows (SAME AS LOGIN) ===== */}
<div className="ltr:xl:-skew-x-[14deg] rtl:xl:skew-x-[14deg] flex items-center justify-center w-full">
<img {/* Blue */}
src="/assets/images/auth/sign-in.webp" <div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
alt="Login Illustration"
className="max-w-[430px] w-full" {/* Green left */}
/> <div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
</div>
</div> {/* Pink left */}
<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]"> <div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
{/* ✅ Top-right logo (responsive + transparent) */}
<div className="absolute right-4 top-0 sm:top-2 md:top-3 lg:top-0 z-10"> {/* Pink bottom */}
<Link href="/" className="block"> <div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
<img
src="/assets/images/auth/logo_tri.png" {/* Orange */}
alt="data4autos" <div className="absolute top-[100px] right-[260px] w-[100px] h-[100px] bg-[#f28f50] rounded-full blur-2xl opacity-80" />
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"
/> {/* Green right */}
</Link> <div className="absolute top-10 right-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
</div>
<div className="w-full max-w-[440px] lg:mt-16"> {/* Purple */}
<div className="mb-7"> <div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
<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> {/* Yellow */}
</div> <div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
<ComponentsAuthResetPasswordForm />
</div> {/* ===== CARD ===== */}
<p className="absolute bottom-6 w-full text-center dark:text-white">© {new Date().getFullYear()}.Data4Autos All Rights Reserved.</p> <div className="relative z-10 w-full max-w-[500px] p-8 rounded-3xl
</div> 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="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>
{/* Reset Form (UNCHANGED) */}
<ComponentsAuthResetPasswordForm />
{/* 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> </div>
</div> </div>
); );
}; }
export default CoverPasswordReset;

View File

@ -1,218 +1,61 @@
import ComponentsAuthRegisterForm from '@/components/auth/components-auth-register-form'; 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 { Metadata } from 'next';
import Link from 'next/link'; import Link from 'next/link';
import React from 'react'; import React from 'react';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Register Cover', title: 'Sign Up',
}; };
const CoverRegister = () => { export default function BoxedSignUp() {
return ( return (
<div> <div className="relative min-h-screen overflow-hidden bg-[#0a0b17] flex items-center justify-center p-4">
{/* 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 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"> {/* ===== Background Glows ===== */}
{/* Decorative images */} <div className="absolute top-[180px] left-52 w-[100px] h-[100px] bg-[#1d8be0] rounded-full blur-2xl opacity-90" />
<img <div className="absolute top-10 left-0 w-[60px] h-[60px] bg-[#6cb655] rounded-full blur-2xl opacity-90" />
src="/assets/images/auth/coming-soon-object1.png" <div className="absolute -left-[80px] bottom-[140px] w-[100px] h-[200px] bg-[#db21d9] blur-3xl opacity-90" />
alt="image" <div className="absolute bottom-20 left-[440px] w-[60px] h-[60px] bg-[#db21d9] rounded-full blur-xl opacity-80" />
className="absolute left-0 top-1/2 h-full max-h-[893px] -translate-y-1/2" <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" />
<img <div className="absolute bottom-20 right-[180px] w-[80px] h-[80px] bg-[#783e8d] rounded-full blur-2xl opacity-80" />
src="/assets/images/auth/coming-soon-object2.png" <div className="absolute top-[280px] -right-[20px] w-[160px] h-[160px] bg-[#f1b74d] rounded-full blur-2xl opacity-90" />
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 */} {/* ===== SIGN UP CARD ===== */}
<div className="relative flex w-full max-w-[1502px] flex-col justify-between overflow-hidden rounded-md bg-white/60 backdrop-blur-lg dark:bg-black/50 lg:min-h-[758px] lg:flex-row lg:gap-10 xl:gap-0"> <div className="relative z-10 w-full max-w-[540px] p-8 rounded-3xl bg-white/10 backdrop-blur-xl border border-white/20 shadow-2xl">
{/* LEFT SIDE */}
<div
className="relative hidden w-full items-center justify-center
bg-[linear-gradient(135deg,#006AE0_0%,#00B4DB_50%,#19D4FB_100%)]
{/* Logo */}
<div className="flex flex-col items-center justify-center mb-6">
<img
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)]"
/>
p-5 lg:inline-flex lg:max-w-[835px] <h1 className="text-xl text-white font-medium text-center mt-3">
xl:-ms-28 ltr:xl:skew-x-[14deg] rtl:xl:skew-x-[-14deg]" Create Your SocialBuddy Account
</h1>
</div>
{/* Register Form */}
<ComponentsAuthRegisterForm />
{/* Footer link */}
<div className="text-center text-gray-400 text-sm mt-6">
Already have an account?{' '}
<Link
href="/login"
className="text-blue-400 hover:underline"
> >
<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> SIGN IN
</Link>
{/* 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>
<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;
<Link
href="/login"
className="uppercase text-primary underline transition hover:text-black dark:hover:text-white"
>
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> </div>
</div> </div>
); );
}; }
export default CoverRegister;

View File

@ -6,7 +6,76 @@ export const metadata: Metadata = {
}; };
const Sales = () => { 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; 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 React, { useState } from "react";
import axios from "axios"; import axios from "axios";
import { Mail } from "lucide-react";
export default function ForgotPasswordForm() { export default function ForgotPasswordForm() {
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
@ -12,12 +13,16 @@ export default function ForgotPasswordForm() {
e.preventDefault(); e.preventDefault();
setLoading(true); setLoading(true);
setMessage(""); setMessage("");
try { 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."); setMessage("✅ Weve emailed you a reset code / link. Enter it below.");
} catch (err: any) { } catch (err) {
console.error(err); console.error(err);
setMessage("Something went wrong. Try again."); setMessage("Something went wrong. Try again.");
} finally { } finally {
setLoading(false); setLoading(false);
} }
@ -25,27 +30,59 @@ export default function ForgotPasswordForm() {
return ( return (
<form onSubmit={handleForgot} className="space-y-5"> <form onSubmit={handleForgot} className="space-y-5">
{/* Email */}
<div> <div>
<label className="block text-sm font-medium text-white-dark mb-1"> <label className="block text-sm font-medium text-white-dark mb-1">
Email Email
</label> </label>
<input
type="email" <div className="relative">
required {/* Icon */}
value={email} <Mail
onChange={(e) => setEmail(e.target.value)} className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"
className="form-input ps-10 placeholder:text-white-dark" size={18}
placeholder="you@example.com" />
/>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
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> </div>
<button
type="submit" {/* Button */}
disabled={loading} <button
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%)]" type="submit"
> 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 ? "Sending..." : "Send Reset Link"} {loading ? "Sending..." : "Send Reset Link"}
</button> </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> </form>
); );
} }

View File

@ -1,148 +1,217 @@
'use client'; 'use client';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation'; import { useRouter, useSearchParams } from 'next/navigation';
import IconLockDots from '@/components/icon/icon-lock-dots'; import IconLockDots from '@/components/icon/icon-lock-dots';
import IconMail from '@/components/icon/icon-mail'; 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 ComponentsAuthLoginForm = () => {
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const nextUrl = searchParams.get('next') || '/'; const nextUrl = searchParams.get('next') || '/';
const [email, setEmail] = useState(''); const [formData, setFormData] = useState({
const [password, setPassword] = useState(''); email: '',
password: '',
});
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [err, setErr] = useState<string | null>(null); const [err, setErr] = useState<string | null>(null);
const [msg, setMsg] = 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>) => { const submitForm = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
setErr(null); setErr(null);
setMsg(null); setMsg(null);
if (!email || !password) { if (!formData.email || !formData.password) {
setErr('Please enter email and password.'); setErr('Please enter email and password.');
return; return;
} }
setLoading(true); setLoading(true);
try { try {
// ✅ Call your Next.js API (same origin), which sets d4a_uid, d4a_session, d4a_exp cookies // ✅ SAME backend logic as your old working code
const res = await fetch('https://ebay.backend.data4autos.com/api/auth/login', { const res = await fetch(
method: 'POST', 'https://ebay.backend.data4autos.com/api/auth/login',
headers: { 'Content-Type': 'application/json' }, {
// credentials not required for same-origin, but harmless: method: 'POST',
credentials: 'same-origin', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }), credentials: 'same-origin',
}); body: JSON.stringify(formData),
}
);
const contentType = res.headers.get('content-type') || ''; const contentType = res.headers.get('content-type') || '';
const data = contentType.includes('application/json') ? await res.json() : await res.text(); const data =
console.log("data data", data) contentType.includes('application/json')
try { ? await res.json()
console.log('data:', data.store); : await res.text();
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');
}
if (!res.ok) { 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: // ✅ Preserve existing storage behavior
if (process.env.NODE_ENV !== 'production') { try {
try { sessionStorage.setItem('USERID', data.userid);
const who = await fetch('/api/debug/whoami', { cache: 'no-store' }).then((r) => r.json()); sessionStorage.setItem('EBAYSTOREID', data.store?.urlPath);
console.log('whoami:', who); 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!'); setMsg('Login successful!');
setTimeout(() => router.push(nextUrl), 500); setTimeout(() => router.push(nextUrl), 500);
} catch (e: any) { } catch (e: any) {
setErr(e?.message || 'Something went wrong. Please try again.'); setErr(e?.message || 'Login failed');
} finally { } finally {
setLoading(false); setLoading(false);
} }
}; };
return ( 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>}
{/* Email */} {/* Alerts */}
<div> {err && (
<label htmlFor="Email">Email</label> <div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
<div className="relative text-white-dark"> {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 className="mb-4 relative">
<input <input
id="Email" name="email"
type="email" type="email"
placeholder="Enter Email" placeholder="Email Address"
className="form-input ps-10 placeholder:text-white-dark" className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
value={email} border border-white/15 rounded-lg text-white
onChange={(e) => setEmail(e.target.value)} focus:outline-none focus:border-white/30"
value={formData.email}
onChange={handleChange}
autoComplete="email" autoComplete="email"
/> />
<span className="absolute start-4 top-1/2 -translate-y-1/2"> <span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconMail fill={true} /> <IconMail fill />
</span> </span>
</div> </div>
</div>
{/* Password */} {/* Password */}
<div> <div className="mb-2 relative">
<label htmlFor="Password">Password</label>
<div className="relative text-white-dark">
<input <input
id="Password" name="password"
type="password" type={showPassword ? 'text' : 'password'}
placeholder="Enter Password" placeholder="Password"
className="form-input ps-10 placeholder:text-white-dark" className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
value={password} border border-white/15 rounded-lg text-white
onChange={(e) => setPassword(e.target.value)} focus:outline-none focus:border-white/30"
value={formData.password}
onChange={handleChange}
autoComplete="current-password" autoComplete="current-password"
/> />
<span className="absolute start-4 top-1/2 -translate-y-1/2"> <span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
<IconLockDots fill={true} /> <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> </span>
</div> </div>
</div>
{/* Optional newsletter */} {/* Google Sign-in */}
<div> <div className="flex justify-center px-8 mb-4">
<label className="flex cursor-pointer items-center"> <Link
<input type="checkbox" className="form-checkbox bg-white dark:bg-black" /> href="https://ebay.backend.data4autos.com/api/auth/google/"
<span className="text-white-dark">Subscribe to weekly newsletter</span> className="flex items-center gap-3 px-8 py-3 rounded-lg
</label> border border-white/20 text-white
</div> hover:bg-white/10 transition active:scale-[0.98]"
>
<FcGoogle size={20} />
<span className="text-sm">Continue with Google</span>
</Link>
</div>
{/* <button {/* Footer */}
type="submit" <div className="text-center text-sm text-gray-400">
disabled={loading} Don&rsquo;t have an account?{' '}
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" <Link href="/signup" className="text-blue-400 hover:underline">
> SIGN UP
{loading ? 'Signing in…' : 'Sign in'} </Link>
</button> */} </div>
<button </div>
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> </form>
); );
}; };
export default ComponentsAuthLoginForm; export default ComponentsAuthLoginForm;

View File

@ -7,9 +7,7 @@ import IconUser from '@/components/icon/icon-user';
const API_BASE = const API_BASE =
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, '') || process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, '') ||
// 'https://ebay.backend.data4autos.com'; 'https://ebay.backend.data4autos.com';
'https://ebay.backend.data4autos.com';
const ComponentsAuthRegisterForm = () => { const ComponentsAuthRegisterForm = () => {
const router = useRouter(); const router = useRouter();
@ -18,7 +16,6 @@ const ComponentsAuthRegisterForm = () => {
const [phonenumber, setPhonenumber] = useState(''); const [phonenumber, setPhonenumber] = useState('');
const [email, setEmail] = useState(''); const [email, setEmail] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [subscribe, setSubscribe] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [err, setErr] = useState<string | null>(null); const [err, setErr] = useState<string | null>(null);
@ -39,157 +36,127 @@ const ComponentsAuthRegisterForm = () => {
const res = await fetch(`${API_BASE}/api/auth/signup`, { const res = await fetch(`${API_BASE}/api/auth/signup`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
// If your API sets cookies, uncomment:
// credentials: 'include',
body: JSON.stringify({ body: JSON.stringify({
name, name,
email, email,
password, password,
phonenumber, phonenumber,
// You can also send `subscribe` if your API supports it
// subscribe,
}), }),
}); });
const contentType = res.headers.get('content-type') || ''; const data = await res.json();
let data: any = null; if (!res.ok) throw new Error(data?.message || 'Signup failed');
if (contentType.includes('application/json')) {
data = await res.json();
} else {
data = await res.text();
}
if (!res.ok) { setMsg('Signup successful!');
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)
setTimeout(() => router.push('/login'), 1000); setTimeout(() => router.push('/login'), 1000);
} catch (e: any) { } catch (e: any) {
setErr(e?.message || 'Something went wrong. Please try again.'); setErr(e?.message || 'Something went wrong.');
} finally { } finally {
setLoading(false); setLoading(false);
} }
}; };
return ( return (
<form className="space-y-3 p-4 dark:text-white" onSubmit={submitForm}> <form onSubmit={submitForm} className="dark:text-white">
{/* 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> */}
{/* Alerts */} {/* Alerts */}
{err && ( {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} {err}
</div> </div>
)} )}
{msg && ( {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} {msg}
</div> </div>
)} )}
{/* Submit */} <div className="space-y-4">
<button
type="submit" {/* Name */}
disabled={loading} <div className="relative">
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%)]" <input
> type="text"
{loading ? 'Creating account…' : 'Sign Up'} placeholder="Full Name"
</button> 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
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"
>
{loading ? 'Creating account…' : 'SIGN UP'}
</button>
</div>
</form> </form>
); );
}; };

View File

@ -10,22 +10,48 @@ const ComponentsAuthResetPasswordForm = () => {
e.preventDefault(); e.preventDefault();
router.push('/'); router.push('/');
}; };
return ( return (
<form className="space-y-5" onSubmit={submitForm}> <form onSubmit={submitForm} className="dark:text-white">
<div>
<label htmlFor="Email" className="dark:text-white"> <div className="space-y-4">
Email
</label> {/* Email */}
<div className="relative text-white-dark"> <div className="relative">
<input id="Email" type="email" placeholder="Enter Email" className="form-input ps-10 placeholder:text-white-dark" /> <label
<span className="absolute start-4 top-1/2 -translate-y-1/2"> htmlFor="Email"
<IconMail fill={true} /> className="block mb-1 text-sm text-gray-300"
>
Email
</label>
<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> </span>
</div> </div>
{/* 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> </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%)]">
RECOVER
</button>
</form> </form>
); );
}; };

View File

@ -33,27 +33,21 @@ const ComponentsAuthChangePasswordForm = () => {
return; return;
} }
// ✅ Create FormData and append fields
const formData = new FormData(); const formData = new FormData();
formData.append('currentPassword', currentPassword); formData.append('currentPassword', currentPassword);
formData.append('newPassword', newPassword); formData.append('newPassword', newPassword);
// ✅ Axios call with generic type
const res = await axios.post<ChangePasswordResponse>( const res = await axios.post<ChangePasswordResponse>(
`https://ebay.backend.data4autos.com/api/auth/change-password`, `https://ebay.backend.data4autos.com/api/auth/change-password`,
formData, formData,
{ {
headers: { headers: {
Authorization: `Bearer ${token}`, 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!'); setSuccess(res.data.message || 'Password updated successfully!');
// Optional: force re-login after password change
localStorage.removeItem('token'); localStorage.removeItem('token');
router.push('/login'); router.push('/login');
} catch (err: any) { } catch (err: any) {
@ -65,59 +59,91 @@ const ComponentsAuthChangePasswordForm = () => {
}; };
return ( return (
<form className="space-y-5" onSubmit={submitForm}> <form onSubmit={submitForm} className="dark:text-white">
{/* Current password */}
<div> {/* Alerts */}
<label htmlFor="currentPassword" className="dark:text-white"> {error && (
Current Password <div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
</label> {error}
<div className="relative text-white-dark"> </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>
<input <input
id="currentPassword" id="currentPassword"
type="password" type="password"
placeholder="Enter Current Password" placeholder="Current Password"
className="form-input ps-10 placeholder:text-white-dark"
value={currentPassword} value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)} onChange={(e) => setCurrentPassword(e.target.value)}
required 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> </span>
</div> </div>
</div>
{/* New password */} {/* New Password */}
<div> <div className="relative">
<label htmlFor="newPassword" className="dark:text-white"> <label
New Password htmlFor="newPassword"
</label> className="block mb-1 text-sm text-gray-300"
<div className="relative text-white-dark"> >
New Password
</label>
<input <input
id="newPassword" id="newPassword"
type="password" type="password"
placeholder="Enter New Password" placeholder="New Password"
className="form-input ps-10 placeholder:text-white-dark"
value={newPassword} value={newPassword}
onChange={(e) => setNewPassword(e.target.value)} onChange={(e) => setNewPassword(e.target.value)}
required 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> </span>
</div> </div>
{/* Submit */}
<button
type="submit"
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"
>
{loading ? 'UPDATING…' : 'CHANGE PASSWORD'}
</button>
</div> </div>
{error && <p className="text-red-500 text-sm">{error}</p>}
{success && <p className="text-green-500 text-sm">{success}</p>}
<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%)]"
>
{loading ? 'UPDATING…' : 'CHANGE PASSWORD'}
</button>
</form> </form>
); );
}; };

View File

@ -1,4 +1,5 @@
'use client'; 'use client';
import { IRootState } from '@/store'; import { IRootState } from '@/store';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
@ -18,11 +19,21 @@ const ContentAnimation = ({ children }: { children: React.ReactNode }) => {
setTimeout(() => { setTimeout(() => {
setAnimation(''); setAnimation('');
}, 1100); }, 1100);
}, [pathname]); }, [pathname, themeConfig.animation]);
return ( return (
<> <>
{/* BEGIN CONTENT AREA */} {/* 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 */} {/* END CONTENT AREA */}
</> </>
); );

View File

@ -1,6 +1,23 @@
const Footer = () => { const Footer = () => {
return ( 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 ( return (
<header className={`z-40 ${themeConfig.semidark && themeConfig.menu === 'horizontal' ? 'dark' : ''}`}> <header className={`z-40 ${themeConfig.semidark && themeConfig.menu === 'horizontal' ? 'dark' : ''}`}>
<div className="shadow-sm"> <div className="shadow-sm">
<div className="relative flex w-full items-center bg-white px-5 py-2.5 dark:bg-black"> <div
<div className="horizontal-logo flex items-center justify-between ltr:mr-2 rtl:ml-2 lg:hidden"> 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 <button
type="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" 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" /> <IconMenu className="h-5 w-5" />
</button> </button>
<Link href="/" className="main-logo flex shrink-0 items-center ml-3"> <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
<img className="inline w-[164px] h-[40px] ltr:-ml-1 rtl:-mr-1 hidden dark:block" src="/assets/images/logo_light.png" alt="logo" /> 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> */} {/* <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> </Link>
@ -244,7 +264,7 @@ const Header = () => {
</li> </li>
</ul> </ul>
</div> */} </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"> {/* <div className="sm:ltr:mr-auto sm:rtl:ml-auto">
<form <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`} 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'}`} placement={`${isRtl ? 'bottom-start' : 'bottom-end'}`}
btnClassName="relative group block" btnClassName="relative group block"
button={<div className="flex items-center justify-center"> 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 <svg
xmlns="http://www.w3.org/2000/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" 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" /> <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> </svg>
</button> </div>
</div>} </div>}
> >
<ul className="w-[300px] !py-0 font-semibold text-dark dark:text-white-dark dark:text-white-light/90"> <ul className="w-[300px] !py-0 font-semibold text-dark dark:text-white-dark dark:text-white-light/90">
<li> <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"> <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 <svg
xmlns="http://www.w3.org/2000/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" 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" /> <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> </svg>
</button> <div className="truncate ltr:pl-4 rtl:pr-4"> </button> <div className="truncate ltr:pl-4 rtl:pr-4">
<h4 className="text-base"> <h4 className="text-base text-white">
Data4Autos socialbuddy
{/* <span className="rounded bg-success-light px-1 text-xs text-success ltr:ml-2 rtl:ml-2">Pro</span> */} {/* <span className="rounded bg-success-light px-1 text-xs text-success ltr:ml-2 rtl:ml-2">Pro</span> */}
</h4> </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} {user && user}
</button> </button>
</div> </div>
</div> </div>
</li> </li>
{/* <li> <li className="bg-black dark:border-white-light/10">
<Link href="/users/profile" className="dark:hover:text-white"> <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" /> <IconUser className="h-4.5 w-4.5 shrink-0 ltr:mr-2 rtl:ml-2" />
Profile Profile
</Link> </Link>
</li> </li>
<li> {/* <li>
<Link href="/apps/mailbox" className="dark:hover:text-white"> <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" /> <IconMail className="h-4.5 w-4.5 shrink-0 ltr:mr-2 rtl:ml-2" />
Inbox Inbox
@ -525,7 +545,7 @@ const Header = () => {
Lock Screen Lock Screen
</Link> </Link>
</li> */} </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 <button
onClick={handleSignOut} onClick={handleSignOut}
className="!py-3 text-danger flex items-center" className="!py-3 text-danger flex items-center"

View File

@ -1,4 +1,5 @@
'use client'; 'use client';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
const ScrollToTop = () => { const ScrollToTop = () => {
@ -20,26 +21,37 @@ const ScrollToTop = () => {
useEffect(() => { useEffect(() => {
window.addEventListener('scroll', onScrollHandler); window.addEventListener('scroll', onScrollHandler);
return () => { return () => {
window.removeEventListener('onscroll', onScrollHandler); window.removeEventListener('scroll', onScrollHandler);
}; };
}); });
return ( return (
<div className="fixed bottom-6 z-50 ltr:right-6 rtl:left-6"> <div className="fixed bottom-6 z-50 ltr:right-6 rtl:left-6">
{showTopButton && ( {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}> <button
<svg width="24" height="24" className="h-4 w-4" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 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 <path
opacity="0.5" opacity="0.5"
fillRule="evenodd" fillRule="evenodd"
clipRule="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" 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" fill="currentColor"
></path> />
<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" 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" fill="currentColor"
></path> />
</svg> </svg>
</button> </button>
)} )}

View File

@ -1,199 +1,331 @@
'use client'; 'use client';
/* ======================================================
IMPORTS
====================================================== */
import { useState } from 'react'; import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { IRootState } from '@/store'; 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 IconSettings from '@/components/icon/icon-settings';
import IconX from '@/components/icon/icon-x'; import IconX from '@/components/icon/icon-x';
import IconSun from '@/components/icon/icon-sun'; import IconSun from '@/components/icon/icon-sun';
import IconMoon from '@/components/icon/icon-moon'; import IconMoon from '@/components/icon/icon-moon';
import IconLaptop from '@/components/icon/icon-laptop'; import IconLaptop from '@/components/icon/icon-laptop';
/* ======================================================
COMPONENT
====================================================== */
const Setting = () => { const Setting = () => {
const themeConfig = useSelector((state: IRootState) => state.themeConfig); const themeConfig = useSelector((state: IRootState) => state.themeConfig);
const dispatch = useDispatch(); const dispatch = useDispatch();
const [showCustomizer, setShowCustomizer] = useState(false); const [showCustomizer, setShowCustomizer] = useState(false);
return ( return (
<div> <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 <nav
className={`${ className={`
(showCustomizer && 'ltr:!right-0 rtl:!left-0') || '' fixed top-0 bottom-0 z-[52]
} 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`} 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 <button
type="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)} 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> </button>
<div className="perfect-scrollbar h-full overflow-y-auto overflow-x-hidden"> {/* ==================================================
<div className="relative pb-5 text-center"> CONTENT (Glass effect over footer bg)
<button type="button" className="absolute top-0 opacity-30 hover:opacity-100 ltr:right-0 rtl:left-0 dark:text-white" onClick={() => setShowCustomizer(false)}> ================================================== */}
<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" /> <IconX className="h-5 w-5" />
</button> </button>
<h4 className="mb-1 dark:text-white">TEMPLATE CUSTOMIZER</h4> <h4 className="text-lg font-semibold">
<p className="text-white-dark">Set preferences that will be cookied for your live preview demonstration.</p> Template Customizer
</h4>
<p className="text-sm text-gray-400">
UI preferences (saved automatically)
</p>
</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">Color Scheme</h5> SETTINGS SECTIONS
<p className="text-xs text-white-dark">Overall light or dark presentation.</p> ================================================== */}
<div className="mt-3 grid grid-cols-3 gap-2"> <div className="space-y-5">
<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>
<button type="button" className={`${themeConfig.theme === 'dark' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('dark'))}> {/* COLOR SCHEME */}
<IconMoon className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2" /> <section className="rounded-xl bg-white/5 border border-white/10 p-4">
Dark <h5 className="font-medium mb-2">Color Scheme</h5>
</button>
<button type="button" className={`${themeConfig.theme === 'system' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('system'))}> <div className="grid grid-cols-3 gap-2">
<IconLaptop className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2" /> <button
System className={`btn ${
</button> themeConfig.theme === 'light'
</div> ? 'btn-primary'
</div> : 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleTheme('light'))}
>
<IconSun className="w-4 h-4 mr-1" /> Light
</button>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]"> <button
<h5 className="mb-1 text-base leading-none dark:text-white">Navigation Position</h5> className={`btn ${
<p className="text-xs text-white-dark">Select the primary navigation paradigm for your app.</p> themeConfig.theme === 'dark'
<div className="mt-3 grid grid-cols-3 gap-2"> ? 'btn-primary'
<button : 'btn-outline-primary'
type="button" }`}
className={`${themeConfig.menu === 'horizontal' ? 'btn-primary' : 'btn-outline-primary'} btn`} onClick={() => dispatch(toggleTheme('dark'))}
onClick={() => { >
dispatch(toggleMenu('horizontal')); <IconMoon className="w-4 h-4 mr-1" /> Dark
dispatch(resetToggleSidebar()); </button>
}}
>
Horizontal
</button>
<button <button
type="button" className={`btn ${
className={`${themeConfig.menu === 'vertical' ? 'btn-primary' : 'btn-outline-primary'} btn`} themeConfig.theme === 'system'
onClick={() => { ? 'btn-primary'
dispatch(toggleMenu('vertical')); : 'btn-outline-primary'
dispatch(resetToggleSidebar()); }`}
}} onClick={() => dispatch(toggleTheme('system'))}
> >
Vertical <IconLaptop className="w-4 h-4 mr-1" /> System
</button> </button>
</div>
</section>
<button {/* NAVIGATION */}
type="button" <section className="rounded-xl bg-white/5 border border-white/10 p-4">
className={`${themeConfig.menu === 'collapsible-vertical' ? 'btn-primary' : 'btn-outline-primary'} btn`} <h5 className="font-medium mb-2">Navigation</h5>
onClick={() => {
dispatch(toggleMenu('collapsible-vertical'));
dispatch(resetToggleSidebar());
}}
>
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]"> <div className="grid grid-cols-3 gap-2">
<h5 className="mb-1 text-base leading-none dark:text-white">Layout Style</h5> <button
<p className="text-xs text-white-dark">Select the primary layout style for your app.</p> className={`btn ${
<div className="mt-3 flex gap-2"> themeConfig.menu === 'horizontal'
<button ? 'btn-primary'
type="button" : 'btn-outline-primary'
className={`${themeConfig.layout === 'boxed-layout' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} }`}
onClick={() => dispatch(toggleLayout('boxed-layout'))} onClick={() => {
> dispatch(toggleMenu('horizontal'));
Box dispatch(resetToggleSidebar());
</button> }}
>
Horizontal
</button>
<button type="button" className={`${themeConfig.layout === 'full' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleLayout('full'))}> <button
Full className={`btn ${
</button> themeConfig.menu === 'vertical'
</div> ? 'btn-primary'
</div> : 'btn-outline-primary'
}`}
onClick={() => {
dispatch(toggleMenu('vertical'));
dispatch(resetToggleSidebar());
}}
>
Vertical
</button>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]"> <button
<h5 className="mb-1 text-base leading-none dark:text-white">Direction</h5> className={`btn ${
<p className="text-xs text-white-dark">Select the direction for your app.</p> themeConfig.menu === 'collapsible-vertical'
<div className="mt-3 flex gap-2"> ? 'btn-primary'
<button type="button" className={`${themeConfig.rtlClass === 'ltr' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleRTL('ltr'))}> : 'btn-outline-primary'
LTR }`}
</button> onClick={() => {
dispatch(toggleMenu('collapsible-vertical'));
dispatch(resetToggleSidebar());
}}
>
Collapsible
</button>
</div>
<button type="button" className={`${themeConfig.rtlClass === 'rtl' ? 'btn-primary' : 'btn-outline-primary'} btn flex-auto`} onClick={() => dispatch(toggleRTL('rtl'))}> <label className="mt-4 flex items-center gap-2 text-sm text-gray-300">
RTL
</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">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 <input
type="radio" type="checkbox"
checked={themeConfig.navbar === 'navbar-sticky'} className="form-checkbox"
value="navbar-sticky" checked={themeConfig.semidark}
className="form-radio" onChange={(e) =>
onChange={() => dispatch(toggleNavbar('navbar-sticky'))} dispatch(toggleSemidark(e.target.checked))
}
/> />
<span>Sticky</span> Semi-dark Header & Sidebar
</label> </label>
<label className="mb-0 inline-flex"> </section>
<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>
<div className="mb-3 rounded-md border border-dashed border-white-light p-3 dark:border-[#1b2e4b]"> {/* LAYOUT */}
<h5 className="mb-1 text-base leading-none dark:text-white">Router Transition</h5> <section className="rounded-xl bg-white/5 border border-white/10 p-4">
<p className="text-xs text-white-dark">Animation of main content.</p> <h5 className="font-medium mb-3">Layout</h5>
<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-2">
<button
className={`btn flex-1 ${
themeConfig.layout === 'boxed-layout'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() =>
dispatch(toggleLayout('boxed-layout'))
}
>
Boxed
</button>
<button
className={`btn flex-1 ${
themeConfig.layout === 'full'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() =>
dispatch(toggleLayout('full'))
}
>
Full
</button>
</div>
</section>
{/* 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
className={`btn flex-1 ${
themeConfig.rtlClass === 'rtl'
? 'btn-primary'
: 'btn-outline-primary'
}`}
onClick={() => dispatch(toggleRTL('rtl'))}
>
RTL
</button>
</div>
</section>
{/* NAVBAR */}
<section className="rounded-xl bg-white/5 border border-white/10 p-4">
<h5 className="font-medium mb-2">Navbar</h5>
<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=" ">None</option>
<option value="animate__fadeIn">Fade</option> <option value="animate__fadeIn">Fade</option>
<option value="animate__fadeInDown">Fade Down</option>
<option value="animate__fadeInUp">Fade Up</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__fadeInLeft">Fade Left</option>
<option value="animate__fadeInRight">Fade Right</option> <option value="animate__fadeInRight">Fade Right</option>
<option value="animate__slideInDown">Slide Down</option> <option value="animate__zoomIn">Zoom</option>
<option value="animate__slideInLeft">Slide Left</option>
<option value="animate__slideInRight">Slide Right</option>
<option value="animate__zoomIn">Zoom In</option>
</select> </select>
</div> </section>
</div> </div>
</div> </div>
</nav> </nav>

View File

@ -40,14 +40,14 @@ const Sidebar = () => {
} }
} }
} }
}, [pathname]); }, [dispatch, themeConfig.sidebar]);
useEffect(() => { useEffect(() => {
setActiveRoute(); setActiveRoute();
if (window.innerWidth < 1024 && themeConfig.sidebar) { if (window.innerWidth < 1024 && themeConfig.sidebar) {
dispatch(toggleSidebar()); dispatch(toggleSidebar());
} }
}, [pathname]); }, [dispatch, themeConfig.sidebar]);
const setActiveRoute = () => { const setActiveRoute = () => {
let allLinks = document.querySelectorAll('.sidebar ul a.active'); let allLinks = document.querySelectorAll('.sidebar ul a.active');
@ -60,15 +60,13 @@ const Sidebar = () => {
}; };
return ( return (
<div className={semidark ? 'dark' : ''}> <div className="dark">
<nav <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">
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-[#242424]">
>
<div className="h-full bg-white dark:bg-black">
<div className="flex items-center justify-between px-4 py-3"> <div className="flex items-center justify-between px-4 py-3">
<Link href="/" className="main-logo flex shrink-0 items-center"> <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-[184px] h-[70px] flex-none block dark:hidden" src="/assets/images/logo_socialbuddy.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 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> */} {/* <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> </Link>
<button <button

View File

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

20
package-lock.json generated
View File

@ -20,12 +20,14 @@
"eslint-config-next": "14.2.13", "eslint-config-next": "14.2.13",
"i18next": "^23.13.0", "i18next": "^23.13.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"lucide-react": "^0.562.0",
"next": "14.2.13", "next": "14.2.13",
"ni18n": "^1.0.5", "ni18n": "^1.0.5",
"react": "18.3.1", "react": "18.3.1",
"react-animate-height": "^3.1.0", "react-animate-height": "^3.1.0",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-i18next": "^15.0.2", "react-i18next": "^15.0.2",
"react-icons": "^5.5.0",
"react-perfect-scrollbar": "^1.5.8", "react-perfect-scrollbar": "^1.5.8",
"react-popper": "^2.3.0", "react-popper": "^2.3.0",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
@ -4323,6 +4325,15 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" "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": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "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": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "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", "eslint-config-next": "14.2.13",
"i18next": "^23.13.0", "i18next": "^23.13.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"lucide-react": "^0.562.0",
"next": "14.2.13", "next": "14.2.13",
"ni18n": "^1.0.5", "ni18n": "^1.0.5",
"react": "18.3.1", "react": "18.3.1",
"react-animate-height": "^3.1.0", "react-animate-height": "^3.1.0",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-i18next": "^15.0.2", "react-i18next": "^15.0.2",
"react-icons": "^5.5.0",
"react-perfect-scrollbar": "^1.5.8", "react-perfect-scrollbar": "^1.5.8",
"react-popper": "^2.3.0", "react-popper": "^2.3.0",
"react-redux": "^9.1.2", "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