Home Menu
This commit is contained in:
parent
efdba93e32
commit
6dd3cc4c32
1 changed files with 152 additions and 80 deletions
|
|
@ -1,24 +1,20 @@
|
||||||
import View from '@/views/Views'
|
import View from '@/views/Views'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useLocation, Link } from 'react-router-dom'
|
import { useLocation, Link } from 'react-router-dom'
|
||||||
|
import { FaFacebook, FaTwitter, FaLinkedin, FaInstagram } from 'react-icons/fa';
|
||||||
import {
|
import {
|
||||||
FaBars,
|
LuMenu,
|
||||||
FaTimes,
|
LuX,
|
||||||
FaHome,
|
LuHouse,
|
||||||
FaInfoCircle,
|
LuInfo,
|
||||||
FaVectorSquare,
|
LuBriefcase,
|
||||||
FaBriefcase,
|
LuPackage,
|
||||||
FaBook,
|
LuBookOpen,
|
||||||
FaPhone,
|
LuMonitorPlay,
|
||||||
FaFacebook,
|
LuPhone,
|
||||||
FaTwitter,
|
LuMapPin,
|
||||||
FaLinkedin,
|
LuMail,
|
||||||
FaInstagram,
|
} from 'react-icons/lu';
|
||||||
FaMapPin,
|
|
||||||
FaEnvelope,
|
|
||||||
FaPlayCircle,
|
|
||||||
FaBookOpen
|
|
||||||
} from 'react-icons/fa';
|
|
||||||
import Logo from '@/views/public/Logo'
|
import Logo from '@/views/public/Logo'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -66,43 +62,43 @@ const PublicLayout = () => {
|
||||||
resourceKey: 'App.Home',
|
resourceKey: 'App.Home',
|
||||||
name: translate('::App.Home'),
|
name: translate('::App.Home'),
|
||||||
path: ROUTES_ENUM.public.home,
|
path: ROUTES_ENUM.public.home,
|
||||||
icon: FaHome,
|
icon: LuHouse,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'App.About',
|
resourceKey: 'App.About',
|
||||||
name: translate('::App.About'),
|
name: translate('::App.About'),
|
||||||
path: ROUTES_ENUM.public.about,
|
path: ROUTES_ENUM.public.about,
|
||||||
icon: FaInfoCircle,
|
icon: LuInfo,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'App.Services',
|
resourceKey: 'App.Services',
|
||||||
name: translate('::App.Services'),
|
name: translate('::App.Services'),
|
||||||
path: ROUTES_ENUM.public.services,
|
path: ROUTES_ENUM.public.services,
|
||||||
icon: FaBriefcase,
|
icon: LuBriefcase,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'Public.nav.products',
|
resourceKey: 'Public.nav.products',
|
||||||
name: translate('::App.Orders'),
|
name: translate('::App.Orders'),
|
||||||
path: ROUTES_ENUM.public.products,
|
path: ROUTES_ENUM.public.products,
|
||||||
icon: FaVectorSquare,
|
icon: LuPackage,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'Public.nav.blog',
|
resourceKey: 'Public.nav.blog',
|
||||||
name: translate('::App.BlogManagement'),
|
name: translate('::App.BlogManagement'),
|
||||||
path: ROUTES_ENUM.public.blog,
|
path: ROUTES_ENUM.public.blog,
|
||||||
icon: FaBookOpen,
|
icon: LuBookOpen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'App.Demos',
|
resourceKey: 'App.Demos',
|
||||||
name: translate('::App.Demos'),
|
name: translate('::App.Demos'),
|
||||||
action: () => setIsDemoOpen(true),
|
action: () => setIsDemoOpen(true),
|
||||||
icon: FaPlayCircle,
|
icon: LuMonitorPlay,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'Public.nav.contact',
|
resourceKey: 'Public.nav.contact',
|
||||||
name: translate('::App.Contact'),
|
name: translate('::App.Contact'),
|
||||||
path: ROUTES_ENUM.public.contact,
|
path: ROUTES_ENUM.public.contact,
|
||||||
icon: FaPhone,
|
icon: LuPhone,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resourceKey: 'Public.nav.giris',
|
resourceKey: 'Public.nav.giris',
|
||||||
|
|
@ -111,15 +107,12 @@ const PublicLayout = () => {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const getNavItemClass = (resourceKey?: string) => {
|
const isLoginLink = (resourceKey?: string) => resourceKey === 'Public.nav.giris'
|
||||||
switch (resourceKey) {
|
|
||||||
case 'Public.nav.giris':
|
const isActiveLink = (path?: string) => {
|
||||||
return 'bg-blue-600 rounded px-2 py-1'
|
if (!path) return false
|
||||||
case 'Public.nav.basket':
|
if (path === ROUTES_ENUM.public.home) return location.pathname === path
|
||||||
return 'bg-green-600 rounded px-2 py-1'
|
return location.pathname.startsWith(path)
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -127,60 +120,137 @@ const PublicLayout = () => {
|
||||||
<div className="flex flex-col min-h-screen">
|
<div className="flex flex-col min-h-screen">
|
||||||
{/* HEADER */}
|
{/* HEADER */}
|
||||||
<header
|
<header
|
||||||
className={`fixed w-full z-50 transition-all duration-300 ${
|
className={`fixed w-full z-50 transition-all duration-500 ${
|
||||||
scrolled
|
scrolled
|
||||||
? 'bg-gray-900/95 backdrop-blur-sm shadow-md py-2'
|
? 'bg-gray-950 shadow-lg shadow-black/30 py-2 border-b border-white/10'
|
||||||
: 'bg-gray-900/80 backdrop-blur-sm py-4'
|
: 'bg-gray-950/80 backdrop-blur-sm py-4 border-b border-white/5'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="container mx-auto px-4 flex items-center justify-between">
|
<div className="container mx-auto px-6 flex items-center justify-between">
|
||||||
<Logo mode="dark" />
|
<Logo mode="dark" />
|
||||||
|
|
||||||
{/* Desktop Navigation */}
|
{/* Desktop Navigation */}
|
||||||
<nav className="hidden md:flex items-center space-x-4">
|
<nav className="hidden md:flex items-center gap-1">
|
||||||
{navLinks.map((link) =>
|
{navLinks
|
||||||
link.path ? (
|
.filter((l) => !isLoginLink(l.resourceKey))
|
||||||
|
.map((link) => {
|
||||||
|
const active = isActiveLink(link.path)
|
||||||
|
const baseClass =
|
||||||
|
'relative flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md transition-all duration-200 group'
|
||||||
|
const activeClass = active
|
||||||
|
? 'text-white'
|
||||||
|
: 'text-gray-300 hover:text-white'
|
||||||
|
return link.path ? (
|
||||||
<Link
|
<Link
|
||||||
key={link.path}
|
key={link.path}
|
||||||
to={link.path}
|
to={link.path}
|
||||||
className={`flex items-center gap-1 font-medium text-sm text-white hover:text-blue-400 transition-colors ${getNavItemClass(link.resourceKey)}`}
|
className={`${baseClass} ${activeClass}`}
|
||||||
>
|
>
|
||||||
{link.icon && <link.icon size={18} />}
|
{link.icon && (
|
||||||
|
<link.icon
|
||||||
|
size={22}
|
||||||
|
strokeWidth={1.75}
|
||||||
|
className={active ? 'text-blue-400' : 'text-gray-400 group-hover:text-blue-400 transition-colors'}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{link.name}
|
{link.name}
|
||||||
|
<span
|
||||||
|
className={`absolute bottom-0 left-3 right-3 h-0.5 rounded-full bg-blue-500 transition-all duration-200 ${
|
||||||
|
active ? 'opacity-100' : 'opacity-0 group-hover:opacity-60'
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
key={link.name}
|
key={link.name}
|
||||||
onClick={link.action}
|
onClick={link.action}
|
||||||
className={`flex items-center gap-1 font-medium text-sm text-white hover:text-blue-400 transition-colors ${getNavItemClass(link.resourceKey)}`}
|
className={`${baseClass} ${activeClass}`}
|
||||||
>
|
>
|
||||||
{link.icon && <link.icon size={18} />}
|
{link.icon && (
|
||||||
{link.name}
|
<link.icon
|
||||||
</button>
|
size={22}
|
||||||
),
|
strokeWidth={1.75}
|
||||||
|
className="text-gray-400 group-hover:text-blue-400 transition-colors"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<LanguageSelector />
|
{link.name}
|
||||||
|
<span className="absolute bottom-0 left-3 right-3 h-0.5 rounded-full bg-blue-500 opacity-0 group-hover:opacity-60 transition-all duration-200" />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Mobile Menu Button */}
|
{/* Right side: Language + Login */}
|
||||||
<button className="md:hidden text-white" onClick={toggleMenu} aria-label="Toggle menu">
|
<div className="hidden md:flex items-center gap-3">
|
||||||
{isOpen ? <FaTimes size={24} /> : <FaBars size={24} />}
|
<LanguageSelector />
|
||||||
</button>
|
<div className="w-px h-5 bg-white/20" />
|
||||||
</div>
|
{navLinks
|
||||||
|
.filter((l) => isLoginLink(l.resourceKey))
|
||||||
{/* Mobile Navigation */}
|
.map((link) =>
|
||||||
{isOpen && (
|
|
||||||
<div className="md:hidden bg-gray-900/95 backdrop-blur-sm shadow-lg">
|
|
||||||
<div className="container mx-auto px-4">
|
|
||||||
<nav className="flex flex-col space-y-4 py-4">
|
|
||||||
{navLinks.map((link) =>
|
|
||||||
link.path ? (
|
link.path ? (
|
||||||
<Link
|
<Link
|
||||||
key={link.path}
|
key={link.path}
|
||||||
to={link.path}
|
to={link.path}
|
||||||
className={`flex items-center gap-1 font-medium text-white hover:text-blue-400 transition-colors ${getNavItemClass(link.resourceKey)}`}
|
className="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-lg shadow-md shadow-blue-900/30 transition-all duration-200 hover:shadow-blue-700/40 hover:-translate-y-px"
|
||||||
onClick={toggleMenu}
|
|
||||||
>
|
>
|
||||||
{link.icon && <link.icon size={18} />}
|
{link.name}
|
||||||
|
</Link>
|
||||||
|
) : null,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu Button */}
|
||||||
|
<button
|
||||||
|
className="md:hidden flex items-center justify-center w-9 h-9 text-white rounded-md hover:bg-white/10 transition-colors"
|
||||||
|
onClick={toggleMenu}
|
||||||
|
aria-label="Toggle menu"
|
||||||
|
>
|
||||||
|
{isOpen ? <LuX size={20} strokeWidth={2} /> : <LuMenu size={20} strokeWidth={2} />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Navigation */}
|
||||||
|
<div
|
||||||
|
className={`md:hidden overflow-hidden transition-all duration-300 ease-in-out ${
|
||||||
|
isOpen ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="bg-gray-950/98 backdrop-blur-md border-t border-white/10">
|
||||||
|
<div className="container mx-auto px-6 py-3">
|
||||||
|
<nav className="flex flex-col gap-1">
|
||||||
|
{navLinks.map((link) => {
|
||||||
|
const active = isActiveLink(link.path)
|
||||||
|
const isLogin = isLoginLink(link.resourceKey)
|
||||||
|
if (isLogin) {
|
||||||
|
return link.path ? (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
onClick={toggleMenu}
|
||||||
|
className="mt-2 flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-lg transition-colors"
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
</Link>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
return link.path ? (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
onClick={toggleMenu}
|
||||||
|
className={`flex items-center gap-2.5 px-3 py-2.5 text-sm font-medium rounded-md transition-colors ${
|
||||||
|
active
|
||||||
|
? 'bg-white/10 text-white'
|
||||||
|
: 'text-gray-300 hover:bg-white/5 hover:text-white'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{link.icon && (
|
||||||
|
<link.icon
|
||||||
|
size={16}
|
||||||
|
strokeWidth={1.75}
|
||||||
|
className={active ? 'text-blue-400' : 'text-gray-400'}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{link.name}
|
{link.name}
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -190,18 +260,20 @@ const PublicLayout = () => {
|
||||||
link.action?.()
|
link.action?.()
|
||||||
toggleMenu()
|
toggleMenu()
|
||||||
}}
|
}}
|
||||||
className={`flex items-center gap-1 font-medium text-white hover:text-blue-400 transition-colors text-left ${getNavItemClass(link.resourceKey)}`}
|
className="flex items-center gap-2.5 px-3 py-2.5 text-sm font-medium text-gray-300 hover:bg-white/5 hover:text-white rounded-md transition-colors text-left"
|
||||||
>
|
>
|
||||||
{link.icon && <link.icon size={18} />}
|
{link.icon && <link.icon size={16} strokeWidth={1.75} className="text-gray-400" />}
|
||||||
{link.name}
|
{link.name}
|
||||||
</button>
|
</button>
|
||||||
),
|
)
|
||||||
)}
|
})}
|
||||||
|
<div className="pt-2 pb-1 border-t border-white/10 mt-1">
|
||||||
<LanguageSelector />
|
<LanguageSelector />
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main className="flex-grow">
|
<main className="flex-grow">
|
||||||
|
|
@ -373,11 +445,11 @@ const PublicLayout = () => {
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="space-y-3">
|
<ul className="space-y-3">
|
||||||
<li className="flex items-start space-x-3">
|
<li className="flex items-start space-x-3">
|
||||||
<FaMapPin size={20} className="text-gray-400 mt-1 flex-shrink-0" />
|
<LuMapPin size={18} strokeWidth={1.75} className="text-gray-400 mt-1 flex-shrink-0" />
|
||||||
<span className="text-gray-400">{translate('::Public.footer.address')}</span>
|
<span className="text-gray-400">{translate('::Public.footer.address')}</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="flex items-center space-x-3">
|
<li className="flex items-center space-x-3">
|
||||||
<FaPhone size={20} className="text-gray-400 flex-shrink-0" />
|
<LuPhone size={18} strokeWidth={1.75} className="text-gray-400 flex-shrink-0" />
|
||||||
<a
|
<a
|
||||||
href="tel:+905447697638"
|
href="tel:+905447697638"
|
||||||
className="text-gray-400 hover:text-white transition-colors"
|
className="text-gray-400 hover:text-white transition-colors"
|
||||||
|
|
@ -386,7 +458,7 @@ const PublicLayout = () => {
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="flex items-center space-x-3">
|
<li className="flex items-center space-x-3">
|
||||||
<FaEnvelope size={20} className="text-gray-400 flex-shrink-0" />
|
<LuMail size={18} strokeWidth={1.75} className="text-gray-400 flex-shrink-0" />
|
||||||
<a
|
<a
|
||||||
href="mailto:destek@sozsoft.com"
|
href="mailto:destek@sozsoft.com"
|
||||||
className="text-gray-400 hover:text-white transition-colors"
|
className="text-gray-400 hover:text-white transition-colors"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue