diff --git a/src/components/MainPageLayout.js b/src/components/MainPageLayout.js index 34d8851..8cbb53d 100644 --- a/src/components/MainPageLayout.js +++ b/src/components/MainPageLayout.js @@ -23,6 +23,39 @@ const MainPageLayout = () => { const isAktionen = currentPath === "/aktionen"; const isFiliale = currentPath === "/filiale"; + // Add CSS animations for rotating stars + React.useEffect(() => { + const style = document.createElement('style'); + style.textContent = ` + @keyframes rotateClockwise { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + @keyframes rotateCounterClockwise { + from { transform: rotate(0deg); } + to { transform: rotate(-360deg); } + } + + .star-rotate-slow-cw { + animation: rotateClockwise 60s linear infinite; + } + + .star-rotate-slow-ccw { + animation: rotateCounterClockwise 45s linear infinite; + } + + .star-rotate-medium-cw { + animation: rotateClockwise 30s linear infinite; + } + `; + document.head.appendChild(style); + + return () => { + document.head.removeChild(style); + }; + }, []); + // Get navigation config based on current page const getNavigationConfig = () => { if (isHome) { @@ -359,6 +392,7 @@ const MainPageLayout = () => { viewBox="0 0 60 60" width="168" height="168" + className="star-rotate-slow-cw" style={{ position: 'absolute', top: '-9px', @@ -378,6 +412,7 @@ const MainPageLayout = () => { viewBox="0 0 60 60" width="159" height="159" + className="star-rotate-slow-ccw" style={{ position: 'absolute', top: '-4.5px', @@ -397,6 +432,7 @@ const MainPageLayout = () => { viewBox="0 0 60 60" width="150" height="150" + className="star-rotate-medium-cw" > { )} + {/* Multi-pointed star for stecklinge box - bottom right */} + {index === 1 && pageType === "home" && ( +
+ {/* Background star - slightly larger and rotated */} + + + + + {/* Middle star - medium size with different rotation */} + + + + + {/* Foreground star - main star with text */} + + + + + {/* Text positioned in the center of the star */} +
+ {t('sections.indoorSeason')} +
+
+ )} +
{ }; // Initialize categories -const initializeCategories = () => { +const initializeCategories = (language = 'en') => { const productCache = getProductCache(); + if (productCache && productCache[`categoryTree_209_${language}`]) { + const cached = productCache[`categoryTree_209_${language}`]; + if (cached.categoryTree) { + return processCategoryTree(cached.categoryTree); + } + } + + // Fallback to old cache format if language-specific cache doesn't exist if (productCache && productCache["categoryTree_209"]) { const cached = productCache["categoryTree_209"]; if (cached.categoryTree) { return processCategoryTree(cached.categoryTree); } } + return []; }; const SharedCarousel = () => { const { carouselRef, filteredCategories, setFilteredCategories, moveCarousel } = useCarousel(); const context = useContext(SocketContext); - const { t } = useTranslation(); + const { t, i18n } = useTranslation(); const [rootCategories, setRootCategories] = useState([]); + const [currentLanguage, setCurrentLanguage] = useState(i18n.language); useEffect(() => { - const initialCategories = initializeCategories(); + const initialCategories = initializeCategories(currentLanguage); setRootCategories(initialCategories); - }, []); + }, [currentLanguage]); + + // Listen for language changes + useEffect(() => { + const handleLanguageChange = (lng) => { + setCurrentLanguage(lng); + // Clear categories to force refetch + setRootCategories([]); + }; + + i18n.on('languageChanged', handleLanguageChange); + return () => { + i18n.off('languageChanged', handleLanguageChange); + }; + }, [i18n]); useEffect(() => { // Only fetch from socket if we don't already have categories @@ -68,12 +92,30 @@ const SharedCarousel = () => { context && context.socket && context.socket.connected && typeof window !== "undefined" ) { - context.socket.emit("categoryList", { categoryId: 209, language: 'en', requestTranslation: true }, (response) => { - if (response && response.categoryTree) { - // Store in cache + context.socket.emit("categoryList", { categoryId: 209, language: currentLanguage, requestTranslation: true }, (response) => { + if (response && response.success) { + // Use translated data if available, otherwise fall back to original + const categoryTreeToUse = response.translation || response.categoryTree; + + if (categoryTreeToUse) { + // Store in cache with language-specific key + try { + if (!window.productCache) window.productCache = {}; + window.productCache[`categoryTree_209_${currentLanguage}`] = { + categoryTree: categoryTreeToUse, + timestamp: Date.now(), + }; + } catch (err) { + console.error(err); + } + setRootCategories(categoryTreeToUse.children || []); + } + } else if (response && response.categoryTree) { + // Fallback for old response format + // Store in cache with language-specific key try { if (!window.productCache) window.productCache = {}; - window.productCache["categoryTree_209"] = { + window.productCache[`categoryTree_209_${currentLanguage}`] = { categoryTree: response.categoryTree, timestamp: Date.now(), }; @@ -84,7 +126,7 @@ const SharedCarousel = () => { } }); } - }, [context, context?.socket?.connected, rootCategories.length]); + }, [context, context?.socket?.connected, rootCategories.length, currentLanguage]); useEffect(() => { const filtered = rootCategories.filter( diff --git a/src/i18n/index.js b/src/i18n/index.js index dcdef8e..14f2775 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -350,7 +350,6 @@ i18n .init({ resources, fallbackLng: 'de', // German as fallback since it's your primary language - lng: 'de', // Default language debug: process.env.NODE_ENV === 'development', // Language detection options diff --git a/src/i18n/locales/ar/sections.js b/src/i18n/locales/ar/sections.js index 7cabafd..6718b0a 100644 --- a/src/i18n/locales/ar/sections.js +++ b/src/i18n/locales/ar/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "ورينا أجمل صورة عندك", - "selectSeedRate": "اختار البذرة واضغط للتقييم" + "selectSeedRate": "اختار البذرة واضغط تقييم", + "indoorSeason": "موسم الزراعة الداخلية بدأ" }; diff --git a/src/i18n/locales/bg/sections.js b/src/i18n/locales/bg/sections.js index ccfcb29..ffcbe64 100644 --- a/src/i18n/locales/bg/sections.js +++ b/src/i18n/locales/bg/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Покажи ни най-красивата си снимка", - "selectSeedRate": "Избери семе, кликни за оценка" + "selectSeedRate": "Избери семе, кликни за оценка", + "indoorSeason": "Вътрешният сезон започва" }; diff --git a/src/i18n/locales/cs/sections.js b/src/i18n/locales/cs/sections.js index f0db928..104e877 100644 --- a/src/i18n/locales/cs/sections.js +++ b/src/i18n/locales/cs/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Ukaž nám svou nejkrásnější fotku", - "selectSeedRate": "Vyber semeno, klikni pro hodnocení" + "selectSeedRate": "Vyber semeno, klikni na hodnocení", + "indoorSeason": "Začíná indoor sezóna" }; diff --git a/src/i18n/locales/de/sections.js b/src/i18n/locales/de/sections.js index d557997..f5aaeba 100644 --- a/src/i18n/locales/de/sections.js +++ b/src/i18n/locales/de/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Zeig uns dein schönstes Foto", - "selectSeedRate": "Wähle Seed aus, klicke Bewerten" + "selectSeedRate": "Wähle Seed aus, klicke Bewerten", + "indoorSeason": "Die Indoorsaison beginnt" }; \ No newline at end of file diff --git a/src/i18n/locales/el/sections.js b/src/i18n/locales/el/sections.js index 772a6af..37b8c6a 100644 --- a/src/i18n/locales/el/sections.js +++ b/src/i18n/locales/el/sections.js @@ -5,6 +5,7 @@ export default { "thcTest": "Τεστ THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", - "showUsPhoto": "Δείξε μας τη πιο όμορφη φωτογραφία σου", - "selectSeedRate": "Επίλεξε σπόρο, κάνε κλικ για αξιολόγηση" + "showUsPhoto": "Δείξε μας την πιο όμορφη φωτογραφία σου", + "selectSeedRate": "Επίλεξε σπόρο, κάνε κλικ για αξιολόγηση", + "indoorSeason": "Η εσωτερική σεζόν ξεκινά" }; diff --git a/src/i18n/locales/en/sections.js b/src/i18n/locales/en/sections.js index cdc4ff4..97311d2 100644 --- a/src/i18n/locales/en/sections.js +++ b/src/i18n/locales/en/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", // Trachenberger Straße 14 "address2": "01129 Dresden", // 01129 Dresden "showUsPhoto": "Show us your most beautiful photo", // Zeig uns dein schönstes Foto - "selectSeedRate": "Select seed, click to rate" // Wähle Seed aus, klicke Bewerten + "selectSeedRate": "Select seed, click rate", // Wähle Seed aus, klicke Bewerten + "indoorSeason": "The indoor season begins" // Die Indoorsaison beginnt }; diff --git a/src/i18n/locales/es/sections.js b/src/i18n/locales/es/sections.js index 5018c88..8aa575f 100644 --- a/src/i18n/locales/es/sections.js +++ b/src/i18n/locales/es/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Muéstranos tu foto más hermosa", - "selectSeedRate": "Selecciona semilla, haz clic para calificar" + "selectSeedRate": "Selecciona semilla, haz clic para valorar", + "indoorSeason": "Comienza la temporada de interior" }; diff --git a/src/i18n/locales/fr/sections.js b/src/i18n/locales/fr/sections.js index e508dc0..8e1ab16 100644 --- a/src/i18n/locales/fr/sections.js +++ b/src/i18n/locales/fr/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Montre-nous ta plus belle photo", - "selectSeedRate": "Sélectionne une graine, clique pour évaluer" + "selectSeedRate": "Sélectionne une graine, clique pour noter", + "indoorSeason": "La saison en intérieur commence" }; diff --git a/src/i18n/locales/hr/sections.js b/src/i18n/locales/hr/sections.js index 59e79cb..ce583ea 100644 --- a/src/i18n/locales/hr/sections.js +++ b/src/i18n/locales/hr/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaži nam svoju najljepšu fotografiju", - "selectSeedRate": "Odaberi sjeme, klikni za ocjenu" + "selectSeedRate": "Odaberi sjeme, klikni ocjenu", + "indoorSeason": "Počinje sezona uzgoja u zatvorenom" }; diff --git a/src/i18n/locales/hu/sections.js b/src/i18n/locales/hu/sections.js index cfee627..6589499 100644 --- a/src/i18n/locales/hu/sections.js +++ b/src/i18n/locales/hu/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Mutasd meg nekünk a legszebb fotódat", - "selectSeedRate": "Válassz magot, kattints az értékeléshez" + "selectSeedRate": "Válassz magot, kattints az értékelésre", + "indoorSeason": "Kezdődik a beltéri szezon" }; diff --git a/src/i18n/locales/it/sections.js b/src/i18n/locales/it/sections.js index fc60922..e183cad 100644 --- a/src/i18n/locales/it/sections.js +++ b/src/i18n/locales/it/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Mostraci la tua foto più bella", - "selectSeedRate": "Seleziona il seme, clicca per valutare" + "selectSeedRate": "Seleziona il seme, clicca per valutare", + "indoorSeason": "Inizia la stagione indoor" }; diff --git a/src/i18n/locales/pl/sections.js b/src/i18n/locales/pl/sections.js index c4c0760..65e682a 100644 --- a/src/i18n/locales/pl/sections.js +++ b/src/i18n/locales/pl/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaż nam swoje najpiękniejsze zdjęcie", - "selectSeedRate": "Wybierz nasiono, kliknij, aby ocenić" + "selectSeedRate": "Wybierz nasiono, kliknij ocenę", + "indoorSeason": "Sezon indoor się zaczyna" }; diff --git a/src/i18n/locales/ro/sections.js b/src/i18n/locales/ro/sections.js index 3ce9381..c8c04da 100644 --- a/src/i18n/locales/ro/sections.js +++ b/src/i18n/locales/ro/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Arată-ne cea mai frumoasă fotografie a ta", - "selectSeedRate": "Selectează sămânța, fă clic pentru a evalua" + "selectSeedRate": "Selectează sămânța, apasă pentru evaluare", + "indoorSeason": "Sezonul indoor începe" }; diff --git a/src/i18n/locales/ru/sections.js b/src/i18n/locales/ru/sections.js index 55959c2..ca66ba3 100644 --- a/src/i18n/locales/ru/sections.js +++ b/src/i18n/locales/ru/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Покажи нам свою самую красивую фотографию", - "selectSeedRate": "Выберите семя, нажмите для оценки" + "selectSeedRate": "Выберите семя, нажмите оценить", + "indoorSeason": "Начинается сезон для выращивания в помещении" }; diff --git a/src/i18n/locales/sk/sections.js b/src/i18n/locales/sk/sections.js index 88b24f5..57cbbe6 100644 --- a/src/i18n/locales/sk/sections.js +++ b/src/i18n/locales/sk/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Ukážte nám svoju najkrajšiu fotku", - "selectSeedRate": "Vyberte semienko, kliknite na hodnotenie" + "selectSeedRate": "Vyberte semienko, kliknite na hodnotenie", + "indoorSeason": "Začína sezóna pestovania v interiéri" }; diff --git a/src/i18n/locales/sl/sections.js b/src/i18n/locales/sl/sections.js index efa2b2f..2905fbb 100644 --- a/src/i18n/locales/sl/sections.js +++ b/src/i18n/locales/sl/sections.js @@ -1,10 +1,11 @@ export default { "seeds": "Semena", "stecklinge": "Rezalci", - "oilPress": "Izposodi si stiskalnico olja", + "oilPress": "Izposodi si stiskalnico za olje", "thcTest": "THC test", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaži nam svojo najlepšo fotografijo", - "selectSeedRate": "Izberi seme, klikni za oceno" + "selectSeedRate": "Izberi seme, klikni oceno", + "indoorSeason": "Začne se sezona gojenja v zaprtih prostorih" }; diff --git a/src/i18n/locales/sr/sections.js b/src/i18n/locales/sr/sections.js index 7af3df1..6fb4167 100644 --- a/src/i18n/locales/sr/sections.js +++ b/src/i18n/locales/sr/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaži nam svoju najlepšu fotografiju", - "selectSeedRate": "Izaberi seme, klikni da oceniš" + "selectSeedRate": "Izaberi seme, klikni oceni", + "indoorSeason": "Počinje sezona za uzgoj u zatvorenom" }; diff --git a/src/i18n/locales/sv/sections.js b/src/i18n/locales/sv/sections.js index 33dd849..301999e 100644 --- a/src/i18n/locales/sv/sections.js +++ b/src/i18n/locales/sv/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Visa oss ditt vackraste foto", - "selectSeedRate": "Välj frö, klicka för att betygsätta" + "selectSeedRate": "Välj frö, klicka betyg", + "indoorSeason": "Inomhussäsongen börjar" }; diff --git a/src/i18n/locales/tr/sections.js b/src/i18n/locales/tr/sections.js index a5d4e55..adbf867 100644 --- a/src/i18n/locales/tr/sections.js +++ b/src/i18n/locales/tr/sections.js @@ -1,10 +1,11 @@ export default { "seeds": "Tohumlar", "stecklinge": "Çelikler", - "oilPress": "Yağ presi ödünç al", + "oilPress": "Yağ presini ödünç al", "thcTest": "THC testi", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", - "showUsPhoto": "Bize en güzel fotoğrafını göster", - "selectSeedRate": "Tohumu seç, değerlendirmek için tıkla" + "showUsPhoto": "En güzel fotoğrafını göster", + "selectSeedRate": "Tohumu seç, oy ver", + "indoorSeason": "Kapalı sezon başlıyor" }; diff --git a/src/i18n/locales/uk/sections.js b/src/i18n/locales/uk/sections.js index 2b988dd..fb17e3e 100644 --- a/src/i18n/locales/uk/sections.js +++ b/src/i18n/locales/uk/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Покажи нам своє найкрасивіше фото", - "selectSeedRate": "Виберіть насіння, натисніть, щоб оцінити" + "selectSeedRate": "Виберіть насіння, натисніть оцінити", + "indoorSeason": "Починається сезон для вирощування в приміщенні" }; diff --git a/src/i18n/locales/zh/sections.js b/src/i18n/locales/zh/sections.js index 1c75b30..a0f6bbb 100644 --- a/src/i18n/locales/zh/sections.js +++ b/src/i18n/locales/zh/sections.js @@ -6,5 +6,6 @@ export default { "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "展示你最美的照片", - "selectSeedRate": "选择种子,点击评分" + "selectSeedRate": "选择种子,点击评分", + "indoorSeason": "室内季节开始了" }; diff --git a/src/i18n/withTranslation.js b/src/i18n/withTranslation.js index 2f10a09..8743030 100644 --- a/src/i18n/withTranslation.js +++ b/src/i18n/withTranslation.js @@ -28,14 +28,15 @@ export class LanguageProvider extends Component { } componentDidMount() { - // Listen for language changes from i18n 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() { - // Clean up listener if (this.props.i18n) { this.props.i18n.off('languageChanged', this.handleLanguageChanged); } @@ -47,6 +48,13 @@ export class LanguageProvider extends Component { // 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