About Sayfası dinamik hale getiriliyor.
This commit is contained in:
parent
13362f4745
commit
6fdc2c3231
1 changed files with 137 additions and 51 deletions
|
|
@ -8,14 +8,101 @@ import {
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { useCountUp } from '@/utils/hooks/useCountUp'
|
import { useCountUp } from '@/utils/hooks/useCountUp'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
|
import { IconType } from 'react-icons'
|
||||||
|
|
||||||
|
interface StatItem {
|
||||||
|
icon: IconType
|
||||||
|
value: string | number
|
||||||
|
labelKey: string
|
||||||
|
useCounter?: boolean
|
||||||
|
counterEnd?: number
|
||||||
|
counterSuffix?: string
|
||||||
|
counterDuration?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContentSection {
|
||||||
|
key: string
|
||||||
|
descKey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AboutPageData {
|
||||||
|
stats: StatItem[]
|
||||||
|
descriptions: string[]
|
||||||
|
sections: ContentSection[]
|
||||||
|
}
|
||||||
|
|
||||||
const About: React.FC = () => {
|
const About: React.FC = () => {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
// Counter animations
|
// About page data configuration
|
||||||
const clientsCount = useCountUp({ end: 300, suffix: '+', duration: 2500 })
|
const aboutPageData: AboutPageData = {
|
||||||
const experienceCount = useCountUp({ end: 20, suffix: '+', duration: 2000 })
|
stats: [
|
||||||
const countriesCount = useCountUp({ end: 3, duration: 1500 })
|
{
|
||||||
|
icon: FaUsers,
|
||||||
|
value: 300,
|
||||||
|
labelKey: '::Public.about.stats.clients',
|
||||||
|
useCounter: true,
|
||||||
|
counterEnd: 300,
|
||||||
|
counterSuffix: '+',
|
||||||
|
counterDuration: 2500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaAward,
|
||||||
|
value: 20,
|
||||||
|
labelKey: '::Public.about.stats.experience',
|
||||||
|
useCounter: true,
|
||||||
|
counterEnd: 20,
|
||||||
|
counterSuffix: '+',
|
||||||
|
counterDuration: 2000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaClock,
|
||||||
|
value: '7/24',
|
||||||
|
labelKey: '::Public.about.stats.support',
|
||||||
|
useCounter: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaGlobe,
|
||||||
|
value: 3,
|
||||||
|
labelKey: '::Public.about.stats.countries',
|
||||||
|
useCounter: true,
|
||||||
|
counterEnd: 3,
|
||||||
|
counterDuration: 1500
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descriptions: [
|
||||||
|
'::Public.about.description.part1',
|
||||||
|
'::Public.about.description.motto',
|
||||||
|
'::Public.about.description.part2',
|
||||||
|
'::Public.about.description.closing'
|
||||||
|
],
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
key: '::Public.about.mission',
|
||||||
|
descKey: '::Public.about.mission.desc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '::Public.about.vision',
|
||||||
|
descKey: '::Public.about.vision.desc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counter animations based on data
|
||||||
|
const clientsCount = useCountUp({
|
||||||
|
end: aboutPageData.stats[0].counterEnd!,
|
||||||
|
suffix: aboutPageData.stats[0].counterSuffix,
|
||||||
|
duration: aboutPageData.stats[0].counterDuration!
|
||||||
|
})
|
||||||
|
const experienceCount = useCountUp({
|
||||||
|
end: aboutPageData.stats[1].counterEnd!,
|
||||||
|
suffix: aboutPageData.stats[1].counterSuffix,
|
||||||
|
duration: aboutPageData.stats[1].counterDuration!
|
||||||
|
})
|
||||||
|
const countriesCount = useCountUp({
|
||||||
|
end: aboutPageData.stats[3].counterEnd!,
|
||||||
|
duration: aboutPageData.stats[3].counterDuration!
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -49,32 +136,35 @@ const About: React.FC = () => {
|
||||||
<div className="py-10 bg-white">
|
<div className="py-10 bg-white">
|
||||||
<div className="container mx-auto px-4">
|
<div className="container mx-auto px-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||||
<div className="text-center" ref={clientsCount.elementRef}>
|
{aboutPageData.stats.map((stat, index) => {
|
||||||
<FaUsers className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
const IconComponent = stat.icon
|
||||||
|
let displayValue = stat.value
|
||||||
|
let elementRef = undefined
|
||||||
|
|
||||||
|
// Handle counter values
|
||||||
|
if (stat.useCounter) {
|
||||||
|
if (index === 0) {
|
||||||
|
displayValue = clientsCount.displayValue
|
||||||
|
elementRef = clientsCount.elementRef
|
||||||
|
} else if (index === 1) {
|
||||||
|
displayValue = experienceCount.displayValue
|
||||||
|
elementRef = experienceCount.elementRef
|
||||||
|
} else if (index === 3) {
|
||||||
|
displayValue = countriesCount.displayValue
|
||||||
|
elementRef = countriesCount.elementRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={index} className="text-center" ref={elementRef}>
|
||||||
|
<IconComponent className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
||||||
<div className="text-4xl font-bold text-gray-900 mb-2">
|
<div className="text-4xl font-bold text-gray-900 mb-2">
|
||||||
{clientsCount.displayValue}
|
{displayValue}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-gray-600">{translate('::Public.about.stats.clients')}</div>
|
<div className="text-gray-600">{translate(stat.labelKey)}</div>
|
||||||
</div>
|
|
||||||
<div className="text-center" ref={experienceCount.elementRef}>
|
|
||||||
<FaAward className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
|
||||||
<div className="text-4xl font-bold text-gray-900 mb-2">
|
|
||||||
{experienceCount.displayValue}
|
|
||||||
</div>
|
|
||||||
<div className="text-gray-600">{translate('::Public.about.stats.experience')}</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<FaClock className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
|
||||||
<div className="text-4xl font-bold text-gray-900 mb-2">7/24</div>
|
|
||||||
<div className="text-gray-600">{translate('::Public.about.stats.support')}</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-center" ref={countriesCount.elementRef}>
|
|
||||||
<FaGlobe className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
|
||||||
<div className="text-4xl font-bold text-gray-900 mb-2">
|
|
||||||
{countriesCount.displayValue}
|
|
||||||
</div>
|
|
||||||
<div className="text-gray-600">{translate('::Public.about.stats.countries')}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -83,35 +173,31 @@ const About: React.FC = () => {
|
||||||
<div className="py-6">
|
<div className="py-6">
|
||||||
<div className="container mx-auto px-4">
|
<div className="container mx-auto px-4">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="space-y-6 mx-auto mx-auto text-gray-800 text-lg leading-relaxed">
|
<div className="p-5 mx-auto mx-auto text-gray-800 text-lg leading-relaxed shadow-md bg-white border-l-4 border-blue-600">
|
||||||
<p className="bg-white p-5 shadow-md border-l-4 border-blue-600">
|
<p>
|
||||||
{translate('::Public.about.description.part1')}
|
{translate(aboutPageData.descriptions[0])}
|
||||||
</p>
|
</p>
|
||||||
<p className="italic text-center text-blue-700 font-semibold">
|
<p className="text-center p-5 text-blue-800">
|
||||||
{translate('::Public.about.description.motto')}
|
{translate(aboutPageData.descriptions[1])}
|
||||||
</p>
|
</p>
|
||||||
<p className="bg-white p-5 shadow-md border-l-4 border-blue-600">
|
<p>
|
||||||
{translate('::Public.about.description.part2')}
|
{translate(aboutPageData.descriptions[2])}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-center text-blue-700 font-medium">
|
<p className="text-center p-5 text-blue-800">
|
||||||
{translate('::Public.about.description.closing')}
|
{translate(aboutPageData.descriptions[3])}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||||
<div className="bg-white p-8 rounded-xl shadow-lg">
|
{aboutPageData.sections.map((section, index) => (
|
||||||
|
<div key={index} className="bg-white p-8 rounded-xl shadow-lg">
|
||||||
<h3 className="text-2xl font-bold text-gray-900 mb-4">
|
<h3 className="text-2xl font-bold text-gray-900 mb-4">
|
||||||
{translate('::Public.about.mission')}
|
{translate(section.key)}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-gray-700">{translate('::Public.about.mission.desc')}</p>
|
<p className="text-gray-700">{translate(section.descKey)}</p>
|
||||||
</div>
|
|
||||||
<div className="bg-white p-8 rounded-xl shadow-lg">
|
|
||||||
<h3 className="text-2xl font-bold text-gray-900 mb-4">
|
|
||||||
{translate('::Public.about.vision')}
|
|
||||||
</h3>
|
|
||||||
<p className="text-gray-700">{translate('::Public.about.vision.desc')}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue