diff --git a/prerender/seo/llms.cjs b/prerender/seo/llms.cjs index 745766c..2263bf6 100644 --- a/prerender/seo/llms.cjs +++ b/prerender/seo/llms.cjs @@ -55,29 +55,29 @@ GrowHeads.de is a German online shop and local store in Dresden specializing in const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-'); const productsPerPage = 50; const totalPages = Math.ceil(productCount / productsPerPage); - + llmsTxt += `#### ${category.name} (${productCount} products)`; - + if (totalPages > 1) { llmsTxt += ` - **Product Catalog**: ${totalPages} pages available - **Page 1**: ${baseUrl}/llms-${categorySlug}-page-1.txt (Products 1-${Math.min(productsPerPage, productCount)})`; - + if (totalPages > 2) { llmsTxt += ` - **Page 2**: ${baseUrl}/llms-${categorySlug}-page-2.txt (Products ${productsPerPage + 1}-${Math.min(productsPerPage * 2, productCount)})`; } - + if (totalPages > 3) { llmsTxt += ` - **...**: Additional pages available`; } - + if (totalPages > 2) { llmsTxt += ` - **Page ${totalPages}**: ${baseUrl}/llms-${categorySlug}-page-${totalPages}.txt (Products ${((totalPages - 1) * productsPerPage) + 1}-${productCount})`; } - + llmsTxt += ` - **Access Pattern**: Replace "page-X" with desired page number (1-${totalPages})`; } else if (productCount > 0) { @@ -87,7 +87,7 @@ GrowHeads.de is a German online shop and local store in Dresden specializing in llmsTxt += ` - **Product Catalog**: No products available`; } - + llmsTxt += ` `; @@ -106,7 +106,7 @@ GrowHeads.de is a German online shop and local store in Dresden specializing in const generateCategoryLlmsTxt = (category, categoryProducts = [], baseUrl, config, pageNumber = 1, productsPerPage = 50) => { const currentDate = new Date().toISOString().split("T")[0]; // YYYY-MM-DD format const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-'); - + // Calculate pagination const totalProducts = categoryProducts.length; const totalPages = Math.ceil(totalProducts / productsPerPage); @@ -140,28 +140,28 @@ This file contains products ${startIndex + 1}-${endIndex} of ${totalProducts} in **How to access other pages in this category:** `; - + if (pageNumber > 1) { categoryLlmsTxt += `- **Previous Page**: ${baseUrl}/llms-${categorySlug}-page-${pageNumber - 1}.txt `; } - + if (pageNumber < totalPages) { categoryLlmsTxt += `- **Next Page**: ${baseUrl}/llms-${categorySlug}-page-${pageNumber + 1}.txt `; } - + categoryLlmsTxt += `- **First Page**: ${baseUrl}/llms-${categorySlug}-page-1.txt - **Last Page**: ${baseUrl}/llms-${categorySlug}-page-${totalPages}.txt **All pages in this category:** `; - + for (let i = 1; i <= totalPages; i++) { - categoryLlmsTxt += `- **Page ${i}**: ${baseUrl}/llms-${categorySlug}-page-${i}.txt (Products ${((i-1) * productsPerPage) + 1}-${Math.min(i * productsPerPage, totalProducts)}) + categoryLlmsTxt += `- **Page ${i}**: ${baseUrl}/llms-${categorySlug}-page-${i}.txt (Products ${((i - 1) * productsPerPage) + 1}-${Math.min(i * productsPerPage, totalProducts)}) `; } - + categoryLlmsTxt += ` `; @@ -173,10 +173,10 @@ This file contains products ${startIndex + 1}-${endIndex} of ${totalProducts} in // Clean description for markdown (remove HTML tags and limit length) const cleanDescription = product.description ? product.description - .replace(/<[^>]*>/g, "") - .replace(/\n/g, " ") - .trim() - .substring(0, 300) + .replace(/<[^>]*>/g, "") + .replace(/\n/g, " ") + .trim() + .substring(0, 300) : ""; const globalIndex = startIndex + index + 1; @@ -234,13 +234,13 @@ This category currently contains no products. if (pageNumber > 1) { categoryLlmsTxt += `← [Previous Page](${baseUrl}/llms-${categorySlug}-page-${pageNumber - 1}.txt) | `; } - + categoryLlmsTxt += `[Category Overview](${baseUrl}/llms-${categorySlug}-page-1.txt)`; - + if (pageNumber < totalPages) { categoryLlmsTxt += ` | [Next Page](${baseUrl}/llms-${categorySlug}-page-${pageNumber + 1}.txt) →`; } - + categoryLlmsTxt += ` `; @@ -260,7 +260,7 @@ const generateCategoryProductList = (category, categoryProducts = []) => { const fileName = `llms-${categorySlug}-list.txt`; const subcategoryIds = (category.subcategories || []).join(','); - let content = `${String(category.name)},${String(category.id)},[${subcategoryIds}]\n`; + let content = '';//`${String(category.name)},${String(category.id)},[${subcategoryIds}]\n`; categoryProducts.forEach((product) => { const artnr = String(product.articleNumber || ''); diff --git a/process_llms_cat.cjs b/process_llms_cat.cjs index 2ac9105..5dc7232 100644 --- a/process_llms_cat.cjs +++ b/process_llms_cat.cjs @@ -1,9 +1,10 @@ const fs = require('fs'); const path = require('path'); -// Read the input file -const inputFile = path.join(__dirname, 'dist', 'llms-cat.txt'); -const outputFile = path.join(__dirname, 'output.csv'); +// Read the input file from public +const inputFile = path.join(__dirname, 'public', 'llms-cat.txt'); +// Write the output file to dist +const outputFile = path.join(__dirname, 'dist', 'llms-cat.txt'); // Function to parse a CSV line with escaped quotes function parseCSVLine(line) { @@ -38,44 +39,65 @@ function parseCSVLine(line) { } try { + if (!fs.existsSync(inputFile)) { + throw new Error(`Input file not found: ${inputFile}`); + } + const data = fs.readFileSync(inputFile, 'utf8'); const lines = data.trim().split('\n'); - const outputLines = ['URL,SEO Description']; + // Keep the header as intended: URL and Description + const outputLines = ['URL of product list for article numbers,SEO Description']; - for (const line of lines) { + let skippedLines = 0; + let processedLines = 0; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; if (line.trim() === '') continue; + // Skip comment lines or lines not starting with a number/quote (simple heuristic for header/comments) + // The file starts with text "this file has..." and then header "categoryId..." + // Actual data lines start with " + if (!line.trim().startsWith('"')) { + continue; + } + // Parse the CSV line properly handling escaped quotes const fields = parseCSVLine(line); if (fields.length !== 3) { - console.warn(`Skipping malformed line (got ${fields.length} fields): ${line.substring(0, 100)}...`); + console.warn(`Skipping malformed line ${i + 1} (got ${fields.length} fields): ${line.substring(0, 50)}...`); + skippedLines++; continue; } - const [field1, field2, field3] = fields; - const url = field2; + // Input: categoryId, listFileName, seoDescription + // Output: URL, SEO Description + const [categoryId, listFileName, seoDescription] = fields; - // field3 is a JSON string - parse it directly - let seoDescription = ''; - try { - const parsed = JSON.parse(field3); - seoDescription = parsed.seo_description || ''; - } catch (e) { - console.warn(`Failed to parse JSON for URL ${url}: ${e.message}`); - console.warn(`JSON string: ${field3.substring(0, 200)}...`); - } + // Use listFileName as URL + const url = listFileName; - // Escape quotes for CSV output - URL doesn't need quotes, description does - const escapedDescription = '"' + seoDescription.replace(/"/g, '""') + '"'; + // Use seoDescription as description directly (it's already a string) + const description = seoDescription; + + // Escape quotes for CSV output + const escapedDescription = '"' + description.replace(/"/g, '""') + '"'; outputLines.push(`${url},${escapedDescription}`); + processedLines++; + } + + // Ensure dist directory exists + const distDir = path.dirname(outputFile); + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); } // Write the output CSV fs.writeFileSync(outputFile, outputLines.join('\n'), 'utf8'); - console.log(`Processed ${lines.length} lines and created ${outputFile}`); + console.log(`Processed ${processedLines} lines (skipped ${skippedLines}) and created ${outputFile}`); } catch (error) { console.error('Error processing file:', error.message); diff --git a/public/llms-cat.txt b/public/llms-cat.txt index 9ff5bc0..66031bc 100644 --- a/public/llms-cat.txt +++ b/public/llms-cat.txt @@ -1,3 +1,5 @@ +this file has the list of category overview lists, where you can find article numbers + categoryId,listFileName,seoDescription "703","https://growheads.de/llms-abluft-sets-list.txt","Abluft-Sets für Growbox & Indoor-Grow: leise, energiesparend & mit Aktivkohlefilter zur Geruchsneutralisation. Ideal für Zelte von 60 cm bis 1 m²." "317","https://growheads.de/llms-air-pot-list.txt","Air-Pot Pflanztöpfe für maximales Wurzelwachstum: Air-Pruning, optimale Belüftung & Drainage. Ideal für Indoor, Outdoor, Hydroponik & Anzucht." diff --git a/src/components/Content.js b/src/components/Content.js index 0a50062..ec78c90 100644 --- a/src/components/Content.js +++ b/src/components/Content.js @@ -36,11 +36,11 @@ function getCachedCategoryData(categoryId, language = 'de') { try { const cacheKey = `categoryProducts_${categoryId}_${language}`; const cachedData = window.productCache[cacheKey]; - + if (cachedData) { const { timestamp } = cachedData; const cacheAge = Date.now() - timestamp; - const tenMinutes = 10 * 60 * 1000; + const tenMinutes = 10 * 60 * 1000; if (cacheAge < tenMinutes) { return cachedData; } @@ -58,21 +58,21 @@ function getFilteredProducts(unfilteredProducts, attributes, t) { const attributeSettings = getAllSettingsWithPrefix('filter_attribute_'); const manufacturerSettings = getAllSettingsWithPrefix('filter_manufacturer_'); const availabilitySettings = getAllSettingsWithPrefix('filter_availability_'); - + const attributeFilters = []; Object.keys(attributeSettings).forEach(key => { if (attributeSettings[key] === 'true') { attributeFilters.push(key.split('_')[2]); } }); - + const manufacturerFilters = []; Object.keys(manufacturerSettings).forEach(key => { if (manufacturerSettings[key] === 'true') { manufacturerFilters.push(key.split('_')[2]); } }); - + const availabilityFilters = []; Object.keys(availabilitySettings).forEach(key => { if (availabilitySettings[key] === 'true') { @@ -82,9 +82,9 @@ function getFilteredProducts(unfilteredProducts, attributes, t) { const uniqueAttributes = [...new Set((attributes || []).map(attr => attr.kMerkmalWert ? attr.kMerkmalWert.toString() : ''))]; const uniqueManufacturers = [...new Set((unfilteredProducts || []).filter(product => product.manufacturerId).map(product => product.manufacturerId ? product.manufacturerId.toString() : ''))]; - const uniqueManufacturersWithName = [...new Set((unfilteredProducts || []).filter(product => product.manufacturerId).map(product => ({id:product.manufacturerId ? product.manufacturerId.toString() : '',value:product.manufacturer})))]; + const uniqueManufacturersWithName = [...new Set((unfilteredProducts || []).filter(product => product.manufacturerId).map(product => ({ id: product.manufacturerId ? product.manufacturerId.toString() : '', value: product.manufacturer })))]; const activeAttributeFilters = attributeFilters.filter(filter => uniqueAttributes.includes(filter)); - const activeManufacturerFilters = manufacturerFilters.filter(filter => uniqueManufacturers.includes(filter)); + const activeManufacturerFilters = manufacturerFilters.filter(filter => uniqueManufacturers.includes(filter)); const attributeFiltersByGroup = {}; for (const filterId of activeAttributeFilters) { const attribute = attributes.find(attr => attr.kMerkmalWert.toString() === filterId); @@ -95,26 +95,26 @@ function getFilteredProducts(unfilteredProducts, attributes, t) { attributeFiltersByGroup[attribute.cName].push(filterId); } } - + let filteredProducts = (unfilteredProducts || []).filter(product => { const availabilityFilter = sessionStorage.getItem('filter_availability'); - let inStockMatch = availabilityFilter == 1 ? true : (product.available>0); - + let inStockMatch = availabilityFilter == 1 ? true : (product.available > 0); + // Check if there are any new products in the entire set const hasNewProducts = (unfilteredProducts || []).some(product => isNew(product.neu)); - + // Only apply the new filter if there are actually new products and the filter is active const isNewMatch = availabilityFilters.includes('2') && hasNewProducts ? isNew(product.neu) : true; let soonMatch = availabilityFilters.includes('3') ? !product.available && product.incoming : true; - const soon2Match = (availabilityFilter != 1)&&availabilityFilters.includes('3') ? (product.available) || (!product.available && product.incoming) : true; - if( (availabilityFilter != 1)&&availabilityFilters.includes('3') && ((product.available) || (!product.available && product.incoming))){ + const soon2Match = (availabilityFilter != 1) && availabilityFilters.includes('3') ? (product.available) || (!product.available && product.incoming) : true; + if ((availabilityFilter != 1) && availabilityFilters.includes('3') && ((product.available) || (!product.available && product.incoming))) { inStockMatch = true; soonMatch = true; console.log("soon2Match", product.cName); } - const manufacturerMatch = activeManufacturerFilters.length === 0 || + const manufacturerMatch = activeManufacturerFilters.length === 0 || (product.manufacturerId && activeManufacturerFilters.includes(product.manufacturerId.toString())); if (Object.keys(attributeFiltersByGroup).length === 0) { @@ -130,41 +130,41 @@ function getFilteredProducts(unfilteredProducts, attributes, t) { }); return manufacturerMatch && attributeMatch && soon2Match && inStockMatch && soonMatch && isNewMatch; }); - + const activeAttributeFiltersWithNames = activeAttributeFilters.map(filter => { const attribute = attributes.find(attr => attr.kMerkmalWert.toString() === filter); - return {name: attribute.cName, value: attribute.cWert, id: attribute.kMerkmalWert}; + return { name: attribute.cName, value: attribute.cWert, id: attribute.kMerkmalWert }; }); const activeManufacturerFiltersWithNames = activeManufacturerFilters.map(filter => { const manufacturer = uniqueManufacturersWithName.find(manufacturer => manufacturer.id === filter); - return {name: manufacturer.value, value: manufacturer.id}; + return { name: manufacturer.value, value: manufacturer.id }; }); // Extract active availability filters const availabilityFilter = sessionStorage.getItem('filter_availability'); const activeAvailabilityFilters = []; - + // Check if there are actually products with these characteristics const hasNewProducts = (unfilteredProducts || []).some(product => isNew(product.neu)); const hasComingSoonProducts = (unfilteredProducts || []).some(product => !product.available && product.incoming); - + // Check for "auf Lager" filter (in stock) - it's active when filter_availability is NOT set to '1' if (availabilityFilter !== '1') { - activeAvailabilityFilters.push({id: '1', name: t ? t('product.inStock') : 'auf Lager'}); - } - - // Check for "Neu" filter (new) - only show if there are actually new products and filter is active - if (availabilityFilters.includes('2') && hasNewProducts) { - activeAvailabilityFilters.push({id: '2', name: t ? t('product.new') : 'Neu'}); - } - - // Check for "Bald verfügbar" filter (coming soon) - only show if there are actually coming soon products and filter is active - if (availabilityFilters.includes('3') && hasComingSoonProducts) { - activeAvailabilityFilters.push({id: '3', name: t ? t('product.comingSoon') : 'Bald verfügbar'}); + activeAvailabilityFilters.push({ id: '1', name: t ? t('product.inStock') : 'auf Lager' }); } - return {filteredProducts,activeAttributeFilters:activeAttributeFiltersWithNames,activeManufacturerFilters:activeManufacturerFiltersWithNames,activeAvailabilityFilters}; + // Check for "Neu" filter (new) - only show if there are actually new products and filter is active + if (availabilityFilters.includes('2') && hasNewProducts) { + activeAvailabilityFilters.push({ id: '2', name: t ? t('product.new') : 'Neu' }); + } + + // Check for "Bald verfügbar" filter (coming soon) - only show if there are actually coming soon products and filter is active + if (availabilityFilters.includes('3') && hasComingSoonProducts) { + activeAvailabilityFilters.push({ id: '3', name: t ? t('product.comingSoon') : 'Bald verfügbar' }); + } + + return { filteredProducts, activeAttributeFilters: activeAttributeFiltersWithNames, activeManufacturerFilters: activeManufacturerFiltersWithNames, activeAvailabilityFilters }; } function setCachedCategoryData(categoryId, data, language = 'de') { if (!window.productCache) { @@ -176,7 +176,7 @@ function setCachedCategoryData(categoryId, data, language = 'de') { try { const cacheKey = `categoryProducts_${categoryId}_${language}`; - if(data.products) for(const product of data.products) { + if (data.products) for (const product of data.products) { const productCacheKey = `product_${product.id}_${language}`; window.productDetailCache[productCacheKey] = product; } @@ -195,7 +195,7 @@ class Content extends Component { this.state = { loaded: false, - categoryName: null, + categoryName: null, unfilteredProducts: [], filteredProducts: [], attributes: [], @@ -206,11 +206,13 @@ class Content extends Component { componentDidMount() { const currentLanguage = this.props.i18n?.language || 'de'; - if(this.props.params.categoryId) {this.setState({loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage}, () => { + if (this.props.params.categoryId) { + this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => { this.fetchCategoryData(this.props.params.categoryId); - })} + }) + } else if (this.props.searchParams?.get('q')) { - this.setState({loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage}, () => { + this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => { this.fetchSearchData(this.props.searchParams?.get('q')); }) } @@ -220,29 +222,29 @@ class Content extends Component { const currentLanguage = this.props.i18n?.language || 'de'; const categoryChanged = this.props.params.categoryId && (prevProps.params.categoryId !== this.props.params.categoryId); const searchChanged = this.props.searchParams?.get('q') && (prevProps.searchParams?.get('q') !== this.props.searchParams?.get('q')); - - if(categoryChanged) { - // Clear context for new category loading - if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) { - this.props.categoryContext.setCurrentCategory(null); - } - window.currentSearchQuery = null; - this.setState({loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage}, () => { - this.fetchCategoryData(this.props.params.categoryId); - }); - return; // Don't check language change if category changed - } + if (categoryChanged) { + // Clear context for new category loading + if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) { + this.props.categoryContext.setCurrentCategory(null); + } + + window.currentSearchQuery = null; + this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => { + this.fetchCategoryData(this.props.params.categoryId); + }); + return; // Don't check language change if category changed + } else if (searchChanged) { - this.setState({loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage}, () => { + this.setState({ loaded: false, unfilteredProducts: [], filteredProducts: [], attributes: [], categoryName: null, childCategories: [], lastFetchedLanguage: currentLanguage }, () => { this.fetchSearchData(this.props.searchParams?.get('q')); }); return; // Don't check language change if search changed } - + // Re-fetch products when language changes to get translated content const languageChanged = currentLanguage !== this.state.lastFetchedLanguage; - + console.log('Content componentDidUpdate:', { languageChanged, lastFetchedLang: this.state.lastFetchedLanguage, @@ -252,27 +254,27 @@ class Content extends Component { categoryId: this.props.params.categoryId, hasSearchQuery: !!this.props.searchParams?.get('q') }); - - if(languageChanged) { + + if (languageChanged) { console.log('Content: Language changed! Re-fetching data...'); // Re-fetch current data with new language // Note: Language is now part of the cache key, so it will automatically fetch fresh data - if(this.props.params.categoryId) { + if (this.props.params.categoryId) { // Re-fetch category data with new language console.log('Content: Re-fetching category', this.props.params.categoryId); - this.setState({loaded: false, lastFetchedLanguage: currentLanguage}, () => { + this.setState({ loaded: false, lastFetchedLanguage: currentLanguage }, () => { this.fetchCategoryData(this.props.params.categoryId); }); - } else if(this.props.searchParams?.get('q')) { + } else if (this.props.searchParams?.get('q')) { // Re-fetch search data with new language console.log('Content: Re-fetching search', this.props.searchParams?.get('q')); - this.setState({loaded: false, lastFetchedLanguage: currentLanguage}, () => { + this.setState({ loaded: false, lastFetchedLanguage: currentLanguage }, () => { this.fetchSearchData(this.props.searchParams?.get('q')); }); } else { // If not viewing category or search, just re-filter existing products console.log('Content: Just re-filtering existing products'); - this.setState({lastFetchedLanguage: currentLanguage}); + this.setState({ lastFetchedLanguage: currentLanguage }); this.filterProducts(); } } @@ -281,7 +283,7 @@ class Content extends Component { processData(response) { const rawProducts = response.products; const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de'; - + if (!window.individualProductCache) { window.individualProductCache = {}; } @@ -289,10 +291,10 @@ class Content extends Component { const unfilteredProducts = []; //console.log("processData", rawProducts); - if(rawProducts) rawProducts.forEach(product => { + if (rawProducts) rawProducts.forEach(product => { const effectiveProduct = product.translatedProduct || product; const cacheKey = `${effectiveProduct.id}_${currentLanguage}`; - + window.individualProductCache[cacheKey] = { data: effectiveProduct, timestamp: Date.now() @@ -319,16 +321,16 @@ class Content extends Component { categoryName: response.categoryName, name: response.name }); - + if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) { if (response.categoryName || response.name) { - console.log('Content: Setting category context'); - this.props.categoryContext.setCurrentCategory({ - id: this.props.params.categoryId, - name: response.categoryName || response.name - }); + console.log('Content: Setting category context'); + this.props.categoryContext.setCurrentCategory({ + id: this.props.params.categoryId, + name: response.categoryName || response.name + }); } else { - console.log('Content: No category name found to set in context'); + console.log('Content: No category name found to set in context'); } } else { console.warn('Content: categoryContext prop is missing!'); @@ -352,7 +354,7 @@ class Content extends Component { // Track if we've received the full response to ignore stub response if needed let receivedFullResponse = false; - window.socketManager.on(`productList:${categoryId}`,(response) => { + window.socketManager.on(`productList:${categoryId}`, (response) => { console.log("getCategoryProducts full response", response); receivedFullResponse = true; setCachedCategoryData(categoryId, response, currentLanguage); @@ -382,7 +384,7 @@ class Content extends Component { } ); } - + processDataWithCategoryTree(response, categoryId) { console.log("---------------processDataWithCategoryTree", response, categoryId); // Get child categories from the cached category tree @@ -392,10 +394,10 @@ class Content extends Component { const categoryTreeCache = window.categoryService.getSync(209, currentLanguage); if (categoryTreeCache) { // If categoryId is a string (SEO name), find by seoName, otherwise by ID - const targetCategory = typeof categoryId === 'string' + const targetCategory = typeof categoryId === 'string' ? this.findCategoryBySeoName(categoryTreeCache, categoryId) : this.findCategoryById(categoryTreeCache, categoryId); - + if (targetCategory && targetCategory.children) { childCategories = targetCategory.children; } @@ -403,7 +405,7 @@ class Content extends Component { } catch (err) { console.error('Error getting child categories from tree:', err); } - + // Add child categories to the response const enhancedResponse = { ...response, @@ -412,42 +414,42 @@ class Content extends Component { // Attempt to set category name from the tree if missing in response if (!enhancedResponse.categoryName && !enhancedResponse.name) { - // Try to find name in the tree using the ID or SEO name - try { - const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de'; - const categoryTreeCache = window.categoryService.getSync(209, currentLanguage); - - if (categoryTreeCache) { - const targetCategory = typeof categoryId === 'string' - ? this.findCategoryBySeoName(categoryTreeCache, categoryId) - : this.findCategoryById(categoryTreeCache, categoryId); - - if (targetCategory && targetCategory.name) { - enhancedResponse.categoryName = targetCategory.name; - } - } - } catch (err) { - console.error('Error finding category name in tree:', err); - } + // Try to find name in the tree using the ID or SEO name + try { + const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de'; + const categoryTreeCache = window.categoryService.getSync(209, currentLanguage); + + if (categoryTreeCache) { + const targetCategory = typeof categoryId === 'string' + ? this.findCategoryBySeoName(categoryTreeCache, categoryId) + : this.findCategoryById(categoryTreeCache, categoryId); + + if (targetCategory && targetCategory.name) { + enhancedResponse.categoryName = targetCategory.name; + } + } + } catch (err) { + console.error('Error finding category name in tree:', err); + } } - + this.processData(enhancedResponse); } - + findCategoryById(category, targetId) { if (!category) return null; - + if (category.id === targetId) { return category; } - + if (category.children) { for (let child of category.children) { const found = this.findCategoryById(child, targetId); if (found) return found; } } - + return null; } @@ -472,7 +474,7 @@ class Content extends Component { } filterProducts() { - this.setState({ + this.setState({ ...getFilteredProducts( this.state.unfilteredProducts, this.state.attributes, @@ -484,25 +486,25 @@ class Content extends Component { // Helper function to find category by seoName findCategoryBySeoName = (categoryNode, seoName) => { if (!categoryNode) return null; - + if (categoryNode.seoName === seoName) { return categoryNode; } - + if (categoryNode.children) { for (const child of categoryNode.children) { const found = this.findCategoryBySeoName(child, seoName); if (found) return found; } } - + return null; } // Helper function to get current category ID from seoName getCurrentCategoryId = () => { const seoName = this.props.params.categoryId; - + // Get the category tree from cache const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de'; const categoryTreeCache = window.categoryService.getSync(209, currentLanguage); @@ -521,7 +523,7 @@ class Content extends Component { renderParentCategoryNavigation = () => { const currentCategoryId = this.getCurrentCategoryId(); if (!currentCategoryId) return null; - + // Get the category tree from cache const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de'; const categoryTreeCache = window.categoryService.getSync(209, currentLanguage); @@ -558,289 +560,289 @@ class Content extends Component { render() { // console.log('Content props:', this.props); // Check if we should show category boxes instead of product list - const showCategoryBoxes = this.state.loaded && - this.state.unfilteredProducts.length === 0 && - this.state.childCategories.length > 0; + const showCategoryBoxes = this.state.loaded && + this.state.unfilteredProducts.length === 0 && + this.state.childCategories.length > 0; console.log("showCategoryBoxes", showCategoryBoxes, this.state.unfilteredProducts.length, this.state.childCategories.length); - + return ( {showCategoryBoxes ? ( // Show category boxes layout when no products but have child categories - ) : ( <> {/* Show subcategories above main layout when there are both products and child categories */} - {this.state.loaded && - this.state.unfilteredProducts.length > 0 && - this.state.childCategories.length > 0 && ( - - {(() => { - const parentCategory = this.renderParentCategoryNavigation(); - if (parentCategory) { - // Show parent category to the left of subcategories - return ( - - {/* Parent Category Box */} - - - {/* Up Arrow Overlay */} - - + {this.state.loaded && + this.state.unfilteredProducts.length > 0 && + this.state.childCategories.length > 0 && ( + + {(() => { + const parentCategory = this.renderParentCategoryNavigation(); + if (parentCategory) { + // Show parent category to the left of subcategories + return ( + + {/* Parent Category Box */} + + + {/* Up Arrow Overlay */} + + + + + + {/* Subcategories Grid */} + + - - {/* Subcategories Grid */} - - - - - ); - } else { - // No parent category, just show subcategories - return ; - } - })()} - - )} + ); + } else { + // No parent category, just show subcategories + return ; + } + })()} + + )} {/* Show standalone parent category navigation when there are only products */} - {this.state.loaded && - this.props.params.categoryId && - !(this.state.unfilteredProducts.length > 0 && this.state.childCategories.length > 0) && (() => { - const parentCategory = this.renderParentCategoryNavigation(); - if (parentCategory) { - return ( - - - - {/* Up Arrow Overlay */} - - + {this.state.loaded && + this.props.params.categoryId && + !(this.state.unfilteredProducts.length > 0 && this.state.childCategories.length > 0) && (() => { + const parentCategory = this.renderParentCategoryNavigation(); + if (parentCategory) { + return ( + + + + {/* Up Arrow Overlay */} + + + - - ); - } - return null; - })()} + ); + } + return null; + })()} {/* Show normal product list layout */} - - - - - - {this.filterProducts()}} - dataType={this.state.dataType} - dataParam={this.state.dataParam} - categoryName={this.state.categoryName} - /> - - - {(this.props.params.categoryId == 'Stecklinge' || this.props.params.categoryId == 'Seeds') && - - - {this.props.t ? this.props.t('navigation.otherCategories') : 'Andere Kategorien'} - - - } - - {this.props.params.categoryId == 'Stecklinge' && - {/* Image Container - Place your seeds image here */} - - Seeds - {/* Overlay text - optional */} - - - {this.props.t('sections.seeds')} - + + + + { this.filterProducts() }} + dataType={this.state.dataType} + dataParam={this.state.dataParam} + categoryName={this.state.categoryName} + /> + + + {(this.props.params.categoryId == 'Stecklinge___' || this.props.params.categoryId == 'Seeds___') && + + + {this.props.t ? this.props.t('navigation.otherCategories') : 'Andere Kategorien'} + + + } + + {this.props.params.categoryId == 'Stecklinge' && + {/* Image Container - Place your seeds image here */} + + Seeds + {/* Overlay text - optional */} + + + {this.props.t('sections.seeds')} + + + + + } + + {this.props.params.categoryId == 'Seeds___' && + {/* Image Container - Place your cutlings image here */} + + Stecklinge + {/* Overlay text - optional */} + + + {this.props.t('sections.stecklinge')} + + + + } + + + + { this.filterProducts() }} + dataType={this.state.dataType} + dataParam={this.state.dataParam} + /> - - } - - {this.props.params.categoryId == 'Seeds' && - {/* Image Container - Place your cutlings image here */} - - Stecklinge - {/* Overlay text - optional */} - - - {this.props.t('sections.stecklinge')} - - - - } - - - - {this.filterProducts()}} - dataType={this.state.dataType} - dataParam={this.state.dataParam} - /> - - )} diff --git a/src/components/MainPageLayout.js b/src/components/MainPageLayout.js index 1370be6..562b743 100644 --- a/src/components/MainPageLayout.js +++ b/src/components/MainPageLayout.js @@ -156,7 +156,7 @@ const MainPageLayout = () => { }; const allTitles = { - home: t('titles.home') , + home: t('titles.home'), aktionen: t('titles.aktionen'), filiale: t('titles.filiale') }; @@ -164,7 +164,7 @@ const MainPageLayout = () => { const allContentBoxes = { home: [ { title: t('sections.seeds'), image: "/assets/images/seeds.avif", bgcolor: "#e1f0d3", link: "/Kategorie/Seeds" }, - { title: t('sections.stecklinge'), image: "/assets/images/cutlings.avif", bgcolor: "#e8f5d6", link: "/Kategorie/Stecklinge" } + { title: t('sections.konfigurator'), image: "/assets/images/konfigurator.avif", bgcolor: "#e8f5d6", link: "/Konfigurator" } ], aktionen: [ { title: t('sections.oilPress'), image: "/assets/images/presse.jpg", bgcolor: "#e1f0d3", link: "/presseverleih" }, @@ -262,16 +262,16 @@ const MainPageLayout = () => { position: pageType === "home" ? "relative" : "absolute", top: 0, left: 0, width: "100%", pointerEvents: getOpacity(pageType) === 1 ? "auto" : "none" }}> {contentBoxes.map((box, index) => ( - + ))} ))} diff --git a/src/i18n/locales/ar/sections.js b/src/i18n/locales/ar/sections.js index b5e5d7a..ab5bffd 100644 --- a/src/i18n/locales/ar/sections.js +++ b/src/i18n/locales/ar/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "بذور", "stecklinge": "قصاصات", - "oilPress": "استعارة معصرة الزيت", + "konfigurator": "المُكوّن", + "oilPress": "استعارة مكبس الزيت", "thcTest": "اختبار THC", - "address1": "Trachenberger Straße 14", - "address2": "01129 Dresden", - "showUsPhoto": "ورينا أجمل صورة عندك", - "selectSeedRate": "اختار البذرة واضغط تقييم", - "indoorSeason": "موسم الزراعة الداخلية بدأ" + "address1": "شارع تراشينبرجر 14", + "address2": "01129 دريسدن", + "showUsPhoto": "اعرض لنا أجمل صورة لديك", + "selectSeedRate": "اختر البذرة، واضغط للتقييم", + "indoorSeason": "بدأ موسم الزراعة الداخلية" }; diff --git a/src/i18n/locales/ar/titles.js b/src/i18n/locales/ar/titles.js index a252087..ff15ae4 100644 --- a/src/i18n/locales/ar/titles.js +++ b/src/i18n/locales/ar/titles.js @@ -1,5 +1,5 @@ export default { - "home": "بذور وقصاصات القنب الممتازة", + "home": "بذور القنب الممتازة", "aktionen": "العروض والتخفيضات الحالية", - "filiale": "متجرنا في دريسدن", + "filiale": "متجرنا في دريسدن" }; diff --git a/src/i18n/locales/bg/sections.js b/src/i18n/locales/bg/sections.js index ffcbe64..c1684cd 100644 --- a/src/i18n/locales/bg/sections.js +++ b/src/i18n/locales/bg/sections.js @@ -1,7 +1,8 @@ export default { "seeds": "Семена", "stecklinge": "Резници", - "oilPress": "Наеми преса за масло", + "konfigurator": "Конфигуратор", + "oilPress": "Наеми преса за олио", "thcTest": "THC тест", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", diff --git a/src/i18n/locales/bg/titles.js b/src/i18n/locales/bg/titles.js index b2fa7d5..515f0fd 100644 --- a/src/i18n/locales/bg/titles.js +++ b/src/i18n/locales/bg/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Фини семена и резници от канабис", + "home": "Качествени канабис семена", "aktionen": "Текущи промоции и оферти", - "filiale": "Нашият магазин в Дрезден", + "filiale": "Нашият магазин в Дрезден" }; diff --git a/src/i18n/locales/cs/sections.js b/src/i18n/locales/cs/sections.js index 104e877..731a374 100644 --- a/src/i18n/locales/cs/sections.js +++ b/src/i18n/locales/cs/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Semena", "stecklinge": "Řízky", + "konfigurator": "Konfigurátor", "oilPress": "Půjčit lis na olej", "thcTest": "THC test", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/cs/titles.js b/src/i18n/locales/cs/titles.js index 685f793..539b91d 100644 --- a/src/i18n/locales/cs/titles.js +++ b/src/i18n/locales/cs/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kvalitní semena a řízky konopí", + "home": "Kvalitní semena konopí", "aktionen": "Aktuální akce a nabídky", - "filiale": "Naše prodejna v Drážďanech", + "filiale": "Naše prodejna v Drážďanech" }; diff --git a/src/i18n/locales/de/sections.js b/src/i18n/locales/de/sections.js index f5aaeba..15bda6f 100644 --- a/src/i18n/locales/de/sections.js +++ b/src/i18n/locales/de/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Seeds", "stecklinge": "Stecklinge", + "konfigurator": "Konfigurator", "oilPress": "Ölpresse ausleihen", "thcTest": "THC Test", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/de/titles.js b/src/i18n/locales/de/titles.js index 1580674..b551200 100644 --- a/src/i18n/locales/de/titles.js +++ b/src/i18n/locales/de/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Fine Cannabis Seeds & Cuttings", + "home": "Fine Cannabis Seeds", "aktionen": "Aktuelle Aktionen & Angebote", "filiale": "Unsere Filiale in Dresden" }; \ No newline at end of file diff --git a/src/i18n/locales/el/sections.js b/src/i18n/locales/el/sections.js index 37b8c6a..7b70ca3 100644 --- a/src/i18n/locales/el/sections.js +++ b/src/i18n/locales/el/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Σπόροι", "stecklinge": "Μοσχεύματα", + "konfigurator": "Διαμορφωτής", "oilPress": "Δανείσου πρέσα λαδιού", "thcTest": "Τεστ THC", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/el/titles.js b/src/i18n/locales/el/titles.js index 37301fe..ced2856 100644 --- a/src/i18n/locales/el/titles.js +++ b/src/i18n/locales/el/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Ποιοτικοί Σπόροι & Μοσχεύματα Κάνναβης", - "aktionen": "Τρέχουσες Προσφορές & Εκπτώσεις", - "filiale": "Το Κατάστημά μας στη Δρέσδη", + "home": "Ποιοτικοί Σπόροι Κάνναβης", + "aktionen": "Τρέχουσες προσφορές & εκπτώσεις", + "filiale": "Το κατάστημά μας στη Δρέσδη" }; diff --git a/src/i18n/locales/en/sections.js b/src/i18n/locales/en/sections.js index 97311d2..c79d2fc 100644 --- a/src/i18n/locales/en/sections.js +++ b/src/i18n/locales/en/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Seeds", // Seeds "stecklinge": "Cuttings", // Stecklinge + "konfigurator": "Configurator", // Konfigurator "oilPress": "Borrow oil press", // Ölpresse ausleihen "thcTest": "THC test", // THC Test "address1": "Trachenberger Straße 14", // Trachenberger Straße 14 diff --git a/src/i18n/locales/en/titles.js b/src/i18n/locales/en/titles.js index ed70f4f..d1e70ec 100644 --- a/src/i18n/locales/en/titles.js +++ b/src/i18n/locales/en/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Fine Cannabis Seeds & Cuttings", // Fine Cannabis Samen & Stecklinge - "aktionen": "Current Promotions & Offers", // Aktuelle Aktionen & Angebote - "filiale": "Our Store in Dresden", // Unsere Filiale in Dresden + "home": "Fine Cannabis Seeds", // Fine Cannabis Seeds + "aktionen": "Current promotions & offers", // Aktuelle Aktionen & Angebote + "filiale": "Our store in Dresden" // Unsere Filiale in Dresden }; diff --git a/src/i18n/locales/es/sections.js b/src/i18n/locales/es/sections.js index 8aa575f..4fbddda 100644 --- a/src/i18n/locales/es/sections.js +++ b/src/i18n/locales/es/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Semillas", "stecklinge": "Esquejes", + "konfigurator": "Configurador", "oilPress": "Pedir prestada prensa de aceite", "thcTest": "Prueba de THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Muéstranos tu foto más hermosa", - "selectSeedRate": "Selecciona semilla, haz clic para valorar", + "selectSeedRate": "Selecciona semilla, haz clic en valorar", "indoorSeason": "Comienza la temporada de interior" }; diff --git a/src/i18n/locales/es/titles.js b/src/i18n/locales/es/titles.js index 338bf3d..7e3e0bf 100644 --- a/src/i18n/locales/es/titles.js +++ b/src/i18n/locales/es/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Semillas y esquejes de cannabis de calidad", + "home": "Semillas de Cannabis de Calidad", "aktionen": "Promociones y ofertas actuales", - "filiale": "Nuestra tienda en Dresden", + "filiale": "Nuestra tienda en Dresden" }; diff --git a/src/i18n/locales/fr/sections.js b/src/i18n/locales/fr/sections.js index 8e1ab16..b1c4328 100644 --- a/src/i18n/locales/fr/sections.js +++ b/src/i18n/locales/fr/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Graines", "stecklinge": "Boutures", - "oilPress": "Emprunter la presse à huile", + "konfigurator": "Configurateur", + "oilPress": "Emprunter une presse à huile", "thcTest": "Test THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Montre-nous ta plus belle photo", "selectSeedRate": "Sélectionne une graine, clique pour noter", - "indoorSeason": "La saison en intérieur commence" + "indoorSeason": "La saison indoor commence" }; diff --git a/src/i18n/locales/fr/titles.js b/src/i18n/locales/fr/titles.js index b1df56b..8438257 100644 --- a/src/i18n/locales/fr/titles.js +++ b/src/i18n/locales/fr/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Graines et boutures de cannabis de qualité", - "aktionen": "Promotions et offres actuelles", - "filiale": "Notre magasin à Dresde", + "home": "Graines de cannabis de qualité", + "aktionen": "Promotions et offres en cours", + "filiale": "Notre magasin à Dresde" }; diff --git a/src/i18n/locales/hr/sections.js b/src/i18n/locales/hr/sections.js index ce583ea..0e65f6e 100644 --- a/src/i18n/locales/hr/sections.js +++ b/src/i18n/locales/hr/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Sjemenke", "stecklinge": "Reznice", + "konfigurator": "Konfigurator", "oilPress": "Posudi prešu za ulje", "thcTest": "THC test", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaži nam svoju najljepšu fotografiju", - "selectSeedRate": "Odaberi sjeme, klikni ocjenu", + "selectSeedRate": "Odaberi sjeme, klikni ocijeni", "indoorSeason": "Počinje sezona uzgoja u zatvorenom" }; diff --git a/src/i18n/locales/hr/titles.js b/src/i18n/locales/hr/titles.js index 03eb15e..3911daa 100644 --- a/src/i18n/locales/hr/titles.js +++ b/src/i18n/locales/hr/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kvalitetne sjemenke i reznice kanabisa", + "home": "Kvalitetne sjemenke kanabisa", "aktionen": "Trenutne promocije i ponude", - "filiale": "Naša trgovina u Dresdenu", + "filiale": "Naša trgovina u Dresdenu" }; diff --git a/src/i18n/locales/hu/sections.js b/src/i18n/locales/hu/sections.js index 6589499..34f2ab5 100644 --- a/src/i18n/locales/hu/sections.js +++ b/src/i18n/locales/hu/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Magok", "stecklinge": "Cserepek", + "konfigurator": "Konfigurátor", "oilPress": "Olajprés kölcsönzése", "thcTest": "THC teszt", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/hu/titles.js b/src/i18n/locales/hu/titles.js index fc57e7f..e86a409 100644 --- a/src/i18n/locales/hu/titles.js +++ b/src/i18n/locales/hu/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Minőségi kannabisz magok és dugványok", - "aktionen": "Aktuális promóciók és ajánlatok", - "filiale": "Üzletünk Drezdában", + "home": "Minőségi kannabisz magok", + "aktionen": "Aktuális akciók és ajánlatok", + "filiale": "Üzletünk Drezdában" }; diff --git a/src/i18n/locales/it/sections.js b/src/i18n/locales/it/sections.js index e183cad..9804f34 100644 --- a/src/i18n/locales/it/sections.js +++ b/src/i18n/locales/it/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Semi", "stecklinge": "Talee", - "oilPress": "Prendere in prestito la pressa per olio", + "konfigurator": "Configuratore", + "oilPress": "Noleggia pressa per olio", "thcTest": "Test THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Mostraci la tua foto più bella", "selectSeedRate": "Seleziona il seme, clicca per valutare", - "indoorSeason": "Inizia la stagione indoor" + "indoorSeason": "La stagione indoor inizia" }; diff --git a/src/i18n/locales/it/titles.js b/src/i18n/locales/it/titles.js index 59822c3..c1f7bdf 100644 --- a/src/i18n/locales/it/titles.js +++ b/src/i18n/locales/it/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Semi e talee di cannabis di alta qualità", + "home": "Semi di Cannabis di Qualità", "aktionen": "Promozioni e offerte attuali", - "filiale": "Il nostro negozio a Dresda", + "filiale": "Il nostro negozio a Dresda" }; diff --git a/src/i18n/locales/pl/sections.js b/src/i18n/locales/pl/sections.js index 65e682a..ef40b25 100644 --- a/src/i18n/locales/pl/sections.js +++ b/src/i18n/locales/pl/sections.js @@ -1,11 +1,13 @@ export default { "seeds": "Nasiona", "stecklinge": "Sadzonki", + "konfigurator": "Konfigurator", "oilPress": "Wypożycz prasę do oleju", "thcTest": "Test THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaż nam swoje najpiękniejsze zdjęcie", "selectSeedRate": "Wybierz nasiono, kliknij ocenę", - "indoorSeason": "Sezon indoor się zaczyna" + "indoorSeason": "Sezon indoorowy się zaczyna", + "locale": "pl" }; diff --git a/src/i18n/locales/pl/titles.js b/src/i18n/locales/pl/titles.js index 2ad0acb..99b6f05 100644 --- a/src/i18n/locales/pl/titles.js +++ b/src/i18n/locales/pl/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Dobre Nasiona i Szczepki Konopi", - "aktionen": "Aktualne Promocje i Oferty", - "filiale": "Nasz Sklep w Dreźnie", + "home": "Dobre nasiona konopi", + "aktionen": "Aktualne promocje i oferty", + "filiale": "Nasz sklep w Dreźnie" }; diff --git a/src/i18n/locales/ro/sections.js b/src/i18n/locales/ro/sections.js index c8c04da..9349d6b 100644 --- a/src/i18n/locales/ro/sections.js +++ b/src/i18n/locales/ro/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Semințe", "stecklinge": "Butășe", + "konfigurator": "Configurator", "oilPress": "Împrumută presa de ulei", "thcTest": "Test THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Arată-ne cea mai frumoasă fotografie a ta", - "selectSeedRate": "Selectează sămânța, apasă pentru evaluare", + "selectSeedRate": "Selectează sămânța, apasă evaluează", "indoorSeason": "Sezonul indoor începe" }; diff --git a/src/i18n/locales/ro/titles.js b/src/i18n/locales/ro/titles.js index 8940662..4223c25 100644 --- a/src/i18n/locales/ro/titles.js +++ b/src/i18n/locales/ro/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Semințe și butași de cannabis de calitate", + "home": "Semințe fine de cannabis", "aktionen": "Promoții și oferte curente", - "filiale": "Magazinul nostru din Dresda", + "filiale": "Magazinul nostru din Dresden" }; diff --git a/src/i18n/locales/ru/sections.js b/src/i18n/locales/ru/sections.js index ca66ba3..c8c1891 100644 --- a/src/i18n/locales/ru/sections.js +++ b/src/i18n/locales/ru/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Семена", "stecklinge": "Черенки", + "konfigurator": "Конфигуратор", "oilPress": "Взять напрокат маслопресс", "thcTest": "Тест на THC", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Покажи нам свою самую красивую фотографию", - "selectSeedRate": "Выберите семя, нажмите оценить", + "selectSeedRate": "Выберите семена, нажмите оценить", "indoorSeason": "Начинается сезон для выращивания в помещении" }; diff --git a/src/i18n/locales/ru/titles.js b/src/i18n/locales/ru/titles.js index d67690f..48270a1 100644 --- a/src/i18n/locales/ru/titles.js +++ b/src/i18n/locales/ru/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Качественные семена и черенки каннабиса", + "home": "Качественные семена каннабиса", "aktionen": "Текущие акции и предложения", - "filiale": "Наш магазин в Дрездене", + "filiale": "Наш магазин в Дрездене" }; diff --git a/src/i18n/locales/sk/sections.js b/src/i18n/locales/sk/sections.js index 57cbbe6..1d85e2d 100644 --- a/src/i18n/locales/sk/sections.js +++ b/src/i18n/locales/sk/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Semienka", "stecklinge": "Rezky", + "konfigurator": "Konfigurátor", "oilPress": "Požičajte si lis na olej", "thcTest": "THC test", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/sk/titles.js b/src/i18n/locales/sk/titles.js index ce6def1..35127fb 100644 --- a/src/i18n/locales/sk/titles.js +++ b/src/i18n/locales/sk/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kvalitné semená a odrezky konope", + "home": "Kvalitné semená konope", "aktionen": "Aktuálne akcie a ponuky", - "filiale": "Naša predajňa v Drážďanoch", + "filiale": "Náš obchod v Drážďanoch" }; diff --git a/src/i18n/locales/sl/sections.js b/src/i18n/locales/sl/sections.js index 2905fbb..934b706 100644 --- a/src/i18n/locales/sl/sections.js +++ b/src/i18n/locales/sl/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Semena", "stecklinge": "Rezalci", - "oilPress": "Izposodi si stiskalnico za olje", + "konfigurator": "Konfigurator", + "oilPress": "Izposodi si stiskalnico olja", "thcTest": "THC test", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", "showUsPhoto": "Pokaži nam svojo najlepšo fotografijo", - "selectSeedRate": "Izberi seme, klikni oceno", + "selectSeedRate": "Izberi seme, klikni oceni", "indoorSeason": "Začne se sezona gojenja v zaprtih prostorih" }; diff --git a/src/i18n/locales/sl/titles.js b/src/i18n/locales/sl/titles.js index 2715800..3abee3f 100644 --- a/src/i18n/locales/sl/titles.js +++ b/src/i18n/locales/sl/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kakovostna semena in reznice konoplje", + "home": "Kakovostna semena konoplje", "aktionen": "Trenutne promocije in ponudbe", - "filiale": "Naša trgovina v Dresdnu", + "filiale": "Naša trgovina v Dresdnu" }; diff --git a/src/i18n/locales/sq/sections.js b/src/i18n/locales/sq/sections.js index 0a62f73..df4aaf8 100644 --- a/src/i18n/locales/sq/sections.js +++ b/src/i18n/locales/sq/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Farëra", "stecklinge": "Përkëmbëza", + "konfigurator": "Konfiguruesi", "oilPress": "Huazo shtypësin e vajit", "thcTest": "Testi THC", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/sq/titles.js b/src/i18n/locales/sq/titles.js index 43cb16b..b09ac32 100644 --- a/src/i18n/locales/sq/titles.js +++ b/src/i18n/locales/sq/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Farëra dhe Gjethe Kanabisi të Kualitetit të Lartë", - "aktionen": "Promocionet dhe Ofertat Aktualë", - "filiale": "Dyqani Ynë në Dresden", + "home": "Farëra të mira kanabisi", + "aktionen": "Promocionet dhe ofertat aktuale", + "filiale": "Dyqani ynë në Dresden" }; diff --git a/src/i18n/locales/sr/sections.js b/src/i18n/locales/sr/sections.js index 6fb4167..57faba5 100644 --- a/src/i18n/locales/sr/sections.js +++ b/src/i18n/locales/sr/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Semena", "stecklinge": "Reznice", + "konfigurator": "Konfigurator", "oilPress": "Pozajmi prešu za ulje", "thcTest": "THC test", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/sr/titles.js b/src/i18n/locales/sr/titles.js index 03c4d58..1d4d1b2 100644 --- a/src/i18n/locales/sr/titles.js +++ b/src/i18n/locales/sr/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kvalitetni seme i reznice kanabisa", + "home": "Kvalitetne semenke kanabisa", "aktionen": "Trenutne promocije i ponude", - "filiale": "Naša prodavnica u Dresdenu", + "filiale": "Naša prodavnica u Dresdenu" }; diff --git a/src/i18n/locales/sv/sections.js b/src/i18n/locales/sv/sections.js index 301999e..744066b 100644 --- a/src/i18n/locales/sv/sections.js +++ b/src/i18n/locales/sv/sections.js @@ -1,11 +1,12 @@ export default { "seeds": "Frön", "stecklinge": "Sticklingar", + "konfigurator": "Konfigurator", "oilPress": "Låna oljepress", "thcTest": "THC-test", "address1": "Trachenberger Straße 14", "address2": "01129 Dresden", - "showUsPhoto": "Visa oss ditt vackraste foto", + "showUsPhoto": "Visa oss din vackraste bild", "selectSeedRate": "Välj frö, klicka betyg", "indoorSeason": "Inomhussäsongen börjar" }; diff --git a/src/i18n/locales/sv/titles.js b/src/i18n/locales/sv/titles.js index f37c3b9..3c3668d 100644 --- a/src/i18n/locales/sv/titles.js +++ b/src/i18n/locales/sv/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Fina cannabisfrön & sticklingar", + "home": "Fina cannabisfrön", "aktionen": "Aktuella kampanjer & erbjudanden", - "filiale": "Vår butik i Dresden", + "filiale": "Vår butik i Dresden" }; diff --git a/src/i18n/locales/tr/sections.js b/src/i18n/locales/tr/sections.js index adbf867..cd076cd 100644 --- a/src/i18n/locales/tr/sections.js +++ b/src/i18n/locales/tr/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Tohumlar", "stecklinge": "Çelikler", + "konfigurator": "Konfigüratör", "oilPress": "Yağ presini ödünç al", "thcTest": "THC testi", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/tr/titles.js b/src/i18n/locales/tr/titles.js index 045598c..6ba3818 100644 --- a/src/i18n/locales/tr/titles.js +++ b/src/i18n/locales/tr/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Kaliteli Kenevir Tohumları ve Çelikleri", - "aktionen": "Güncel Kampanyalar ve Teklifler", - "filiale": "Dresden'deki Mağazamız", + "home": "Kaliteli Kenevir Tohumları", + "aktionen": "Mevcut promosyonlar ve teklifler", + "filiale": "Dresden'deki mağazamız" }; diff --git a/src/i18n/locales/uk/sections.js b/src/i18n/locales/uk/sections.js index fb17e3e..fa2a712 100644 --- a/src/i18n/locales/uk/sections.js +++ b/src/i18n/locales/uk/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "Насіння", "stecklinge": "Живці", + "konfigurator": "Конфігуратор", "oilPress": "Позичити олійний прес", "thcTest": "Тест на THC", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/uk/titles.js b/src/i18n/locales/uk/titles.js index bce4d76..2aaffbc 100644 --- a/src/i18n/locales/uk/titles.js +++ b/src/i18n/locales/uk/titles.js @@ -1,5 +1,5 @@ export default { - "home": "Якісне насіння та живці канабісу", + "home": "Якісне насіння канабісу", "aktionen": "Поточні акції та пропозиції", - "filiale": "Наш магазин у Дрездені", + "filiale": "Наш магазин у Дрездені" }; diff --git a/src/i18n/locales/zh/sections.js b/src/i18n/locales/zh/sections.js index a0f6bbb..f8bc5a1 100644 --- a/src/i18n/locales/zh/sections.js +++ b/src/i18n/locales/zh/sections.js @@ -1,6 +1,7 @@ export default { "seeds": "种子", "stecklinge": "插枝", + "konfigurator": "配置器", "oilPress": "借用榨油机", "thcTest": "THC 测试", "address1": "Trachenberger Straße 14", diff --git a/src/i18n/locales/zh/titles.js b/src/i18n/locales/zh/titles.js index ff7b2a2..1aed13e 100644 --- a/src/i18n/locales/zh/titles.js +++ b/src/i18n/locales/zh/titles.js @@ -1,5 +1,5 @@ export default { - "home": "优质大麻种子和插枝", + "home": "优质大麻种子", "aktionen": "当前促销与优惠", - "filiale": "我们在德累斯顿的门店", + "filiale": "我们在德累斯顿的门店" };