364 lines
13 KiB
TypeScript
364 lines
13 KiB
TypeScript
|
|
import React, { useState, useEffect } from 'react'
|
||
|
|
import { Link } from 'react-router-dom'
|
||
|
|
import {
|
||
|
|
FaArrowRight,
|
||
|
|
FaCalendarAlt,
|
||
|
|
FaUsers,
|
||
|
|
FaShieldAlt,
|
||
|
|
FaDesktop,
|
||
|
|
FaMobileAlt,
|
||
|
|
FaServer,
|
||
|
|
FaDatabase,
|
||
|
|
FaChartBar,
|
||
|
|
FaBookOpen,
|
||
|
|
FaCreditCard,
|
||
|
|
FaRegComment,
|
||
|
|
FaPhone,
|
||
|
|
FaChevronLeft,
|
||
|
|
FaChevronRight,
|
||
|
|
} from 'react-icons/fa'
|
||
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||
|
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||
|
|
import { Helmet } from 'react-helmet'
|
||
|
|
import { APP_NAME } from '@/constants/app.constant'
|
||
|
|
|
||
|
|
const Home: React.FC = () => {
|
||
|
|
const { translate } = useLocalization()
|
||
|
|
const [currentSlide, setCurrentSlide] = useState(0)
|
||
|
|
|
||
|
|
const slides = [
|
||
|
|
{
|
||
|
|
title: translate('::Public.hero.slide1.title'),
|
||
|
|
subtitle: translate('::Public.hero.slide1.subtitle'),
|
||
|
|
services: [
|
||
|
|
{
|
||
|
|
icon: <FaCalendarAlt className="mx-auto mb-4 text-blue-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide1.service1.title'),
|
||
|
|
desc: translate('::Public.hero.slide1.service1.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaUsers className="mx-auto mb-4 text-purple-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide1.service2.title'),
|
||
|
|
desc: translate('::Public.hero.slide1.service2.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaShieldAlt className="mx-auto mb-4 text-indigo-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide1.service3.title'),
|
||
|
|
desc: translate('::Public.hero.slide1.service3.desc'),
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: translate('::Public.hero.slide2.title'),
|
||
|
|
subtitle: translate('::Public.hero.slide2.subtitle'),
|
||
|
|
services: [
|
||
|
|
{
|
||
|
|
icon: <FaChartBar className="mx-auto mb-4 text-green-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide2.service1.title'),
|
||
|
|
desc: translate('::Public.hero.slide2.service1.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaCreditCard className="mx-auto mb-4 text-yellow-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide2.service2.title'),
|
||
|
|
desc: translate('::Public.hero.slide2.service2.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaDatabase className="mx-auto mb-4 text-red-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide2.service3.title'),
|
||
|
|
desc: translate('::Public.hero.slide2.service3.desc'),
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: translate('::Public.hero.slide3.title'),
|
||
|
|
subtitle: translate('::Public.hero.slide3.subtitle'),
|
||
|
|
services: [
|
||
|
|
{
|
||
|
|
icon: <FaDesktop className="mx-auto mb-4 text-cyan-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide3.service1.title'),
|
||
|
|
desc: translate('::Public.hero.slide3.service1.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaServer className="mx-auto mb-4 text-orange-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide3.service2.title'),
|
||
|
|
desc: translate('::Public.hero.slide3.service2.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaMobileAlt className="mx-auto mb-4 text-pink-400" size={40} />,
|
||
|
|
title: translate('::Public.hero.slide3.service3.title'),
|
||
|
|
desc: translate('::Public.hero.slide3.service3.desc'),
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const timer = setInterval(() => {
|
||
|
|
setCurrentSlide((prev) => (prev + 1) % slides.length)
|
||
|
|
}, 10000)
|
||
|
|
return () => clearInterval(timer)
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
const nextSlide = () => {
|
||
|
|
setCurrentSlide((prev) => (prev + 1) % slides.length)
|
||
|
|
}
|
||
|
|
|
||
|
|
const prevSlide = () => {
|
||
|
|
setCurrentSlide((prev) => (prev - 1 + slides.length) % slides.length)
|
||
|
|
}
|
||
|
|
|
||
|
|
const features = [
|
||
|
|
{
|
||
|
|
icon: <FaUsers className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.reliable'),
|
||
|
|
description: translate('::Public.features.reliable.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaCalendarAlt className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::App.Coordinator.Classroom.Planning'),
|
||
|
|
description: translate('::Public.features.rapid.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaBookOpen className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.expert'),
|
||
|
|
description: translate('::Public.features.expert.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaCreditCard className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.muhasebe'),
|
||
|
|
description: translate('::Public.features.muhasebe.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaRegComment className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.iletisim'),
|
||
|
|
description: translate('::Public.features.iletisim.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaPhone className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.mobil'),
|
||
|
|
description: translate('::Public.features.mobil.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaChartBar className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.scalable'),
|
||
|
|
description: translate('::Public.features.scalable.desc'),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaShieldAlt className="w-12 h-12 text-blue-500" />,
|
||
|
|
title: translate('::Public.features.guvenlik'),
|
||
|
|
description: translate('::Public.features.guvenlik.desc'),
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
const solutions = [
|
||
|
|
{
|
||
|
|
icon: <FaDesktop className="w-16 h-16 text-white" />,
|
||
|
|
title: translate('::Public.services.web.title'),
|
||
|
|
description: translate('::Public.solutions.web.desc'),
|
||
|
|
color: 'bg-blue-600',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaMobileAlt className="w-16 h-16 text-white" />,
|
||
|
|
title: translate('::Public.services.mobile.title'),
|
||
|
|
description: translate('::Public.solutions.mobile.desc'),
|
||
|
|
color: 'bg-purple-600',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaServer className="w-16 h-16 text-white" />,
|
||
|
|
title: translate('::Public.solutions.custom.title'),
|
||
|
|
description: translate('::Public.solutions.custom.desc'),
|
||
|
|
color: 'bg-green-600',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
icon: <FaDatabase className="w-16 h-16 text-white" />,
|
||
|
|
title: translate('::Public.solutions.database.title'),
|
||
|
|
description: translate('::Public.solutions.database.desc'),
|
||
|
|
color: 'bg-red-600',
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen">
|
||
|
|
<Helmet
|
||
|
|
titleTemplate={`%s | ${APP_NAME}`}
|
||
|
|
title={translate('::' + 'App.Home')}
|
||
|
|
defaultTitle={APP_NAME}
|
||
|
|
></Helmet>
|
||
|
|
|
||
|
|
{/* Hero Carousel */}
|
||
|
|
<div className="relative min-h-screen overflow-hidden">
|
||
|
|
<div className="absolute inset-0 bg-gradient-to-br from-blue-900 via-indigo-900 to-purple-900"></div>
|
||
|
|
<div
|
||
|
|
className="absolute inset-0 opacity-20"
|
||
|
|
style={{
|
||
|
|
backgroundImage:
|
||
|
|
'url("https://images.pexels.com/photos/3183150/pexels-photo-3183150.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||
|
|
backgroundSize: 'cover',
|
||
|
|
backgroundPosition: 'center',
|
||
|
|
}}
|
||
|
|
></div>
|
||
|
|
|
||
|
|
{/* Carousel Content */}
|
||
|
|
<div className="relative container mx-auto px-4 pt-32 pb-16 h-screen flex items-center">
|
||
|
|
{slides.map((slide, index) => (
|
||
|
|
<div
|
||
|
|
key={index}
|
||
|
|
className={`absolute inset-0 transition-all duration-700 ease-in-out ${
|
||
|
|
index === currentSlide
|
||
|
|
? 'opacity-100 translate-x-0'
|
||
|
|
: index < currentSlide
|
||
|
|
? 'opacity-0 -translate-x-full'
|
||
|
|
: 'opacity-0 translate-x-full'
|
||
|
|
}`}
|
||
|
|
>
|
||
|
|
<div className="container mx-auto px-4 pt-32">
|
||
|
|
<div className="max-w-4xl mx-auto text-center">
|
||
|
|
<h1 className="text-3xl md:text-6xl font-bold mb-6 text-white animate-fade-in">
|
||
|
|
{slide.title}
|
||
|
|
</h1>
|
||
|
|
<p className="text-xl md:text-2xl text-gray-300 mb-12 animate-fade-in-delay">
|
||
|
|
{slide.subtitle}
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<div className="flex flex-col md:flex-row justify-center gap-6 mb-16">
|
||
|
|
<Link
|
||
|
|
to={ROUTES_ENUM.public.contact}
|
||
|
|
className="inline-flex items-center justify-center px-8 py-4 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white rounded-lg font-semibold transition-all transform hover:scale-105"
|
||
|
|
>
|
||
|
|
{translate('::Public.hero.cta.consultation')}{' '}
|
||
|
|
<FaArrowRight className="ml-2" size={20} />
|
||
|
|
</Link>
|
||
|
|
<Link
|
||
|
|
to={ROUTES_ENUM.public.products}
|
||
|
|
className="inline-flex items-center justify-center px-8 py-4 bg-white/10 hover:bg-white/20 text-white rounded-lg font-semibold backdrop-blur-sm transition-all transform hover:scale-105"
|
||
|
|
>
|
||
|
|
{translate('::Public.hero.cta.discover')}
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
|
||
|
|
{slide.services.map((service, i) => (
|
||
|
|
<div
|
||
|
|
key={i}
|
||
|
|
className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all"
|
||
|
|
>
|
||
|
|
{service.icon}
|
||
|
|
<h3 className="text-xl font-semibold mb-3 text-white">{service.title}</h3>
|
||
|
|
<p className="text-gray-300">{service.desc}</p>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Navigation Buttons */}
|
||
|
|
<button
|
||
|
|
onClick={prevSlide}
|
||
|
|
className="absolute left-4 top-1/2 -translate-y-1/2 bg-white/10 hover:bg-white/20 backdrop-blur-sm text-white p-4 rounded-full transition-all z-10"
|
||
|
|
aria-label="Previous slide"
|
||
|
|
>
|
||
|
|
<FaChevronLeft size={24} />
|
||
|
|
</button>
|
||
|
|
<button
|
||
|
|
onClick={nextSlide}
|
||
|
|
className="absolute right-4 top-1/2 -translate-y-1/2 bg-white/10 hover:bg-white/20 backdrop-blur-sm text-white p-4 rounded-full transition-all z-10"
|
||
|
|
aria-label="Next slide"
|
||
|
|
>
|
||
|
|
<FaChevronRight size={24} />
|
||
|
|
</button>
|
||
|
|
|
||
|
|
{/* Slide Indicators */}
|
||
|
|
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 flex gap-3 z-10">
|
||
|
|
{slides.map((_, index) => (
|
||
|
|
<button
|
||
|
|
key={index}
|
||
|
|
onClick={() => setCurrentSlide(index)}
|
||
|
|
className={`w-3 h-3 rounded-full transition-all ${
|
||
|
|
index === currentSlide ? 'bg-white w-8' : 'bg-white/50 hover:bg-white/70'
|
||
|
|
}`}
|
||
|
|
aria-label={`Go to slide ${index + 1}`}
|
||
|
|
/>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Features */}
|
||
|
|
<section className="py-20 bg-white">
|
||
|
|
<div className="container mx-auto px-4">
|
||
|
|
<div className="text-center mb-16">
|
||
|
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||
|
|
{translate('::Public.features.title')}
|
||
|
|
</h2>
|
||
|
|
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||
|
|
{translate('::Public.features.subtitle')}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||
|
|
{features.map((feature, i) => (
|
||
|
|
<div
|
||
|
|
key={i}
|
||
|
|
className="p-8 bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow"
|
||
|
|
>
|
||
|
|
<div className="mb-6">{feature.icon}</div>
|
||
|
|
<h2 className="text-2xl font-bold text-gray-900">{feature.title}</h2>
|
||
|
|
<p className="text-gray-600">{feature.description}</p>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
{/* Solutions */}
|
||
|
|
<section className="py-20 bg-gray-50">
|
||
|
|
<div className="container mx-auto px-4">
|
||
|
|
<div className="text-center mb-16">
|
||
|
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||
|
|
{translate('::Public.solutions.title')}
|
||
|
|
</h2>
|
||
|
|
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||
|
|
{translate('::Public.solutions.subtitle')}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||
|
|
{solutions.map((s, i) => (
|
||
|
|
<div
|
||
|
|
key={i}
|
||
|
|
className="group relative overflow-hidden rounded-2xl transition-all hover:scale-105"
|
||
|
|
>
|
||
|
|
<div className={`${s.color} p-8 h-full`}>
|
||
|
|
<div className="mb-6">{s.icon}</div>
|
||
|
|
<h3 className="text-2xl font-semibold text-white mb-4">{s.title}</h3>
|
||
|
|
<p className="text-white/90">{s.description}</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
{/* Call to Action */}
|
||
|
|
<section className="bg-blue-600 py-16">
|
||
|
|
<div className="container mx-auto px-4 text-center">
|
||
|
|
<h2 className="text-3xl font-bold text-white mb-4">
|
||
|
|
{translate('::Public.common.getStarted')}
|
||
|
|
</h2>
|
||
|
|
<p className="text-white text-lg mb-8">{translate('::Public.common.contact')}</p>
|
||
|
|
<Link
|
||
|
|
to={ROUTES_ENUM.public.contact}
|
||
|
|
className="bg-white text-blue-600 px-8 py-3 rounded-lg font-semibold hover:bg-blue-50 transition-colors"
|
||
|
|
>
|
||
|
|
{translate('::Public.common.learnMore')}
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export default Home
|