From 04e97c25223fc5d03f1797cb0883b60f4338ec65 Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Fri, 18 Jul 2025 15:26:11 +0200 Subject: [PATCH] Add CSS animations for rotating stars in MainPageLayout: Implemented new animations for star graphics to enhance visual appeal. Updated SharedCarousel to support dynamic language changes and improved category fetching logic. Enhanced localization files with new text for indoor season prompts in multiple languages. --- src/components/MainPageLayout.js | 126 +++++++++++++++++++++++++++++++ src/components/SharedCarousel.js | 60 ++++++++++++--- src/i18n/index.js | 1 - src/i18n/locales/ar/sections.js | 3 +- src/i18n/locales/bg/sections.js | 3 +- src/i18n/locales/cs/sections.js | 3 +- src/i18n/locales/de/sections.js | 3 +- src/i18n/locales/el/sections.js | 5 +- src/i18n/locales/en/sections.js | 3 +- src/i18n/locales/es/sections.js | 3 +- src/i18n/locales/fr/sections.js | 3 +- src/i18n/locales/hr/sections.js | 3 +- src/i18n/locales/hu/sections.js | 3 +- src/i18n/locales/it/sections.js | 3 +- src/i18n/locales/pl/sections.js | 3 +- src/i18n/locales/ro/sections.js | 3 +- src/i18n/locales/ru/sections.js | 3 +- src/i18n/locales/sk/sections.js | 3 +- src/i18n/locales/sl/sections.js | 5 +- src/i18n/locales/sr/sections.js | 3 +- src/i18n/locales/sv/sections.js | 3 +- src/i18n/locales/tr/sections.js | 7 +- src/i18n/locales/uk/sections.js | 3 +- src/i18n/locales/zh/sections.js | 3 +- src/i18n/withTranslation.js | 12 ++- 25 files changed, 233 insertions(+), 37 deletions(-) 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