import React, { Component } from 'react';
import { withTranslation as reactI18nextWithTranslation } from 'react-i18next';
// HOC to provide translation functions to class components
export const withTranslation = (namespaces = 'translation') => (WrappedComponent) => {
return reactI18nextWithTranslation(namespaces)(WrappedComponent);
};
// Context for language switching
export const LanguageContext = React.createContext({
currentLanguage: 'de',
changeLanguage: () => {},
availableLanguages: ['ar', 'bg', 'cs', 'de', 'el', 'en', 'es', 'fr', 'hr', 'hu', 'it', 'pl', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv', 'tr', 'uk', 'zh']
});
// Provider component for language management
export class LanguageProvider extends Component {
constructor(props) {
super(props);
// Get initial language from i18n instance
const currentLanguage = props.i18n?.language || 'de';
this.state = {
currentLanguage,
availableLanguages: ['ar', 'bg', 'cs', 'de', 'el', 'en', 'es', 'fr', 'hr', 'hu', 'it', 'pl', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv', 'tr', 'uk', 'zh']
};
}
componentDidMount() {
if (this.props.i18n) {
this.props.i18n.on('languageChanged', this.handleLanguageChanged);
// Set initial language state and HTML attribute
this.setState({ currentLanguage: this.props.i18n.language });
document.documentElement.lang = this.props.i18n.language;
}
}
componentWillUnmount() {
if (this.props.i18n) {
this.props.i18n.off('languageChanged', this.handleLanguageChanged);
}
}
handleLanguageChanged = (lng) => {
this.setState({ currentLanguage: lng });
// Update HTML lang attribute for SEO
document.documentElement.lang = lng;
// Ensure language is saved to localStorage
try {
localStorage.setItem('i18nextLng', lng);
} catch (error) {
console.warn('Could not save language to localStorage:', error);
}
// Update config if available
if (window.shopConfig) {
// Language code mapping for all supported languages
const languageMap = {
'ar': 'ar-EG',
'bg': 'bg-BG',
'cs': 'cs-CZ',
'de': 'de-DE',
'el': 'el-GR',
'en': 'en-US',
'es': 'es-ES',
'fr': 'fr-FR',
'hr': 'hr-HR',
'hu': 'hu-HU',
'it': 'it-IT',
'pl': 'pl-PL',
'ro': 'ro-RO',
'ru': 'ru-RU',
'sk': 'sk-SK',
'sl': 'sl-SI',
'sr': 'sr-RS',
'sv': 'sv-SE',
'tr': 'tr-TR',
'uk': 'uk-UA',
'zh': 'zh-CN'
};
window.shopConfig.language = languageMap[lng] || 'de-DE';
}
};
changeLanguage = (language) => {
if (this.props.i18n && this.state.availableLanguages.includes(language)) {
this.props.i18n.changeLanguage(language);
}
};
render() {
const contextValue = {
currentLanguage: this.state.currentLanguage,
changeLanguage: this.changeLanguage,
availableLanguages: this.state.availableLanguages
};
return (
{this.props.children}
);
}
}
// HOC to inject language context into class components
export const withLanguage = (WrappedComponent) => {
return class extends Component {
render() {
return (
{(languageContext) => (
)}
);
}
};
};
// Combined HOC that provides both translation and language context
export const withI18n = (namespaces = 'translation') => (WrappedComponent) => {
const WithTranslationComponent = withTranslation(namespaces)(WrappedComponent);
return withLanguage(WithTranslationComponent);
};