erp-platform/ui/src/views/public/Services.tsx
2025-08-20 13:06:40 +03:00

308 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react'
import {
FaCode,
FaGlobe,
FaServer,
FaUsers,
FaShieldAlt,
FaCog,
FaCheckCircle,
} from 'react-icons/fa'
import { Link } from 'react-router-dom'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { Helmet } from 'react-helmet'
import { ServiceDto } from '@/proxy/services/models'
import { getServices } from '@/services/service.service'
import navigationIcon from '@/configs/navigation-icon.config'
const Services: React.FC = () => {
const { translate } = useLocalization()
const [services, setServices] = useState<ServiceDto[]>([])
// const services: ServiceDto[] = [
// {
// icon: <FaCode className="w-12 h-12 text-blue-600" />,
// title: translate('::Public.services.software.title'),
// description: translate('::Public.services.software.desc'),
// type: 'service',
// features: [
// translate('::Public.services.software.features.analysis'),
// translate('::Public.services.software.features.design'),
// translate('::Public.services.software.features.development'),
// translate('::Public.services.software.features.testing'),
// translate('::Public.services.software.features.maintenance'),
// ],
// },
// {
// icon: <FaUsers className="w-12 h-12 text-purple-600" />,
// title: translate('::Public.services.web.title'),
// description: translate('::Public.services.web.desc'),
// type: 'service',
// features: [
// translate('::Public.services.web.features.frontend'),
// translate('::Public.services.web.features.backend'),
// translate('::Public.services.web.features.api'),
// translate('::Public.services.web.features.seo'),
// translate('::Public.services.web.features.performance'),
// ],
// },
// {
// icon: <FaShieldAlt className="w-12 h-12 text-green-600" />,
// title: translate('::Public.services.mobile.title'),
// description: translate('::Public.services.mobile.desc'),
// type: 'service',
// features: [
// translate('::Public.services.mobile.features.design'),
// translate('::Public.services.mobile.features.native'),
// translate('::Public.services.mobile.features.cross'),
// translate('::Public.services.mobile.features.push'),
// translate('::Public.services.mobile.features.store'),
// ],
// },
// {
// icon: <FaServer className="w-12 h-12 text-red-600" />,
// title: translate('::Public.services.database.title'),
// description: translate('::Public.services.database.desc'),
// type: 'service',
// features: [
// translate('::Public.services.database.features.design'),
// translate('::Public.services.database.features.optimization'),
// translate('::Public.services.database.features.migration'),
// translate('::Public.services.database.features.backup'),
// translate('::Public.services.database.features.recovery'),
// ],
// },
// {
// icon: <FaGlobe className="w-12 h-12 text-yellow-600" />,
// title: translate('::Public.services.integration.title'),
// description: translate('::Public.services.integration.desc'),
// type: 'service',
// features: [
// translate('::Public.services.integration.features.api'),
// translate('::Public.services.integration.features.middleware'),
// translate('::Public.services.integration.features.legacy'),
// translate('::Public.services.integration.features.realtime'),
// translate('::Public.services.integration.features.monitoring'),
// ],
// },
// {
// icon: <FaCog className="w-12 h-12 text-indigo-600" />,
// title: translate('::Public.services.consulting.title'),
// description: translate('::Public.services.consulting.desc'),
// type: 'service',
// features: [
// translate('::Public.services.consulting.features.tech'),
// translate('::Public.services.consulting.features.project'),
// translate('::Public.services.consulting.features.digital'),
// translate('::Public.services.consulting.features.risk'),
// translate('::Public.services.consulting.features.training'),
// ],
// },
// {
// icon: <FaUsers className="w-12 h-12 text-pink-600" />, // Remote Branch Support
// title: translate('::Public.services.support.branchRemote.title'),
// description: '',
// type: 'support',
// features: [
// translate('::Public.services.support.branchRemote.features.priority'),
// translate('::Public.services.support.branchRemote.features.remote'),
// translate('::Public.services.support.branchRemote.features.optimization'),
// translate('::Public.services.support.branchRemote.features.maintenance'),
// translate('::Public.services.support.branchRemote.features.consulting'),
// ],
// },
// {
// icon: <FaServer className="w-12 h-12 text-orange-600" />, // Backup Support
// title: translate('::Public.services.support.backup.title'),
// description: '',
// type: 'support',
// features: [
// translate('::Public.services.support.backup.features.daily'),
// translate('::Public.services.support.backup.features.encrypted'),
// translate('::Public.services.support.backup.features.recovery'),
// translate('::Public.services.support.backup.features.verification'),
// translate('::Public.services.support.backup.features.access'),
// ],
// },
// {
// icon: <FaGlobe className="w-12 h-12 text-cyan-600" />, // SMS Support
// title: translate('::Public.services.support.sms.title'),
// description: '',
// type: 'support',
// features: [
// translate('::Public.services.support.sms.features.packages'),
// translate('::Public.services.support.sms.features.bulk'),
// translate('::Public.services.support.sms.features.template'),
// translate('::Public.services.support.sms.features.reporting'),
// translate('::Public.services.support.sms.features.api'),
// ],
// },
// ]
// Botları çek
const iconColors = [
'text-blue-600',
'text-red-600',
'text-green-600',
'text-purple-600',
'text-yellow-600',
'text-indigo-600',
]
function getRandomColor() {
return iconColors[Math.floor(Math.random() * iconColors.length)]
}
useEffect(() => {
const fetchServices = async () => {
try {
const result = await getServices()
const items = result?.data?.map((service: ServiceDto) => ({
icon: service.icon,
title: service.title,
description: service.description,
type: service.type,
features: service.features,
}))
setServices(items)
} catch (error) {
console.error('Service listesi alınırken hata oluştu:', error)
}
}
fetchServices()
}, [])
return (
<div className="min-h-screen bg-gray-50">
<Helmet
titleTemplate="%s | Sözsoft"
title={translate('::' + 'Public.nav.services')}
defaultTitle="Sözsoft"
></Helmet>
{/* Hero Section */}
<div className="relative bg-blue-900 text-white py-12">
<div
className="absolute inset-0 opacity-20"
style={{
backgroundImage:
'url("https://images.pexels.com/photos/3183173/pexels-photo-3183173.jpeg?auto=compress&cs=tinysrgb&w=1920")',
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
></div>
<div className="container mx-auto pt-20 relative">
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">
{translate('::Public.services.title')}
</h1>
<p className="text-xl max-w-3xl ml-4">{translate('::Public.services.subtitle')}</p>
</div>
</div>
{/* Services Grid */}
<div className="py-16">
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{services
.filter((a) => a.type === 'service')
.map((service, index) => {
const IconComponent = navigationIcon[service.icon || '']
return (
<div
key={index}
className="bg-white rounded-xl shadow-lg p-8 hover:shadow-xl transition-shadow"
>
<div className="mb-6">
{IconComponent && (
<IconComponent className={`w-12 h-12 ${getRandomColor()}`} />
)}
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-4">
{translate('::' + service.title)}
</h3>
<p className="text-gray-600 mb-6">{translate('::' + service.description)}</p>
<ul className="space-y-2">
{service.features.map((feature, fIndex) => (
<li key={fIndex} className="flex items-center text-gray-700">
<span className="w-2 h-2 bg-blue-600 rounded-full mr-2"></span>
{translate('::' + feature)}
</li>
))}
</ul>
</div>
)
})}
</div>
</div>
</div>
{/* Support Plans */}
<div className="bg-white py-10">
<div className="container mx-auto px-4">
<h2 className="text-3xl font-bold text-center mb-10">
{translate('::Public.services.support.title')}
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{services
.filter((a) => a.type === 'support')
.map((plan, index) => {
const IconComponent = navigationIcon[plan.icon || '']
return (
<div
key={index}
className="bg-white rounded-xl shadow-lg p-8 border border-gray-200"
>
<div className="mb-6">
{IconComponent && (
<IconComponent className={`w-12 h-12 ${getRandomColor()}`} />
)}
</div>
<h3 className="text-xl font-bold mb-4">{translate('::' + plan.title)}</h3>
<ul className="space-y-3 mb-8">
{plan.features.map((feature, fIndex) => (
<li key={fIndex} className="flex items-center space-x-2 text-gray-700">
<FaCheckCircle className="w-5 h-5 text-green-500 flex-shrink-0" />
<span>{translate('::' + feature)}</span>
</li>
))}
</ul>
<Link
to={ROUTES_ENUM.public.contact}
className="block text-center bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors"
>
{translate('::Public.services.support.contactButton')}
</Link>
</div>
)
})}
</div>
</div>
</div>
{/* Call to Action */}
<div className="bg-blue-900 text-white py-16">
<div className="container mx-auto px-4 text-center">
<h2 className="text-3xl font-bold mb-6 text-white">
{translate('::Public.services.cta.title')}
</h2>
<p className="text-xl mb-8 max-w-2xl mx-auto">
{translate('::Public.services.cta.description')}
</p>
<Link
to={ROUTES_ENUM.public.contact}
className="bg-white text-blue-900 px-8 py-3 rounded-lg font-semibold hover:bg-blue-50 transition-colors"
>
{translate('::Public.services.cta.contact')}
</Link>
</div>
</div>
</div>
)
}
export default Services