import React, { useEffect, useState } from 'react' import { Link } from 'react-router-dom' import { FaArrowRight, 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' import { useStoreActions, useStoreState } from '@/store' import Loading from '@/components/shared/Loading' import navigationIcon from '@/proxy/menus/navigation-icon.config' import DesignerDrawer from './designer/DesignerDrawer' import SelectableBlock from './designer/SelectableBlock' import { DesignerSelection } from './designer/types' import { useDesignerState } from './designer/useDesignerState' import { getHome, HomeDto, saveHomePage } from '@/services/home.service' interface HomeSlideServiceContent { icon: string title: string titleKey: string description: string descriptionKey: string } interface HomeSlideContent { title: string titleKey: string subtitle: string subtitleKey: string services: HomeSlideServiceContent[] } interface HomeFeatureContent { icon: string title: string titleKey: string description: string descriptionKey: string } interface HomeSolutionContent { icon: string colorClass: string title: string titleKey: string description: string descriptionKey: string } interface HomeContent { heroBackgroundImage: string heroBackgroundImageKey: string heroPrimaryCtaLabel: string heroPrimaryCtaKey: string heroSecondaryCtaLabel: string heroSecondaryCtaKey: string featuresTitle: string featuresTitleKey: string featuresSubtitle: string featuresSubtitleKey: string solutionsTitle: string solutionsTitleKey: string solutionsSubtitle: string solutionsSubtitleKey: string ctaTitle: string ctaTitleKey: string ctaSubtitle: string ctaSubtitleKey: string ctaButtonLabel: string ctaButtonLabelKey: string slides: HomeSlideContent[] features: HomeFeatureContent[] solutions: HomeSolutionContent[] } const HOME_HERO_BACKGROUND_KEY = 'Public.home.hero.backgroundImage' const HOME_HERO_DEFAULT_IMAGE = 'https://images.pexels.com/photos/3183150/pexels-photo-3183150.jpeg?auto=compress&cs=tinysrgb&w=1920' const HOME_HERO_PRIMARY_CTA_KEY = 'Public.hero.cta.consultation' const HOME_HERO_SECONDARY_CTA_KEY = 'Public.hero.cta.discover' const HOME_FEATURES_TITLE_KEY = 'Public.features.title' const HOME_FEATURES_SUBTITLE_KEY = 'Public.features.subtitle' const HOME_SOLUTIONS_TITLE_KEY = 'Public.solutions.title' const HOME_SOLUTIONS_SUBTITLE_KEY = 'Public.solutions.subtitle' const HOME_CTA_TITLE_KEY = 'Public.common.getStarted' const HOME_CTA_SUBTITLE_KEY = 'Public.common.contact' const HOME_CTA_BUTTON_KEY = 'Public.common.learnMore' function isLikelyLocalizationKey(value?: string) { return Boolean(value && /^[A-Za-z0-9_.-]+$/.test(value) && value.includes('.')) } function resolveLocalizedValue( translate: (key: string) => string, keyOrValue: string | undefined, fallback = '', ) { if (!keyOrValue) { return fallback } if (!isLikelyLocalizationKey(keyOrValue)) { return keyOrValue } const translatedValue = translate('::' + keyOrValue) return translatedValue === keyOrValue ? fallback || keyOrValue : translatedValue } function defaultSlides() { return [ { titleKey: 'Public.hero.slide1.title', subtitleKey: 'Public.hero.slide1.subtitle', services: [ { icon: 'FaCalendarAlt', titleKey: 'Public.hero.slide1.service1.title', descriptionKey: 'Public.hero.slide1.service1.desc', }, { icon: 'FaUsers', titleKey: 'Public.hero.slide1.service2.title', descriptionKey: 'Public.hero.slide1.service2.desc', }, { icon: 'FaShieldAlt', titleKey: 'Public.hero.slide1.service3.title', descriptionKey: 'Public.hero.slide1.service3.desc', }, ], }, { titleKey: 'Public.hero.slide2.title', subtitleKey: 'Public.hero.slide2.subtitle', services: [ { icon: 'FaChartBar', titleKey: 'Public.hero.slide2.service1.title', descriptionKey: 'Public.hero.slide2.service1.desc', }, { icon: 'FaCreditCard', titleKey: 'Public.hero.slide2.service2.title', descriptionKey: 'Public.hero.slide2.service2.desc', }, { icon: 'FaDatabase', titleKey: 'Public.hero.slide2.service3.title', descriptionKey: 'Public.hero.slide2.service3.desc', }, ], }, { titleKey: 'Public.hero.slide3.title', subtitleKey: 'Public.hero.slide3.subtitle', services: [ { icon: 'FaDesktop', titleKey: 'Public.hero.slide3.service1.title', descriptionKey: 'Public.hero.slide3.service1.desc', }, { icon: 'FaServer', titleKey: 'Public.hero.slide3.service2.title', descriptionKey: 'Public.hero.slide3.service2.desc', }, { icon: 'FaMobileAlt', titleKey: 'Public.hero.slide3.service3.title', descriptionKey: 'Public.hero.slide3.service3.desc', }, ], }, ] } function defaultFeatures() { return [ { icon: 'FaUsers', titleKey: 'Public.features.reliable', descriptionKey: 'Public.features.reliable.desc' }, { icon: 'FaCalendarAlt', titleKey: 'App.Coordinator.Classroom.Planning', descriptionKey: 'Public.features.rapid.desc', }, { icon: 'FaBookOpen', titleKey: 'Public.features.expert', descriptionKey: 'Public.features.expert.desc' }, { icon: 'FaCreditCard', titleKey: 'Public.features.muhasebe', descriptionKey: 'Public.features.muhasebe.desc', }, { icon: 'FaRegComment', titleKey: 'Public.features.iletisim', descriptionKey: 'Public.features.iletisim.desc', }, { icon: 'FaPhone', titleKey: 'Public.features.mobil', descriptionKey: 'Public.features.mobil.desc' }, { icon: 'FaChartBar', titleKey: 'Public.features.scalable', descriptionKey: 'Public.features.scalable.desc' }, { icon: 'FaShieldAlt', titleKey: 'Public.features.guvenlik', descriptionKey: 'Public.features.guvenlik.desc', }, ] } function defaultSolutions() { return [ { icon: 'FaDesktop', colorClass: 'bg-blue-600', titleKey: 'Public.services.web.title', descriptionKey: 'Public.solutions.web.desc', }, { icon: 'FaMobileAlt', colorClass: 'bg-purple-600', titleKey: 'Public.services.mobile.title', descriptionKey: 'Public.solutions.mobile.desc', }, { icon: 'FaServer', colorClass: 'bg-green-600', titleKey: 'Public.solutions.custom.title', descriptionKey: 'Public.solutions.custom.desc', }, { icon: 'FaDatabase', colorClass: 'bg-red-600', titleKey: 'Public.solutions.database.title', descriptionKey: 'Public.solutions.database.desc', }, ] } function buildHomeContent(home: HomeDto | undefined, translate: (key: string) => string): HomeContent { const slideItems = home?.slidesDto?.length ? home.slidesDto : defaultSlides() const featureItems = home?.featuresDto?.length ? home.featuresDto : defaultFeatures() const solutionItems = home?.solutionsDto?.length ? home.solutionsDto : defaultSolutions() return { heroBackgroundImage: resolveLocalizedValue( translate, home?.heroBackgroundImageKey || HOME_HERO_BACKGROUND_KEY, HOME_HERO_DEFAULT_IMAGE, ), heroBackgroundImageKey: home?.heroBackgroundImageKey || HOME_HERO_BACKGROUND_KEY, heroPrimaryCtaLabel: resolveLocalizedValue( translate, home?.heroPrimaryCtaKey || HOME_HERO_PRIMARY_CTA_KEY, ), heroPrimaryCtaKey: home?.heroPrimaryCtaKey || HOME_HERO_PRIMARY_CTA_KEY, heroSecondaryCtaLabel: resolveLocalizedValue( translate, home?.heroSecondaryCtaKey || HOME_HERO_SECONDARY_CTA_KEY, ), heroSecondaryCtaKey: home?.heroSecondaryCtaKey || HOME_HERO_SECONDARY_CTA_KEY, featuresTitle: resolveLocalizedValue(translate, home?.featuresTitleKey || HOME_FEATURES_TITLE_KEY), featuresTitleKey: home?.featuresTitleKey || HOME_FEATURES_TITLE_KEY, featuresSubtitle: resolveLocalizedValue( translate, home?.featuresSubtitleKey || HOME_FEATURES_SUBTITLE_KEY, ), featuresSubtitleKey: home?.featuresSubtitleKey || HOME_FEATURES_SUBTITLE_KEY, solutionsTitle: resolveLocalizedValue(translate, home?.solutionsTitleKey || HOME_SOLUTIONS_TITLE_KEY), solutionsTitleKey: home?.solutionsTitleKey || HOME_SOLUTIONS_TITLE_KEY, solutionsSubtitle: resolveLocalizedValue( translate, home?.solutionsSubtitleKey || HOME_SOLUTIONS_SUBTITLE_KEY, ), solutionsSubtitleKey: home?.solutionsSubtitleKey || HOME_SOLUTIONS_SUBTITLE_KEY, ctaTitle: resolveLocalizedValue(translate, home?.ctaTitleKey || HOME_CTA_TITLE_KEY), ctaTitleKey: home?.ctaTitleKey || HOME_CTA_TITLE_KEY, ctaSubtitle: resolveLocalizedValue(translate, home?.ctaSubtitleKey || HOME_CTA_SUBTITLE_KEY), ctaSubtitleKey: home?.ctaSubtitleKey || HOME_CTA_SUBTITLE_KEY, ctaButtonLabel: resolveLocalizedValue(translate, home?.ctaButtonLabelKey || HOME_CTA_BUTTON_KEY), ctaButtonLabelKey: home?.ctaButtonLabelKey || HOME_CTA_BUTTON_KEY, slides: slideItems.map((slide, slideIndex) => ({ title: resolveLocalizedValue(translate, slide.titleKey, slide.titleKey), titleKey: slide.titleKey || `Public.home.dynamic.slide.${slideIndex + 1}.title`, subtitle: resolveLocalizedValue(translate, slide.subtitleKey, slide.subtitleKey), subtitleKey: slide.subtitleKey || `Public.home.dynamic.slide.${slideIndex + 1}.subtitle`, services: (slide.services || []).map((service, serviceIndex) => ({ icon: service.icon || 'FaCircle', title: resolveLocalizedValue(translate, service.titleKey, service.titleKey), titleKey: service.titleKey || `Public.home.dynamic.slide.${slideIndex + 1}.service.${serviceIndex + 1}.title`, description: resolveLocalizedValue(translate, service.descriptionKey, service.descriptionKey), descriptionKey: service.descriptionKey || `Public.home.dynamic.slide.${slideIndex + 1}.service.${serviceIndex + 1}.description`, })), })), features: featureItems.map((feature, index) => ({ icon: feature.icon || 'FaCircle', title: resolveLocalizedValue(translate, feature.titleKey, feature.titleKey), titleKey: feature.titleKey || `Public.home.dynamic.feature.${index + 1}.title`, description: resolveLocalizedValue(translate, feature.descriptionKey, feature.descriptionKey), descriptionKey: feature.descriptionKey || `Public.home.dynamic.feature.${index + 1}.description`, })), solutions: solutionItems.map((solution, index) => ({ icon: solution.icon || 'FaCircle', colorClass: solution.colorClass || 'bg-blue-600', title: resolveLocalizedValue(translate, solution.titleKey, solution.titleKey), titleKey: solution.titleKey || `Public.home.dynamic.solution.${index + 1}.title`, description: resolveLocalizedValue(translate, solution.descriptionKey, solution.descriptionKey), descriptionKey: solution.descriptionKey || `Public.home.dynamic.solution.${index + 1}.description`, })), } } const Home: React.FC = () => { const { translate } = useLocalization() const { setLang } = useStoreActions((actions) => actions.locale) const { getConfig } = useStoreActions((actions) => actions.abpConfig) const configCultureName = useStoreState( (state) => state.abpConfig.config?.localization.currentCulture.cultureName, ) const localeCurrentLang = useStoreState((state) => state.locale?.currentLang) const currentLanguage = configCultureName || localeCurrentLang || 'tr' const abpLanguages = useStoreState((state) => state.abpConfig.config?.localization.languages) || [] const languageOptions = abpLanguages .filter((language) => Boolean(language.cultureName)) .map((language) => { const cultureName = language.cultureName || 'tr' return { key: cultureName.toLowerCase().split('-')[0], cultureName, displayName: language.displayName || cultureName, } }) const languagesFromConfig = languageOptions.map((language) => language.key) const editorLanguages = Array.from( new Set((languagesFromConfig.length > 0 ? languagesFromConfig : [currentLanguage]).filter(Boolean)), ) const [home, setHome] = useState() const [loading, setLoading] = useState(true) const [isSaving, setIsSaving] = useState(false) const [isPanelVisible, setIsPanelVisible] = useState(true) const [currentSlide, setCurrentSlide] = useState(0) const initialContent = !loading ? buildHomeContent(home, translate) : null const { content, isDesignMode, selectedBlockId, selectedLanguage, supportedLanguages, setContent, setSelectedBlockId, resetContent, } = useDesignerState('home', initialContent, { currentLanguage, supportedLanguages: editorLanguages, }) useEffect(() => { setLoading(true) const fetchHome = async () => { try { const result = await getHome() setHome(result.data) } catch (error) { console.error('Home alinirken hata olustu:', error) } finally { setLoading(false) } } fetchHome() }, []) useEffect(() => { if (!content?.slides?.length) { return } if (currentSlide >= content.slides.length) { setCurrentSlide(0) } }, [content?.slides.length, currentSlide]) useEffect(() => { if (!content?.slides?.length) { return } const timer = setInterval(() => { setCurrentSlide((prev) => (prev + 1) % content.slides.length) }, 10000) return () => clearInterval(timer) }, [content?.slides.length]) const nextSlide = () => { const size = content?.slides.length || 1 setCurrentSlide((prev) => (prev + 1) % size) } const prevSlide = () => { const size = content?.slides.length || 1 setCurrentSlide((prev) => (prev - 1 + size) % size) } const updateContent = (updater: (current: HomeContent) => HomeContent) => { setContent((current) => { if (!current) { return current } return updater(current) }) } const handleFieldChange = (fieldKey: string, value: string | string[]) => { const nextValue = value as string updateContent((current) => { if ( fieldKey === 'heroBackgroundImage' || fieldKey === 'heroPrimaryCtaLabel' || fieldKey === 'heroSecondaryCtaLabel' || fieldKey === 'featuresTitle' || fieldKey === 'featuresSubtitle' || fieldKey === 'solutionsTitle' || fieldKey === 'solutionsSubtitle' || fieldKey === 'ctaTitle' || fieldKey === 'ctaSubtitle' || fieldKey === 'ctaButtonLabel' ) { return { ...current, [fieldKey]: nextValue, } } if (selectedBlockId?.startsWith('slide-')) { const index = Number(selectedBlockId.replace('slide-', '')) if (Number.isNaN(index)) { return current } const slides = [...current.slides] const target = { ...slides[index] } if (fieldKey === 'title' || fieldKey === 'subtitle') { target[fieldKey] = nextValue } else if (fieldKey.startsWith('service-')) { const parts = fieldKey.split('-') const serviceIndex = Number(parts[1]) const serviceField = parts[2] as 'icon' | 'title' | 'description' const services = [...target.services] const service = { ...services[serviceIndex] } service[serviceField] = nextValue services[serviceIndex] = service target.services = services } slides[index] = target return { ...current, slides, } } if (selectedBlockId?.startsWith('feature-')) { const index = Number(selectedBlockId.replace('feature-', '')) if (Number.isNaN(index)) { return current } const features = [...current.features] const feature = { ...features[index] } const key = fieldKey as 'icon' | 'title' | 'description' feature[key] = nextValue features[index] = feature return { ...current, features, } } if (selectedBlockId?.startsWith('solution-')) { const index = Number(selectedBlockId.replace('solution-', '')) if (Number.isNaN(index)) { return current } const solutions = [...current.solutions] const solution = { ...solutions[index] } const key = fieldKey as 'icon' | 'title' | 'description' | 'colorClass' solution[key] = nextValue solutions[index] = solution return { ...current, solutions, } } return current }) } const selectedSelection: DesignerSelection | null = React.useMemo(() => { if (!content || !selectedBlockId) { return null } if (selectedBlockId === 'hero') { return { id: 'hero', title: 'Public.home.hero.*', description: 'Hero arka planini ve CTA metinlerini duzenleyin.', fields: [ { key: 'heroBackgroundImage', label: content.heroBackgroundImageKey, type: 'image', value: content.heroBackgroundImage, }, { key: 'heroPrimaryCtaLabel', label: content.heroPrimaryCtaKey, type: 'text', value: content.heroPrimaryCtaLabel, }, { key: 'heroSecondaryCtaLabel', label: content.heroSecondaryCtaKey, type: 'text', value: content.heroSecondaryCtaLabel, }, ], } } if (selectedBlockId.startsWith('slide-')) { const index = Number(selectedBlockId.replace('slide-', '')) const slide = content.slides[index] if (!slide) { return null } return { id: selectedBlockId, title: slide.titleKey, description: 'Slayt baslik, alt baslik ve servis kartlarini duzenleyin.', fields: [ { key: 'title', label: slide.titleKey, type: 'text', value: slide.title, }, { key: 'subtitle', label: slide.subtitleKey, type: 'textarea', value: slide.subtitle, }, ...slide.services.flatMap((service, serviceIndex) => [ { key: `service-${serviceIndex}-icon`, label: `Slide${index + 1}.Service${serviceIndex + 1}.Icon`, type: 'icon' as const, value: service.icon, placeholder: 'Ornek: FaUsers', }, { key: `service-${serviceIndex}-title`, label: service.titleKey, type: 'text' as const, value: service.title, }, { key: `service-${serviceIndex}-description`, label: service.descriptionKey, type: 'textarea' as const, value: service.description, }, ]), ], } } if (selectedBlockId === 'features-heading') { return { id: selectedBlockId, title: content.featuresTitleKey, description: 'Features bolum basliklarini duzenleyin.', fields: [ { key: 'featuresTitle', label: content.featuresTitleKey, type: 'text', value: content.featuresTitle, }, { key: 'featuresSubtitle', label: content.featuresSubtitleKey, type: 'textarea', value: content.featuresSubtitle, }, ], } } if (selectedBlockId.startsWith('feature-')) { const index = Number(selectedBlockId.replace('feature-', '')) const item = content.features[index] if (!item) { return null } return { id: selectedBlockId, title: item.titleKey, description: 'Feature ikon ve metinlerini duzenleyin.', fields: [ { key: 'icon', label: `Feature${index + 1}.Icon`, type: 'icon', value: item.icon, placeholder: 'Ornek: FaChartBar', }, { key: 'title', label: item.titleKey, type: 'text', value: item.title, }, { key: 'description', label: item.descriptionKey, type: 'textarea', value: item.description, }, ], } } if (selectedBlockId === 'solutions-heading') { return { id: selectedBlockId, title: content.solutionsTitleKey, description: 'Solutions bolum basliklarini duzenleyin.', fields: [ { key: 'solutionsTitle', label: content.solutionsTitleKey, type: 'text', value: content.solutionsTitle, }, { key: 'solutionsSubtitle', label: content.solutionsSubtitleKey, type: 'textarea', value: content.solutionsSubtitle, }, ], } } if (selectedBlockId.startsWith('solution-')) { const index = Number(selectedBlockId.replace('solution-', '')) const item = content.solutions[index] if (!item) { return null } return { id: selectedBlockId, title: item.titleKey, description: 'Solution kartini tamamen duzenleyin.', fields: [ { key: 'colorClass', label: `Solution${index + 1}.ColorClass`, type: 'text', value: item.colorClass, }, { key: 'icon', label: `Solution${index + 1}.Icon`, type: 'icon', value: item.icon, placeholder: 'Ornek: FaDesktop', }, { key: 'title', label: item.titleKey, type: 'text', value: item.title, }, { key: 'description', label: item.descriptionKey, type: 'textarea', value: item.description, }, ], } } if (selectedBlockId === 'cta') { return { id: selectedBlockId, title: content.ctaTitleKey, description: 'Sayfa alti cta metinlerini duzenleyin.', fields: [ { key: 'ctaTitle', label: content.ctaTitleKey, type: 'text', value: content.ctaTitle, }, { key: 'ctaSubtitle', label: content.ctaSubtitleKey, type: 'textarea', value: content.ctaSubtitle, }, { key: 'ctaButtonLabel', label: content.ctaButtonLabelKey, type: 'text', value: content.ctaButtonLabel, }, ], } } return null }, [content, selectedBlockId]) const handleSaveAndExit = async () => { if (!content || isSaving) { return } setIsSaving(true) try { await saveHomePage({ cultureName: selectedLanguage, heroBackgroundImageKey: content.heroBackgroundImageKey, heroBackgroundImageValue: content.heroBackgroundImage, heroPrimaryCtaKey: content.heroPrimaryCtaKey, heroPrimaryCtaValue: content.heroPrimaryCtaLabel, heroSecondaryCtaKey: content.heroSecondaryCtaKey, heroSecondaryCtaValue: content.heroSecondaryCtaLabel, featuresTitleKey: content.featuresTitleKey, featuresTitleValue: content.featuresTitle, featuresSubtitleKey: content.featuresSubtitleKey, featuresSubtitleValue: content.featuresSubtitle, solutionsTitleKey: content.solutionsTitleKey, solutionsTitleValue: content.solutionsTitle, solutionsSubtitleKey: content.solutionsSubtitleKey, solutionsSubtitleValue: content.solutionsSubtitle, ctaTitleKey: content.ctaTitleKey, ctaTitleValue: content.ctaTitle, ctaSubtitleKey: content.ctaSubtitleKey, ctaSubtitleValue: content.ctaSubtitle, ctaButtonLabelKey: content.ctaButtonLabelKey, ctaButtonLabelValue: content.ctaButtonLabel, slides: content.slides.map((slide, slideIndex) => ({ titleKey: slide.titleKey || `Public.home.dynamic.slide.${slideIndex + 1}.title`, titleValue: slide.title, subtitleKey: slide.subtitleKey || `Public.home.dynamic.slide.${slideIndex + 1}.subtitle`, subtitleValue: slide.subtitle, services: slide.services.map((service, serviceIndex) => ({ icon: service.icon, titleKey: service.titleKey || `Public.home.dynamic.slide.${slideIndex + 1}.service.${serviceIndex + 1}.title`, titleValue: service.title, descriptionKey: service.descriptionKey || `Public.home.dynamic.slide.${slideIndex + 1}.service.${serviceIndex + 1}.description`, descriptionValue: service.description, })), })), features: content.features.map((feature, index) => ({ icon: feature.icon, titleKey: feature.titleKey || `Public.home.dynamic.feature.${index + 1}.title`, titleValue: feature.title, descriptionKey: feature.descriptionKey || `Public.home.dynamic.feature.${index + 1}.description`, descriptionValue: feature.description, })), solutions: content.solutions.map((solution, index) => ({ icon: solution.icon, colorClass: solution.colorClass, titleKey: solution.titleKey || `Public.home.dynamic.solution.${index + 1}.title`, titleValue: solution.title, descriptionKey: solution.descriptionKey || `Public.home.dynamic.solution.${index + 1}.description`, descriptionValue: solution.description, })), }) await getConfig(false) setSelectedBlockId(null) } catch (error) { console.error('Home tasarimi kaydedilemedi:', error) } finally { setIsSaving(false) } } const handleLanguageChange = (language: string) => { setLang(language) } const handleSelectBlock = (blockId: string) => { setSelectedBlockId(blockId) if (!isPanelVisible) { setIsPanelVisible(true) } } if (loading) { return (
) } return (
{isDesignMode && (
Home designer aktif
)} {isDesignMode && !isPanelVisible && ( )} {/* Hero Carousel */}
{/* Carousel Content */}
{(content?.slides || []).map((slide, index) => (
{ setCurrentSlide(index) handleSelectBlock(id) }} className="h-full" >

{slide.title}

{slide.subtitle}

{content?.heroPrimaryCtaLabel}{' '} {content?.heroSecondaryCtaLabel}
{slide.services.map((service, i) => (
{(() => { const IconComponent = navigationIcon[service.icon || ''] return IconComponent ? ( ) : null })()}

{service.title}

{service.description}

))}
))}
{/* Navigation Buttons */} {/* Slide Indicators */}
{(content?.slides || []).map((_, index) => (
{isDesignMode && (
{(content?.slides || []).map((_, index) => ( ))}
)}
{/* Features */}

{content?.featuresTitle}

{content?.featuresSubtitle}

{(content?.features || []).map((feature, i) => (
{(() => { const IconComponent = navigationIcon[feature.icon || ''] return IconComponent ? : null })()}

{feature.title}

{feature.description}

))}
{/* Solutions */}

{content?.solutionsTitle}

{content?.solutionsSubtitle}

{(content?.solutions || []).map((s, i) => (
{(() => { const IconComponent = navigationIcon[s.icon || ''] return IconComponent ? : null })()}

{s.title}

{s.description}

))}
{/* Call to Action */}

{content?.ctaTitle}

{content?.ctaSubtitle}

{content?.ctaButtonLabel}
0 ? languageOptions : supportedLanguages.map((language) => ({ key: language, cultureName: language, displayName: language.toUpperCase(), })) } onClose={() => setIsPanelVisible(false)} onSave={handleSaveAndExit} onLanguageChange={handleLanguageChange} onReset={resetContent} onFieldChange={handleFieldChange} />
) } export default Home