Merge branch 'dev' of https://git.profit-planet.partners/Seazn/profit-planet-frontend into dev
This commit is contained in:
commit
a6c3251a6f
189
src/app/affiliate-links/page.tsx
Normal file
189
src/app/affiliate-links/page.tsx
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import PageLayout from '../components/PageLayout';
|
||||||
|
|
||||||
|
const posts = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: 'TechInnovate Solutions',
|
||||||
|
href: 'https://example.com/affiliate/techinnovate',
|
||||||
|
description:
|
||||||
|
'Leading provider of innovative tech solutions for businesses. Earn commissions on referrals.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3603&q=80',
|
||||||
|
category: { title: 'Technology', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: 'GreenEnergy Corp',
|
||||||
|
href: 'https://example.com/affiliate/greenenergy',
|
||||||
|
description:
|
||||||
|
'Sustainable energy products and services. Partner with us for eco-friendly commissions.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Energy', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: 'FinanceHub Advisors',
|
||||||
|
href: 'https://example.com/affiliate/financehub',
|
||||||
|
description:
|
||||||
|
'Expert financial advisory services. Get rewarded for every successful referral.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Finance', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: 'HealthWell Clinics',
|
||||||
|
href: 'https://example.com/affiliate/healthwell',
|
||||||
|
description:
|
||||||
|
'Comprehensive healthcare solutions. Affiliate program with competitive payouts.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1559136555-9303baea8ebd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Healthcare', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: 'EduLearn Academy',
|
||||||
|
href: 'https://example.com/affiliate/edulearn',
|
||||||
|
description:
|
||||||
|
'Online education platforms for all ages. Earn from educational referrals.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1485217988980-11786ced9454?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Education', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: 'TravelEase Agency',
|
||||||
|
href: 'https://example.com/affiliate/travelease',
|
||||||
|
description:
|
||||||
|
'Seamless travel booking services. Commissions on every trip booked through affiliates.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1670272504528-790c24957dda?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Travel', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: 'RetailMax Stores',
|
||||||
|
href: 'https://example.com/affiliate/retailmax',
|
||||||
|
description:
|
||||||
|
'Wide range of retail products. Join our affiliate network for sales commissions.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1670272505284-8faba1c31f7d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Retail', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
title: 'BuildPro Contractors',
|
||||||
|
href: 'https://example.com/affiliate/buildpro',
|
||||||
|
description:
|
||||||
|
'Professional construction and renovation services. Affiliate rewards for leads.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Construction', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
title: 'FoodieDelight Catering',
|
||||||
|
href: 'https://example.com/affiliate/foodiedelight',
|
||||||
|
description:
|
||||||
|
'Delicious catering services for events. Earn commissions on catering bookings.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Food', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
title: 'AutoCare Mechanics',
|
||||||
|
href: 'https://example.com/affiliate/autocare',
|
||||||
|
description:
|
||||||
|
'Reliable automotive repair and maintenance. Affiliate program with steady payouts.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Automotive', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 11,
|
||||||
|
title: 'FashionForward Boutique',
|
||||||
|
href: 'https://example.com/affiliate/fashionforward',
|
||||||
|
description:
|
||||||
|
'Trendy fashion and accessories. Commissions on fashion sales through affiliates.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Fashion', href: '#' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 12,
|
||||||
|
title: 'PetCare Essentials',
|
||||||
|
href: 'https://example.com/affiliate/petcare',
|
||||||
|
description:
|
||||||
|
'Everything for your pets. Earn from pet product referrals.',
|
||||||
|
imageUrl:
|
||||||
|
'https://images.unsplash.com/photo-1559136555-9303baea8ebd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3270&q=80',
|
||||||
|
category: { title: 'Pets', href: '#' },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AffiliateLinksPage() {
|
||||||
|
return (
|
||||||
|
<PageLayout>
|
||||||
|
<div className="bg-gray-900 py-24 sm:py-32">
|
||||||
|
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||||
|
<div className="mx-auto max-w-2xl text-center">
|
||||||
|
<h2 className="text-4xl font-semibold tracking-tight text-balance text-white sm:text-5xl">
|
||||||
|
Affiliate Partners
|
||||||
|
</h2>
|
||||||
|
<p className="mt-2 text-lg/8 text-gray-300">
|
||||||
|
Discover our trusted partners and earn commissions through affiliate
|
||||||
|
links.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mx-auto mt-16 grid max-w-2xl grid-cols-1 gap-x-8 gap-y-20 lg:mx-0 lg:max-w-none lg:grid-cols-3">
|
||||||
|
{posts.map((post) => (
|
||||||
|
<article key={post.id} className="flex flex-col items-start justify-between">
|
||||||
|
<div className="relative w-full">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src={post.imageUrl}
|
||||||
|
className="aspect-video w-full rounded-2xl bg-gray-800 object-cover sm:aspect-2/1 lg:aspect-3/2"
|
||||||
|
/>
|
||||||
|
<div className="absolute inset-0 rounded-2xl inset-ring inset-ring-white/10" />
|
||||||
|
</div>
|
||||||
|
<div className="flex max-w-xl grow flex-col justify-between">
|
||||||
|
<div className="mt-8 flex items-center gap-x-4 text-xs">
|
||||||
|
<a
|
||||||
|
href={post.category.href}
|
||||||
|
className="relative z-10 rounded-full bg-gray-800/60 px-3 py-1.5 font-medium text-gray-300 hover:bg-gray-800"
|
||||||
|
>
|
||||||
|
{post.category.title}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="group relative grow">
|
||||||
|
<h3 className="mt-3 text-lg/6 font-semibold text-white group-hover:text-gray-300">
|
||||||
|
<a href={post.href} target="_blank" rel="noopener noreferrer">
|
||||||
|
<span className="absolute inset-0" />
|
||||||
|
{post.title}
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
<p className="mt-5 line-clamp-3 text-sm/6 text-gray-400">
|
||||||
|
{post.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="relative mt-8 flex items-center gap-x-4 justify-self-end">
|
||||||
|
<a
|
||||||
|
href={post.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-sm font-semibold text-indigo-400 hover:text-indigo-300"
|
||||||
|
>
|
||||||
|
Visit Affiliate Link →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import { useTranslation } from '../i18n/useTranslation';
|
|||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<footer className="bg-[#0F172A] py-4 px-6 shadow-inner">
|
<footer className="relative z-50 w-full bg-[#0F172A] py-4 px-6 shadow-inner">
|
||||||
<div className="container mx-auto flex justify-between items-center">
|
<div className="container mx-auto flex justify-between items-center">
|
||||||
<div className="text-sm text-white/70">
|
<div className="text-sm text-white/70">
|
||||||
© {new Date().getFullYear()} {t('footer.company')} - {t('footer.rights')}
|
© {new Date().getFullYear()} {t('footer.company')} - {t('footer.rights')}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export default function PageLayout({
|
|||||||
const isMobile = isMobileDevice();
|
const isMobile = isMobileDevice();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen w-full flex flex-col relative overflow-x-hidden bg-white">
|
<div className="min-h-screen w-full flex flex-col relative overflow-x-hidden bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 transition-colors">
|
||||||
|
|
||||||
{showHeader && (
|
{showHeader && (
|
||||||
<div className="relative z-50 w-full">
|
<div className="relative z-50 w-full">
|
||||||
@ -39,7 +39,7 @@ export default function PageLayout({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showFooter && (
|
{showFooter && (
|
||||||
<div className="relative z-20 w-full">
|
<div className="mt-auto relative z-50">
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState } from 'react'
|
import { useState, useEffect, useCallback } from 'react'
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import {
|
import {
|
||||||
@ -21,7 +21,9 @@ import {
|
|||||||
HomeIcon,
|
HomeIcon,
|
||||||
UserCircleIcon,
|
UserCircleIcon,
|
||||||
XMarkIcon,
|
XMarkIcon,
|
||||||
ArrowRightOnRectangleIcon
|
ArrowRightOnRectangleIcon,
|
||||||
|
MoonIcon,
|
||||||
|
SunIcon
|
||||||
} from '@heroicons/react/24/outline'
|
} from '@heroicons/react/24/outline'
|
||||||
import { ChevronDownIcon } from '@heroicons/react/20/solid'
|
import { ChevronDownIcon } from '@heroicons/react/20/solid'
|
||||||
import useAuthStore from '../../store/authStore';
|
import useAuthStore from '../../store/authStore';
|
||||||
@ -51,6 +53,7 @@ const products = [
|
|||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||||
|
const [isDark, setIsDark] = useState(false)
|
||||||
const user = useAuthStore((s) => s.user);
|
const user = useAuthStore((s) => s.user);
|
||||||
const logout = useAuthStore((s) => s.logout);
|
const logout = useAuthStore((s) => s.logout);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -79,6 +82,32 @@ export default function Header() {
|
|||||||
return 'U';
|
return 'U';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Theme initialization & persistence
|
||||||
|
useEffect(() => {
|
||||||
|
const stored = localStorage.getItem('theme')
|
||||||
|
if (stored === 'dark' || (!stored && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
document.documentElement.classList.add('dark')
|
||||||
|
setIsDark(true)
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark')
|
||||||
|
setIsDark(false)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const toggleTheme = useCallback(() => {
|
||||||
|
setIsDark(prev => {
|
||||||
|
const next = !prev
|
||||||
|
if (next) {
|
||||||
|
document.documentElement.classList.add('dark')
|
||||||
|
localStorage.setItem('theme', 'dark')
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark')
|
||||||
|
localStorage.setItem('theme', 'light')
|
||||||
|
}
|
||||||
|
return next
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="relative isolate z-10 border-b border-white/10" style={{
|
<header className="relative isolate z-10 border-b border-white/10" style={{
|
||||||
backgroundColor: '#162647',
|
backgroundColor: '#162647',
|
||||||
@ -112,31 +141,31 @@ export default function Header() {
|
|||||||
</div>
|
</div>
|
||||||
<PopoverGroup className="hidden lg:flex lg:gap-x-12">
|
<PopoverGroup className="hidden lg:flex lg:gap-x-12">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverButton className="flex items-center gap-x-1 text-sm/6 font-semibold text-white">
|
<PopoverButton className="flex items-center gap-x-1 text-sm/6 font-semibold text-gray-900 dark:text-white">
|
||||||
Product
|
Product
|
||||||
<ChevronDownIcon aria-hidden="true" className="size-5 flex-none text-gray-500" />
|
<ChevronDownIcon aria-hidden="true" className="size-5 flex-none text-gray-500" />
|
||||||
</PopoverButton>
|
</PopoverButton>
|
||||||
|
|
||||||
<PopoverPanel
|
<PopoverPanel
|
||||||
transition
|
transition
|
||||||
className="absolute inset-x-0 top-16 bg-gray-900 transition data-closed:-translate-y-1 data-closed:opacity-0 data-enter:duration-200 data-enter:ease-out data-leave:duration-150 data-leave:ease-in"
|
className="absolute inset-x-0 top-16 bg-white dark:bg-gray-900 transition data-closed:-translate-y-1 data-closed:opacity-0 data-enter:duration-200 data-enter:ease-out data-leave:duration-150 data-leave:ease-in"
|
||||||
>
|
>
|
||||||
<div aria-hidden="true" className="absolute inset-0 top-1/2 bg-gray-900 ring-1 ring-white/15" />
|
<div aria-hidden="true" className="absolute inset-0 top-1/2 bg-white dark:bg-gray-900 ring-1 ring-black/5 dark:ring-white/15" />
|
||||||
<div className="relative bg-gray-900">
|
<div className="relative bg-white dark:bg-gray-900">
|
||||||
<div className="mx-auto grid max-w-7xl grid-cols-3 gap-x-4 px-6 py-10 lg:px-8 xl:gap-x-8">
|
<div className="mx-auto grid max-w-7xl grid-cols-3 gap-x-4 px-6 py-10 lg:px-8 xl:gap-x-8">
|
||||||
{products.map((item) => (
|
{products.map((item) => (
|
||||||
<div key={item.name} className="group relative rounded-lg p-6 text-sm/6 hover:bg-white/5">
|
<div key={item.name} className="group relative rounded-lg p-6 text-sm/6 hover:bg-gray-100/70 dark:hover:bg-white/5 transition-colors">
|
||||||
<div className="flex size-11 items-center justify-center rounded-lg bg-gray-700/50 group-hover:bg-gray-700">
|
<div className="flex size-11 items-center justify-center rounded-lg bg-gray-200/70 dark:bg-gray-700/50 group-hover:bg-gray-300 dark:group-hover:bg-gray-700">
|
||||||
<item.icon aria-hidden="true" className="size-6 text-gray-400 group-hover:text-white" />
|
<item.icon aria-hidden="true" className="size-6 text-gray-600 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(item.href)}
|
onClick={() => router.push(item.href)}
|
||||||
className="mt-6 block font-semibold text-white"
|
className="mt-6 block font-semibold text-gray-900 dark:text-white"
|
||||||
>
|
>
|
||||||
{item.name}
|
{item.name}
|
||||||
<span className="absolute inset-0" />
|
<span className="absolute inset-0" />
|
||||||
</button>
|
</button>
|
||||||
<p className="mt-1 text-gray-400">{item.description}</p>
|
<p className="mt-1 text-gray-600 dark:text-gray-400">{item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -146,21 +175,21 @@ export default function Header() {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push('/features')}
|
onClick={() => router.push('/features')}
|
||||||
className="text-sm/6 font-semibold text-white hover:text-indigo-400 transition-colors"
|
className="text-sm/6 font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
|
||||||
>
|
>
|
||||||
Features
|
Features
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push('/marketplace')}
|
onClick={() => router.push('/marketplace')}
|
||||||
className="text-sm/6 font-semibold text-white hover:text-indigo-400 transition-colors"
|
className="text-sm/6 font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
|
||||||
>
|
>
|
||||||
Marketplace
|
Marketplace
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push('/company')}
|
onClick={() => router.push('/company')}
|
||||||
className="text-sm/6 font-semibold text-white hover:text-indigo-400 transition-colors"
|
className="text-sm/6 font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
|
||||||
>
|
>
|
||||||
Company
|
Company
|
||||||
</button>
|
</button>
|
||||||
@ -168,7 +197,7 @@ export default function Header() {
|
|||||||
{/* Profile Dropdown - nur wenn eingeloggt */}
|
{/* Profile Dropdown - nur wenn eingeloggt */}
|
||||||
{user && (
|
{user && (
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverButton className="flex items-center gap-x-1 text-sm/6 font-semibold text-white">
|
<PopoverButton className="flex items-center gap-x-1 text-sm/6 font-semibold text-gray-900 dark:text-white">
|
||||||
<Avatar
|
<Avatar
|
||||||
src=""
|
src=""
|
||||||
initials={getUserInitials()}
|
initials={getUserInitials()}
|
||||||
@ -179,7 +208,7 @@ export default function Header() {
|
|||||||
|
|
||||||
<PopoverPanel
|
<PopoverPanel
|
||||||
transition
|
transition
|
||||||
className="absolute right-0 top-16 w-64 bg-gray-900 ring-1 ring-white/15 transition data-closed:-translate-y-1 data-closed:opacity-0 data-enter:duration-200 data-enter:ease-out data-leave:duration-150 data-leave:ease-in"
|
className="absolute right-0 top-16 w-64 bg-white dark:bg-gray-900 ring-1 ring-black/5 dark:ring-white/15 transition data-closed:-translate-y-1 data-closed:opacity-0 data-enter:duration-200 data-enter:ease-out data-leave:duration-150 data-leave:ease-in"
|
||||||
>
|
>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="flex flex-col border-b border-white/10 pb-4 mb-4">
|
<div className="flex flex-col border-b border-white/10 pb-4 mb-4">
|
||||||
@ -213,13 +242,21 @@ export default function Header() {
|
|||||||
)}
|
)}
|
||||||
</PopoverGroup>
|
</PopoverGroup>
|
||||||
<div className="hidden lg:flex lg:flex-1 lg:justify-end lg:items-center lg:gap-x-4">
|
<div className="hidden lg:flex lg:flex-1 lg:justify-end lg:items-center lg:gap-x-4">
|
||||||
|
{/* Theme Toggle */}
|
||||||
|
<button
|
||||||
|
onClick={toggleTheme}
|
||||||
|
aria-label="Toggle theme"
|
||||||
|
className="p-2 rounded-md border border-gray-300 dark:border-white/10 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-200 transition-colors"
|
||||||
|
>
|
||||||
|
{isDark ? <SunIcon className="h-5 w-5" /> : <MoonIcon className="h-5 w-5" />}
|
||||||
|
</button>
|
||||||
{/* Language Switcher */}
|
{/* Language Switcher */}
|
||||||
<LanguageSwitcher variant="dark" />
|
<LanguageSwitcher variant={isDark ? 'dark' : 'light'} />
|
||||||
|
|
||||||
{!user && (
|
{!user && (
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push('/login')}
|
onClick={() => router.push('/login')}
|
||||||
className="text-sm/6 font-semibold text-white hover:text-indigo-400 transition-colors"
|
className="text-sm/6 font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
|
||||||
>
|
>
|
||||||
Log in <span aria-hidden="true">→</span>
|
Log in <span aria-hidden="true">→</span>
|
||||||
</button>
|
</button>
|
||||||
@ -228,7 +265,7 @@ export default function Header() {
|
|||||||
</nav>
|
</nav>
|
||||||
<Dialog open={mobileMenuOpen} onClose={setMobileMenuOpen} className="lg:hidden">
|
<Dialog open={mobileMenuOpen} onClose={setMobileMenuOpen} className="lg:hidden">
|
||||||
<div className="fixed inset-0 z-50" />
|
<div className="fixed inset-0 z-50" />
|
||||||
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-gray-900 p-6 sm:max-w-sm sm:ring-1 sm:ring-gray-100/10">
|
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white dark:bg-gray-900 p-6 sm:max-w-sm sm:ring-1 sm:ring-black/10 dark:sm:ring-gray-100/10 transition-colors">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push('/')}
|
onClick={() => router.push('/')}
|
||||||
@ -253,12 +290,22 @@ export default function Header() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6 flow-root">
|
<div className="mt-6 flow-root">
|
||||||
<div className="-my-6 divide-y divide-white/10">
|
<div className="-my-6 divide-y divide-gray-200 dark:divide-white/10">
|
||||||
|
{/* Insert theme toggle in mobile */}
|
||||||
|
<div className="py-6">
|
||||||
|
<button
|
||||||
|
onClick={toggleTheme}
|
||||||
|
className="flex items-center gap-x-2 rounded-lg px-3 py-2.5 text-base/7 font-semibold text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-white/5 w-full"
|
||||||
|
>
|
||||||
|
{isDark ? <SunIcon className="h-5 w-5" /> : <MoonIcon className="h-5 w-5" />}
|
||||||
|
{isDark ? 'Light Mode' : 'Dark Mode'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{user ? (
|
{user ? (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-2 py-6">
|
<div className="space-y-2 py-6">
|
||||||
<Disclosure as="div" className="-mx-3">
|
<Disclosure as="div" className="-mx-3">
|
||||||
<DisclosureButton className="group flex w-full items-center justify-between rounded-lg py-2 pr-3.5 pl-3 text-base/7 font-semibold text-white hover:bg-white/5">
|
<DisclosureButton className="group flex w-full items-center justify-between rounded-lg py-2 pr-3.5 pl-3 text-base/7 font-semibold text-gray-900 dark:text-white hover:bg-white/5">
|
||||||
Navigation
|
Navigation
|
||||||
<ChevronDownIcon aria-hidden="true" className="size-5 flex-none group-data-open:rotate-180" />
|
<ChevronDownIcon aria-hidden="true" className="size-5 flex-none group-data-open:rotate-180" />
|
||||||
</DisclosureButton>
|
</DisclosureButton>
|
||||||
@ -271,7 +318,7 @@ export default function Header() {
|
|||||||
router.push(item.href);
|
router.push(item.href);
|
||||||
setMobileMenuOpen(false);
|
setMobileMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="block rounded-lg py-2 pr-3 pl-6 text-sm/7 font-semibold text-white hover:bg-white/5 w-full text-left"
|
className="block rounded-lg py-2 pr-3 pl-6 text-sm/7 font-semibold text-gray-900 dark:text-white hover:bg-white/5 w-full text-left"
|
||||||
>
|
>
|
||||||
{item.name}
|
{item.name}
|
||||||
</DisclosureButton>
|
</DisclosureButton>
|
||||||
@ -300,7 +347,7 @@ export default function Header() {
|
|||||||
router.push('/profile');
|
router.push('/profile');
|
||||||
setMobileMenuOpen(false);
|
setMobileMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-white hover:bg-white/5 w-full text-left"
|
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-gray-900 dark:text-white hover:bg-white/5 w-full text-left"
|
||||||
>
|
>
|
||||||
Profile
|
Profile
|
||||||
</button>
|
</button>
|
||||||
@ -309,7 +356,7 @@ export default function Header() {
|
|||||||
handleLogout();
|
handleLogout();
|
||||||
setMobileMenuOpen(false);
|
setMobileMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-white hover:bg-white/5 w-full text-left"
|
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-gray-900 dark:text-white hover:bg-white/5 w-full text-left"
|
||||||
>
|
>
|
||||||
Logout
|
Logout
|
||||||
</button>
|
</button>
|
||||||
@ -326,7 +373,7 @@ export default function Header() {
|
|||||||
router.push('/login');
|
router.push('/login');
|
||||||
setMobileMenuOpen(false);
|
setMobileMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="-mx-3 block rounded-lg px-3 py-2.5 text-base/7 font-semibold text-white hover:bg-white/5 w-full text-left"
|
className="-mx-3 block rounded-lg px-3 py-2.5 text-base/7 font-semibold text-gray-900 dark:text-white hover:bg-white/5 w-full text-left"
|
||||||
>
|
>
|
||||||
Log in
|
Log in
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="en" >
|
<html lang="en" >
|
||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100 transition-colors`}
|
||||||
>
|
>
|
||||||
<ClientWrapper>
|
<ClientWrapper>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
219
src/app/page.tsx
219
src/app/page.tsx
@ -1,108 +1,141 @@
|
|||||||
'use client';
|
import PageLayout from './components/PageLayout';
|
||||||
|
|
||||||
import Image from "next/image";
|
|
||||||
import { useRouter } from 'next/navigation';
|
|
||||||
import GlobalAnimatedBackground from './background/GlobalAnimatedBackground';
|
|
||||||
import Footer from './components/Footer';
|
|
||||||
import Header from './components/nav/Header';
|
|
||||||
import { useTranslation } from './i18n/useTranslation';
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
const router = useRouter();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col bg-white">
|
<PageLayout>
|
||||||
{/* Header */}
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
{/* Main Content */}
|
|
||||||
<main className="relative flex-1 flex flex-col items-center justify-center px-4 sm:px-6 lg:px-8">
|
|
||||||
<div className="max-w-7xl mx-auto text-center">
|
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="space-y-8 sm:space-y-12">
|
<section
|
||||||
{/* Logo/Title */}
|
id="hero"
|
||||||
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-extrabold text-[#0F172A] tracking-tight drop-shadow-lg">
|
className="relative isolate flex flex-col min-h-screen" // added min-h-screen to ensure full height and push footer to bottom
|
||||||
{t('home.title')}
|
>
|
||||||
</h1>
|
{/* ...existing code (pattern SVG + blurred polygon) ... */}
|
||||||
|
<svg
|
||||||
{/* Tagline */}
|
aria-hidden="true"
|
||||||
<p className="text-xl sm:text-2xl text-[#FFFFFF] max-w-3xl mx-auto">
|
className="absolute inset-x-0 top-0 -z-10 h-256 w-full mask-[radial-gradient(32rem_32rem_at_center,white,transparent)] stroke-gray-900/10 dark:stroke-white/10"
|
||||||
{t('home.tagline')}
|
>
|
||||||
</p>
|
<defs>
|
||||||
|
<pattern
|
||||||
{/* Feature Highlights */}
|
x="50%"
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mt-16 max-w-5xl mx-auto">
|
y={-1}
|
||||||
{[
|
id="hero-pattern"
|
||||||
{
|
width={200}
|
||||||
title: t('home.features.sustainable.title'),
|
height={200}
|
||||||
description: t('home.features.sustainable.description')
|
patternUnits="userSpaceOnUse"
|
||||||
},
|
>
|
||||||
{
|
<path d="M.5 200V.5H200" fill="none" />
|
||||||
title: t('home.features.community.title'),
|
</pattern>
|
||||||
description: t('home.features.community.description')
|
</defs>
|
||||||
},
|
<svg x="50%" y={-1} className="overflow-visible fill-gray-100 dark:fill-gray-800">
|
||||||
{
|
<path
|
||||||
title: t('home.features.rewards.title'),
|
d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z"
|
||||||
description: t('home.features.rewards.description')
|
strokeWidth={0}
|
||||||
}
|
/>
|
||||||
].map((feature, index) => (
|
</svg>
|
||||||
|
<rect fill="url(#hero-pattern)" width="100%" height="100%" strokeWidth={0} />
|
||||||
|
</svg>
|
||||||
<div
|
<div
|
||||||
key={index}
|
aria-hidden="true"
|
||||||
className="bg-white/80 backdrop-blur-lg rounded-xl p-6 shadow-lg border border-[#8D6B1D]/20 hover:border-[#8D6B1D]/30 transition-all duration-300 hover:transform hover:-translate-y-1"
|
className="absolute top-0 right-0 left-1/2 -z-10 -ml-24 transform-gpu overflow-hidden blur-3xl lg:ml-24 xl:ml-48"
|
||||||
>
|
>
|
||||||
<h3 className="text-lg font-semibold text-[#0F172A] mb-2">
|
<div
|
||||||
{feature.title}
|
style={{
|
||||||
</h3>
|
clipPath:
|
||||||
<p className="text-[#4A4A4A]">
|
'polygon(63.1% 29.5%, 100% 17.1%, 76.6% 3%, 48.4% 0%, 44.6% 4.7%, 54.5% 25.3%, 59.8% 49%, 55.2% 57.8%, 44.4% 57.2%, 27.8% 47.9%, 35.1% 81.5%, 0% 97.7%, 39.2% 100%, 35.2% 81.4%, 97.2% 52.8%, 63.1% 29.5%)',
|
||||||
{feature.description}
|
}}
|
||||||
|
className="aspect-801/1036 w-200.25 bg-linear-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 dark:opacity-30"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Background layering */}
|
||||||
|
<div className="relative flex-1 overflow-hidden flex">
|
||||||
|
{/* ...existing code (absolute layers) ... */}
|
||||||
|
<div className="absolute inset-0 -z-30 bg-white dark:bg-gray-950" />
|
||||||
|
<div className="absolute inset-0 -z-20 bg-gradient-to-b from-gray-900/95 via-gray-900/80 to-gray-900 dark:from-gray-900/95 dark:via-gray-900/80 dark:to-gray-900" />
|
||||||
|
<div className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,0.18),transparent_65%)] dark:bg-[radial-gradient(circle_at_35%_25%,rgba(255,255,255,0.08),transparent_60%)]" />
|
||||||
|
<div className="pointer-events-none absolute inset-0 -z-10 mix-blend-overlay [background-image:linear-gradient(rgba(255,255,255,0.04)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[size:40px_40px]" />
|
||||||
|
|
||||||
|
{/* Content wrapper now fills and centers vertically */}
|
||||||
|
<div className="mx-auto max-w-7xl px-6 py-20 lg:py-28 flex w-full items-center min-h-full">
|
||||||
|
<div className="mx-auto max-w-2xl gap-x-14 lg:mx-0 lg:flex lg:max-w-none lg:items-center">
|
||||||
|
<div className="relative w-full lg:max-w-xl lg:shrink-0 xl:max-w-2xl">
|
||||||
|
<h1 className="text-5xl font-semibold tracking-tight text-pretty text-white sm:text-7xl">
|
||||||
|
Profit Planet
|
||||||
|
</h1>
|
||||||
|
<p className="mt-4 text-xl italic text-gray-300 sm:text-2xl">
|
||||||
|
Building a Community that will bring change
|
||||||
</p>
|
</p>
|
||||||
</div>
|
<p className="mt-8 text-lg font-medium text-pretty text-gray-400 sm:max-w-md sm:text-xl/8 lg:max-w-none">
|
||||||
))}
|
Profit Planet is a platform building a vibrant community where members access diverse services and products from within. Users enjoy benefits like cashback and discounts, fostering a smart, rewarding ecosystem.
|
||||||
</div>
|
</p>
|
||||||
|
<div className="mt-10 flex items-center gap-x-6">
|
||||||
{/* Community Stats */}
|
<a
|
||||||
<div className="flex justify-center gap-8 mt-12">
|
href="/shop"
|
||||||
<div className="text-center">
|
className="rounded-md bg-indigo-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs hover:bg-indigo-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
|
||||||
<div className="text-4xl font-bold text-[#FFFFFF]">10k+</div>
|
|
||||||
<div className="text-sm text-[#FFFFFF]">{t('home.stats.members')}</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<div className="text-4xl font-bold text-[#FFFFFF]">50k+</div>
|
|
||||||
<div className="text-sm text-[#FFFFFF]">{t('home.stats.products')}</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<div className="text-4xl font-bold text-[#FFFFFF]">100</div>
|
|
||||||
<div className="text-sm text-[#FFFFFF]">{t('home.stats.communities')}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* CTA Buttons */}
|
|
||||||
<div className="flex flex-col sm:flex-row gap-4 justify-center mt-12">
|
|
||||||
<button
|
|
||||||
onClick={() => router.push('/shop')}
|
|
||||||
className="px-8 py-3 rounded-lg bg-[#8D6B1D] text-white font-semibold hover:bg-[#8D6B1D]/90 transition-colors duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5"
|
|
||||||
>
|
>
|
||||||
{t('home.cta.getStarted')}
|
Shop
|
||||||
</button>
|
</a>
|
||||||
<button
|
<a href="/login" className="text-sm/6 font-semibold text-white">
|
||||||
onClick={() => router.push('/register')}
|
Login <span aria-hidden="true">→</span>
|
||||||
className="px-8 py-3 rounded-lg bg-white text-[#8D6B1D] font-semibold hover:bg-[#8D6B1D]/5 transition-colors duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 border border-[#8D6B1D]/20"
|
</a>
|
||||||
>
|
</div>
|
||||||
{t('home.cta.learnMore')}
|
</div>
|
||||||
</button>
|
{/* Removed sm:-mt-44 to prevent height reduction */}
|
||||||
|
<div className="mt-14 flex justify-end gap-8 sm:mt-14 sm:justify-start sm:pl-20 lg:mt-0 lg:pl-0">
|
||||||
|
{/* ...existing code (image stacks) ... */}
|
||||||
|
<div className="ml-auto w-44 flex-none space-y-8 pt-32 sm:ml-0 sm:pt-80 lg:order-last lg:pt-36 xl:order-0 xl:pt-80">
|
||||||
|
<div className="relative">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src="https://images.unsplash.com/photo-1557804506-669a67965ba0?auto=format&fit=crop&h=528&q=80"
|
||||||
|
className="aspect-2/3 w-full rounded-xl bg-gray-700/5 object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-white/10 ring-inset" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mr-auto w-44 flex-none space-y-8 sm:mr-0 sm:pt-52 lg:pt-36">
|
||||||
|
<div className="relative">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src="https://images.unsplash.com/photo-1485217988980-11786ced9454?auto=format&fit=crop&h=528&q=80"
|
||||||
|
className="aspect-2/3 w-full rounded-xl bg-gray-700/5 object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-white/10 ring-inset" />
|
||||||
|
</div>
|
||||||
|
<div className="relative">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src="https://images.unsplash.com/photo-1559136555-9303baea8ebd?auto=format&fit=crop&crop=focalpoint&fp-x=.4&w=396&h=528&q=80"
|
||||||
|
className="aspect-2/3 w-full rounded-xl bg-gray-700/5 object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-white/10 ring-inset" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-44 flex-none space-y-8 pt-32 sm:pt-0">
|
||||||
|
<div className="relative">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src="https://images.unsplash.com/photo-1670272504528-790c24957dda?auto=format&fit=crop&crop=left&w=400&h=528&q=80"
|
||||||
|
className="aspect-2/3 w-full rounded-xl bg-gray-700/5 object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-white/10 ring-inset" />
|
||||||
|
</div>
|
||||||
|
<div className="relative">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src="https://images.unsplash.com/photo-1670272505284-8faba1c31f7d?auto=format&fit=crop&h=528&q=80"
|
||||||
|
className="aspect-2/3 w-full rounded-xl bg-gray-700/5 object-cover shadow-lg"
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded-xl ring-1 ring-white/10 ring-inset" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
|
|
||||||
{/* Footer */}
|
|
||||||
<div className="relative z-10">
|
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Decorative Elements */}
|
{/* Bottom fade (optional) */}
|
||||||
<div className="fixed bottom-0 left-0 w-full h-32 bg-gradient-to-t from-white/50 to-transparent z-[1]" />
|
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-24 bg-gradient-to-b from-transparent to-[#0F172A]" />
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
</PageLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user