2026-02-24 20:44:16 +00:00
|
|
|
import View from '@/views/Views'
|
|
|
|
|
import React, { useEffect, useState } from 'react'
|
2026-06-26 08:59:13 +00:00
|
|
|
import { useLocation, Link, useNavigate } from 'react-router-dom'
|
2026-05-26 16:09:26 +00:00
|
|
|
import { FaFacebook, FaTwitter, FaLinkedin, FaInstagram } from 'react-icons/fa'
|
2026-05-15 21:06:58 +00:00
|
|
|
import {
|
|
|
|
|
LuMenu,
|
|
|
|
|
LuX,
|
|
|
|
|
LuHouse,
|
|
|
|
|
LuInfo,
|
|
|
|
|
LuBriefcase,
|
|
|
|
|
LuPackage,
|
|
|
|
|
LuBookOpen,
|
|
|
|
|
LuPhone,
|
|
|
|
|
LuMapPin,
|
|
|
|
|
LuMail,
|
2026-05-26 16:09:26 +00:00
|
|
|
LuMoon,
|
|
|
|
|
LuSun,
|
|
|
|
|
} from 'react-icons/lu'
|
2026-02-24 20:44:16 +00:00
|
|
|
import Logo from '@/views/public/Logo'
|
|
|
|
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
|
|
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
|
|
|
import LanguageSelector from '../template/LanguageSelector'
|
|
|
|
|
import Demo from '@/views/public/Demo'
|
|
|
|
|
import { ScrollContext } from '@/contexts/ScrollContext'
|
2026-06-29 07:13:58 +00:00
|
|
|
import { DemoProvider } from '@/contexts/DemoContext'
|
2026-05-26 16:09:26 +00:00
|
|
|
import useDarkMode from '@/utils/hooks/useDarkmode'
|
|
|
|
|
import { THEME_ENUM } from '@/constants/theme.constant'
|
2026-06-25 22:55:44 +00:00
|
|
|
import { Button } from '../ui'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
interface NavLink {
|
|
|
|
|
resourceKey?: string
|
|
|
|
|
name: string
|
|
|
|
|
path?: string
|
|
|
|
|
action?: () => void
|
|
|
|
|
icon?: React.ComponentType<any>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const PublicLayout = () => {
|
|
|
|
|
const location = useLocation()
|
2026-06-26 08:59:13 +00:00
|
|
|
const navigate = useNavigate()
|
2026-02-24 20:44:16 +00:00
|
|
|
const { translate } = useLocalization()
|
2026-05-26 16:09:26 +00:00
|
|
|
const [isDarkMode, setThemeMode] = useDarkMode()
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
const [isOpen, setIsOpen] = useState(false)
|
|
|
|
|
const [scrolled, setScrolled] = useState(false)
|
|
|
|
|
const [isDemoOpen, setIsDemoOpen] = useState(false)
|
|
|
|
|
const currentYear = new Date().getFullYear()
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
window.scrollTo(0, 0)
|
|
|
|
|
}, [location.pathname])
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleScroll = () => {
|
|
|
|
|
const isScrolled = window.scrollY > 10
|
|
|
|
|
if (isScrolled !== scrolled) {
|
|
|
|
|
setScrolled(isScrolled)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.addEventListener('scroll', handleScroll)
|
|
|
|
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
|
|
|
}, [scrolled])
|
|
|
|
|
|
|
|
|
|
const toggleMenu = () => setIsOpen(!isOpen)
|
|
|
|
|
|
|
|
|
|
const navLinks: NavLink[] = [
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'App.Home',
|
|
|
|
|
name: translate('::App.Home'),
|
|
|
|
|
path: ROUTES_ENUM.public.home,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuHouse,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'App.About',
|
|
|
|
|
name: translate('::App.About'),
|
|
|
|
|
path: ROUTES_ENUM.public.about,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuInfo,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'App.Services',
|
|
|
|
|
name: translate('::App.Services'),
|
|
|
|
|
path: ROUTES_ENUM.public.services,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuBriefcase,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'Public.nav.products',
|
|
|
|
|
name: translate('::App.Orders'),
|
|
|
|
|
path: ROUTES_ENUM.public.products,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuPackage,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'Public.nav.blog',
|
|
|
|
|
name: translate('::App.BlogManagement'),
|
|
|
|
|
path: ROUTES_ENUM.public.blog,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuBookOpen,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'Public.nav.contact',
|
|
|
|
|
name: translate('::App.Contact'),
|
|
|
|
|
path: ROUTES_ENUM.public.contact,
|
2026-05-15 21:06:58 +00:00
|
|
|
icon: LuPhone,
|
2026-02-24 20:44:16 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
resourceKey: 'Public.nav.giris',
|
|
|
|
|
name: translate('::Public.nav.giris'),
|
|
|
|
|
path: ROUTES_ENUM.authenticated.login,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
2026-05-15 21:06:58 +00:00
|
|
|
const isLoginLink = (resourceKey?: string) => resourceKey === 'Public.nav.giris'
|
|
|
|
|
|
2026-06-25 08:39:42 +00:00
|
|
|
const demoButton = (className = '', onClick?: () => void) => (
|
2026-06-25 22:55:44 +00:00
|
|
|
<Button
|
2026-06-25 08:39:42 +00:00
|
|
|
type="button"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setIsDemoOpen(true)
|
|
|
|
|
onClick?.()
|
|
|
|
|
}}
|
2026-06-25 22:55:44 +00:00
|
|
|
variant="plain"
|
|
|
|
|
size="sm"
|
|
|
|
|
className={`group !h-9 !w-9 !bg-transparent !px-0 !text-gray-200 hover:!bg-transparent hover:!text-white !shadow-none !overflow-visible transition-colors ${className}`}
|
2026-06-25 08:39:42 +00:00
|
|
|
>
|
|
|
|
|
<span className="relative inline-flex h-7 w-7 items-center justify-center overflow-visible rounded-full border-2 border-stone-700 bg-gradient-to-b from-red-400 via-red-600 to-red-800 shadow-[inset_0_-3px_6px_rgba(0,0,0,0.35),0_1px_3px_rgba(0,0,0,0.35)] ring-1 ring-black/60 transition-all duration-200 group-hover:scale-105 group-hover:from-red-300 group-hover:via-red-500 group-hover:to-red-700 group-hover:shadow-[inset_0_-3px_6px_rgba(0,0,0,0.3),0_2px_8px_rgba(239,68,68,0.35)]">
|
|
|
|
|
<span className="absolute inset-x-1 top-1 h-2 rounded-full bg-white/35 blur-[1px] transition-colors group-hover:bg-white/50" />
|
|
|
|
|
<span className="absolute left-1/2 top-1/2 z-10 w-12 -translate-x-1/2 -translate-y-1/2 text-center uppercase leading-none tracking-tight text-white drop-shadow">
|
|
|
|
|
{translate('::App.Demos')}
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
2026-06-25 22:55:44 +00:00
|
|
|
</Button>
|
2026-06-25 08:39:42 +00:00
|
|
|
)
|
|
|
|
|
|
2026-05-26 16:09:26 +00:00
|
|
|
const themeToggle = (
|
2026-06-25 22:55:44 +00:00
|
|
|
<div className="inline-flex h-9 items-center rounded-lg p-0.5">
|
|
|
|
|
<Button
|
2026-05-26 16:09:26 +00:00
|
|
|
type="button"
|
|
|
|
|
onClick={() => setThemeMode(THEME_ENUM.MODE_LIGHT)}
|
|
|
|
|
aria-pressed={!isDarkMode}
|
|
|
|
|
title="Light mode"
|
2026-06-25 22:55:44 +00:00
|
|
|
icon={<LuSun size={15} strokeWidth={1.8} />}
|
|
|
|
|
variant="plain"
|
|
|
|
|
size="xs"
|
|
|
|
|
className={`!h-8 !w-8 xl:!w-auto !px-0 xl:!px-2.5 !rounded-l-md !rounded-r-none !border-transparent !shadow-none ${
|
|
|
|
|
!isDarkMode
|
|
|
|
|
? '!bg-white !text-gray-950'
|
|
|
|
|
: '!bg-transparent !text-gray-300 hover:!bg-transparent hover:!text-white'
|
2026-05-26 16:09:26 +00:00
|
|
|
}`}
|
2026-06-25 22:55:44 +00:00
|
|
|
/>
|
2026-05-26 16:09:26 +00:00
|
|
|
|
2026-06-25 22:55:44 +00:00
|
|
|
<Button
|
2026-05-26 16:09:26 +00:00
|
|
|
type="button"
|
|
|
|
|
onClick={() => setThemeMode(THEME_ENUM.MODE_DARK)}
|
|
|
|
|
aria-pressed={isDarkMode}
|
|
|
|
|
title="Dark mode"
|
2026-06-25 22:55:44 +00:00
|
|
|
icon={<LuMoon size={15} strokeWidth={1.8} />}
|
|
|
|
|
variant="plain"
|
|
|
|
|
size="xs"
|
|
|
|
|
className={`!h-8 !w-8 xl:!w-auto !px-0 xl:!px-2.5 !rounded-r-md !rounded-l-none !border-transparent !shadow-none ${
|
|
|
|
|
isDarkMode
|
2026-06-26 08:59:13 +00:00
|
|
|
? '!bg-gray-300 !text-gray-800'
|
2026-06-25 22:55:44 +00:00
|
|
|
: '!bg-transparent !text-gray-300 hover:!bg-transparent hover:!text-white'
|
2026-05-26 16:09:26 +00:00
|
|
|
}`}
|
2026-06-25 22:55:44 +00:00
|
|
|
/>
|
2026-05-26 16:09:26 +00:00
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-15 21:06:58 +00:00
|
|
|
const isActiveLink = (path?: string) => {
|
|
|
|
|
if (!path) return false
|
|
|
|
|
if (path === ROUTES_ENUM.public.home) return location.pathname === path
|
|
|
|
|
return location.pathname.startsWith(path)
|
2026-02-24 20:44:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2026-06-29 07:13:58 +00:00
|
|
|
<DemoProvider value={{ openDemo: () => setIsDemoOpen(true) }}>
|
|
|
|
|
<ScrollContext.Provider value={scrolled}>
|
|
|
|
|
<div className="flex flex-col min-h-screen">
|
2026-02-24 20:44:16 +00:00
|
|
|
{/* HEADER */}
|
|
|
|
|
<header
|
2026-05-15 21:06:58 +00:00
|
|
|
className={`fixed w-full z-50 transition-all duration-500 ${
|
2026-02-24 20:44:16 +00:00
|
|
|
scrolled
|
2026-05-15 21:06:58 +00:00
|
|
|
? 'bg-gray-950 shadow-lg shadow-black/30 py-2 border-b border-white/10'
|
|
|
|
|
: 'bg-gray-950/80 backdrop-blur-sm py-4 border-b border-white/5'
|
2026-02-24 20:44:16 +00:00
|
|
|
}`}
|
|
|
|
|
>
|
2026-06-04 12:08:52 +00:00
|
|
|
<div className="container mx-auto px-6 relative grid grid-cols-[auto_1fr_auto] items-center lg:grid-cols-[1fr_auto] xl:grid-cols-[auto_1fr_auto]">
|
|
|
|
|
<Logo
|
2026-07-04 16:30:16 +00:00
|
|
|
mode={isDarkMode ? 'dark' : 'light'}
|
2026-06-04 12:08:52 +00:00
|
|
|
className="relative z-10 max-w-[190px] overflow-hidden lg:hidden xl:block xl:max-w-none"
|
|
|
|
|
imgClass="h-10 w-auto object-contain xl:h-auto"
|
|
|
|
|
/>
|
2026-05-15 21:06:58 +00:00
|
|
|
|
2026-06-04 12:08:52 +00:00
|
|
|
{/* Desktop / tablet navigation */}
|
|
|
|
|
<nav className="hidden lg:flex lg:col-start-1 xl:col-start-2 items-center justify-self-start xl:justify-self-center gap-1">
|
2026-05-15 21:06:58 +00:00
|
|
|
{navLinks
|
|
|
|
|
.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'
|
2026-05-26 16:09:26 +00:00
|
|
|
const activeClass = active ? 'text-white' : 'text-gray-300 hover:text-white'
|
2026-05-15 21:06:58 +00:00
|
|
|
return link.path ? (
|
2026-05-26 16:09:26 +00:00
|
|
|
<Link key={link.path} to={link.path} className={`${baseClass} ${activeClass}`}>
|
2026-05-15 21:06:58 +00:00
|
|
|
{link.icon && (
|
|
|
|
|
<link.icon
|
|
|
|
|
size={22}
|
|
|
|
|
strokeWidth={1.75}
|
2026-05-26 16:09:26 +00:00
|
|
|
className={
|
|
|
|
|
active
|
|
|
|
|
? 'text-blue-400'
|
|
|
|
|
: 'text-gray-400 group-hover:text-blue-400 transition-colors'
|
|
|
|
|
}
|
2026-05-15 21:06:58 +00:00
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{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>
|
|
|
|
|
) : (
|
2026-06-25 22:55:44 +00:00
|
|
|
<Button
|
2026-05-15 21:06:58 +00:00
|
|
|
key={link.name}
|
|
|
|
|
onClick={link.action}
|
2026-06-25 22:55:44 +00:00
|
|
|
variant="plain"
|
|
|
|
|
size="sm"
|
2026-05-15 21:06:58 +00:00
|
|
|
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" />
|
2026-06-25 22:55:44 +00:00
|
|
|
</Button>
|
2026-05-15 21:06:58 +00:00
|
|
|
)
|
|
|
|
|
})}
|
2026-02-24 20:44:16 +00:00
|
|
|
</nav>
|
|
|
|
|
|
2026-06-25 22:55:44 +00:00
|
|
|
<div className="relative z-10 hidden lg:flex lg:col-start-2 xl:col-start-3 lg:justify-self-end items-center gap-3">
|
|
|
|
|
{demoButton('rounded-lg')}
|
|
|
|
|
<div className="h-5 w-px bg-white/20" />
|
|
|
|
|
<div className="flex h-9 w-9 items-center justify-center">
|
2026-06-25 08:39:42 +00:00
|
|
|
<LanguageSelector className="!bg-transparent hover:!bg-transparent dark:hover:!bg-transparent" />
|
|
|
|
|
</div>
|
2026-06-25 22:55:44 +00:00
|
|
|
<div className="h-5 w-px bg-white/20" />
|
2026-05-26 16:09:26 +00:00
|
|
|
{themeToggle}
|
2026-06-25 22:55:44 +00:00
|
|
|
<div className="h-5 w-px bg-white/20" />
|
2026-05-15 21:06:58 +00:00
|
|
|
{navLinks
|
|
|
|
|
.filter((l) => isLoginLink(l.resourceKey))
|
|
|
|
|
.map((link) =>
|
|
|
|
|
link.path ? (
|
2026-06-26 08:59:13 +00:00
|
|
|
<Button
|
2026-05-15 21:06:58 +00:00
|
|
|
key={link.path}
|
2026-06-26 08:59:13 +00:00
|
|
|
type="button"
|
|
|
|
|
variant="solid"
|
|
|
|
|
shape="round"
|
|
|
|
|
onClick={() => navigate(link.path!)}
|
2026-05-15 21:06:58 +00:00
|
|
|
>
|
|
|
|
|
{link.name}
|
2026-06-26 08:59:13 +00:00
|
|
|
</Button>
|
2026-05-15 21:06:58 +00:00
|
|
|
) : null,
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
{/* Mobile Menu Button */}
|
2026-06-25 22:55:44 +00:00
|
|
|
<Button
|
2026-06-04 12:08:52 +00:00
|
|
|
className="lg:hidden col-start-3 justify-self-end flex items-center justify-center w-9 h-9 text-white rounded-md hover:bg-white/10 transition-colors"
|
2026-05-15 21:06:58 +00:00
|
|
|
onClick={toggleMenu}
|
|
|
|
|
aria-label="Toggle menu"
|
2026-06-04 12:08:52 +00:00
|
|
|
aria-expanded={isOpen}
|
2026-06-25 22:55:44 +00:00
|
|
|
icon={
|
|
|
|
|
isOpen ? (
|
|
|
|
|
<LuX size={20} strokeWidth={2} />
|
|
|
|
|
) : (
|
|
|
|
|
<LuMenu size={20} strokeWidth={2} />
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
variant="plain"
|
|
|
|
|
size="xs"
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Mobile Navigation */}
|
2026-05-15 21:06:58 +00:00
|
|
|
<div
|
2026-06-25 08:39:42 +00:00
|
|
|
className={`lg:hidden transition-all duration-300 ease-in-out ${
|
|
|
|
|
isOpen
|
|
|
|
|
? 'max-h-screen overflow-visible opacity-100'
|
|
|
|
|
: 'max-h-0 overflow-hidden opacity-0'
|
2026-05-15 21:06:58 +00:00
|
|
|
}`}
|
|
|
|
|
>
|
2026-06-04 12:08:52 +00:00
|
|
|
<div className="border-t border-white/10 bg-gray-950/98 backdrop-blur-md">
|
2026-05-15 21:06:58 +00:00
|
|
|
<div className="container mx-auto px-6 py-3">
|
|
|
|
|
<nav className="flex flex-col gap-1">
|
2026-06-04 12:08:52 +00:00
|
|
|
<div className="lg:hidden 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
|
|
|
|
|
}
|
2026-05-15 21:06:58 +00:00
|
|
|
return link.path ? (
|
|
|
|
|
<Link
|
|
|
|
|
key={link.path}
|
|
|
|
|
to={link.path}
|
|
|
|
|
onClick={toggleMenu}
|
2026-06-04 12:08:52 +00:00
|
|
|
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'
|
|
|
|
|
}`}
|
2026-05-15 21:06:58 +00:00
|
|
|
>
|
2026-06-04 12:08:52 +00:00
|
|
|
{link.icon && (
|
|
|
|
|
<link.icon
|
|
|
|
|
size={16}
|
|
|
|
|
strokeWidth={1.75}
|
|
|
|
|
className={active ? 'text-blue-400' : 'text-gray-400'}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-05-15 21:06:58 +00:00
|
|
|
{link.name}
|
|
|
|
|
</Link>
|
2026-06-04 12:08:52 +00:00
|
|
|
) : (
|
2026-06-25 22:55:44 +00:00
|
|
|
<Button
|
2026-06-04 12:08:52 +00:00
|
|
|
key={link.name}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
link.action?.()
|
|
|
|
|
toggleMenu()
|
|
|
|
|
}}
|
2026-06-25 22:55:44 +00:00
|
|
|
variant="plain"
|
|
|
|
|
size="sm"
|
2026-06-04 12:08:52 +00:00
|
|
|
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={16} strokeWidth={1.75} className="text-gray-400" />
|
|
|
|
|
)}
|
|
|
|
|
{link.name}
|
2026-06-25 22:55:44 +00:00
|
|
|
</Button>
|
2026-06-04 12:08:52 +00:00
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="mt-1 border-t border-white/10 pt-2 pb-1">
|
2026-05-26 16:09:26 +00:00
|
|
|
<div className="flex items-center justify-between gap-3">
|
2026-06-25 08:39:42 +00:00
|
|
|
<div className="flex items-center gap-1">
|
2026-06-25 22:55:44 +00:00
|
|
|
{demoButton('rounded-lg', toggleMenu)}
|
2026-06-25 08:39:42 +00:00
|
|
|
<div className="flex h-10 min-w-10 items-center justify-center rounded-lg">
|
|
|
|
|
<LanguageSelector className="!bg-transparent hover:!bg-transparent dark:hover:!bg-transparent" />
|
|
|
|
|
</div>
|
2026-06-04 12:08:52 +00:00
|
|
|
</div>
|
2026-06-25 08:39:42 +00:00
|
|
|
<div className="flex h-10 items-center rounded-lg px-1">{themeToggle}</div>
|
2026-06-04 12:08:52 +00:00
|
|
|
{navLinks
|
|
|
|
|
.filter((l) => isLoginLink(l.resourceKey))
|
|
|
|
|
.map((link) =>
|
|
|
|
|
link.path ? (
|
|
|
|
|
<Link
|
|
|
|
|
key={link.path}
|
|
|
|
|
to={link.path}
|
|
|
|
|
onClick={toggleMenu}
|
|
|
|
|
className="hidden h-10 lg:inline-flex items-center justify-center px-4 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-lg shadow-md shadow-blue-900/30 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{link.name}
|
|
|
|
|
</Link>
|
|
|
|
|
) : null,
|
|
|
|
|
)}
|
2026-05-26 16:09:26 +00:00
|
|
|
</div>
|
2026-05-15 21:06:58 +00:00
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-15 21:06:58 +00:00
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<main className="flex-grow">
|
|
|
|
|
<View />
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
<footer className="bg-gray-900 text-white pt-16 pb-8">
|
|
|
|
|
<div className="container mx-auto px-4">
|
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
|
|
|
|
<div>
|
2026-07-04 16:30:16 +00:00
|
|
|
<Logo mode={isDarkMode ? 'dark' : 'light'} />
|
2026-02-24 20:44:16 +00:00
|
|
|
<p className="mt-4 text-gray-400 text-sm">
|
|
|
|
|
{translate('::Public.footer.companyInfo')}
|
|
|
|
|
</p>
|
|
|
|
|
<div className="flex space-x-4 mt-6">
|
|
|
|
|
<a
|
|
|
|
|
href="https://facebook.com/sozsoft"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<FaFacebook size={20} />
|
|
|
|
|
</a>
|
|
|
|
|
<a
|
|
|
|
|
href="https://twitter.com/sozsoft"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<FaTwitter size={20} />
|
|
|
|
|
</a>
|
|
|
|
|
<a
|
|
|
|
|
href="https://linkedin.com/sozsoft"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<FaLinkedin size={20} />
|
|
|
|
|
</a>
|
|
|
|
|
<a
|
|
|
|
|
href="https://instagram.com/sozsoft"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<FaInstagram size={20} />
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Quick Links */}
|
|
|
|
|
<div>
|
|
|
|
|
<h3 className="text-lg font-bold mb-4 text-white">
|
|
|
|
|
{translate('::Public.footer.quickLinksTitle')}
|
|
|
|
|
</h3>
|
|
|
|
|
<ul className="space-y-2">
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.home}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.Home')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.products}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.Orders')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.Services')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.about}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.About')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.blog}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.BlogManagement')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.contact}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::App.Contact')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Services */}
|
|
|
|
|
<div>
|
|
|
|
|
<h3 className="text-lg font-bold mb-4 text-white">
|
|
|
|
|
{translate('::Public.services.title')}
|
|
|
|
|
</h3>
|
|
|
|
|
<ul className="space-y-2">
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.software.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.web.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.mobile.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.database.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.integration.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.services}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.services.consulting.title')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Contact Info */}
|
|
|
|
|
<div>
|
2026-05-26 16:09:26 +00:00
|
|
|
<h3 className="text-lg font-bold mb-4 text-white">{translate('::App.Contact')}</h3>
|
2026-02-24 20:44:16 +00:00
|
|
|
<ul className="space-y-3">
|
|
|
|
|
<li className="flex items-start space-x-3">
|
2026-05-26 16:09:26 +00:00
|
|
|
<LuMapPin
|
|
|
|
|
size={18}
|
|
|
|
|
strokeWidth={1.75}
|
|
|
|
|
className="text-gray-400 mt-1 flex-shrink-0"
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
<span className="text-gray-400">{translate('::Public.footer.address')}</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li className="flex items-center space-x-3">
|
2026-05-15 21:06:58 +00:00
|
|
|
<LuPhone size={18} strokeWidth={1.75} className="text-gray-400 flex-shrink-0" />
|
2026-02-24 20:44:16 +00:00
|
|
|
<a
|
|
|
|
|
href="tel:+905447697638"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
+90 (544) 769 7 638
|
|
|
|
|
</a>
|
|
|
|
|
</li>
|
|
|
|
|
<li className="flex items-center space-x-3">
|
2026-05-15 21:06:58 +00:00
|
|
|
<LuMail size={18} strokeWidth={1.75} className="text-gray-400 flex-shrink-0" />
|
2026-02-24 20:44:16 +00:00
|
|
|
<a
|
|
|
|
|
href="mailto:destek@sozsoft.com"
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
destek@sozsoft.com
|
|
|
|
|
</a>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="border-t border-gray-800 mt-12 pt-8">
|
|
|
|
|
<div className="flex flex-col md:flex-row justify-between items-center">
|
|
|
|
|
<p className="text-gray-400 text-sm">
|
2026-02-28 21:37:34 +00:00
|
|
|
© {currentYear} Sözsoft Platform. {translate('::Public.footer.copyright')}
|
2026-02-24 20:44:16 +00:00
|
|
|
</p>
|
|
|
|
|
<div className="mt-4 md:mt-0">
|
|
|
|
|
<ul className="flex space-x-6 text-sm">
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.about}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.footer.privacyPolicy')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<Link
|
|
|
|
|
to={ROUTES_ENUM.public.about}
|
|
|
|
|
className="text-gray-400 hover:text-white transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{translate('::Public.footer.termsOfUse')}
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
{/* Demo Modal */}
|
2026-06-29 07:13:58 +00:00
|
|
|
<Demo isOpen={isDemoOpen} onClose={() => setIsDemoOpen(false)} />
|
|
|
|
|
</div>
|
|
|
|
|
</ScrollContext.Provider>
|
|
|
|
|
</DemoProvider>
|
2026-02-24 20:44:16 +00:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default PublicLayout
|