Home Menu

This commit is contained in:
Sedat Öztürk 2026-05-16 00:06:58 +03:00
parent efdba93e32
commit 6dd3cc4c32

View file

@ -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))
<Link .map((link) => {
key={link.path} const active = isActiveLink(link.path)
to={link.path} const baseClass =
className={`flex items-center gap-1 font-medium text-sm text-white hover:text-blue-400 transition-colors ${getNavItemClass(link.resourceKey)}`} '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
{link.icon && <link.icon size={18} />} ? 'text-white'
{link.name} : 'text-gray-300 hover:text-white'
</Link> return link.path ? (
) : ( <Link
<button key={link.path}
key={link.name} to={link.path}
onClick={link.action} className={`${baseClass} ${activeClass}`}
className={`flex items-center gap-1 font-medium text-sm text-white hover:text-blue-400 transition-colors ${getNavItemClass(link.resourceKey)}`} >
> {link.icon && (
{link.icon && <link.icon size={18} />} <link.icon
{link.name} size={22}
</button> strokeWidth={1.75}
), className={active ? 'text-blue-400' : '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 transition-all duration-200 ${
active ? 'opacity-100' : 'opacity-0 group-hover:opacity-60'
}`}
/>
</Link>
) : (
<button
key={link.name}
onClick={link.action}
className={`${baseClass} ${activeClass}`}
>
{link.icon && (
<link.icon
size={22}
strokeWidth={1.75}
className="text-gray-400 group-hover:text-blue-400 transition-colors"
/>
)}
{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>
{/* Right side: Language + Login */}
<div className="hidden md:flex items-center gap-3">
<LanguageSelector />
<div className="w-px h-5 bg-white/20" />
{navLinks
.filter((l) => isLoginLink(l.resourceKey))
.map((link) =>
link.path ? (
<Link
key={link.path}
to={link.path}
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"
>
{link.name}
</Link>
) : null,
)}
</div>
{/* Mobile Menu Button */} {/* Mobile Menu Button */}
<button className="md:hidden text-white" onClick={toggleMenu} aria-label="Toggle menu"> <button
{isOpen ? <FaTimes size={24} /> : <FaBars size={24} />} 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> </button>
</div> </div>
{/* Mobile Navigation */} {/* Mobile Navigation */}
{isOpen && ( <div
<div className="md:hidden bg-gray-900/95 backdrop-blur-sm shadow-lg"> className={`md:hidden overflow-hidden transition-all duration-300 ease-in-out ${
<div className="container mx-auto px-4"> isOpen ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'
<nav className="flex flex-col space-y-4 py-4"> }`}
{navLinks.map((link) => >
link.path ? ( <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 <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)}`}
onClick={toggleMenu} 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={18} />} {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>
), )
)} })}
<LanguageSelector /> <div className="pt-2 pb-1 border-t border-white/10 mt-1">
<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"