feat: Refine i18n content across multiple locales and improve LLM SEO data processing for catalog generation.
This commit is contained in:
@@ -158,7 +158,7 @@ This file contains products ${startIndex + 1}-${endIndex} of ${totalProducts} in
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
for (let i = 1; i <= totalPages; i++) {
|
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)})
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ const generateCategoryProductList = (category, categoryProducts = []) => {
|
|||||||
const fileName = `llms-${categorySlug}-list.txt`;
|
const fileName = `llms-${categorySlug}-list.txt`;
|
||||||
|
|
||||||
const subcategoryIds = (category.subcategories || []).join(',');
|
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) => {
|
categoryProducts.forEach((product) => {
|
||||||
const artnr = String(product.articleNumber || '');
|
const artnr = String(product.articleNumber || '');
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
// Read the input file
|
// Read the input file from public
|
||||||
const inputFile = path.join(__dirname, 'dist', 'llms-cat.txt');
|
const inputFile = path.join(__dirname, 'public', 'llms-cat.txt');
|
||||||
const outputFile = path.join(__dirname, 'output.csv');
|
// 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 to parse a CSV line with escaped quotes
|
||||||
function parseCSVLine(line) {
|
function parseCSVLine(line) {
|
||||||
@@ -38,44 +39,65 @@ function parseCSVLine(line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!fs.existsSync(inputFile)) {
|
||||||
|
throw new Error(`Input file not found: ${inputFile}`);
|
||||||
|
}
|
||||||
|
|
||||||
const data = fs.readFileSync(inputFile, 'utf8');
|
const data = fs.readFileSync(inputFile, 'utf8');
|
||||||
const lines = data.trim().split('\n');
|
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;
|
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
|
// Parse the CSV line properly handling escaped quotes
|
||||||
const fields = parseCSVLine(line);
|
const fields = parseCSVLine(line);
|
||||||
|
|
||||||
if (fields.length !== 3) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [field1, field2, field3] = fields;
|
// Input: categoryId, listFileName, seoDescription
|
||||||
const url = field2;
|
// Output: URL, SEO Description
|
||||||
|
const [categoryId, listFileName, seoDescription] = fields;
|
||||||
|
|
||||||
// field3 is a JSON string - parse it directly
|
// Use listFileName as URL
|
||||||
let seoDescription = '';
|
const url = listFileName;
|
||||||
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)}...`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape quotes for CSV output - URL doesn't need quotes, description does
|
// Use seoDescription as description directly (it's already a string)
|
||||||
const escapedDescription = '"' + seoDescription.replace(/"/g, '""') + '"';
|
const description = seoDescription;
|
||||||
|
|
||||||
|
// Escape quotes for CSV output
|
||||||
|
const escapedDescription = '"' + description.replace(/"/g, '""') + '"';
|
||||||
|
|
||||||
outputLines.push(`${url},${escapedDescription}`);
|
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
|
// Write the output CSV
|
||||||
fs.writeFileSync(outputFile, outputLines.join('\n'), 'utf8');
|
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) {
|
} catch (error) {
|
||||||
console.error('Error processing file:', error.message);
|
console.error('Error processing file:', error.message);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
this file has the list of category overview lists, where you can find article numbers
|
||||||
|
|
||||||
categoryId,listFileName,seoDescription
|
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²."
|
"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."
|
"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."
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
|
|
||||||
const uniqueAttributes = [...new Set((attributes || []).map(attr => attr.kMerkmalWert ? attr.kMerkmalWert.toString() : ''))];
|
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 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 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 = {};
|
const attributeFiltersByGroup = {};
|
||||||
@@ -98,7 +98,7 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
|
|
||||||
let filteredProducts = (unfilteredProducts || []).filter(product => {
|
let filteredProducts = (unfilteredProducts || []).filter(product => {
|
||||||
const availabilityFilter = sessionStorage.getItem('filter_availability');
|
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
|
// Check if there are any new products in the entire set
|
||||||
const hasNewProducts = (unfilteredProducts || []).some(product => isNew(product.neu));
|
const hasNewProducts = (unfilteredProducts || []).some(product => isNew(product.neu));
|
||||||
@@ -107,8 +107,8 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
const isNewMatch = availabilityFilters.includes('2') && hasNewProducts ? isNew(product.neu) : true;
|
const isNewMatch = availabilityFilters.includes('2') && hasNewProducts ? isNew(product.neu) : true;
|
||||||
let soonMatch = availabilityFilters.includes('3') ? !product.available && product.incoming : 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;
|
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))){
|
if ((availabilityFilter != 1) && availabilityFilters.includes('3') && ((product.available) || (!product.available && product.incoming))) {
|
||||||
inStockMatch = true;
|
inStockMatch = true;
|
||||||
soonMatch = true;
|
soonMatch = true;
|
||||||
console.log("soon2Match", product.cName);
|
console.log("soon2Match", product.cName);
|
||||||
@@ -134,11 +134,11 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
|
|
||||||
const activeAttributeFiltersWithNames = activeAttributeFilters.map(filter => {
|
const activeAttributeFiltersWithNames = activeAttributeFilters.map(filter => {
|
||||||
const attribute = attributes.find(attr => attr.kMerkmalWert.toString() === 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 activeManufacturerFiltersWithNames = activeManufacturerFilters.map(filter => {
|
||||||
const manufacturer = uniqueManufacturersWithName.find(manufacturer => manufacturer.id === 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
|
// Extract active availability filters
|
||||||
@@ -151,20 +151,20 @@ function getFilteredProducts(unfilteredProducts, attributes, t) {
|
|||||||
|
|
||||||
// Check for "auf Lager" filter (in stock) - it's active when filter_availability is NOT set to '1'
|
// Check for "auf Lager" filter (in stock) - it's active when filter_availability is NOT set to '1'
|
||||||
if (availabilityFilter !== '1') {
|
if (availabilityFilter !== '1') {
|
||||||
activeAvailabilityFilters.push({id: '1', name: t ? t('product.inStock') : 'auf Lager'});
|
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
|
// Check for "Neu" filter (new) - only show if there are actually new products and filter is active
|
||||||
if (availabilityFilters.includes('2') && hasNewProducts) {
|
if (availabilityFilters.includes('2') && hasNewProducts) {
|
||||||
activeAvailabilityFilters.push({id: '2', name: t ? t('product.new') : 'Neu'});
|
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
|
// 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) {
|
if (availabilityFilters.includes('3') && hasComingSoonProducts) {
|
||||||
activeAvailabilityFilters.push({id: '3', name: t ? t('product.comingSoon') : 'Bald verfügbar'});
|
activeAvailabilityFilters.push({ id: '3', name: t ? t('product.comingSoon') : 'Bald verfügbar' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return {filteredProducts,activeAttributeFilters:activeAttributeFiltersWithNames,activeManufacturerFilters:activeManufacturerFiltersWithNames,activeAvailabilityFilters};
|
return { filteredProducts, activeAttributeFilters: activeAttributeFiltersWithNames, activeManufacturerFilters: activeManufacturerFiltersWithNames, activeAvailabilityFilters };
|
||||||
}
|
}
|
||||||
function setCachedCategoryData(categoryId, data, language = 'de') {
|
function setCachedCategoryData(categoryId, data, language = 'de') {
|
||||||
if (!window.productCache) {
|
if (!window.productCache) {
|
||||||
@@ -176,7 +176,7 @@ function setCachedCategoryData(categoryId, data, language = 'de') {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = `categoryProducts_${categoryId}_${language}`;
|
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}`;
|
const productCacheKey = `product_${product.id}_${language}`;
|
||||||
window.productDetailCache[productCacheKey] = product;
|
window.productDetailCache[productCacheKey] = product;
|
||||||
}
|
}
|
||||||
@@ -206,11 +206,13 @@ class Content extends Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const currentLanguage = this.props.i18n?.language || 'de';
|
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);
|
this.fetchCategoryData(this.props.params.categoryId);
|
||||||
})}
|
})
|
||||||
|
}
|
||||||
else if (this.props.searchParams?.get('q')) {
|
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'));
|
this.fetchSearchData(this.props.searchParams?.get('q'));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -221,20 +223,20 @@ class Content extends Component {
|
|||||||
const categoryChanged = this.props.params.categoryId && (prevProps.params.categoryId !== this.props.params.categoryId);
|
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'));
|
const searchChanged = this.props.searchParams?.get('q') && (prevProps.searchParams?.get('q') !== this.props.searchParams?.get('q'));
|
||||||
|
|
||||||
if(categoryChanged) {
|
if (categoryChanged) {
|
||||||
// Clear context for new category loading
|
// Clear context for new category loading
|
||||||
if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) {
|
if (this.props.categoryContext && this.props.categoryContext.setCurrentCategory) {
|
||||||
this.props.categoryContext.setCurrentCategory(null);
|
this.props.categoryContext.setCurrentCategory(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.currentSearchQuery = null;
|
window.currentSearchQuery = null;
|
||||||
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.fetchCategoryData(this.props.params.categoryId);
|
this.fetchCategoryData(this.props.params.categoryId);
|
||||||
});
|
});
|
||||||
return; // Don't check language change if category changed
|
return; // Don't check language change if category changed
|
||||||
}
|
}
|
||||||
else if (searchChanged) {
|
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'));
|
this.fetchSearchData(this.props.searchParams?.get('q'));
|
||||||
});
|
});
|
||||||
return; // Don't check language change if search changed
|
return; // Don't check language change if search changed
|
||||||
@@ -253,26 +255,26 @@ class Content extends Component {
|
|||||||
hasSearchQuery: !!this.props.searchParams?.get('q')
|
hasSearchQuery: !!this.props.searchParams?.get('q')
|
||||||
});
|
});
|
||||||
|
|
||||||
if(languageChanged) {
|
if (languageChanged) {
|
||||||
console.log('Content: Language changed! Re-fetching data...');
|
console.log('Content: Language changed! Re-fetching data...');
|
||||||
// Re-fetch current data with new language
|
// Re-fetch current data with new language
|
||||||
// Note: Language is now part of the cache key, so it will automatically fetch fresh data
|
// 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
|
// Re-fetch category data with new language
|
||||||
console.log('Content: Re-fetching category', this.props.params.categoryId);
|
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);
|
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
|
// Re-fetch search data with new language
|
||||||
console.log('Content: Re-fetching search', this.props.searchParams?.get('q'));
|
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'));
|
this.fetchSearchData(this.props.searchParams?.get('q'));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// If not viewing category or search, just re-filter existing products
|
// If not viewing category or search, just re-filter existing products
|
||||||
console.log('Content: Just re-filtering existing products');
|
console.log('Content: Just re-filtering existing products');
|
||||||
this.setState({lastFetchedLanguage: currentLanguage});
|
this.setState({ lastFetchedLanguage: currentLanguage });
|
||||||
this.filterProducts();
|
this.filterProducts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +291,7 @@ class Content extends Component {
|
|||||||
const unfilteredProducts = [];
|
const unfilteredProducts = [];
|
||||||
|
|
||||||
//console.log("processData", rawProducts);
|
//console.log("processData", rawProducts);
|
||||||
if(rawProducts) rawProducts.forEach(product => {
|
if (rawProducts) rawProducts.forEach(product => {
|
||||||
const effectiveProduct = product.translatedProduct || product;
|
const effectiveProduct = product.translatedProduct || product;
|
||||||
const cacheKey = `${effectiveProduct.id}_${currentLanguage}`;
|
const cacheKey = `${effectiveProduct.id}_${currentLanguage}`;
|
||||||
|
|
||||||
@@ -352,7 +354,7 @@ class Content extends Component {
|
|||||||
// Track if we've received the full response to ignore stub response if needed
|
// Track if we've received the full response to ignore stub response if needed
|
||||||
let receivedFullResponse = false;
|
let receivedFullResponse = false;
|
||||||
|
|
||||||
window.socketManager.on(`productList:${categoryId}`,(response) => {
|
window.socketManager.on(`productList:${categoryId}`, (response) => {
|
||||||
console.log("getCategoryProducts full response", response);
|
console.log("getCategoryProducts full response", response);
|
||||||
receivedFullResponse = true;
|
receivedFullResponse = true;
|
||||||
setCachedCategoryData(categoryId, response, currentLanguage);
|
setCachedCategoryData(categoryId, response, currentLanguage);
|
||||||
@@ -588,7 +590,7 @@ class Content extends Component {
|
|||||||
return (
|
return (
|
||||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, flexWrap: 'wrap' }}>
|
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, flexWrap: 'wrap' }}>
|
||||||
{/* Parent Category Box */}
|
{/* Parent Category Box */}
|
||||||
<Box sx={{ mt:2,position: 'relative', flexShrink: 0 }}>
|
<Box sx={{ mt: 2, position: 'relative', flexShrink: 0 }}>
|
||||||
<CategoryBox
|
<CategoryBox
|
||||||
id={parentCategory.id}
|
id={parentCategory.id}
|
||||||
seoName={parentCategory.seoName}
|
seoName={parentCategory.seoName}
|
||||||
@@ -691,16 +693,16 @@ class Content extends Component {
|
|||||||
filteredProducts={this.state.filteredProducts}
|
filteredProducts={this.state.filteredProducts}
|
||||||
attributes={this.state.attributes}
|
attributes={this.state.attributes}
|
||||||
searchParams={this.props.searchParams}
|
searchParams={this.props.searchParams}
|
||||||
onFilterChange={()=>{this.filterProducts()}}
|
onFilterChange={() => { this.filterProducts() }}
|
||||||
dataType={this.state.dataType}
|
dataType={this.state.dataType}
|
||||||
dataParam={this.state.dataParam}
|
dataParam={this.state.dataParam}
|
||||||
categoryName={this.state.categoryName}
|
categoryName={this.state.categoryName}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{(this.props.params.categoryId == 'Stecklinge' || this.props.params.categoryId == 'Seeds') &&
|
{(this.props.params.categoryId == 'Stecklinge___' || this.props.params.categoryId == 'Seeds___') &&
|
||||||
<Box sx={{ display: { xs: 'none', sm: 'block' } }}>
|
<Box sx={{ display: { xs: 'none', sm: 'block' } }}>
|
||||||
<Typography variant="h6" sx={{mt:3}}>
|
<Typography variant="h6" sx={{ mt: 3 }}>
|
||||||
{this.props.t ? this.props.t('navigation.otherCategories') : 'Andere Kategorien'}
|
{this.props.t ? this.props.t('navigation.otherCategories') : 'Andere Kategorien'}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -710,7 +712,7 @@ class Content extends Component {
|
|||||||
component={Link}
|
component={Link}
|
||||||
to="/Kategorie/Seeds"
|
to="/Kategorie/Seeds"
|
||||||
sx={{
|
sx={{
|
||||||
p:0,
|
p: 0,
|
||||||
mt: 1,
|
mt: 1,
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
color: 'text.primary',
|
color: 'text.primary',
|
||||||
@@ -767,7 +769,7 @@ class Content extends Component {
|
|||||||
</Paper>
|
</Paper>
|
||||||
}
|
}
|
||||||
|
|
||||||
{this.props.params.categoryId == 'Seeds' && <Paper
|
{this.props.params.categoryId == 'Seeds___' && <Paper
|
||||||
component={Link}
|
component={Link}
|
||||||
to="/Kategorie/Stecklinge"
|
to="/Kategorie/Stecklinge"
|
||||||
sx={{
|
sx={{
|
||||||
@@ -835,7 +837,7 @@ class Content extends Component {
|
|||||||
activeAttributeFilters={this.state.activeAttributeFilters || []}
|
activeAttributeFilters={this.state.activeAttributeFilters || []}
|
||||||
activeManufacturerFilters={this.state.activeManufacturerFilters || []}
|
activeManufacturerFilters={this.state.activeManufacturerFilters || []}
|
||||||
activeAvailabilityFilters={this.state.activeAvailabilityFilters || []}
|
activeAvailabilityFilters={this.state.activeAvailabilityFilters || []}
|
||||||
onFilterChange={()=>{this.filterProducts()}}
|
onFilterChange={() => { this.filterProducts() }}
|
||||||
dataType={this.state.dataType}
|
dataType={this.state.dataType}
|
||||||
dataParam={this.state.dataParam}
|
dataParam={this.state.dataParam}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ const MainPageLayout = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const allTitles = {
|
const allTitles = {
|
||||||
home: t('titles.home') ,
|
home: t('titles.home'),
|
||||||
aktionen: t('titles.aktionen'),
|
aktionen: t('titles.aktionen'),
|
||||||
filiale: t('titles.filiale')
|
filiale: t('titles.filiale')
|
||||||
};
|
};
|
||||||
@@ -164,7 +164,7 @@ const MainPageLayout = () => {
|
|||||||
const allContentBoxes = {
|
const allContentBoxes = {
|
||||||
home: [
|
home: [
|
||||||
{ title: t('sections.seeds'), image: "/assets/images/seeds.avif", bgcolor: "#e1f0d3", link: "/Kategorie/Seeds" },
|
{ 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: [
|
aktionen: [
|
||||||
{ title: t('sections.oilPress'), image: "/assets/images/presse.jpg", bgcolor: "#e1f0d3", link: "/presseverleih" },
|
{ title: t('sections.oilPress'), image: "/assets/images/presse.jpg", bgcolor: "#e1f0d3", link: "/presseverleih" },
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "بذور",
|
"seeds": "بذور",
|
||||||
"stecklinge": "قصاصات",
|
"stecklinge": "قصاصات",
|
||||||
"oilPress": "استعارة معصرة الزيت",
|
"konfigurator": "المُكوّن",
|
||||||
|
"oilPress": "استعارة مكبس الزيت",
|
||||||
"thcTest": "اختبار THC",
|
"thcTest": "اختبار THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "شارع تراشينبرجر 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 دريسدن",
|
||||||
"showUsPhoto": "ورينا أجمل صورة عندك",
|
"showUsPhoto": "اعرض لنا أجمل صورة لديك",
|
||||||
"selectSeedRate": "اختار البذرة واضغط تقييم",
|
"selectSeedRate": "اختر البذرة، واضغط للتقييم",
|
||||||
"indoorSeason": "موسم الزراعة الداخلية بدأ"
|
"indoorSeason": "بدأ موسم الزراعة الداخلية"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "بذور وقصاصات القنب الممتازة",
|
"home": "بذور القنب الممتازة",
|
||||||
"aktionen": "العروض والتخفيضات الحالية",
|
"aktionen": "العروض والتخفيضات الحالية",
|
||||||
"filiale": "متجرنا في دريسدن",
|
"filiale": "متجرنا في دريسدن"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Семена",
|
"seeds": "Семена",
|
||||||
"stecklinge": "Резници",
|
"stecklinge": "Резници",
|
||||||
"oilPress": "Наеми преса за масло",
|
"konfigurator": "Конфигуратор",
|
||||||
|
"oilPress": "Наеми преса за олио",
|
||||||
"thcTest": "THC тест",
|
"thcTest": "THC тест",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Фини семена и резници от канабис",
|
"home": "Качествени канабис семена",
|
||||||
"aktionen": "Текущи промоции и оферти",
|
"aktionen": "Текущи промоции и оферти",
|
||||||
"filiale": "Нашият магазин в Дрезден",
|
"filiale": "Нашият магазин в Дрезден"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semena",
|
"seeds": "Semena",
|
||||||
"stecklinge": "Řízky",
|
"stecklinge": "Řízky",
|
||||||
|
"konfigurator": "Konfigurátor",
|
||||||
"oilPress": "Půjčit lis na olej",
|
"oilPress": "Půjčit lis na olej",
|
||||||
"thcTest": "THC test",
|
"thcTest": "THC test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kvalitní semena a řízky konopí",
|
"home": "Kvalitní semena konopí",
|
||||||
"aktionen": "Aktuální akce a nabídky",
|
"aktionen": "Aktuální akce a nabídky",
|
||||||
"filiale": "Naše prodejna v Drážďanech",
|
"filiale": "Naše prodejna v Drážďanech"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Seeds",
|
"seeds": "Seeds",
|
||||||
"stecklinge": "Stecklinge",
|
"stecklinge": "Stecklinge",
|
||||||
|
"konfigurator": "Konfigurator",
|
||||||
"oilPress": "Ölpresse ausleihen",
|
"oilPress": "Ölpresse ausleihen",
|
||||||
"thcTest": "THC Test",
|
"thcTest": "THC Test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Fine Cannabis Seeds & Cuttings",
|
"home": "Fine Cannabis Seeds",
|
||||||
"aktionen": "Aktuelle Aktionen & Angebote",
|
"aktionen": "Aktuelle Aktionen & Angebote",
|
||||||
"filiale": "Unsere Filiale in Dresden"
|
"filiale": "Unsere Filiale in Dresden"
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Σπόροι",
|
"seeds": "Σπόροι",
|
||||||
"stecklinge": "Μοσχεύματα",
|
"stecklinge": "Μοσχεύματα",
|
||||||
|
"konfigurator": "Διαμορφωτής",
|
||||||
"oilPress": "Δανείσου πρέσα λαδιού",
|
"oilPress": "Δανείσου πρέσα λαδιού",
|
||||||
"thcTest": "Τεστ THC",
|
"thcTest": "Τεστ THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Ποιοτικοί Σπόροι & Μοσχεύματα Κάνναβης",
|
"home": "Ποιοτικοί Σπόροι Κάνναβης",
|
||||||
"aktionen": "Τρέχουσες Προσφορές & Εκπτώσεις",
|
"aktionen": "Τρέχουσες προσφορές & εκπτώσεις",
|
||||||
"filiale": "Το Κατάστημά μας στη Δρέσδη",
|
"filiale": "Το κατάστημά μας στη Δρέσδη"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Seeds", // Seeds
|
"seeds": "Seeds", // Seeds
|
||||||
"stecklinge": "Cuttings", // Stecklinge
|
"stecklinge": "Cuttings", // Stecklinge
|
||||||
|
"konfigurator": "Configurator", // Konfigurator
|
||||||
"oilPress": "Borrow oil press", // Ölpresse ausleihen
|
"oilPress": "Borrow oil press", // Ölpresse ausleihen
|
||||||
"thcTest": "THC test", // THC Test
|
"thcTest": "THC test", // THC Test
|
||||||
"address1": "Trachenberger Straße 14", // Trachenberger Straße 14
|
"address1": "Trachenberger Straße 14", // Trachenberger Straße 14
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Fine Cannabis Seeds & Cuttings", // Fine Cannabis Samen & Stecklinge
|
"home": "Fine Cannabis Seeds", // Fine Cannabis Seeds
|
||||||
"aktionen": "Current Promotions & Offers", // Aktuelle Aktionen & Angebote
|
"aktionen": "Current promotions & offers", // Aktuelle Aktionen & Angebote
|
||||||
"filiale": "Our Store in Dresden", // Unsere Filiale in Dresden
|
"filiale": "Our store in Dresden" // Unsere Filiale in Dresden
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semillas",
|
"seeds": "Semillas",
|
||||||
"stecklinge": "Esquejes",
|
"stecklinge": "Esquejes",
|
||||||
|
"konfigurator": "Configurador",
|
||||||
"oilPress": "Pedir prestada prensa de aceite",
|
"oilPress": "Pedir prestada prensa de aceite",
|
||||||
"thcTest": "Prueba de THC",
|
"thcTest": "Prueba de THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Muéstranos tu foto más hermosa",
|
"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"
|
"indoorSeason": "Comienza la temporada de interior"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Semillas y esquejes de cannabis de calidad",
|
"home": "Semillas de Cannabis de Calidad",
|
||||||
"aktionen": "Promociones y ofertas actuales",
|
"aktionen": "Promociones y ofertas actuales",
|
||||||
"filiale": "Nuestra tienda en Dresden",
|
"filiale": "Nuestra tienda en Dresden"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Graines",
|
"seeds": "Graines",
|
||||||
"stecklinge": "Boutures",
|
"stecklinge": "Boutures",
|
||||||
"oilPress": "Emprunter la presse à huile",
|
"konfigurator": "Configurateur",
|
||||||
|
"oilPress": "Emprunter une presse à huile",
|
||||||
"thcTest": "Test THC",
|
"thcTest": "Test THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Montre-nous ta plus belle photo",
|
"showUsPhoto": "Montre-nous ta plus belle photo",
|
||||||
"selectSeedRate": "Sélectionne une graine, clique pour noter",
|
"selectSeedRate": "Sélectionne une graine, clique pour noter",
|
||||||
"indoorSeason": "La saison en intérieur commence"
|
"indoorSeason": "La saison indoor commence"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Graines et boutures de cannabis de qualité",
|
"home": "Graines de cannabis de qualité",
|
||||||
"aktionen": "Promotions et offres actuelles",
|
"aktionen": "Promotions et offres en cours",
|
||||||
"filiale": "Notre magasin à Dresde",
|
"filiale": "Notre magasin à Dresde"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Sjemenke",
|
"seeds": "Sjemenke",
|
||||||
"stecklinge": "Reznice",
|
"stecklinge": "Reznice",
|
||||||
|
"konfigurator": "Konfigurator",
|
||||||
"oilPress": "Posudi prešu za ulje",
|
"oilPress": "Posudi prešu za ulje",
|
||||||
"thcTest": "THC test",
|
"thcTest": "THC test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Pokaži nam svoju najljepšu fotografiju",
|
"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"
|
"indoorSeason": "Počinje sezona uzgoja u zatvorenom"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kvalitetne sjemenke i reznice kanabisa",
|
"home": "Kvalitetne sjemenke kanabisa",
|
||||||
"aktionen": "Trenutne promocije i ponude",
|
"aktionen": "Trenutne promocije i ponude",
|
||||||
"filiale": "Naša trgovina u Dresdenu",
|
"filiale": "Naša trgovina u Dresdenu"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Magok",
|
"seeds": "Magok",
|
||||||
"stecklinge": "Cserepek",
|
"stecklinge": "Cserepek",
|
||||||
|
"konfigurator": "Konfigurátor",
|
||||||
"oilPress": "Olajprés kölcsönzése",
|
"oilPress": "Olajprés kölcsönzése",
|
||||||
"thcTest": "THC teszt",
|
"thcTest": "THC teszt",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Minőségi kannabisz magok és dugványok",
|
"home": "Minőségi kannabisz magok",
|
||||||
"aktionen": "Aktuális promóciók és ajánlatok",
|
"aktionen": "Aktuális akciók és ajánlatok",
|
||||||
"filiale": "Üzletünk Drezdában",
|
"filiale": "Üzletünk Drezdában"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semi",
|
"seeds": "Semi",
|
||||||
"stecklinge": "Talee",
|
"stecklinge": "Talee",
|
||||||
"oilPress": "Prendere in prestito la pressa per olio",
|
"konfigurator": "Configuratore",
|
||||||
|
"oilPress": "Noleggia pressa per olio",
|
||||||
"thcTest": "Test THC",
|
"thcTest": "Test THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Mostraci la tua foto più bella",
|
"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"
|
"indoorSeason": "La stagione indoor inizia"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Semi e talee di cannabis di alta qualità",
|
"home": "Semi di Cannabis di Qualità",
|
||||||
"aktionen": "Promozioni e offerte attuali",
|
"aktionen": "Promozioni e offerte attuali",
|
||||||
"filiale": "Il nostro negozio a Dresda",
|
"filiale": "Il nostro negozio a Dresda"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Nasiona",
|
"seeds": "Nasiona",
|
||||||
"stecklinge": "Sadzonki",
|
"stecklinge": "Sadzonki",
|
||||||
|
"konfigurator": "Konfigurator",
|
||||||
"oilPress": "Wypożycz prasę do oleju",
|
"oilPress": "Wypożycz prasę do oleju",
|
||||||
"thcTest": "Test THC",
|
"thcTest": "Test THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Pokaż nam swoje najpiękniejsze zdjęcie",
|
"showUsPhoto": "Pokaż nam swoje najpiękniejsze zdjęcie",
|
||||||
"selectSeedRate": "Wybierz nasiono, kliknij ocenę",
|
"selectSeedRate": "Wybierz nasiono, kliknij ocenę",
|
||||||
"indoorSeason": "Sezon indoor się zaczyna"
|
"indoorSeason": "Sezon indoorowy się zaczyna",
|
||||||
|
"locale": "pl"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Dobre Nasiona i Szczepki Konopi",
|
"home": "Dobre nasiona konopi",
|
||||||
"aktionen": "Aktualne Promocje i Oferty",
|
"aktionen": "Aktualne promocje i oferty",
|
||||||
"filiale": "Nasz Sklep w Dreźnie",
|
"filiale": "Nasz sklep w Dreźnie"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semințe",
|
"seeds": "Semințe",
|
||||||
"stecklinge": "Butășe",
|
"stecklinge": "Butășe",
|
||||||
|
"konfigurator": "Configurator",
|
||||||
"oilPress": "Împrumută presa de ulei",
|
"oilPress": "Împrumută presa de ulei",
|
||||||
"thcTest": "Test THC",
|
"thcTest": "Test THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Arată-ne cea mai frumoasă fotografie a ta",
|
"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"
|
"indoorSeason": "Sezonul indoor începe"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Semințe și butași de cannabis de calitate",
|
"home": "Semințe fine de cannabis",
|
||||||
"aktionen": "Promoții și oferte curente",
|
"aktionen": "Promoții și oferte curente",
|
||||||
"filiale": "Magazinul nostru din Dresda",
|
"filiale": "Magazinul nostru din Dresden"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Семена",
|
"seeds": "Семена",
|
||||||
"stecklinge": "Черенки",
|
"stecklinge": "Черенки",
|
||||||
|
"konfigurator": "Конфигуратор",
|
||||||
"oilPress": "Взять напрокат маслопресс",
|
"oilPress": "Взять напрокат маслопресс",
|
||||||
"thcTest": "Тест на THC",
|
"thcTest": "Тест на THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Покажи нам свою самую красивую фотографию",
|
"showUsPhoto": "Покажи нам свою самую красивую фотографию",
|
||||||
"selectSeedRate": "Выберите семя, нажмите оценить",
|
"selectSeedRate": "Выберите семена, нажмите оценить",
|
||||||
"indoorSeason": "Начинается сезон для выращивания в помещении"
|
"indoorSeason": "Начинается сезон для выращивания в помещении"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Качественные семена и черенки каннабиса",
|
"home": "Качественные семена каннабиса",
|
||||||
"aktionen": "Текущие акции и предложения",
|
"aktionen": "Текущие акции и предложения",
|
||||||
"filiale": "Наш магазин в Дрездене",
|
"filiale": "Наш магазин в Дрездене"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semienka",
|
"seeds": "Semienka",
|
||||||
"stecklinge": "Rezky",
|
"stecklinge": "Rezky",
|
||||||
|
"konfigurator": "Konfigurátor",
|
||||||
"oilPress": "Požičajte si lis na olej",
|
"oilPress": "Požičajte si lis na olej",
|
||||||
"thcTest": "THC test",
|
"thcTest": "THC test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kvalitné semená a odrezky konope",
|
"home": "Kvalitné semená konope",
|
||||||
"aktionen": "Aktuálne akcie a ponuky",
|
"aktionen": "Aktuálne akcie a ponuky",
|
||||||
"filiale": "Naša predajňa v Drážďanoch",
|
"filiale": "Náš obchod v Drážďanoch"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semena",
|
"seeds": "Semena",
|
||||||
"stecklinge": "Rezalci",
|
"stecklinge": "Rezalci",
|
||||||
"oilPress": "Izposodi si stiskalnico za olje",
|
"konfigurator": "Konfigurator",
|
||||||
|
"oilPress": "Izposodi si stiskalnico olja",
|
||||||
"thcTest": "THC test",
|
"thcTest": "THC test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Pokaži nam svojo najlepšo fotografijo",
|
"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"
|
"indoorSeason": "Začne se sezona gojenja v zaprtih prostorih"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kakovostna semena in reznice konoplje",
|
"home": "Kakovostna semena konoplje",
|
||||||
"aktionen": "Trenutne promocije in ponudbe",
|
"aktionen": "Trenutne promocije in ponudbe",
|
||||||
"filiale": "Naša trgovina v Dresdnu",
|
"filiale": "Naša trgovina v Dresdnu"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Farëra",
|
"seeds": "Farëra",
|
||||||
"stecklinge": "Përkëmbëza",
|
"stecklinge": "Përkëmbëza",
|
||||||
|
"konfigurator": "Konfiguruesi",
|
||||||
"oilPress": "Huazo shtypësin e vajit",
|
"oilPress": "Huazo shtypësin e vajit",
|
||||||
"thcTest": "Testi THC",
|
"thcTest": "Testi THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Farëra dhe Gjethe Kanabisi të Kualitetit të Lartë",
|
"home": "Farëra të mira kanabisi",
|
||||||
"aktionen": "Promocionet dhe Ofertat Aktualë",
|
"aktionen": "Promocionet dhe ofertat aktuale",
|
||||||
"filiale": "Dyqani Ynë në Dresden",
|
"filiale": "Dyqani ynë në Dresden"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Semena",
|
"seeds": "Semena",
|
||||||
"stecklinge": "Reznice",
|
"stecklinge": "Reznice",
|
||||||
|
"konfigurator": "Konfigurator",
|
||||||
"oilPress": "Pozajmi prešu za ulje",
|
"oilPress": "Pozajmi prešu za ulje",
|
||||||
"thcTest": "THC test",
|
"thcTest": "THC test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kvalitetni seme i reznice kanabisa",
|
"home": "Kvalitetne semenke kanabisa",
|
||||||
"aktionen": "Trenutne promocije i ponude",
|
"aktionen": "Trenutne promocije i ponude",
|
||||||
"filiale": "Naša prodavnica u Dresdenu",
|
"filiale": "Naša prodavnica u Dresdenu"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Frön",
|
"seeds": "Frön",
|
||||||
"stecklinge": "Sticklingar",
|
"stecklinge": "Sticklingar",
|
||||||
|
"konfigurator": "Konfigurator",
|
||||||
"oilPress": "Låna oljepress",
|
"oilPress": "Låna oljepress",
|
||||||
"thcTest": "THC-test",
|
"thcTest": "THC-test",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
"address2": "01129 Dresden",
|
"address2": "01129 Dresden",
|
||||||
"showUsPhoto": "Visa oss ditt vackraste foto",
|
"showUsPhoto": "Visa oss din vackraste bild",
|
||||||
"selectSeedRate": "Välj frö, klicka betyg",
|
"selectSeedRate": "Välj frö, klicka betyg",
|
||||||
"indoorSeason": "Inomhussäsongen börjar"
|
"indoorSeason": "Inomhussäsongen börjar"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Fina cannabisfrön & sticklingar",
|
"home": "Fina cannabisfrön",
|
||||||
"aktionen": "Aktuella kampanjer & erbjudanden",
|
"aktionen": "Aktuella kampanjer & erbjudanden",
|
||||||
"filiale": "Vår butik i Dresden",
|
"filiale": "Vår butik i Dresden"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Tohumlar",
|
"seeds": "Tohumlar",
|
||||||
"stecklinge": "Çelikler",
|
"stecklinge": "Çelikler",
|
||||||
|
"konfigurator": "Konfigüratör",
|
||||||
"oilPress": "Yağ presini ödünç al",
|
"oilPress": "Yağ presini ödünç al",
|
||||||
"thcTest": "THC testi",
|
"thcTest": "THC testi",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Kaliteli Kenevir Tohumları ve Çelikleri",
|
"home": "Kaliteli Kenevir Tohumları",
|
||||||
"aktionen": "Güncel Kampanyalar ve Teklifler",
|
"aktionen": "Mevcut promosyonlar ve teklifler",
|
||||||
"filiale": "Dresden'deki Mağazamız",
|
"filiale": "Dresden'deki mağazamız"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "Насіння",
|
"seeds": "Насіння",
|
||||||
"stecklinge": "Живці",
|
"stecklinge": "Живці",
|
||||||
|
"konfigurator": "Конфігуратор",
|
||||||
"oilPress": "Позичити олійний прес",
|
"oilPress": "Позичити олійний прес",
|
||||||
"thcTest": "Тест на THC",
|
"thcTest": "Тест на THC",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "Якісне насіння та живці канабісу",
|
"home": "Якісне насіння канабісу",
|
||||||
"aktionen": "Поточні акції та пропозиції",
|
"aktionen": "Поточні акції та пропозиції",
|
||||||
"filiale": "Наш магазин у Дрездені",
|
"filiale": "Наш магазин у Дрездені"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
"seeds": "种子",
|
"seeds": "种子",
|
||||||
"stecklinge": "插枝",
|
"stecklinge": "插枝",
|
||||||
|
"konfigurator": "配置器",
|
||||||
"oilPress": "借用榨油机",
|
"oilPress": "借用榨油机",
|
||||||
"thcTest": "THC 测试",
|
"thcTest": "THC 测试",
|
||||||
"address1": "Trachenberger Straße 14",
|
"address1": "Trachenberger Straße 14",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
"home": "优质大麻种子和插枝",
|
"home": "优质大麻种子",
|
||||||
"aktionen": "当前促销与优惠",
|
"aktionen": "当前促销与优惠",
|
||||||
"filiale": "我们在德累斯顿的门店",
|
"filiale": "我们在德累斯顿的门店"
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user