Compare commits

...

9 Commits

Author SHA1 Message Date
sebseb7
9df5642a6e refactor: reimplement category page display with a recursive tree structure and add configurator image. 2025-12-13 02:14:20 +01:00
sebseb7
a50dd086c3 feat: Include 'Kategorien' in Nginx location regex for HTML content. 2025-12-06 21:02:22 +01:00
sebseb7
e88370ff3e feat: add Categories page with refined layout and translation support 2025-12-06 14:29:33 +01:00
sebseb7
5d3e0832fe doc 2025-12-01 13:11:24 +01:00
sebseb7
3347ba2754 Add missing auth translations and update components to use i18n keys
- Added new translation keys to de/auth.js:
  - resetPassword section (title, button, success, invalidToken, error, emailSent, emailError)
  - errors section (fillAllFields, invalidEmail, passwordsNotMatch, passwordsNotMatchShort, enterEmail, loginFailed, registerFailed, googleLoginFailed, emailExists)
  - success section (registerComplete)
  - newPassword, backToHome keys

- Updated ResetPassword.js to use translation keys instead of hardcoded German strings
- Updated LoginComponent.js to use translation keys instead of hardcoded German strings
- translate-i18n.js generated translations for other languages
2025-12-01 13:02:03 +01:00
sebseb7
013a38ca98 fix: update caniuse-lite version and enhance SPA routing for resetPassword
- Updated caniuse-lite to version 1.0.30001757 in package-lock.json for improved compatibility.
- Added functionality to copy index.html to the resetPassword directory for better SPA routing in production environments.
2025-12-01 12:50:41 +01:00
sebseb7
2d6c8ff25f feat(Orders): add tracking shipment link and update translations
- Implemented a tracking shipment link in the OrdersTab component for DHL deliveries, enhancing user experience by allowing direct access to shipment tracking.
- Added 'trackShipment' translation key across multiple languages to support the new feature.
- Updated existing translations for consistency and improved localization in the orders module.
2025-11-29 14:05:59 +01:00
sebseb7
d2ac8d3fc1 feat(Orders): update order status translations and colors
- Refactored order status translations to use English keys for 'new', 'shipped', and 'delivered'.
- Updated corresponding status colors to maintain consistency in the UI.
- Adjusted the display logic to reflect the new status keys in the OrdersTab component.
2025-11-29 13:45:39 +01:00
sebseb7
8928b3f283 feat(Orders): add 'paid' status and update translations across multiple languages
- Introduced 'paid' status to the orders system, enhancing order tracking capabilities.
- Updated translations for 'paid' status in various languages including German, Spanish, French, and more.
- Adjusted related UI components to reflect the new status and ensure consistent user experience across the application.
2025-11-29 13:21:35 +01:00
59 changed files with 1729 additions and 606 deletions

154
docs/nginx.conf Normal file
View File

@@ -0,0 +1,154 @@
server {
client_max_body_size 64M;
listen 443 ssl;
http2 on;
server_name example.de;
ssl_certificate /etc/letsencrypt/live/example.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.de/privkey.pem;
gzip on;
gzip_comp_level 6;
gzip_min_length 256;
gzip_vary on;
gzip_proxied any;
gzip_types
text/css
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
image/svg+xml;
index index.html;
root /example/dist;
error_log logs/error.log info;
access_log logs/access.log combined;
location /socket.io/ {
proxy_pass http://localhost:9303/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 3600s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
send_timeout 3600s;
proxy_buffering off;
proxy_cache off;
keepalive_timeout 65;
keepalive_requests 100;
}
location /api/ {
proxy_pass http://localhost:9303/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header Content-Type $content_type;
proxy_set_header Content-Length $content_length;
proxy_set_header X-API-Key $http_x_api_key;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering off;
client_max_body_size 10M;
}
location ^~ /Kategorie/ {
types {}
default_type text/html;
}
location ^~ /Artikel/ {
types {}
default_type text/html;
}
location = /sitemap.xml {
types {}
default_type application/xml;
}
location ~ ^/(datenschutz|impressum|batteriegesetzhinweise|widerrufsrecht|sitemap|agb|Kategorien|Konfigurator|404|profile|resetPassword|thc-test|filiale|aktionen|presseverleih|payment/success)(/|$) {
types {}
default_type text/html;
}
location = /404 {
error_page 404 =404 /404-big.html;
return 404;
}
location = /404-big.html {
internal;
alias /home/seb/src/growheads_de/dist/404;
default_type text/html;
}
error_page 404 /404.html;
location = /404.html {
internal;
default_type text/html;
return 404 '<!doctype html><html><body>
<script>
if (!navigator.userAgent.includes("bot")) { location.href="/404"; }
</script>
</body></html>';
}
location ~* \.(js|css)\?.*$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
}
location ~* \.(js|css)$ {
if ($uri ~ "\.[a-f0-9]{7,}\.(js|css)$") {
expires 1y;
add_header Cache-Control "public, immutable";
break;
}
expires 1d;
add_header Cache-Control "public";
add_header Vary Accept-Encoding;
}
location ~* \.(ttf|otf|woff|woff2|eot)$ {
expires 1y;
add_header Cache-Control "public";
add_header Access-Control-Allow-Origin "*";
}
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 1y;
add_header Cache-Control "public";
add_header Vary Accept-Encoding;
}
location = /prerender.css {
expires 1w;
add_header Cache-Control "public";
add_header Vary Accept-Encoding;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public";
add_header Vary Accept-Encoding;
}
}

6
package-lock.json generated
View File

@@ -4554,9 +4554,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001727", "version": "1.0.30001757",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
"integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {

View File

@@ -159,6 +159,7 @@ const Batteriegesetzhinweise =
const Widerrufsrecht = require("./src/pages/Widerrufsrecht.js").default; const Widerrufsrecht = require("./src/pages/Widerrufsrecht.js").default;
const Sitemap = require("./src/pages/Sitemap.js").default; const Sitemap = require("./src/pages/Sitemap.js").default;
const PrerenderSitemap = require("./src/PrerenderSitemap.js").default; const PrerenderSitemap = require("./src/PrerenderSitemap.js").default;
const PrerenderCategoriesPage = require("./src/PrerenderCategoriesPage.js").default;
const AGB = require("./src/pages/AGB.js").default; const AGB = require("./src/pages/AGB.js").default;
const NotFound404 = require("./src/pages/NotFound404.js").default; const NotFound404 = require("./src/pages/NotFound404.js").default;
@@ -422,6 +423,14 @@ const renderApp = async (categoryData, socket) => {
process.exit(1); process.exit(1);
} }
// Copy index.html to resetPassword (no file extension) for SPA routing
if (config.isProduction) {
const indexPath = path.resolve(__dirname, config.outputDir, "index.html");
const resetPasswordPath = path.resolve(__dirname, config.outputDir, "resetPassword");
fs.copyFileSync(indexPath, resetPasswordPath);
console.log(`✅ Copied index.html to ${resetPasswordPath}`);
}
// Render static pages // Render static pages
console.log("\n📄 Rendering static pages..."); console.log("\n📄 Rendering static pages...");
@@ -457,6 +466,13 @@ const renderApp = async (categoryData, socket) => {
description: "Sitemap page", description: "Sitemap page",
needsCategoryData: true, needsCategoryData: true,
}, },
{
component: PrerenderCategoriesPage,
path: "/Kategorien",
filename: "Kategorien",
description: "Categories page",
needsCategoryData: true,
},
{ component: AGB, path: "/agb", filename: "agb", description: "AGB page" }, { component: AGB, path: "/agb", filename: "agb", description: "AGB page" },
{ component: NotFound404, path: "/404", filename: "404", description: "404 Not Found page" }, { component: NotFound404, path: "/404", filename: "404", description: "404 Not Found page" },
{ {
@@ -551,8 +567,7 @@ const renderApp = async (categoryData, socket) => {
try { try {
productData = await fetchCategoryProducts(socket, category.id); productData = await fetchCategoryProducts(socket, category.id);
console.log( console.log(
` ✅ Found ${ ` ✅ Found ${productData.products ? productData.products.length : 0
productData.products ? productData.products.length : 0
} products` } products`
); );
@@ -841,7 +856,7 @@ const fetchCategoryDataAndRender = () => {
const socket = io(socketUrl, { const socket = io(socketUrl, {
path: "/socket.io/", path: "/socket.io/",
transports: [ "websocket"], transports: ["websocket"],
reconnection: false, reconnection: false,
timeout: 10000, timeout: 10000,
}); });

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

View File

@@ -7,6 +7,7 @@ const imagesToConvert = [
{ src: 'seeds.jpg', dest: 'seeds.avif' }, { src: 'seeds.jpg', dest: 'seeds.avif' },
{ src: 'cutlings.jpg', dest: 'cutlings.avif' }, { src: 'cutlings.jpg', dest: 'cutlings.avif' },
{ src: 'gg.png', dest: 'gg.avif' }, { src: 'gg.png', dest: 'gg.avif' },
{ src: 'konfigurator.png', dest: 'konfigurator.avif' },
{ src: 'maps.png', dest: 'maps.avif' } { src: 'maps.png', dest: 'maps.avif' }
]; ];
@@ -18,6 +19,7 @@ const run = async () => {
const inputPath = path.join(imagesDir, image.src); const inputPath = path.join(imagesDir, image.src);
const outputPath = path.join(imagesDir, image.dest); const outputPath = path.join(imagesDir, image.dest);
console.log('d');
if (!fs.existsSync(inputPath)) { if (!fs.existsSync(inputPath)) {
console.warn(`⚠️ Input file not found: ${inputPath}`); console.warn(`⚠️ Input file not found: ${inputPath}`);
continue; continue;
@@ -55,4 +57,5 @@ const run = async () => {
} }
}; };
console.log('dsfs');
run(); run();

View File

@@ -50,6 +50,7 @@ const Datenschutz = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/D
const AGB = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/AGB.js")); const AGB = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/AGB.js"));
//const NotFound404 = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/NotFound404.js")); <Route path="/404" element={<NotFound404 />} /> //const NotFound404 = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/NotFound404.js")); <Route path="/404" element={<NotFound404 />} />
const Sitemap = lazy(() => import(/* webpackChunkName: "sitemap" */ "./pages/Sitemap.js")); const Sitemap = lazy(() => import(/* webpackChunkName: "sitemap" */ "./pages/Sitemap.js"));
const CategoriesPage = lazy(() => import(/* webpackChunkName: "categories" */ "./pages/CategoriesPage.js"));
const Impressum = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Impressum.js")); const Impressum = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Impressum.js"));
const Batteriegesetzhinweise = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Batteriegesetzhinweise.js")); const Batteriegesetzhinweise = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Batteriegesetzhinweise.js"));
const Widerrufsrecht = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Widerrufsrecht.js")); const Widerrufsrecht = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Widerrufsrecht.js"));
@@ -260,19 +261,19 @@ const AppContent = ({ currentTheme, dynamicTheme, onThemeChange }) => {
{/* Category page - Render Content in parallel */} {/* Category page - Render Content in parallel */}
<Route <Route
path="/Kategorie/:categoryId" path="/Kategorie/:categoryId"
element={<Content/>} element={<Content />}
/> />
{/* Single product page */} {/* Single product page */}
<Route <Route
path="/Artikel/:seoName" path="/Artikel/:seoName"
element={<ProductDetail/>} element={<ProductDetail />}
/> />
{/* Search page - Render Content in parallel */} {/* Search page - Render Content in parallel */}
<Route path="/search" element={<Content/>} /> <Route path="/search" element={<Content />} />
{/* Profile page */} {/* Profile page */}
<Route path="/profile" element={<ProfilePage/>} /> <Route path="/profile" element={<ProfilePage />} />
{/* Payment success page for Mollie redirects */} {/* Payment success page for Mollie redirects */}
<Route path="/payment/success" element={<PaymentSuccess />} /> <Route path="/payment/success" element={<PaymentSuccess />} />
@@ -280,22 +281,23 @@ const AppContent = ({ currentTheme, dynamicTheme, onThemeChange }) => {
{/* Reset password page */} {/* Reset password page */}
<Route <Route
path="/resetPassword" path="/resetPassword"
element={<ResetPassword/>} element={<ResetPassword />}
/> />
{/* Admin page */} {/* Admin page */}
<Route path="/admin" element={<AdminPage/>} /> <Route path="/admin" element={<AdminPage />} />
{/* Admin Users page */} {/* Admin Users page */}
<Route path="/admin/users" element={<UsersPage/>} /> <Route path="/admin/users" element={<UsersPage />} />
{/* Admin Server Logs page */} {/* Admin Server Logs page */}
<Route path="/admin/logs" element={<ServerLogsPage/>} /> <Route path="/admin/logs" element={<ServerLogsPage />} />
{/* Legal pages */} {/* Legal pages */}
<Route path="/datenschutz" element={<Datenschutz />} /> <Route path="/datenschutz" element={<Datenschutz />} />
<Route path="/agb" element={<AGB />} /> <Route path="/agb" element={<AGB />} />
<Route path="/sitemap" element={<Sitemap />} /> <Route path="/sitemap" element={<Sitemap />} />
<Route path="/Kategorien" element={<CategoriesPage />} />
<Route path="/impressum" element={<Impressum />} /> <Route path="/impressum" element={<Impressum />} />
<Route <Route
path="/batteriegesetzhinweise" path="/batteriegesetzhinweise"
@@ -304,7 +306,7 @@ const AppContent = ({ currentTheme, dynamicTheme, onThemeChange }) => {
<Route path="/widerrufsrecht" element={<Widerrufsrecht />} /> <Route path="/widerrufsrecht" element={<Widerrufsrecht />} />
{/* Grow Tent Configurator */} {/* Grow Tent Configurator */}
<Route path="/Konfigurator" element={<GrowTentKonfigurator/>} /> <Route path="/Konfigurator" element={<GrowTentKonfigurator />} />
{/* Separate pages that are truly different */} {/* Separate pages that are truly different */}
<Route path="/presseverleih" element={<PresseverleihPage />} /> <Route path="/presseverleih" element={<PresseverleihPage />} />

View File

@@ -0,0 +1,118 @@
import React from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import LegalPage from './pages/LegalPage.js';
import CategoryBox from './components/CategoryBox.js';
const PrerenderCategoriesPage = ({ categoryData }) => {
// Helper function to recursively collect all categories from the tree
const collectAllCategories = (categoryNode, categories = [], level = 0) => {
if (!categoryNode) return categories;
// Add current category (skip root category 209)
if (categoryNode.id !== 209 && categoryNode.seoName) {
categories.push({
id: categoryNode.id,
name: categoryNode.name,
seoName: categoryNode.seoName,
level: level
});
}
// Recursively add children
if (categoryNode.children) {
for (const child of categoryNode.children) {
collectAllCategories(child, categories, level + 1);
}
}
return categories;
};
// The categoryData passed prop is the root tree (id: 209)
const rootTree = categoryData;
const renderLevel1Section = (l1Node) => {
// Collect all descendants (excluding the L1 node itself, which collectAllCategories would include first)
const descendants = collectAllCategories(l1Node).slice(1);
return (
<Paper
key={l1Node.id}
elevation={1}
sx={{
p: 2,
mb: 3,
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
alignItems: { xs: 'flex-start', md: 'flex-start' },
gap: 3
}}
>
{/* Level 1 Header/Box */}
<Box sx={{
minWidth: '150px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 1
}}>
<CategoryBox
id={l1Node.id}
name={l1Node.name}
seoName={l1Node.seoName}
sx={{
boxShadow: 4,
width: '150px',
height: '150px'
}}
/>
</Box>
{/* Descendants area */}
<Box sx={{ flex: 1 }}>
<Box sx={{
display: 'flex',
flexWrap: 'wrap',
gap: 2
}}>
{descendants.map((cat) => (
<CategoryBox
key={cat.id}
id={cat.id}
name={cat.name}
seoName={cat.seoName}
sx={{
width: '100px',
height: '100px',
minWidth: '100px',
minHeight: '100px',
boxShadow: 1,
fontSize: '0.9rem'
}}
/>
))}
</Box>
</Box>
</Paper>
);
};
const content = (
<Box>
<Box>
{rootTree && rootTree.children && rootTree.children.map((child) => (
renderLevel1Section(child)
))}
{(!rootTree || !rootTree.children || rootTree.children.length === 0) && (
<Typography>Keine Kategorien gefunden.</Typography>
)}
</Box>
</Box>
);
return <LegalPage title="Kategorien" content={content} />;
};
export default PrerenderCategoriesPage;

View File

@@ -352,6 +352,9 @@ class Footer extends Component {
<Typography variant="body2" sx={{ fontSize: { xs: '11px', md: '14px' }, lineHeight: 1.5 }}> <Typography variant="body2" sx={{ fontSize: { xs: '11px', md: '14px' }, lineHeight: 1.5 }}>
© {new Date().getFullYear()} <StyledDomainLink href="https://growheads.de" target="_blank" rel="noopener noreferrer">GrowHeads.de</StyledDomainLink> © {new Date().getFullYear()} <StyledDomainLink href="https://growheads.de" target="_blank" rel="noopener noreferrer">GrowHeads.de</StyledDomainLink>
</Typography> </Typography>
<Typography variant="body2" sx={{ fontSize: { xs: '9px', md: '9px' }, lineHeight: 1.5, mt: 1 }}>
<StyledDomainLink href="https://telegraf.growheads.de" target="_blank" rel="noreferrer">Telegraf - sicherer Chat mit unseren Mitarbeitern</StyledDomainLink>
</Typography>
</Box> </Box>
</Stack> </Stack>
</Box> </Box>

View File

@@ -175,12 +175,12 @@ export class LoginComponent extends Component {
const { location, navigate } = this.props; const { location, navigate } = this.props;
if (!email || !password) { if (!email || !password) {
this.setState({ error: 'Bitte füllen Sie alle Felder aus' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.fillAllFields') : 'Bitte füllen Sie alle Felder aus' });
return; return;
} }
if (!this.validateEmail(email)) { if (!this.validateEmail(email)) {
this.setState({ error: 'Bitte geben Sie eine gültige E-Mail-Adresse ein' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.invalidEmail') : 'Bitte geben Sie eine gültige E-Mail-Adresse ein' });
return; return;
} }
@@ -238,7 +238,7 @@ export class LoginComponent extends Component {
} else { } else {
this.setState({ this.setState({
loading: false, loading: false,
error: response.message || 'Anmeldung fehlgeschlagen' error: response.message || (this.props.t ? this.props.t('auth.errors.loginFailed') : 'Anmeldung fehlgeschlagen')
}); });
} }
}); });
@@ -248,22 +248,22 @@ export class LoginComponent extends Component {
const { email, password, confirmPassword } = this.state; const { email, password, confirmPassword } = this.state;
if (!email || !password || !confirmPassword) { if (!email || !password || !confirmPassword) {
this.setState({ error: 'Bitte füllen Sie alle Felder aus' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.fillAllFields') : 'Bitte füllen Sie alle Felder aus' });
return; return;
} }
if (!this.validateEmail(email)) { if (!this.validateEmail(email)) {
this.setState({ error: 'Bitte geben Sie eine gültige E-Mail-Adresse ein' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.invalidEmail') : 'Bitte geben Sie eine gültige E-Mail-Adresse ein' });
return; return;
} }
if (password !== confirmPassword) { if (password !== confirmPassword) {
this.setState({ error: 'Passwörter stimmen nicht überein' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.passwordsNotMatchShort') : 'Passwörter stimmen nicht überein' });
return; return;
} }
if (password.length < 8) { if (password.length < 8) {
this.setState({ error: 'Das Passwort muss mindestens 8 Zeichen lang sein' }); this.setState({ error: this.props.t ? this.props.t('auth.passwordMinLength') : 'Das Passwort muss mindestens 8 Zeichen lang sein' });
return; return;
} }
@@ -274,14 +274,14 @@ export class LoginComponent extends Component {
if (response.success) { if (response.success) {
this.setState({ this.setState({
loading: false, loading: false,
success: 'Registrierung erfolgreich. Sie können sich jetzt anmelden.', success: this.props.t ? this.props.t('auth.success.registerComplete') : 'Registrierung erfolgreich. Sie können sich jetzt anmelden.',
tabValue: 0 // Switch to login tab tabValue: 0 // Switch to login tab
}); });
} else { } else {
let errorMessage = 'Registrierung fehlgeschlagen'; let errorMessage = this.props.t ? this.props.t('auth.errors.registerFailed') : 'Registrierung fehlgeschlagen';
if (response.cause === 'emailExists') { if (response.cause === 'emailExists') {
errorMessage = 'Ein Benutzer mit dieser E-Mail-Adresse existiert bereits. Bitte verwenden Sie eine andere E-Mail-Adresse oder melden Sie sich an.'; errorMessage = this.props.t ? this.props.t('auth.errors.emailExists') : 'Ein Benutzer mit dieser E-Mail-Adresse existiert bereits. Bitte verwenden Sie eine andere E-Mail-Adresse oder melden Sie sich an.';
} else if (response.message) { } else if (response.message) {
errorMessage = response.message; errorMessage = response.message;
} }
@@ -322,12 +322,12 @@ export class LoginComponent extends Component {
const { email } = this.state; const { email } = this.state;
if (!email) { if (!email) {
this.setState({ error: 'Bitte geben Sie Ihre E-Mail-Adresse ein' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.enterEmail') : 'Bitte geben Sie Ihre E-Mail-Adresse ein' });
return; return;
} }
if (!this.validateEmail(email)) { if (!this.validateEmail(email)) {
this.setState({ error: 'Bitte geben Sie eine gültige E-Mail-Adresse ein' }); this.setState({ error: this.props.t ? this.props.t('auth.errors.invalidEmail') : 'Bitte geben Sie eine gültige E-Mail-Adresse ein' });
return; return;
} }
@@ -342,12 +342,12 @@ export class LoginComponent extends Component {
if (response.success) { if (response.success) {
this.setState({ this.setState({
loading: false, loading: false,
success: 'Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail-Adresse gesendet.' success: this.props.t ? this.props.t('auth.resetPassword.emailSent') : 'Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail-Adresse gesendet.'
}); });
} else { } else {
this.setState({ this.setState({
loading: false, loading: false,
error: response.message || 'Fehler beim Senden der E-Mail' error: response.message || (this.props.t ? this.props.t('auth.resetPassword.emailError') : 'Fehler beim Senden der E-Mail')
}); });
} }
}); });
@@ -408,7 +408,7 @@ export class LoginComponent extends Component {
} else { } else {
this.setState({ this.setState({
loading: false, loading: false,
error: 'Google-Anmeldung fehlgeschlagen', error: this.props.t ? this.props.t('auth.errors.googleLoginFailed') : 'Google-Anmeldung fehlgeschlagen',
showGoogleAuth: false // Reset Google auth state on failed login showGoogleAuth: false // Reset Google auth state on failed login
}); });
} }
@@ -418,7 +418,7 @@ export class LoginComponent extends Component {
handleGoogleLoginError = (error) => { handleGoogleLoginError = (error) => {
console.error('Google Login Error:', error); console.error('Google Login Error:', error);
this.setState({ this.setState({
error: 'Google-Anmeldung fehlgeschlagen', error: this.props.t ? this.props.t('auth.errors.googleLoginFailed') : 'Google-Anmeldung fehlgeschlagen',
showGoogleAuth: false, // Reset Google auth state on error showGoogleAuth: false, // Reset Google auth state on error
loading: false loading: false
}); });

View File

@@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom';
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
@@ -60,9 +61,9 @@ class SharedCarousel extends React.Component {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
console.log("componentDidUpdate", prevProps.languageContext?.currentLanguage, this.props.languageContext?.currentLanguage); console.log("componentDidUpdate", prevProps.languageContext?.currentLanguage, this.props.languageContext?.currentLanguage);
if(prevProps.languageContext?.currentLanguage !== this.props.languageContext?.currentLanguage) { if (prevProps.languageContext?.currentLanguage !== this.props.languageContext?.currentLanguage) {
this.setState({ categories: [] },() => { this.setState({ categories: [] }, () => {
window.categoryService.get(209,this.props.languageContext?.currentLanguage || this.props.i18n.language).then((response) => { window.categoryService.get(209, this.props.languageContext?.currentLanguage || this.props.i18n.language).then((response) => {
console.log("response", response); console.log("response", response);
if (response.children && response.children.length > 0) { if (response.children && response.children.length > 0) {
this.originalCategories = response.children; this.originalCategories = response.children;
@@ -268,25 +269,41 @@ class SharedCarousel extends React.Component {
const { t } = this.props; const { t } = this.props;
const { categories } = this.state; const { categories } = this.state;
if(!categories || categories.length === 0) { if (!categories || categories.length === 0) {
return null; return null;
} }
return ( return (
<Box sx={{ mt: 3 }}> <Box sx={{ mt: 3 }}>
<Box
component={Link}
to="/Kategorien"
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
textDecoration: "none",
color: "primary.main",
mb: 2,
transition: "all 0.3s ease",
"&:hover": {
transform: "translateX(5px)",
color: "primary.dark"
}
}}
>
<Typography <Typography
variant="h4" variant="h4"
component="h1" component="span"
sx={{ sx={{
mb: 2,
fontFamily: "SwashingtonCP", fontFamily: "SwashingtonCP",
color: "primary.main",
textAlign: "center",
textShadow: "3px 3px 10px rgba(0, 0, 0, 0.4)" textShadow: "3px 3px 10px rgba(0, 0, 0, 0.4)"
}} }}
> >
{t('navigation.categories')} {t('navigation.categories')}
</Typography> </Typography>
<ChevronRight sx={{ fontSize: "2.5rem", ml: 1 }} />
</Box>
<div <div
className="carousel-wrapper" className="carousel-wrapper"

View File

@@ -53,12 +53,12 @@ class CategoryList extends Component {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
console.log("componentDidUpdate", prevProps.languageContext?.currentLanguage, this.props.languageContext?.currentLanguage); console.log("componentDidUpdate", prevProps.languageContext?.currentLanguage, this.props.languageContext?.currentLanguage);
if(prevProps.languageContext?.currentLanguage !== this.props.languageContext?.currentLanguage) { if (prevProps.languageContext?.currentLanguage !== this.props.languageContext?.currentLanguage) {
this.setState({ this.setState({
categories: [], categories: [],
activeCategoryId: null activeCategoryId: null
},() => { }, () => {
window.categoryService.get(209,this.props.languageContext?.currentLanguage || this.props.i18n.language).then((response) => { window.categoryService.get(209, this.props.languageContext?.currentLanguage || this.props.i18n.language).then((response) => {
console.log("response", response); console.log("response", response);
if (response.children && response.children.length > 0) { if (response.children && response.children.length > 0) {
this.setState({ this.setState({
@@ -76,7 +76,7 @@ class CategoryList extends Component {
setLevel1CategoryId = (input) => { setLevel1CategoryId = (input) => {
if(input) { if (input) {
const language = this.props.languageContext?.currentLanguage || this.props.i18n.language; const language = this.props.languageContext?.currentLanguage || this.props.i18n.language;
const categoryTreeCache = window.categoryService.getSync(209, language); const categoryTreeCache = window.categoryService.getSync(209, language);
@@ -385,7 +385,7 @@ class CategoryList extends Component {
); );
})} })}
</> </>
) : ( !isMobile && ( ) : (!isMobile && (
<Typography <Typography
variant="caption" variant="caption"
color="inherit" color="inherit"
@@ -545,7 +545,7 @@ class CategoryList extends Component {
fontWeight: "bold", fontWeight: "bold",
textShadow: "0 1px 2px rgba(0,0,0,0.3)" textShadow: "0 1px 2px rgba(0,0,0,0.3)"
}}> }}>
{this.props.t ? this.props.t('navigation.categories') : 'Kategorien'} {this.props.t ? this.props.t('navigation.categories') : 'Kategorien'}
</Typography> </Typography>
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
{mobileMenuOpen ? <CloseIcon /> : <MenuIcon />} {mobileMenuOpen ? <CloseIcon /> : <MenuIcon />}

View File

@@ -31,6 +31,7 @@ const getStatusTranslation = (status, t) => {
new: t ? t('orders.status.new') : "in Bearbeitung", new: t ? t('orders.status.new') : "in Bearbeitung",
pending: t ? t('orders.status.pending') : "Neu", pending: t ? t('orders.status.pending') : "Neu",
processing: t ? t('orders.status.processing') : "in Bearbeitung", processing: t ? t('orders.status.processing') : "in Bearbeitung",
paid: t ? t('orders.status.paid') : "Bezahlt",
cancelled: t ? t('orders.status.cancelled') : "Storniert", cancelled: t ? t('orders.status.cancelled') : "Storniert",
shipped: t ? t('orders.status.shipped') : "Verschickt", shipped: t ? t('orders.status.shipped') : "Verschickt",
delivered: t ? t('orders.status.delivered') : "Geliefert", delivered: t ? t('orders.status.delivered') : "Geliefert",
@@ -39,29 +40,23 @@ const getStatusTranslation = (status, t) => {
}; };
const statusEmojis = { const statusEmojis = {
"in Bearbeitung": "⚙️", new: "⚙️",
pending: "⏳", pending: "⏳",
processing: "🔄", processing: "🔄",
paid: "🏦",
cancelled: "❌", cancelled: "❌",
Verschickt: "🚚", shipped: "🚚",
Geliefert: "✅", delivered: "✅",
Storniert: "❌",
Retoure: "↩️",
"Teil Retoure": "↪️",
"Teil geliefert": "⚡",
}; };
const statusColors = { const statusColors = {
"in Bearbeitung": "#ed6c02", // orange new: "#ed6c02", // orange
pending: "#ff9800", // orange for pending pending: "#ff9800", // orange for pending
processing: "#2196f3", // blue for processing processing: "#2196f3", // blue for processing
paid: "#2e7d32", // green
cancelled: "#d32f2f", // red for cancelled cancelled: "#d32f2f", // red for cancelled
Verschickt: "#2e7d32", // green shipped: "#2e7d32", // green
Geliefert: "#2e7d32", // green delivered: "#2e7d32", // green
Storniert: "#d32f2f", // red
Retoure: "#9c27b0", // purple
"Teil Retoure": "#9c27b0", // purple
"Teil geliefert": "#009688", // teal
}; };
const currencyFormatter = new Intl.NumberFormat("de-DE", { const currencyFormatter = new Intl.NumberFormat("de-DE", {
@@ -229,11 +224,11 @@ const OrdersTab = ({ orderIdFromHash, t }) => {
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
gap: "8px", gap: "8px",
color: getStatusColor(displayStatus), color: getStatusColor(order.status),
}} }}
> >
<span style={{ fontSize: "1.2rem" }}> <span style={{ fontSize: "1.2rem" }}>
{getStatusEmoji(displayStatus)} {getStatusEmoji(order.status)}
</span> </span>
<Typography <Typography
variant="body2" variant="body2"
@@ -243,6 +238,18 @@ const OrdersTab = ({ orderIdFromHash, t }) => {
{displayStatus} {displayStatus}
</Typography> </Typography>
</Box> </Box>
{order.delivery_method === 'DHL' && order.trackingCode && (
<Box sx={{ mt: 0.5 }}>
<a
href={`https://www.dhl.de/de/privatkunden/dhl-sendungsverfolgung.html?piececode=${order.trackingCode}`}
target="_blank"
rel="noopener noreferrer"
style={{ fontSize: '0.85rem', color: '#d40511' }}
>
📦 {t ? t('orders.trackShipment') : 'Sendung verfolgen'}
</a>
</Box>
)}
</TableCell> </TableCell>
<TableCell> <TableCell>
{order.items {order.items

View File

@@ -5,6 +5,7 @@ export default {
"profile": "الملف الشخصي", "profile": "الملف الشخصي",
"email": "البريد الإلكتروني", "email": "البريد الإلكتروني",
"password": "كلمة المرور", "password": "كلمة المرور",
"newPassword": "كلمة المرور الجديدة",
"confirmPassword": "تأكيد كلمة المرور", "confirmPassword": "تأكيد كلمة المرور",
"forgotPassword": "هل نسيت كلمة المرور؟", "forgotPassword": "هل نسيت كلمة المرور؟",
"loginWithGoogle": "تسجيل الدخول باستخدام جوجل", "loginWithGoogle": "تسجيل الدخول باستخدام جوجل",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "سياسة الخصوصية", "privacyPolicy": "سياسة الخصوصية",
"passwordMinLength": "يجب أن تكون كلمة المرور 8 أحرف على الأقل", "passwordMinLength": "يجب أن تكون كلمة المرور 8 أحرف على الأقل",
"newPasswordMinLength": "يجب أن تكون كلمة المرور الجديدة 8 أحرف على الأقل", "newPasswordMinLength": "يجب أن تكون كلمة المرور الجديدة 8 أحرف على الأقل",
"backToHome": "العودة إلى الصفحة الرئيسية",
"menu": { "menu": {
"profile": "الملف الشخصي", "profile": "الملف الشخصي",
"myProfile": "ملفي الشخصي", "myProfile": "ملفي الشخصي",
@@ -21,5 +23,28 @@ export default {
"settings": "الإعدادات", "settings": "الإعدادات",
"adminDashboard": "لوحة تحكم المسؤول", "adminDashboard": "لوحة تحكم المسؤول",
"adminUsers": "مستخدمو المسؤول" "adminUsers": "مستخدمو المسؤول"
},
"resetPassword": {
"title": "إعادة تعيين كلمة المرور",
"button": "إعادة تعيين كلمة المرور",
"success": "تم إعادة تعيين كلمة المرور بنجاح! سيتم توجيهك لتسجيل الدخول قريبًا...",
"invalidToken": "لم يتم العثور على رمز صالح. يرجى استخدام الرابط من بريدك الإلكتروني.",
"error": "حدث خطأ أثناء إعادة تعيين كلمة المرور",
"emailSent": "تم إرسال رابط لإعادة تعيين كلمة المرور إلى بريدك الإلكتروني.",
"emailError": "حدث خطأ أثناء إرسال البريد الإلكتروني"
},
"errors": {
"fillAllFields": "يرجى ملء جميع الحقول",
"invalidEmail": "يرجى إدخال بريد إلكتروني صالح",
"passwordsNotMatch": "كلمات المرور غير متطابقة",
"passwordsNotMatchShort": "كلمات المرور غير متطابقة",
"enterEmail": "يرجى إدخال بريدك الإلكتروني",
"loginFailed": "فشل تسجيل الدخول",
"registerFailed": "فشل التسجيل",
"googleLoginFailed": "فشل تسجيل الدخول عبر جوجل",
"emailExists": "يوجد مستخدم بهذا البريد الإلكتروني بالفعل. يرجى استخدام بريد إلكتروني آخر أو تسجيل الدخول."
},
"success": {
"registerComplete": "تم التسجيل بنجاح. يمكنك الآن تسجيل الدخول."
} }
}; };

View File

@@ -3,7 +3,8 @@ export default {
"new": "قيد التنفيذ", "new": "قيد التنفيذ",
"pending": "جديد", "pending": "جديد",
"processing": "قيد التنفيذ", "processing": "قيد التنفيذ",
"cancelled": لغاة", "paid": دفوع",
"cancelled": "ملغي",
"shipped": "تم الشحن", "shipped": "تم الشحن",
"delivered": "تم التوصيل", "delivered": "تم التوصيل",
"return": "إرجاع", "return": "إرجاع",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "إلغاء الطلب" "cancelOrder": "إلغاء الطلب"
}, },
"noOrders": "لم تقم بوضع أي طلبات بعد.", "noOrders": "لم تقم بوضع أي طلبات بعد.",
"trackShipment": "تتبع الشحنة",
"details": { "details": {
"title": "تفاصيل الطلب: {{orderId}}", "title": "تفاصيل الطلب: {{orderId}}",
"deliveryAddress": "عنوان التوصيل", "deliveryAddress": "عنوان التوصيل",
@@ -36,14 +38,13 @@ export default {
"item": "العنصر", "item": "العنصر",
"quantity": "الكمية", "quantity": "الكمية",
"price": "السعر", "price": "السعر",
"vat": "ضريبة القيمة المضافة",
"total": "الإجمالي", "total": "الإجمالي",
"cancelOrder": "إلغاء الطلب" "cancelOrder": "إلغاء الطلب"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "إلغاء الطلب", "title": "إلغاء الطلب",
"message": "هل أنت متأكد أنك تريد إلغاء هذا الطلب؟", "message": "هل أنت متأكد أنك تريد إلغاء هذا الطلب؟",
"confirm": "إلغاء الطلب", "confirm": "إلغاء",
"cancelling": "جارٍ الإلغاء..." "cancelling": "جارٍ الإلغاء..."
}, },
"processing": "يتم إكمال الطلب..." "processing": "يتم إكمال الطلب..."

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Профил", "profile": "Профил",
"email": "Имейл", "email": "Имейл",
"password": "Парола", "password": "Парола",
"newPassword": "Нова парола",
"confirmPassword": "Потвърдете паролата", "confirmPassword": "Потвърдете паролата",
"forgotPassword": "Забравена парола?", "forgotPassword": "Забравена парола?",
"loginWithGoogle": "Вход с Google", "loginWithGoogle": "Вход с Google",
"or": "ИЛИ", "or": "ИЛИ",
"privacyAccept": "С натискане на \"Вход с Google\" приемам", "privacyAccept": "С натискането на \"Вход с Google\" приемам",
"privacyPolicy": "Политиката за поверителност", "privacyPolicy": "Политиката за поверителност",
"passwordMinLength": "Паролата трябва да е поне 8 символа", "passwordMinLength": "Паролата трябва да е поне 8 символа",
"newPasswordMinLength": "Новата парола трябва да е поне 8 символа", "newPasswordMinLength": "Новата парола трябва да е поне 8 символа",
"backToHome": "Обратно към началната страница",
"menu": { "menu": {
"profile": "Профил", "profile": "Профил",
"myProfile": "Моят профил", "myProfile": "Моят профил",
@@ -21,5 +23,28 @@ export default {
"settings": "Настройки", "settings": "Настройки",
"adminDashboard": "Админ табло", "adminDashboard": "Админ табло",
"adminUsers": "Админ потребители" "adminUsers": "Админ потребители"
},
"resetPassword": {
"title": "Нулиране на парола",
"button": "Нулиране на парола",
"success": "Вашата парола беше успешно нулирана! Скоро ще бъдете пренасочени към вход...",
"invalidToken": "Няма валиден токен. Моля, използвайте линка от имейла си.",
"error": "Грешка при нулиране на паролата",
"emailSent": "Линк за нулиране на паролата беше изпратен на вашия имейл.",
"emailError": "Грешка при изпращане на имейла"
},
"errors": {
"fillAllFields": "Моля, попълнете всички полета",
"invalidEmail": "Моля, въведете валиден имейл адрес",
"passwordsNotMatch": "Паролите не съвпадат",
"passwordsNotMatchShort": "Паролите не съвпадат",
"enterEmail": "Моля, въведете вашия имейл адрес",
"loginFailed": "Входът не бе успешен",
"registerFailed": "Регистрацията не бе успешна",
"googleLoginFailed": "Вход с Google не бе успешен",
"emailExists": "Потребител с този имейл вече съществува. Моля, използвайте друг имейл или влезте в системата."
},
"success": {
"registerComplete": "Регистрацията беше успешна. Сега можете да влезете."
} }
}; };

View File

@@ -1,14 +1,15 @@
export default { export default {
"status": { "status": {
"new": "В процес", "new": "в процес",
"pending": "Нова", "pending": "Ново",
"processing": "В процес", "processing": "в процес",
"cancelled": "Отменена", "paid": "Платено",
"shipped": "Изпратена", "cancelled": "Отменено",
"delivered": "Доставена", "shipped": "Изпратено",
"delivered": "Доставено",
"return": "Връщане", "return": "Връщане",
"partialReturn": "Частично връщане", "partialReturn": "Частично връщане",
"partialDelivered": "Частично доставена" "partialDelivered": "Частично доставено"
}, },
"table": { "table": {
"orderNumber": "Номер на поръчка", "orderNumber": "Номер на поръчка",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Отмени поръчката" "cancelOrder": "Отмени поръчката"
}, },
"noOrders": "Все още не сте направили поръчки.", "noOrders": "Все още не сте направили поръчки.",
"trackShipment": "Проследи пратката",
"details": { "details": {
"title": "Подробности за поръчка: {{orderId}}", "title": "Подробности за поръчка: {{orderId}}",
"deliveryAddress": "Адрес за доставка", "deliveryAddress": "Адрес за доставка",
@@ -36,15 +38,14 @@ export default {
"item": "Артикул", "item": "Артикул",
"quantity": "Количество", "quantity": "Количество",
"price": "Цена", "price": "Цена",
"vat": "ДДС",
"total": "Общо", "total": "Общо",
"cancelOrder": "Отмени поръчката" "cancelOrder": "Отмени поръчката"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Отмяна на поръчка", "title": "Отмени поръчката",
"message": "Сигурни ли сте, че искате да отмените тази поръчка?", "message": "Сигурни ли сте, че искате да отмените тази поръчка?",
"confirm": "Отмени поръчката", "confirm": "Отмени",
"cancelling": "Отмяна..." "cancelling": "Отмяна..."
}, },
"processing": "Поръчката се обработва...", "processing": "Поръчката се обработва..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Heslo", "password": "Heslo",
"newPassword": "Nové heslo",
"confirmPassword": "Potvrdit heslo", "confirmPassword": "Potvrdit heslo",
"forgotPassword": "Zapomněli jste heslo?", "forgotPassword": "Zapomněli jste heslo?",
"loginWithGoogle": "Přihlásit se přes Google", "loginWithGoogle": "Přihlásit se přes Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Zásadami ochrany osobních údajů", "privacyPolicy": "Zásadami ochrany osobních údajů",
"passwordMinLength": "Heslo musí mít alespoň 8 znaků", "passwordMinLength": "Heslo musí mít alespoň 8 znaků",
"newPasswordMinLength": "Nové heslo musí mít alespoň 8 znaků", "newPasswordMinLength": "Nové heslo musí mít alespoň 8 znaků",
"backToHome": "Zpět na domovskou stránku",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Můj profil", "myProfile": "Můj profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Nastavení", "settings": "Nastavení",
"adminDashboard": "Admin Dashboard", "adminDashboard": "Admin Dashboard",
"adminUsers": "Admin Users" "adminUsers": "Admin Users"
},
"resetPassword": {
"title": "Obnovení hesla",
"button": "Obnovit heslo",
"success": "Vaše heslo bylo úspěšně obnoveno! Brzy budete přesměrováni na přihlášení...",
"invalidToken": "Nebyl nalezen platný token. Použijte prosím odkaz z vašeho e-mailu.",
"error": "Chyba při obnově hesla",
"emailSent": "Odkaz pro obnovení hesla byl odeslán na vaši e-mailovou adresu.",
"emailError": "Chyba při odesílání e-mailu"
},
"errors": {
"fillAllFields": "Vyplňte prosím všechna pole",
"invalidEmail": "Zadejte platnou e-mailovou adresu",
"passwordsNotMatch": "Hesla se neshodují",
"passwordsNotMatchShort": "Hesla se neshodují",
"enterEmail": "Zadejte prosím svou e-mailovou adresu",
"loginFailed": "Přihlášení selhalo",
"registerFailed": "Registrace selhala",
"googleLoginFailed": "Přihlášení přes Google selhalo",
"emailExists": "Uživatel s touto e-mailovou adresou již existuje. Použijte prosím jinou e-mailovou adresu nebo se přihlaste."
},
"success": {
"registerComplete": "Registrace byla úspěšná. Nyní se můžete přihlásit."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "Probíhá", "new": "probíhá",
"pending": "Nová", "pending": "Nové",
"processing": "Probíhá", "processing": "probíhá",
"paid": "Zaplaceno",
"cancelled": "Zrušeno", "cancelled": "Zrušeno",
"shipped": "Odesláno", "shipped": "Odesláno",
"delivered": "Doručeno", "delivered": "Doručeno",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Zrušit objednávku" "cancelOrder": "Zrušit objednávku"
}, },
"noOrders": "Ještě jste neprovedli žádné objednávky.", "noOrders": "Ještě jste neprovedli žádné objednávky.",
"trackShipment": "Sledovat zásilku",
"details": { "details": {
"title": "Detaily objednávky: {{orderId}}", "title": "Detaily objednávky: {{orderId}}",
"deliveryAddress": "Dodací adresa", "deliveryAddress": "Dodací adresa",
@@ -36,15 +38,14 @@ export default {
"item": "Položka", "item": "Položka",
"quantity": "Množství", "quantity": "Množství",
"price": "Cena", "price": "Cena",
"vat": "DPH",
"total": "Celkem", "total": "Celkem",
"cancelOrder": "Zrušit objednávku" "cancelOrder": "Zrušit objednávku"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Zrušit objednávku", "title": "Zrušit objednávku",
"message": "Opravdu chcete tuto objednávku zrušit?", "message": "Opravdu chcete tuto objednávku zrušit?",
"confirm": "Zrušit objednávku", "confirm": "Zrušit",
"cancelling": "Rušení..." "cancelling": "Rušení..."
}, },
"processing": "Objednávka se dokončuje...", "processing": "Objednávka se dokončuje..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "E-Mail", "email": "E-Mail",
"password": "Passwort", "password": "Passwort",
"newPassword": "Neues Passwort",
"confirmPassword": "Passwort bestätigen", "confirmPassword": "Passwort bestätigen",
"forgotPassword": "Passwort vergessen?", "forgotPassword": "Passwort vergessen?",
"loginWithGoogle": "Mit Google anmelden", "loginWithGoogle": "Mit Google anmelden",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Datenschutzbestimmungen", "privacyPolicy": "Datenschutzbestimmungen",
"passwordMinLength": "Das Passwort muss mindestens 8 Zeichen lang sein", "passwordMinLength": "Das Passwort muss mindestens 8 Zeichen lang sein",
"newPasswordMinLength": "Das neue Passwort muss mindestens 8 Zeichen lang sein", "newPasswordMinLength": "Das neue Passwort muss mindestens 8 Zeichen lang sein",
"backToHome": "Zurück zur Startseite",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Mein Profil", "myProfile": "Mein Profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Einstellungen", "settings": "Einstellungen",
"adminDashboard": "Admin Dashboard", "adminDashboard": "Admin Dashboard",
"adminUsers": "Admin Users" "adminUsers": "Admin Users"
},
"resetPassword": {
"title": "Passwort zurücksetzen",
"button": "Passwort zurücksetzen",
"success": "Ihr Passwort wurde erfolgreich zurückgesetzt! Sie werden in Kürze zur Anmeldung weitergeleitet...",
"invalidToken": "Kein gültiger Token gefunden. Bitte verwenden Sie den Link aus Ihrer E-Mail.",
"error": "Fehler beim Zurücksetzen des Passworts",
"emailSent": "Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail-Adresse gesendet.",
"emailError": "Fehler beim Senden der E-Mail"
},
"errors": {
"fillAllFields": "Bitte füllen Sie alle Felder aus",
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
"passwordsNotMatch": "Die Passwörter stimmen nicht überein",
"passwordsNotMatchShort": "Passwörter stimmen nicht überein",
"enterEmail": "Bitte geben Sie Ihre E-Mail-Adresse ein",
"loginFailed": "Anmeldung fehlgeschlagen",
"registerFailed": "Registrierung fehlgeschlagen",
"googleLoginFailed": "Google-Anmeldung fehlgeschlagen",
"emailExists": "Ein Benutzer mit dieser E-Mail-Adresse existiert bereits. Bitte verwenden Sie eine andere E-Mail-Adresse oder melden Sie sich an."
},
"success": {
"registerComplete": "Registrierung erfolgreich. Sie können sich jetzt anmelden."
} }
}; };

View File

@@ -3,6 +3,7 @@ export default {
"new": "in Bearbeitung", "new": "in Bearbeitung",
"pending": "Neu", "pending": "Neu",
"processing": "in Bearbeitung", "processing": "in Bearbeitung",
"paid": "Bezahlt",
"cancelled": "Storniert", "cancelled": "Storniert",
"shipped": "Verschickt", "shipped": "Verschickt",
"delivered": "Geliefert", "delivered": "Geliefert",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Bestellung stornieren" "cancelOrder": "Bestellung stornieren"
}, },
"noOrders": "Sie haben noch keine Bestellungen aufgegeben.", "noOrders": "Sie haben noch keine Bestellungen aufgegeben.",
"trackShipment": "Sendung verfolgen",
"details": { "details": {
"title": "Bestelldetails: {{orderId}}", "title": "Bestelldetails: {{orderId}}",
"deliveryAddress": "Lieferadresse", "deliveryAddress": "Lieferadresse",

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Προφίλ", "profile": "Προφίλ",
"email": "Email", "email": "Email",
"password": "Κωδικός", "password": "Κωδικός",
"newPassword": "Νέος κωδικός",
"confirmPassword": "Επιβεβαίωση κωδικού", "confirmPassword": "Επιβεβαίωση κωδικού",
"forgotPassword": "Ξεχάσατε τον κωδικό;", "forgotPassword": "Ξεχάσατε τον κωδικό;",
"loginWithGoogle": "Σύνδεση με Google", "loginWithGoogle": "Σύνδεση με Google",
"or": "Ή", "or": "Ή",
"privacyAccept": "Κάνοντας κλικ στο \"Σύνδεση με Google\" αποδέχομαι την", "privacyAccept": "Κάνοντας κλικ στο \"Σύνδεση με Google\" αποδέχομαι την",
"privacyPolicy": "Πολιτική Απορρήτου", "privacyPolicy": "Πολιτική απορρήτου",
"passwordMinLength": "Ο κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες", "passwordMinLength": "Ο κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες",
"newPasswordMinLength": "Ο νέος κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες", "newPasswordMinLength": "Ο νέος κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες",
"backToHome": "Επιστροφή στην αρχική σελίδα",
"menu": { "menu": {
"profile": "Προφίλ", "profile": "Προφίλ",
"myProfile": "Το προφίλ μου", "myProfile": "Το προφίλ μου",
@@ -21,5 +23,28 @@ export default {
"settings": "Ρυθμίσεις", "settings": "Ρυθμίσεις",
"adminDashboard": "Πίνακας διαχείρισης", "adminDashboard": "Πίνακας διαχείρισης",
"adminUsers": "Διαχειριστές" "adminUsers": "Διαχειριστές"
},
"resetPassword": {
"title": "Επαναφορά κωδικού",
"button": "Επαναφορά κωδικού",
"success": "Ο κωδικός σας επαναφέρθηκε με επιτυχία! Θα ανακατευθυνθείτε στη σύνδεση σύντομα...",
"invalidToken": "Δεν βρέθηκε έγκυρο διακριτικό. Παρακαλώ χρησιμοποιήστε τον σύνδεσμο από το email σας.",
"error": "Σφάλμα κατά την επαναφορά του κωδικού",
"emailSent": "Ένας σύνδεσμος για επαναφορά του κωδικού σας έχει σταλεί στη διεύθυνση email σας.",
"emailError": "Σφάλμα κατά την αποστολή του email"
},
"errors": {
"fillAllFields": "Παρακαλώ συμπληρώστε όλα τα πεδία",
"invalidEmail": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email",
"passwordsNotMatch": "Οι κωδικοί δεν ταιριάζουν",
"passwordsNotMatchShort": "Οι κωδικοί δεν ταιριάζουν",
"enterEmail": "Παρακαλώ εισάγετε τη διεύθυνση email σας",
"loginFailed": "Η σύνδεση απέτυχε",
"registerFailed": "Η εγγραφή απέτυχε",
"googleLoginFailed": "Η σύνδεση με Google απέτυχε",
"emailExists": "Υπάρχει ήδη χρήστης με αυτή τη διεύθυνση email. Παρακαλώ χρησιμοποιήστε άλλη διεύθυνση ή συνδεθείτε."
},
"success": {
"registerComplete": "Η εγγραφή ολοκληρώθηκε με επιτυχία. Μπορείτε τώρα να συνδεθείτε."
} }
}; };

View File

@@ -1,10 +1,11 @@
export default { export default {
"status": { "status": {
"new": "Σε εξέλιξη", "new": "σε εξέλιξη",
"pending": "Νέο", "pending": "Νέο",
"processing": "Σε εξέλιξη", "processing": "σε εξέλιξη",
"paid": "Πληρωμένο",
"cancelled": "Ακυρώθηκε", "cancelled": "Ακυρώθηκε",
"shipped": "Απεστάλη", "shipped": "Απεσταλμένο",
"delivered": "Παραδόθηκε", "delivered": "Παραδόθηκε",
"return": "Επιστροφή", "return": "Επιστροφή",
"partialReturn": "Μερική επιστροφή", "partialReturn": "Μερική επιστροφή",
@@ -24,10 +25,11 @@ export default {
"cancelOrder": "Ακύρωση παραγγελίας" "cancelOrder": "Ακύρωση παραγγελίας"
}, },
"noOrders": "Δεν έχετε κάνει ακόμα καμία παραγγελία.", "noOrders": "Δεν έχετε κάνει ακόμα καμία παραγγελία.",
"trackShipment": "Παρακολούθηση αποστολής",
"details": { "details": {
"title": "Λεπτομέρειες παραγγελίας: {{orderId}}", "title": "Λεπτομέρειες παραγγελίας: {{orderId}}",
"deliveryAddress": "Διεύθυνση παράδοσης", "deliveryAddress": "Διεύθυνση παράδοσης",
"invoiceAddress": "Διεύθυνση τιμολόγησης", "invoiceAddress": "Διεύθυνση τιμολογίου",
"orderDetails": "Λεπτομέρειες παραγγελίας", "orderDetails": "Λεπτομέρειες παραγγελίας",
"deliveryMethod": "Τρόπος παράδοσης:", "deliveryMethod": "Τρόπος παράδοσης:",
"paymentMethod": "Τρόπος πληρωμής:", "paymentMethod": "Τρόπος πληρωμής:",
@@ -36,15 +38,14 @@ export default {
"item": "Είδος", "item": "Είδος",
"quantity": "Ποσότητα", "quantity": "Ποσότητα",
"price": "Τιμή", "price": "Τιμή",
"vat": "ΦΠΑ",
"total": "Σύνολο", "total": "Σύνολο",
"cancelOrder": "Ακύρωση παραγγελίας" "cancelOrder": "Ακύρωση παραγγελίας"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Ακύρωση παραγγελίας", "title": "Ακύρωση παραγγελίας",
"message": "Είστε σίγουροι ότι θέλετε να ακυρώσετε αυτήν την παραγγελία;", "message": "Είστε σίγουροι ότι θέλετε να ακυρώσετε αυτή την παραγγελία;",
"confirm": "Ακύρωση παραγγελίας", "confirm": "Ακύρωση",
"cancelling": "Ακύρωση..." "cancelling": "Ακύρωση σε εξέλιξη..."
}, },
"processing": "Η παραγγελία ολοκληρώνεται..." "processing": "Η παραγγελία ολοκληρώνεται..."
}; };

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Profile", // Profil "profile": "Profile", // Profil
"email": "Email", // E-Mail "email": "Email", // E-Mail
"password": "Password", // Passwort "password": "Password", // Passwort
"newPassword": "New password", // Neues Passwort
"confirmPassword": "Confirm password", // Passwort bestätigen "confirmPassword": "Confirm password", // Passwort bestätigen
"forgotPassword": "Forgot password?", // Passwort vergessen? "forgotPassword": "Forgot password?", // Passwort vergessen?
"loginWithGoogle": "Sign in with Google", // Mit Google anmelden "loginWithGoogle": "Sign in with Google", // Mit Google anmelden
"or": "OR", // ODER "or": "OR", // ODER
"privacyAccept": "By clicking \"Sign in with Google\" I accept the", // Mit dem Click auf "Mit Google anmelden" akzeptiere ich die "privacyAccept": "By clicking on \"Sign in with Google\" I accept the", // Mit dem Click auf "Mit Google anmelden" akzeptiere ich die
"privacyPolicy": "Privacy Policy", // Datenschutzbestimmungen "privacyPolicy": "Privacy policy", // Datenschutzbestimmungen
"passwordMinLength": "The password must be at least 8 characters long", // Das Passwort muss mindestens 8 Zeichen lang sein "passwordMinLength": "The password must be at least 8 characters long", // Das Passwort muss mindestens 8 Zeichen lang sein
"newPasswordMinLength": "The new password must be at least 8 characters long", // Das neue Passwort muss mindestens 8 Zeichen lang sein "newPasswordMinLength": "The new password must be at least 8 characters long", // Das neue Passwort muss mindestens 8 Zeichen lang sein
"backToHome": "Back to homepage", // Zurück zur Startseite
"menu": { "menu": {
"profile": "Profile", // Profil "profile": "Profile", // Profil
"myProfile": "My profile", // Mein Profil "myProfile": "My profile", // Mein Profil
@@ -21,5 +23,28 @@ export default {
"settings": "Settings", // Einstellungen "settings": "Settings", // Einstellungen
"adminDashboard": "Admin Dashboard", // Admin Dashboard "adminDashboard": "Admin Dashboard", // Admin Dashboard
"adminUsers": "Admin Users" // Admin Users "adminUsers": "Admin Users" // Admin Users
},
"resetPassword": {
"title": "Reset password", // Passwort zurücksetzen
"button": "Reset password", // Passwort zurücksetzen
"success": "Your password has been reset successfully! You will be redirected to login shortly...", // Ihr Passwort wurde erfolgreich zurückgesetzt! Sie werden in Kürze zur Anmeldung weitergeleitet...
"invalidToken": "No valid token found. Please use the link from your email.", // Kein gültiger Token gefunden. Bitte verwenden Sie den Link aus Ihrer E-Mail.
"error": "Error resetting password", // Fehler beim Zurücksetzen des Passworts
"emailSent": "A link to reset your password has been sent to your email address.", // Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail-Adresse gesendet.
"emailError": "Error sending email" // Fehler beim Senden der E-Mail
},
"errors": {
"fillAllFields": "Please fill in all fields", // Bitte füllen Sie alle Felder aus
"invalidEmail": "Please enter a valid email address", // Bitte geben Sie eine gültige E-Mail-Adresse ein
"passwordsNotMatch": "The passwords do not match", // Die Passwörter stimmen nicht überein
"passwordsNotMatchShort": "Passwords do not match", // Passwörter stimmen nicht überein
"enterEmail": "Please enter your email address", // Bitte geben Sie Ihre E-Mail-Adresse ein
"loginFailed": "Login failed", // Anmeldung fehlgeschlagen
"registerFailed": "Registration failed", // Registrierung fehlgeschlagen
"googleLoginFailed": "Google login failed", // Google-Anmeldung fehlgeschlagen
"emailExists": "A user with this email address already exists. Please use another email address or log in." // Ein Benutzer mit dieser E-Mail-Adresse existiert bereits. Bitte verwenden Sie eine andere E-Mail-Adresse oder melden Sie sich an.
},
"success": {
"registerComplete": "Registration successful. You can now log in." // Registrierung erfolgreich. Sie können sich jetzt anmelden.
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "In progress", // in Bearbeitung "new": "in progress", // in Bearbeitung
"pending": "New", // Neu "pending": "New", // Neu
"processing": "In progress", // in Bearbeitung "processing": "in progress", // in Bearbeitung
"paid": "Paid", // Bezahlt
"cancelled": "Cancelled", // Storniert "cancelled": "Cancelled", // Storniert
"shipped": "Shipped", // Verschickt "shipped": "Shipped", // Verschickt
"delivered": "Delivered", // Geliefert "delivered": "Delivered", // Geliefert
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Cancel order" // Bestellung stornieren "cancelOrder": "Cancel order" // Bestellung stornieren
}, },
"noOrders": "You have not placed any orders yet.", // Sie haben noch keine Bestellungen aufgegeben. "noOrders": "You have not placed any orders yet.", // Sie haben noch keine Bestellungen aufgegeben.
"trackShipment": "Track shipment", // Sendung verfolgen
"details": { "details": {
"title": "Order details: {{orderId}}", // Bestelldetails: {{orderId}} "title": "Order details: {{orderId}}", // Bestelldetails: {{orderId}}
"deliveryAddress": "Delivery address", // Lieferadresse "deliveryAddress": "Delivery address", // Lieferadresse
@@ -36,15 +38,14 @@ export default {
"item": "Item", // Artikel "item": "Item", // Artikel
"quantity": "Quantity", // Menge "quantity": "Quantity", // Menge
"price": "Price", // Preis "price": "Price", // Preis
"vat": "VAT", // MwSt.
"total": "Total", // Gesamt "total": "Total", // Gesamt
"cancelOrder": "Cancel order" // Bestellung stornieren "cancelOrder": "Cancel order" // Bestellung stornieren
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Cancel Order", "title": "Cancel order", // Bestellung stornieren
"message": "Are you sure you want to cancel this order?", "message": "Are you sure you want to cancel this order?", // Sind Sie sicher, dass Sie diese Bestellung stornieren möchten?
"confirm": "Cancel Order", "confirm": "Cancel", // Stornieren
"cancelling": "Cancelling..." "cancelling": "Cancelling..." // Wird storniert...
}, },
"processing": "Order is being completed...", // Bestellung wird abgeschlossen... "processing": "Order is being completed..." // Bestellung wird abgeschlossen...
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Perfil", "profile": "Perfil",
"email": "Correo electrónico", "email": "Correo electrónico",
"password": "Contraseña", "password": "Contraseña",
"newPassword": "Nueva contraseña",
"confirmPassword": "Confirmar contraseña", "confirmPassword": "Confirmar contraseña",
"forgotPassword": "¿Olvidaste tu contraseña?", "forgotPassword": "¿Olvidaste tu contraseña?",
"loginWithGoogle": "Iniciar sesión con Google", "loginWithGoogle": "Iniciar sesión con Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Política de privacidad", "privacyPolicy": "Política de privacidad",
"passwordMinLength": "La contraseña debe tener al menos 8 caracteres", "passwordMinLength": "La contraseña debe tener al menos 8 caracteres",
"newPasswordMinLength": "La nueva contraseña debe tener al menos 8 caracteres", "newPasswordMinLength": "La nueva contraseña debe tener al menos 8 caracteres",
"backToHome": "Volver a la página principal",
"menu": { "menu": {
"profile": "Perfil", "profile": "Perfil",
"myProfile": "Mi perfil", "myProfile": "Mi perfil",
@@ -21,5 +23,28 @@ export default {
"settings": "Configuración", "settings": "Configuración",
"adminDashboard": "Panel de administración", "adminDashboard": "Panel de administración",
"adminUsers": "Usuarios administradores" "adminUsers": "Usuarios administradores"
},
"resetPassword": {
"title": "Restablecer contraseña",
"button": "Restablecer contraseña",
"success": "¡Tu contraseña ha sido restablecida con éxito! Serás redirigido para iniciar sesión en breve...",
"invalidToken": "No se encontró un token válido. Por favor, usa el enlace de tu correo electrónico.",
"error": "Error al restablecer la contraseña",
"emailSent": "Se ha enviado un enlace para restablecer tu contraseña a tu dirección de correo electrónico.",
"emailError": "Error al enviar el correo electrónico"
},
"errors": {
"fillAllFields": "Por favor, completa todos los campos",
"invalidEmail": "Por favor, introduce una dirección de correo electrónico válida",
"passwordsNotMatch": "Las contraseñas no coinciden",
"passwordsNotMatchShort": "Las contraseñas no coinciden",
"enterEmail": "Por favor, introduce tu dirección de correo electrónico",
"loginFailed": "Error al iniciar sesión",
"registerFailed": "Error al registrarse",
"googleLoginFailed": "Error al iniciar sesión con Google",
"emailExists": "Ya existe un usuario con esta dirección de correo electrónico. Por favor, usa otra dirección de correo electrónico o inicia sesión."
},
"success": {
"registerComplete": "Registro exitoso. Ahora puedes iniciar sesión."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "En progreso", "new": "en progreso",
"pending": "Nuevo", "pending": "Nuevo",
"processing": "En progreso", "processing": "en progreso",
"paid": "Pagado",
"cancelled": "Cancelado", "cancelled": "Cancelado",
"shipped": "Enviado", "shipped": "Enviado",
"delivered": "Entregado", "delivered": "Entregado",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Cancelar pedido" "cancelOrder": "Cancelar pedido"
}, },
"noOrders": "Aún no has realizado ningún pedido.", "noOrders": "Aún no has realizado ningún pedido.",
"trackShipment": "Rastrear envío",
"details": { "details": {
"title": "Detalles del pedido: {{orderId}}", "title": "Detalles del pedido: {{orderId}}",
"deliveryAddress": "Dirección de entrega", "deliveryAddress": "Dirección de entrega",
@@ -36,15 +38,14 @@ export default {
"item": "Artículo", "item": "Artículo",
"quantity": "Cantidad", "quantity": "Cantidad",
"price": "Precio", "price": "Precio",
"vat": "IVA",
"total": "Total", "total": "Total",
"cancelOrder": "Cancelar pedido" "cancelOrder": "Cancelar pedido"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Cancelar pedido", "title": "Cancelar pedido",
"message": "¿Estás seguro de que deseas cancelar este pedido?", "message": "¿Está seguro de que desea cancelar este pedido?",
"confirm": "Cancelar pedido", "confirm": "Cancelar",
"cancelling": "Cancelando..." "cancelling": "Cancelando..."
}, },
"processing": "El pedido se está completando...", "processing": "El pedido se está completando..."
}; };

View File

@@ -1,10 +1,11 @@
export default { export default {
"login": "Connexion", "login": "Connexion",
"register": "S'inscrire", "register": "Inscription",
"logout": "Déconnexion", "logout": "Déconnexion",
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Mot de passe", "password": "Mot de passe",
"newPassword": "Nouveau mot de passe",
"confirmPassword": "Confirmer le mot de passe", "confirmPassword": "Confirmer le mot de passe",
"forgotPassword": "Mot de passe oublié ?", "forgotPassword": "Mot de passe oublié ?",
"loginWithGoogle": "Se connecter avec Google", "loginWithGoogle": "Se connecter avec Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Politique de confidentialité", "privacyPolicy": "Politique de confidentialité",
"passwordMinLength": "Le mot de passe doit contenir au moins 8 caractères", "passwordMinLength": "Le mot de passe doit contenir au moins 8 caractères",
"newPasswordMinLength": "Le nouveau mot de passe doit contenir au moins 8 caractères", "newPasswordMinLength": "Le nouveau mot de passe doit contenir au moins 8 caractères",
"backToHome": "Retour à la page d'accueil",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Mon profil", "myProfile": "Mon profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Paramètres", "settings": "Paramètres",
"adminDashboard": "Tableau de bord Admin", "adminDashboard": "Tableau de bord Admin",
"adminUsers": "Utilisateurs Admin" "adminUsers": "Utilisateurs Admin"
},
"resetPassword": {
"title": "Réinitialiser le mot de passe",
"button": "Réinitialiser le mot de passe",
"success": "Votre mot de passe a été réinitialisé avec succès ! Vous serez redirigé vers la connexion sous peu...",
"invalidToken": "Aucun jeton valide trouvé. Veuillez utiliser le lien de votre email.",
"error": "Erreur lors de la réinitialisation du mot de passe",
"emailSent": "Un lien pour réinitialiser votre mot de passe a été envoyé à votre adresse email.",
"emailError": "Erreur lors de l'envoi de l'email"
},
"errors": {
"fillAllFields": "Veuillez remplir tous les champs",
"invalidEmail": "Veuillez entrer une adresse email valide",
"passwordsNotMatch": "Les mots de passe ne correspondent pas",
"passwordsNotMatchShort": "Les mots de passe ne correspondent pas",
"enterEmail": "Veuillez entrer votre adresse email",
"loginFailed": "Échec de la connexion",
"registerFailed": "Échec de l'inscription",
"googleLoginFailed": "Échec de la connexion Google",
"emailExists": "Un utilisateur avec cette adresse email existe déjà. Veuillez utiliser une autre adresse email ou vous connecter."
},
"success": {
"registerComplete": "Inscription réussie. Vous pouvez maintenant vous connecter."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "En cours", "new": "en cours",
"pending": "Nouveau", "pending": "Nouveau",
"processing": "En cours", "processing": "en cours",
"paid": "Payé",
"cancelled": "Annulé", "cancelled": "Annulé",
"shipped": "Expédié", "shipped": "Expédié",
"delivered": "Livré", "delivered": "Livré",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Annuler la commande" "cancelOrder": "Annuler la commande"
}, },
"noOrders": "Vous n'avez pas encore passé de commandes.", "noOrders": "Vous n'avez pas encore passé de commandes.",
"trackShipment": "Suivre l'envoi",
"details": { "details": {
"title": "Détails de la commande : {{orderId}}", "title": "Détails de la commande : {{orderId}}",
"deliveryAddress": "Adresse de livraison", "deliveryAddress": "Adresse de livraison",
@@ -36,14 +38,13 @@ export default {
"item": "Article", "item": "Article",
"quantity": "Quantité", "quantity": "Quantité",
"price": "Prix", "price": "Prix",
"vat": "TVA",
"total": "Total", "total": "Total",
"cancelOrder": "Annuler la commande" "cancelOrder": "Annuler la commande"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Annuler la commande", "title": "Annuler la commande",
"message": "Êtes-vous sûr de vouloir annuler cette commande ?", "message": "Êtes-vous sûr de vouloir annuler cette commande ?",
"confirm": "Annuler la commande", "confirm": "Annuler",
"cancelling": "Annulation en cours..." "cancelling": "Annulation en cours..."
}, },
"processing": "La commande est en cours de traitement..." "processing": "La commande est en cours de traitement..."

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Lozinka", "password": "Lozinka",
"newPassword": "Nova lozinka",
"confirmPassword": "Potvrdi lozinku", "confirmPassword": "Potvrdi lozinku",
"forgotPassword": "Zaboravili ste lozinku?", "forgotPassword": "Zaboravili ste lozinku?",
"loginWithGoogle": "Prijavite se putem Googlea", "loginWithGoogle": "Prijavite se putem Googlea",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Pravila privatnosti", "privacyPolicy": "Pravila privatnosti",
"passwordMinLength": "Lozinka mora imati najmanje 8 znakova", "passwordMinLength": "Lozinka mora imati najmanje 8 znakova",
"newPasswordMinLength": "Nova lozinka mora imati najmanje 8 znakova", "newPasswordMinLength": "Nova lozinka mora imati najmanje 8 znakova",
"backToHome": "Natrag na početnu stranicu",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Moj profil", "myProfile": "Moj profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Postavke", "settings": "Postavke",
"adminDashboard": "Admin nadzorna ploča", "adminDashboard": "Admin nadzorna ploča",
"adminUsers": "Admin korisnici" "adminUsers": "Admin korisnici"
},
"resetPassword": {
"title": "Resetiraj lozinku",
"button": "Resetiraj lozinku",
"success": "Vaša lozinka je uspješno resetirana! Uskoro ćete biti preusmjereni na prijavu...",
"invalidToken": "Nije pronađen valjani token. Molimo koristite link iz vaše e-pošte.",
"error": "Pogreška pri resetiranju lozinke",
"emailSent": "Link za resetiranje lozinke poslan je na vašu e-mail adresu.",
"emailError": "Pogreška pri slanju e-pošte"
},
"errors": {
"fillAllFields": "Molimo ispunite sva polja",
"invalidEmail": "Molimo unesite valjanu e-mail adresu",
"passwordsNotMatch": "Lozinke se ne podudaraju",
"passwordsNotMatchShort": "Lozinke se ne podudaraju",
"enterEmail": "Molimo unesite vašu e-mail adresu",
"loginFailed": "Prijava nije uspjela",
"registerFailed": "Registracija nije uspjela",
"googleLoginFailed": "Prijava putem Googlea nije uspjela",
"emailExists": "Korisnik s ovom e-mail adresom već postoji. Molimo koristite drugu e-mail adresu ili se prijavite."
},
"success": {
"registerComplete": "Registracija uspješna. Sada se možete prijaviti."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "U tijeku", "new": "u tijeku",
"pending": "Novo", "pending": "Novo",
"processing": "U tijeku", "processing": "u tijeku",
"paid": "Plaćeno",
"cancelled": "Otkazano", "cancelled": "Otkazano",
"shipped": "Poslano", "shipped": "Poslano",
"delivered": "Isporučeno", "delivered": "Isporučeno",
@@ -23,7 +24,8 @@ export default {
"viewDetails": "Pogledaj detalje", "viewDetails": "Pogledaj detalje",
"cancelOrder": "Otkaži narudžbu" "cancelOrder": "Otkaži narudžbu"
}, },
"noOrders": "Još niste napravili nijednu narudžbu.", "noOrders": "Još niste izvršili nijednu narudžbu.",
"trackShipment": "Prati pošiljku",
"details": { "details": {
"title": "Detalji narudžbe: {{orderId}}", "title": "Detalji narudžbe: {{orderId}}",
"deliveryAddress": "Adresa dostave", "deliveryAddress": "Adresa dostave",
@@ -36,15 +38,14 @@ export default {
"item": "Artikl", "item": "Artikl",
"quantity": "Količina", "quantity": "Količina",
"price": "Cijena", "price": "Cijena",
"vat": "PDV",
"total": "Ukupno", "total": "Ukupno",
"cancelOrder": "Otkaži narudžbu" "cancelOrder": "Otkaži narudžbu"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Otkaži narudžbu", "title": "Otkaži narudžbu",
"message": "Jeste li sigurni da želite otkazati ovu narudžbu?", "message": "Jeste li sigurni da želite otkazati ovu narudžbu?",
"confirm": "Otkaži narudžbu", "confirm": "Otkaži",
"cancelling": "Otkazivanje..." "cancelling": "Otkazivanje..."
}, },
"processing": "Narudžba se dovršava...", "processing": "Narudžba se obrađuje..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Jelszó", "password": "Jelszó",
"newPassword": "Új jelszó",
"confirmPassword": "Jelszó megerősítése", "confirmPassword": "Jelszó megerősítése",
"forgotPassword": "Elfelejtett jelszó?", "forgotPassword": "Elfelejtett jelszó?",
"loginWithGoogle": "Bejelentkezés Google-lal", "loginWithGoogle": "Bejelentkezés Google-lal",
@@ -13,13 +14,37 @@ export default {
"privacyPolicy": "Adatvédelmi szabályzatot", "privacyPolicy": "Adatvédelmi szabályzatot",
"passwordMinLength": "A jelszónak legalább 8 karakter hosszúnak kell lennie", "passwordMinLength": "A jelszónak legalább 8 karakter hosszúnak kell lennie",
"newPasswordMinLength": "Az új jelszónak legalább 8 karakter hosszúnak kell lennie", "newPasswordMinLength": "Az új jelszónak legalább 8 karakter hosszúnak kell lennie",
"backToHome": "Vissza a kezdőlapra",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Saját profilom", "myProfile": "Saját profil",
"checkout": "Pénztár", "checkout": "Pénztár",
"orders": "Rendelések", "orders": "Rendelések",
"settings": "Beállítások", "settings": "Beállítások",
"adminDashboard": "Admin Vezérlőpult", "adminDashboard": "Admin Vezérlőpult",
"adminUsers": "Admin Felhasználók" "adminUsers": "Admin Felhasználók"
},
"resetPassword": {
"title": "Jelszó visszaállítása",
"button": "Jelszó visszaállítása",
"success": "A jelszavad sikeresen visszaállítva! Hamarosan átirányítunk a bejelentkezéshez...",
"invalidToken": "Érvényes token nem található. Kérjük, használd az emailedben található linket.",
"error": "Hiba történt a jelszó visszaállítása során",
"emailSent": "Egy link a jelszó visszaállításához elküldésre került az email címedre.",
"emailError": "Hiba történt az email küldése során"
},
"errors": {
"fillAllFields": "Kérjük, tölts ki minden mezőt",
"invalidEmail": "Kérjük, adj meg egy érvényes email címet",
"passwordsNotMatch": "A jelszavak nem egyeznek",
"passwordsNotMatchShort": "A jelszavak nem egyeznek",
"enterEmail": "Kérjük, add meg az email címed",
"loginFailed": "Bejelentkezés sikertelen",
"registerFailed": "Regisztráció sikertelen",
"googleLoginFailed": "Google bejelentkezés sikertelen",
"emailExists": "Már létezik felhasználó ezzel az email címmel. Kérjük, használj másik email címet vagy jelentkezz be."
},
"success": {
"registerComplete": "Sikeres regisztráció. Most már bejelentkezhetsz."
} }
}; };

View File

@@ -1,14 +1,15 @@
export default { export default {
"status": { "status": {
"new": "Folyamatban", "new": "feldolgozás alatt",
"pending": "Új", "pending": "Új",
"processing": "Folyamatban", "processing": "feldolgozás alatt",
"paid": "Fizetve",
"cancelled": "Törölve", "cancelled": "Törölve",
"shipped": "Kiszállítva", "shipped": "Feladva",
"delivered": "Kézbesítve", "delivered": "Kiszállítva",
"return": "Visszaküldés", "return": "Visszaküldés",
"partialReturn": "Részleges visszaküldés", "partialReturn": "Részleges visszaküldés",
"partialDelivered": "Részben kézbesítve" "partialDelivered": "Részben kiszállítva"
}, },
"table": { "table": {
"orderNumber": "Rendelésszám", "orderNumber": "Rendelésszám",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Rendelés törlése" "cancelOrder": "Rendelés törlése"
}, },
"noOrders": "Még nem adott le rendelést.", "noOrders": "Még nem adott le rendelést.",
"trackShipment": "Szállítmány követése",
"details": { "details": {
"title": "Rendelés részletei: {{orderId}}", "title": "Rendelés részletei: {{orderId}}",
"deliveryAddress": "Szállítási cím", "deliveryAddress": "Szállítási cím",
@@ -36,14 +38,13 @@ export default {
"item": "Termék", "item": "Termék",
"quantity": "Mennyiség", "quantity": "Mennyiség",
"price": "Ár", "price": "Ár",
"vat": "ÁFA",
"total": "Összesen", "total": "Összesen",
"cancelOrder": "Rendelés törlése" "cancelOrder": "Rendelés törlése"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Rendelés törlése", "title": "Rendelés törlése",
"message": "Biztosan törölni szeretné ezt a rendelést?", "message": "Biztosan törölni szeretné ezt a rendelést?",
"confirm": "Rendelés törlése", "confirm": "Törlés",
"cancelling": "Törlés folyamatban..." "cancelling": "Törlés folyamatban..."
}, },
"processing": "A rendelés feldolgozása folyamatban..." "processing": "A rendelés feldolgozása folyamatban..."

View File

@@ -5,21 +5,46 @@ export default {
"profile": "Profilo", "profile": "Profilo",
"email": "Email", "email": "Email",
"password": "Password", "password": "Password",
"newPassword": "Nuova password",
"confirmPassword": "Conferma password", "confirmPassword": "Conferma password",
"forgotPassword": "Password dimenticata?", "forgotPassword": "Password dimenticata?",
"loginWithGoogle": "Accedi con Google", "loginWithGoogle": "Accedi con Google",
"or": "O", "or": "O",
"privacyAccept": "Cliccando su \"Accedi con Google\" accetto la", "privacyAccept": "Cliccando su \"Accedi con Google\" accetto la",
"privacyPolicy": "Informativa sulla privacy", "privacyPolicy": "Privacy policy",
"passwordMinLength": "La password deve contenere almeno 8 caratteri", "passwordMinLength": "La password deve contenere almeno 8 caratteri",
"newPasswordMinLength": "La nuova password deve contenere almeno 8 caratteri", "newPasswordMinLength": "La nuova password deve contenere almeno 8 caratteri",
"backToHome": "Torna alla homepage",
"menu": { "menu": {
"profile": "Profilo", "profile": "Profilo",
"myProfile": "Il mio profilo", "myProfile": "Il mio profilo",
"checkout": "Pagamento", "checkout": "Checkout",
"orders": "Ordini", "orders": "Ordini",
"settings": "Impostazioni", "settings": "Impostazioni",
"adminDashboard": "Pannello di amministrazione", "adminDashboard": "Admin Dashboard",
"adminUsers": "Utenti amministratori" "adminUsers": "Admin Users"
},
"resetPassword": {
"title": "Reimposta password",
"button": "Reimposta password",
"success": "La tua password è stata reimpostata con successo! Verrai reindirizzato alla pagina di accesso a breve...",
"invalidToken": "Nessun token valido trovato. Per favore usa il link nella tua email.",
"error": "Errore durante la reimpostazione della password",
"emailSent": "Un link per reimpostare la password è stato inviato al tuo indirizzo email.",
"emailError": "Errore nell'invio dell'email"
},
"errors": {
"fillAllFields": "Per favore compila tutti i campi",
"invalidEmail": "Per favore inserisci un indirizzo email valido",
"passwordsNotMatch": "Le password non corrispondono",
"passwordsNotMatchShort": "Le password non corrispondono",
"enterEmail": "Per favore inserisci il tuo indirizzo email",
"loginFailed": "Accesso fallito",
"registerFailed": "Registrazione fallita",
"googleLoginFailed": "Accesso con Google fallito",
"emailExists": "Esiste già un utente con questo indirizzo email. Per favore usa un altro indirizzo email o accedi."
},
"success": {
"registerComplete": "Registrazione completata con successo. Ora puoi accedere."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "In lavorazione", "new": "in lavorazione",
"pending": "Nuovo", "pending": "Nuovo",
"processing": "In lavorazione", "processing": "in lavorazione",
"paid": "Pagato",
"cancelled": "Annullato", "cancelled": "Annullato",
"shipped": "Spedito", "shipped": "Spedito",
"delivered": "Consegnato", "delivered": "Consegnato",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Annulla ordine" "cancelOrder": "Annulla ordine"
}, },
"noOrders": "Non hai ancora effettuato ordini.", "noOrders": "Non hai ancora effettuato ordini.",
"trackShipment": "Traccia spedizione",
"details": { "details": {
"title": "Dettagli ordine: {{orderId}}", "title": "Dettagli ordine: {{orderId}}",
"deliveryAddress": "Indirizzo di consegna", "deliveryAddress": "Indirizzo di consegna",
@@ -36,15 +38,14 @@ export default {
"item": "Articolo", "item": "Articolo",
"quantity": "Quantità", "quantity": "Quantità",
"price": "Prezzo", "price": "Prezzo",
"vat": "IVA",
"total": "Totale", "total": "Totale",
"cancelOrder": "Annulla ordine" "cancelOrder": "Annulla ordine"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Annulla ordine", "title": "Annulla ordine",
"message": "Sei sicuro di voler annullare questo ordine?", "message": "Sei sicuro di voler annullare questo ordine?",
"confirm": "Annulla ordine", "confirm": "Annulla",
"cancelling": "Annullamento in corso..." "cancelling": "Annullamento in corso..."
}, },
"processing": "Ordine in elaborazione..." "processing": "Ordine in fase di completamento..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Hasło", "password": "Hasło",
"newPassword": "Nowe hasło",
"confirmPassword": "Potwierdź hasło", "confirmPassword": "Potwierdź hasło",
"forgotPassword": "Zapomniałeś hasła?", "forgotPassword": "Zapomniałeś hasła?",
"loginWithGoogle": "Zaloguj się przez Google", "loginWithGoogle": "Zaloguj się przez Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Politykę prywatności", "privacyPolicy": "Politykę prywatności",
"passwordMinLength": "Hasło musi mieć co najmniej 8 znaków", "passwordMinLength": "Hasło musi mieć co najmniej 8 znaków",
"newPasswordMinLength": "Nowe hasło musi mieć co najmniej 8 znaków", "newPasswordMinLength": "Nowe hasło musi mieć co najmniej 8 znaków",
"backToHome": "Powrót do strony głównej",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Mój profil", "myProfile": "Mój profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Ustawienia", "settings": "Ustawienia",
"adminDashboard": "Panel administratora", "adminDashboard": "Panel administratora",
"adminUsers": "Użytkownicy administratora" "adminUsers": "Użytkownicy administratora"
},
"resetPassword": {
"title": "Resetowanie hasła",
"button": "Resetuj hasło",
"success": "Twoje hasło zostało pomyślnie zresetowane! Wkrótce nastąpi przekierowanie do logowania...",
"invalidToken": "Nie znaleziono ważnego tokenu. Proszę użyć linku z e-maila.",
"error": "Błąd podczas resetowania hasła",
"emailSent": "Link do resetowania hasła został wysłany na Twój adres e-mail.",
"emailError": "Błąd podczas wysyłania e-maila"
},
"errors": {
"fillAllFields": "Proszę wypełnić wszystkie pola",
"invalidEmail": "Proszę podać prawidłowy adres e-mail",
"passwordsNotMatch": "Hasła nie są zgodne",
"passwordsNotMatchShort": "Hasła nie są zgodne",
"enterEmail": "Proszę podać swój adres e-mail",
"loginFailed": "Logowanie nie powiodło się",
"registerFailed": "Rejestracja nie powiodła się",
"googleLoginFailed": "Logowanie przez Google nie powiodło się",
"emailExists": "Użytkownik z tym adresem e-mail już istnieje. Proszę użyć innego adresu e-mail lub się zalogować."
},
"success": {
"registerComplete": "Rejestracja zakończona sukcesem. Możesz się teraz zalogować."
} }
}; };

View File

@@ -1,14 +1,15 @@
export default { export default {
"status": { "status": {
"new": "W trakcie realizacji", "new": "w trakcie realizacji",
"pending": "Nowe", "pending": "Nowe",
"processing": "W trakcie realizacji", "processing": "w trakcie realizacji",
"cancelled": "Anulowano", "paid": "Opłacone",
"shipped": "Wysłano", "cancelled": "Anulowane",
"delivered": "Dostarczono", "shipped": "Wysłane",
"delivered": "Dostarczone",
"return": "Zwrot", "return": "Zwrot",
"partialReturn": "Częściowy zwrot", "partialReturn": "Częściowy zwrot",
"partialDelivered": "Częściowo dostarczono" "partialDelivered": "Częściowo dostarczone"
}, },
"table": { "table": {
"orderNumber": "Numer zamówienia", "orderNumber": "Numer zamówienia",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Anuluj zamówienie" "cancelOrder": "Anuluj zamówienie"
}, },
"noOrders": "Nie złożyłeś jeszcze żadnych zamówień.", "noOrders": "Nie złożyłeś jeszcze żadnych zamówień.",
"trackShipment": "Śledź przesyłkę",
"details": { "details": {
"title": "Szczegóły zamówienia: {{orderId}}", "title": "Szczegóły zamówienia: {{orderId}}",
"deliveryAddress": "Adres dostawy", "deliveryAddress": "Adres dostawy",
@@ -36,15 +38,14 @@ export default {
"item": "Produkt", "item": "Produkt",
"quantity": "Ilość", "quantity": "Ilość",
"price": "Cena", "price": "Cena",
"vat": "VAT",
"total": "Razem", "total": "Razem",
"cancelOrder": "Anuluj zamówienie" "cancelOrder": "Anuluj zamówienie"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Anuluj zamówienie", "title": "Anuluj zamówienie",
"message": "Czy na pewno chcesz anulować to zamówienie?", "message": "Czy na pewno chcesz anulować to zamówienie?",
"confirm": "Anuluj zamówienie", "confirm": "Anuluj",
"cancelling": "Anulowanie..." "cancelling": "Anulowanie..."
}, },
"processing": "Zamówienie jest realizowane...", "processing": "Zamówienie jest realizowane..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Parolă", "password": "Parolă",
"newPassword": "Parolă nouă",
"confirmPassword": "Confirmă parola", "confirmPassword": "Confirmă parola",
"forgotPassword": "Ai uitat parola?", "forgotPassword": "Ai uitat parola?",
"loginWithGoogle": "Autentifică-te cu Google", "loginWithGoogle": "Autentifică-te cu Google",
@@ -12,14 +13,38 @@ export default {
"privacyAccept": "Prin clic pe „Autentifică-te cu Google” accept", "privacyAccept": "Prin clic pe „Autentifică-te cu Google” accept",
"privacyPolicy": "Politica de confidențialitate", "privacyPolicy": "Politica de confidențialitate",
"passwordMinLength": "Parola trebuie să aibă cel puțin 8 caractere", "passwordMinLength": "Parola trebuie să aibă cel puțin 8 caractere",
"newPasswordMinLength": "Noua parolă trebuie să aibă cel puțin 8 caractere", "newPasswordMinLength": "Parola nouă trebuie să aibă cel puțin 8 caractere",
"backToHome": "Înapoi la pagina principală",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Profilul meu", "myProfile": "Profilul meu",
"checkout": "Finalizare comandă", "checkout": "Finalizare comandă",
"orders": "Comenzi", "orders": "Comenzi",
"settings": "Setări", "settings": "Setări",
"adminDashboard": "Panou de administrare", "adminDashboard": "Panou Admin",
"adminUsers": "Utilizatori administratori" "adminUsers": "Utilizatori Admin"
},
"resetPassword": {
"title": "Resetează parola",
"button": "Resetează parola",
"success": "Parola ta a fost resetată cu succes! Vei fi redirecționat către autentificare în scurt timp...",
"invalidToken": "Nu a fost găsit un token valid. Te rugăm să folosești linkul din emailul tău.",
"error": "Eroare la resetarea parolei",
"emailSent": "Un link pentru resetarea parolei a fost trimis la adresa ta de email.",
"emailError": "Eroare la trimiterea emailului"
},
"errors": {
"fillAllFields": "Te rugăm să completezi toate câmpurile",
"invalidEmail": "Te rugăm să introduci o adresă de email validă",
"passwordsNotMatch": "Parolele nu coincid",
"passwordsNotMatchShort": "Parolele nu coincid",
"enterEmail": "Te rugăm să introduci adresa ta de email",
"loginFailed": "Autentificare eșuată",
"registerFailed": "Înregistrare eșuată",
"googleLoginFailed": "Autentificare Google eșuată",
"emailExists": "Un utilizator cu această adresă de email există deja. Te rugăm să folosești o altă adresă de email sau să te autentifici."
},
"success": {
"registerComplete": "Înregistrare reușită. Acum te poți autentifica."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "În curs", "new": "în curs",
"pending": "Nou", "pending": "Nou",
"processing": "În curs", "processing": "în curs",
"paid": "Plătit",
"cancelled": "Anulat", "cancelled": "Anulat",
"shipped": "Expediat", "shipped": "Expediat",
"delivered": "Livrat", "delivered": "Livrat",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Anulează comanda" "cancelOrder": "Anulează comanda"
}, },
"noOrders": "Nu ați plasat încă nicio comandă.", "noOrders": "Nu ați plasat încă nicio comandă.",
"trackShipment": "Urmărește expedierea",
"details": { "details": {
"title": "Detalii comandă: {{orderId}}", "title": "Detalii comandă: {{orderId}}",
"deliveryAddress": "Adresa de livrare", "deliveryAddress": "Adresa de livrare",
@@ -36,14 +38,13 @@ export default {
"item": "Articol", "item": "Articol",
"quantity": "Cantitate", "quantity": "Cantitate",
"price": "Preț", "price": "Preț",
"vat": "TVA",
"total": "Total", "total": "Total",
"cancelOrder": "Anulează comanda" "cancelOrder": "Anulează comanda"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Anulează comanda", "title": "Anulează comanda",
"message": "Sigur doriți să anulați această comandă?", "message": "Sigur doriți să anulați această comandă?",
"confirm": "Anulează comanda", "confirm": "Anulează",
"cancelling": "Se anulează..." "cancelling": "Se anulează..."
}, },
"processing": "Comanda este în curs de finalizare..." "processing": "Comanda este în curs de finalizare..."

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Профиль", "profile": "Профиль",
"email": "Электронная почта", "email": "Электронная почта",
"password": "Пароль", "password": "Пароль",
"newPassword": "Новый пароль",
"confirmPassword": "Подтвердите пароль", "confirmPassword": "Подтвердите пароль",
"forgotPassword": "Забыли пароль?", "forgotPassword": "Забыли пароль?",
"loginWithGoogle": "Войти через Google", "loginWithGoogle": "Войти через Google",
"or": "ИЛИ", "or": "ИЛИ",
"privacyAccept": "Нажимая «Войти через Google», я принимаю", "privacyAccept": "Нажимая на \"Войти через Google\", я принимаю",
"privacyPolicy": "Политику конфиденциальности", "privacyPolicy": "Политику конфиденциальности",
"passwordMinLength": "Пароль должен содержать не менее 8 символов", "passwordMinLength": "Пароль должен содержать не менее 8 символов",
"newPasswordMinLength": "Новый пароль должен содержать не менее 8 символов", "newPasswordMinLength": "Новый пароль должен содержать не менее 8 символов",
"backToHome": "Вернуться на главную страницу",
"menu": { "menu": {
"profile": "Профиль", "profile": "Профиль",
"myProfile": "Мой профиль", "myProfile": "Мой профиль",
@@ -21,5 +23,28 @@ export default {
"settings": "Настройки", "settings": "Настройки",
"adminDashboard": "Панель администратора", "adminDashboard": "Панель администратора",
"adminUsers": "Пользователи администратора" "adminUsers": "Пользователи администратора"
},
"resetPassword": {
"title": "Сброс пароля",
"button": "Сбросить пароль",
"success": "Ваш пароль успешно сброшен! Скоро вы будете перенаправлены на страницу входа...",
"invalidToken": "Действительный токен не найден. Пожалуйста, используйте ссылку из вашего письма.",
"error": "Ошибка при сбросе пароля",
"emailSent": "Ссылка для сброса пароля была отправлена на ваш адрес электронной почты.",
"emailError": "Ошибка при отправке письма"
},
"errors": {
"fillAllFields": "Пожалуйста, заполните все поля",
"invalidEmail": "Пожалуйста, введите действительный адрес электронной почты",
"passwordsNotMatch": "Пароли не совпадают",
"passwordsNotMatchShort": "Пароли не совпадают",
"enterEmail": "Пожалуйста, введите ваш адрес электронной почты",
"loginFailed": "Не удалось войти",
"registerFailed": "Не удалось зарегистрироваться",
"googleLoginFailed": "Не удалось войти через Google",
"emailExists": "Пользователь с таким адресом электронной почты уже существует. Пожалуйста, используйте другой адрес электронной почты или войдите в систему."
},
"success": {
"registerComplete": "Регистрация прошла успешно. Теперь вы можете войти."
} }
}; };

View File

@@ -1,14 +1,15 @@
export default { export default {
"status": { "status": {
"new": "В процессе", "new": "в процессе",
"pending": "Новый", "pending": "Новый",
"processing": "В процессе", "processing": "в процессе",
"cancelled": "Отменён", "paid": "Оплачено",
"shipped": "Отправлен", "cancelled": "Отменено",
"delivered": "Доставлен", "shipped": "Отправлено",
"delivered": "Доставлено",
"return": "Возврат", "return": "Возврат",
"partialReturn": "Частичный возврат", "partialReturn": "Частичный возврат",
"partialDelivered": "Частично доставлен" "partialDelivered": "Частично доставлено"
}, },
"table": { "table": {
"orderNumber": "Номер заказа", "orderNumber": "Номер заказа",
@@ -23,11 +24,12 @@ export default {
"viewDetails": "Просмотреть детали", "viewDetails": "Просмотреть детали",
"cancelOrder": "Отменить заказ" "cancelOrder": "Отменить заказ"
}, },
"noOrders": "Вы ещё не сделали ни одного заказа.", "noOrders": "Вы еще не сделали ни одного заказа.",
"trackShipment": "Отследить отправление",
"details": { "details": {
"title": "Детали заказа: {{orderId}}", "title": "Детали заказа: {{orderId}}",
"deliveryAddress": "Адрес доставки", "deliveryAddress": "Адрес доставки",
"invoiceAddress": "Адрес для счёта", "invoiceAddress": "Адрес для счета",
"orderDetails": "Детали заказа", "orderDetails": "Детали заказа",
"deliveryMethod": "Способ доставки:", "deliveryMethod": "Способ доставки:",
"paymentMethod": "Способ оплаты:", "paymentMethod": "Способ оплаты:",
@@ -36,15 +38,14 @@ export default {
"item": "Товар", "item": "Товар",
"quantity": "Количество", "quantity": "Количество",
"price": "Цена", "price": "Цена",
"vat": "НДС",
"total": "Итого", "total": "Итого",
"cancelOrder": "Отменить заказ" "cancelOrder": "Отменить заказ"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Отмена заказа", "title": "Отменить заказ",
"message": "Вы уверены, что хотите отменить этот заказ?", "message": "Вы уверены, что хотите отменить этот заказ?",
"confirm": "Отменить заказ", "confirm": "Отменить",
"cancelling": "Отмена..." "cancelling": "Отмена..."
}, },
"processing": "Заказ обрабатывается...", "processing": "Заказ обрабатывается..."
}; };

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Heslo", "password": "Heslo",
"newPassword": "Nové heslo",
"confirmPassword": "Potvrdiť heslo", "confirmPassword": "Potvrdiť heslo",
"forgotPassword": "Zabudli ste heslo?", "forgotPassword": "Zabudli ste heslo?",
"loginWithGoogle": "Prihlásiť sa cez Google", "loginWithGoogle": "Prihlásiť sa cez Google",
"or": "ALEBO", "or": "ALEBO",
"privacyAccept": "Kliknutím na „Prihlásiť sa cez Google“ súhlasím s", "privacyAccept": "Kliknutím na „Prihlásiť sa cez Google“ súhlasím s",
"privacyPolicy": "Zásadami ochrany osobných údajov", "privacyPolicy": "zásadami ochrany osobných údajov",
"passwordMinLength": "Heslo musí mať aspoň 8 znakov", "passwordMinLength": "Heslo musí mať aspoň 8 znakov",
"newPasswordMinLength": "Nové heslo musí mať aspoň 8 znakov", "newPasswordMinLength": "Nové heslo musí mať aspoň 8 znakov",
"backToHome": "Späť na domovskú stránku",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Môj profil", "myProfile": "Môj profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Nastavenia", "settings": "Nastavenia",
"adminDashboard": "Admin Dashboard", "adminDashboard": "Admin Dashboard",
"adminUsers": "Admin Users" "adminUsers": "Admin Users"
},
"resetPassword": {
"title": "Obnoviť heslo",
"button": "Obnoviť heslo",
"success": "Vaše heslo bolo úspešne obnovené! Čoskoro budete presmerovaní na prihlásenie...",
"invalidToken": "Nenašiel sa platný token. Použite prosím odkaz z vášho e-mailu.",
"error": "Chyba pri obnove hesla",
"emailSent": "Odkaz na obnovenie hesla bol odoslaný na vašu e-mailovú adresu.",
"emailError": "Chyba pri odosielaní e-mailu"
},
"errors": {
"fillAllFields": "Prosím, vyplňte všetky polia",
"invalidEmail": "Zadajte platnú e-mailovú adresu",
"passwordsNotMatch": "Heslá sa nezhodujú",
"passwordsNotMatchShort": "Heslá sa nezhodujú",
"enterEmail": "Zadajte svoju e-mailovú adresu",
"loginFailed": "Prihlásenie zlyhalo",
"registerFailed": "Registrácia zlyhala",
"googleLoginFailed": "Prihlásenie cez Google zlyhalo",
"emailExists": "Používateľ s touto e-mailovou adresou už existuje. Použite prosím inú e-mailovú adresu alebo sa prihláste."
},
"success": {
"registerComplete": "Registrácia bola úspešná. Teraz sa môžete prihlásiť."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "Prebieha", "new": "v procese",
"pending": "Nové", "pending": "Nové",
"processing": "Prebieha", "processing": "v procese",
"paid": "Zaplatené",
"cancelled": "Zrušené", "cancelled": "Zrušené",
"shipped": "Odoslané", "shipped": "Odoslané",
"delivered": "Doručené", "delivered": "Doručené",
@@ -15,7 +16,7 @@ export default {
"date": "Dátum", "date": "Dátum",
"status": "Stav", "status": "Stav",
"items": "Položky", "items": "Položky",
"total": "Spolu", "total": "Celkom",
"actions": "Akcie", "actions": "Akcie",
"viewDetails": "Zobraziť detaily" "viewDetails": "Zobraziť detaily"
}, },
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Zrušiť objednávku" "cancelOrder": "Zrušiť objednávku"
}, },
"noOrders": "Ešte ste neuskutočnili žiadne objednávky.", "noOrders": "Ešte ste neuskutočnili žiadne objednávky.",
"trackShipment": "Sledovať zásielku",
"details": { "details": {
"title": "Detaily objednávky: {{orderId}}", "title": "Detaily objednávky: {{orderId}}",
"deliveryAddress": "Dodacia adresa", "deliveryAddress": "Dodacia adresa",
@@ -36,15 +38,14 @@ export default {
"item": "Položka", "item": "Položka",
"quantity": "Množstvo", "quantity": "Množstvo",
"price": "Cena", "price": "Cena",
"vat": "DPH",
"total": "Spolu", "total": "Spolu",
"cancelOrder": "Zrušiť objednávku" "cancelOrder": "Zrušiť objednávku"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Zrušiť objednávku", "title": "Zrušiť objednávku",
"message": "Naozaj chcete zrušiť túto objednávku?", "message": "Ste si istý, že chcete zrušiť túto objednávku?",
"confirm": "Zrušiť objednávku", "confirm": "Zrušiť",
"cancelling": "Zrušovanie..." "cancelling": "Zrušovanie..."
}, },
"processing": "Objednávka sa dokončuje..." "processing": "Objednávka sa spracováva..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "E-pošta", "email": "E-pošta",
"password": "Geslo", "password": "Geslo",
"newPassword": "Novo geslo",
"confirmPassword": "Potrdi geslo", "confirmPassword": "Potrdi geslo",
"forgotPassword": "Ste pozabili geslo?", "forgotPassword": "Ste pozabili geslo?",
"loginWithGoogle": "Prijava z Google", "loginWithGoogle": "Prijava z Google",
@@ -13,13 +14,37 @@ export default {
"privacyPolicy": "Pravilnik o zasebnosti", "privacyPolicy": "Pravilnik o zasebnosti",
"passwordMinLength": "Geslo mora biti dolgo vsaj 8 znakov", "passwordMinLength": "Geslo mora biti dolgo vsaj 8 znakov",
"newPasswordMinLength": "Novo geslo mora biti dolgo vsaj 8 znakov", "newPasswordMinLength": "Novo geslo mora biti dolgo vsaj 8 znakov",
"backToHome": "Nazaj na domačo stran",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Moj profil", "myProfile": "Moj profil",
"checkout": "Zaključek nakupa", "checkout": "Zaključek nakupa",
"orders": "Naročila", "orders": "Naročila",
"settings": "Nastavitve", "settings": "Nastavitve",
"adminDashboard": "Nadzorna plošča administratorja", "adminDashboard": "Administratorska nadzorna plošča",
"adminUsers": "Administratorji" "adminUsers": "Administratorski uporabniki"
},
"resetPassword": {
"title": "Ponastavi geslo",
"button": "Ponastavi geslo",
"success": "Vaše geslo je bilo uspešno ponastavljeno! Kmalu boste preusmerjeni na prijavo...",
"invalidToken": "Ni najden veljaven žeton. Prosimo, uporabite povezavo iz vašega e-poštnega sporočila.",
"error": "Napaka pri ponastavitvi gesla",
"emailSent": "Povezava za ponastavitev gesla je bila poslana na vaš e-poštni naslov.",
"emailError": "Napaka pri pošiljanju e-pošte"
},
"errors": {
"fillAllFields": "Prosimo, izpolnite vsa polja",
"invalidEmail": "Prosimo, vnesite veljaven e-poštni naslov",
"passwordsNotMatch": "Gesli se ne ujemata",
"passwordsNotMatchShort": "Gesli se ne ujemata",
"enterEmail": "Prosimo, vnesite vaš e-poštni naslov",
"loginFailed": "Prijava ni uspela",
"registerFailed": "Registracija ni uspela",
"googleLoginFailed": "Prijava z Google ni uspela",
"emailExists": "Uporabnik s tem e-poštnim naslovom že obstaja. Prosimo, uporabite drug e-poštni naslov ali se prijavite."
},
"success": {
"registerComplete": "Registracija je bila uspešna. Zdaj se lahko prijavite."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "V teku", "new": "v teku",
"pending": "Novo", "pending": "Novo",
"processing": "V teku", "processing": "v teku",
"paid": "Plačano",
"cancelled": "Preklicano", "cancelled": "Preklicano",
"shipped": "Poslano", "shipped": "Poslano",
"delivered": "Dostavljeno", "delivered": "Dostavljeno",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Prekliči naročilo" "cancelOrder": "Prekliči naročilo"
}, },
"noOrders": "Še niste oddali nobenega naročila.", "noOrders": "Še niste oddali nobenega naročila.",
"trackShipment": "Sledi pošiljki",
"details": { "details": {
"title": "Podrobnosti naročila: {{orderId}}", "title": "Podrobnosti naročila: {{orderId}}",
"deliveryAddress": "Naslov za dostavo", "deliveryAddress": "Naslov za dostavo",
@@ -36,15 +38,14 @@ export default {
"item": "Izdelek", "item": "Izdelek",
"quantity": "Količina", "quantity": "Količina",
"price": "Cena", "price": "Cena",
"vat": "DDV",
"total": "Skupaj", "total": "Skupaj",
"cancelOrder": "Prekliči naročilo" "cancelOrder": "Prekliči naročilo"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Prekliči naročilo", "title": "Prekliči naročilo",
"message": "Ste prepričani, da želite preklicati to naročilo?", "message": "Ste prepričani, da želite preklicati to naročilo?",
"confirm": "Prekliči naročilo", "confirm": "Prekliči",
"cancelling": "Preklicujem..." "cancelling": "Preklicujem..."
}, },
"processing": "Naročilo se zaključuje...", "processing": "Naročilo se zaključuje..."
}; };

View File

@@ -5,21 +5,46 @@ export default {
"profile": "Profili", "profile": "Profili",
"email": "Email", "email": "Email",
"password": "Fjalëkalimi", "password": "Fjalëkalimi",
"newPassword": "Fjalëkalim i ri",
"confirmPassword": "Konfirmo fjalëkalimin", "confirmPassword": "Konfirmo fjalëkalimin",
"forgotPassword": "Keni harruar fjalëkalimin?", "forgotPassword": "Keni harruar fjalëkalimin?",
"loginWithGoogle": "Hyr me Google", "loginWithGoogle": "Hyr me Google",
"or": "OSE", "or": "OSE",
"privacyAccept": "Duke klikuar \"Hyr me Google\" pranoj", "privacyAccept": "Duke klikuar \"Hyr me Google\" unë pranoj",
"privacyPolicy": "Politikën e Privatësisë", "privacyPolicy": "Politikën e privatësisë",
"passwordMinLength": "Fjalëkalimi duhet të ketë të paktën 8 karaktere", "passwordMinLength": "Fjalëkalimi duhet të ketë të paktën 8 karaktere",
"newPasswordMinLength": "Fjalëkalimi i ri duhet të ketë të paktën 8 karaktere", "newPasswordMinLength": "Fjalëkalimi i ri duhet të ketë të paktën 8 karaktere",
"backToHome": "Kthehu në faqen kryesore",
"menu": { "menu": {
"profile": "Profili", "profile": "Profili",
"myProfile": "Profili im", "myProfile": "Profili im",
"checkout": "Përfundimi i porosisë", "checkout": "Përfundimi i porosisë",
"orders": "Porositë", "orders": "Porositë",
"settings": "Cilësimet", "settings": "Cilësimet",
"adminDashboard": "Paneli i Administratorit", "adminDashboard": "Paneli i administratorit",
"adminUsers": "Përdoruesit e Administratorit" "adminUsers": "Përdoruesit e administratorit"
},
"resetPassword": {
"title": "Rivendos fjalëkalimin",
"button": "Rivendos fjalëkalimin",
"success": "Fjalëkalimi juaj u rivendos me sukses! Do të ridrejtoheni për t'u futur së shpejti...",
"invalidToken": "Nuk u gjet asnjë token i vlefshëm. Ju lutemi përdorni lidhjen nga emaili juaj.",
"error": "Gabim gjatë rivendosjes së fjalëkalimit",
"emailSent": "Një lidhje për rivendosjen e fjalëkalimit është dërguar në adresën tuaj të emailit.",
"emailError": "Gabim gjatë dërgimit të emailit"
},
"errors": {
"fillAllFields": "Ju lutemi plotësoni të gjitha fushat",
"invalidEmail": "Ju lutemi shkruani një adresë emaili të vlefshme",
"passwordsNotMatch": "Fjalëkalimet nuk përputhen",
"passwordsNotMatchShort": "Fjalëkalimet nuk përputhen",
"enterEmail": "Ju lutemi shkruani adresën tuaj të emailit",
"loginFailed": "Hyrja dështoi",
"registerFailed": "Regjistrimi dështoi",
"googleLoginFailed": "Hyrja me Google dështoi",
"emailExists": "Një përdorues me këtë adresë emaili ekziston tashmë. Ju lutemi përdorni një adresë tjetër emaili ose hyni."
},
"success": {
"registerComplete": "Regjistrimi u krye me sukses. Tani mund të hyni."
} }
}; };

View File

@@ -1,13 +1,14 @@
export default { export default {
"status": { "status": {
"new": "Në proces", "new": "në proces",
"pending": "E re", "pending": "E re",
"processing": "Në proces", "processing": "në proces",
"paid": "E paguar",
"cancelled": "Anuluar", "cancelled": "Anuluar",
"shipped": "Dërguar", "shipped": "Dërguar",
"delivered": "Dorëzuar", "delivered": "Dorëzuar",
"return": "Kthim", "return": "Kthim",
"partialReturn": "Kthim pjesërisht", "partialReturn": "Kthim i pjesshëm",
"partialDelivered": "Dorëzuar pjesërisht" "partialDelivered": "Dorëzuar pjesërisht"
}, },
"table": { "table": {
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Anulo porosinë" "cancelOrder": "Anulo porosinë"
}, },
"noOrders": "Nuk keni bërë ende asnjë porosi.", "noOrders": "Nuk keni bërë ende asnjë porosi.",
"trackShipment": "Ndjek dërgesën",
"details": { "details": {
"title": "Detajet e porosisë: {{orderId}}", "title": "Detajet e porosisë: {{orderId}}",
"deliveryAddress": "Adresa e dorëzimit", "deliveryAddress": "Adresa e dorëzimit",
@@ -36,15 +38,14 @@ export default {
"item": "Artikulli", "item": "Artikulli",
"quantity": "Sasia", "quantity": "Sasia",
"price": "Çmimi", "price": "Çmimi",
"vat": "TVSH",
"total": "Totali", "total": "Totali",
"cancelOrder": "Anulo porosinë" "cancelOrder": "Anulo porosinë"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Anulo Porosinë", "title": "Anulo porosinë",
"message": "A jeni i sigurt që dëshironi të anuloni këtë porosi?", "message": "A jeni i sigurt që dëshironi të anuloni këtë porosi?",
"confirm": "Anulo Porosinë", "confirm": "Anulo",
"cancelling": "Duke anuluar..." "cancelling": "Duke anuluar..."
}, },
"processing": "Porosia po përpunohet...", "processing": "Porosia po përpunohet..."
}; };

View File

@@ -5,14 +5,16 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "Email", "email": "Email",
"password": "Lozinka", "password": "Lozinka",
"newPassword": "Nova lozinka",
"confirmPassword": "Potvrdi lozinku", "confirmPassword": "Potvrdi lozinku",
"forgotPassword": "Zaboravili ste lozinku?", "forgotPassword": "Zaboravili ste lozinku?",
"loginWithGoogle": "Prijavite se sa Google-om", "loginWithGoogle": "Prijavite se putem Google-a",
"or": "ILI", "or": "ILI",
"privacyAccept": "Klikom na \"Prijavite se sa Google-om\" prihvatam", "privacyAccept": "Klikom na \"Prijavite se putem Google-a\" prihvatam",
"privacyPolicy": "Politiku privatnosti", "privacyPolicy": "Politiku privatnosti",
"passwordMinLength": "Lozinka mora imati najmanje 8 karaktera", "passwordMinLength": "Lozinka mora imati najmanje 8 karaktera",
"newPasswordMinLength": "Nova lozinka mora imati najmanje 8 karaktera", "newPasswordMinLength": "Nova lozinka mora imati najmanje 8 karaktera",
"backToHome": "Nazad na početnu stranicu",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Moj profil", "myProfile": "Moj profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Podešavanja", "settings": "Podešavanja",
"adminDashboard": "Admin kontrolna tabla", "adminDashboard": "Admin kontrolna tabla",
"adminUsers": "Admin korisnici" "adminUsers": "Admin korisnici"
},
"resetPassword": {
"title": "Resetovanje lozinke",
"button": "Resetuj lozinku",
"success": "Vaša lozinka je uspešno resetovana! Uskoro ćete biti preusmereni na prijavu...",
"invalidToken": "Nije pronađen važeći token. Molimo koristite link iz vaše email poruke.",
"error": "Greška pri resetovanju lozinke",
"emailSent": "Link za resetovanje lozinke je poslat na vašu email adresu.",
"emailError": "Greška pri slanju email-a"
},
"errors": {
"fillAllFields": "Molimo popunite sva polja",
"invalidEmail": "Molimo unesite validnu email adresu",
"passwordsNotMatch": "Lozinke se ne poklapaju",
"passwordsNotMatchShort": "Lozinke se ne poklapaju",
"enterEmail": "Molimo unesite vašu email adresu",
"loginFailed": "Prijava nije uspela",
"registerFailed": "Registracija nije uspela",
"googleLoginFailed": "Prijava putem Google-a nije uspela",
"emailExists": "Korisnik sa ovom email adresom već postoji. Molimo koristite drugu email adresu ili se prijavite."
},
"success": {
"registerComplete": "Registracija uspešna. Sada se možete prijaviti."
} }
}; };

View File

@@ -1,13 +1,14 @@
export default { export default {
"status": { "status": {
"new": "U toku", "new": "u toku",
"pending": "Novo", "pending": "Novo",
"processing": "U toku", "processing": "u toku",
"paid": "Plaćeno",
"cancelled": "Otkazano", "cancelled": "Otkazano",
"shipped": "Poslato", "shipped": "Poslato",
"delivered": "Isporučeno", "delivered": "Isporučeno",
"return": "Povraćaj", "return": "Povrat",
"partialReturn": "Delimični povraćaj", "partialReturn": "Delimični povrat",
"partialDelivered": "Delimično isporučeno" "partialDelivered": "Delimično isporučeno"
}, },
"table": { "table": {
@@ -23,7 +24,8 @@ export default {
"viewDetails": "Pogledaj detalje", "viewDetails": "Pogledaj detalje",
"cancelOrder": "Otkaži porudžbinu" "cancelOrder": "Otkaži porudžbinu"
}, },
"noOrders": "Još uvek niste napravili nijednu porudžbinu.", "noOrders": "Još niste napravili nijednu porudžbinu.",
"trackShipment": "Prati pošiljku",
"details": { "details": {
"title": "Detalji porudžbine: {{orderId}}", "title": "Detalji porudžbine: {{orderId}}",
"deliveryAddress": "Adresa za isporuku", "deliveryAddress": "Adresa za isporuku",
@@ -36,15 +38,14 @@ export default {
"item": "Artikal", "item": "Artikal",
"quantity": "Količina", "quantity": "Količina",
"price": "Cena", "price": "Cena",
"vat": "PDV",
"total": "Ukupno", "total": "Ukupno",
"cancelOrder": "Otkaži porudžbinu" "cancelOrder": "Otkaži porudžbinu"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Otkaži porudžbinu", "title": "Otkaži porudžbinu",
"message": "Da li ste sigurni da želite da otkažete ovu porudžbinu?", "message": "Da li ste sigurni da želite da otkažete ovu porudžbinu?",
"confirm": "Otkaži porudžbinu", "confirm": "Otkaži",
"cancelling": "Otkazivanje..." "cancelling": "Otkaživanje..."
}, },
"processing": "Porudžbina se obrađuje...", "processing": "Porudžbina se obrađuje..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Profil", "profile": "Profil",
"email": "E-post", "email": "E-post",
"password": "Lösenord", "password": "Lösenord",
"newPassword": "Nytt lösenord",
"confirmPassword": "Bekräfta lösenord", "confirmPassword": "Bekräfta lösenord",
"forgotPassword": "Glömt lösenord?", "forgotPassword": "Glömt lösenord?",
"loginWithGoogle": "Logga in med Google", "loginWithGoogle": "Logga in med Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Integritetspolicy", "privacyPolicy": "Integritetspolicy",
"passwordMinLength": "Lösenordet måste vara minst 8 tecken långt", "passwordMinLength": "Lösenordet måste vara minst 8 tecken långt",
"newPasswordMinLength": "Det nya lösenordet måste vara minst 8 tecken långt", "newPasswordMinLength": "Det nya lösenordet måste vara minst 8 tecken långt",
"backToHome": "Tillbaka till startsidan",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Min profil", "myProfile": "Min profil",
@@ -21,5 +23,28 @@ export default {
"settings": "Inställningar", "settings": "Inställningar",
"adminDashboard": "Admin Dashboard", "adminDashboard": "Admin Dashboard",
"adminUsers": "Admin Users" "adminUsers": "Admin Users"
},
"resetPassword": {
"title": "Återställ lösenord",
"button": "Återställ lösenord",
"success": "Ditt lösenord har återställts! Du kommer snart att omdirigeras till inloggningen...",
"invalidToken": "Ingen giltig token hittades. Vänligen använd länken från ditt e-postmeddelande.",
"error": "Fel vid återställning av lösenord",
"emailSent": "En länk för att återställa ditt lösenord har skickats till din e-postadress.",
"emailError": "Fel vid sändning av e-post"
},
"errors": {
"fillAllFields": "Vänligen fyll i alla fält",
"invalidEmail": "Ange en giltig e-postadress",
"passwordsNotMatch": "Lösenorden matchar inte",
"passwordsNotMatchShort": "Lösenorden matchar inte",
"enterEmail": "Ange din e-postadress",
"loginFailed": "Inloggning misslyckades",
"registerFailed": "Registrering misslyckades",
"googleLoginFailed": "Google-inloggning misslyckades",
"emailExists": "En användare med denna e-postadress finns redan. Vänligen använd en annan e-postadress eller logga in."
},
"success": {
"registerComplete": "Registreringen lyckades. Du kan nu logga in."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "Pågående", "new": "pågående",
"pending": "Ny", "pending": "Ny",
"processing": "Pågående", "processing": "pågående",
"paid": "Betald",
"cancelled": "Avbruten", "cancelled": "Avbruten",
"shipped": "Skickad", "shipped": "Skickad",
"delivered": "Levererad", "delivered": "Levererad",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Avbryt order" "cancelOrder": "Avbryt order"
}, },
"noOrders": "Du har inte lagt några beställningar än.", "noOrders": "Du har inte lagt några beställningar än.",
"trackShipment": "Spåra försändelse",
"details": { "details": {
"title": "Orderdetaljer: {{orderId}}", "title": "Orderdetaljer: {{orderId}}",
"deliveryAddress": "Leveransadress", "deliveryAddress": "Leveransadress",
@@ -36,14 +38,13 @@ export default {
"item": "Artikel", "item": "Artikel",
"quantity": "Antal", "quantity": "Antal",
"price": "Pris", "price": "Pris",
"vat": "Moms",
"total": "Totalt", "total": "Totalt",
"cancelOrder": "Avbryt order" "cancelOrder": "Avbryt order"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Avbryt order", "title": "Avbryt order",
"message": "Är du säker på att du vill avbryta denna order?", "message": "Är du säker på att du vill avbryta denna order?",
"confirm": "Avbryt order", "confirm": "Avbryt",
"cancelling": "Avbryter..." "cancelling": "Avbryter..."
}, },
"processing": "Ordern behandlas..." "processing": "Ordern behandlas..."

View File

@@ -4,15 +4,17 @@ export default {
"logout": ıkış Yap", "logout": ıkış Yap",
"profile": "Profil", "profile": "Profil",
"email": "E-posta", "email": "E-posta",
"password": "Şifre", "password": "Parola",
"confirmPassword": "Şifreyi Onayla", "newPassword": "Yeni parola",
"forgotPassword": "Şifrenizi mi unuttunuz?", "confirmPassword": "Parolayı onayla",
"forgotPassword": "Parolanızı mı unuttunuz?",
"loginWithGoogle": "Google ile giriş yap", "loginWithGoogle": "Google ile giriş yap",
"or": "VEYA", "or": "VEYA",
"privacyAccept": "\"Google ile giriş yap\" butonuna tıklayarak", "privacyAccept": "\"Google ile giriş yap\" butonuna tıklayarak",
"privacyPolicy": "Gizlilik Politikasını", "privacyPolicy": "Gizlilik politikasını",
"passwordMinLength": "Şifre en az 8 karakter uzunluğunda olmalıdır", "passwordMinLength": "Parola en az 8 karakter uzunluğunda olmalıdır",
"newPasswordMinLength": "Yeni şifre en az 8 karakter uzunluğunda olmalıdır", "newPasswordMinLength": "Yeni parola en az 8 karakter uzunluğunda olmalıdır",
"backToHome": "Ana sayfaya dön",
"menu": { "menu": {
"profile": "Profil", "profile": "Profil",
"myProfile": "Profilim", "myProfile": "Profilim",
@@ -21,5 +23,28 @@ export default {
"settings": "Ayarlar", "settings": "Ayarlar",
"adminDashboard": "Yönetici Paneli", "adminDashboard": "Yönetici Paneli",
"adminUsers": "Yönetici Kullanıcılar" "adminUsers": "Yönetici Kullanıcılar"
},
"resetPassword": {
"title": "Parolayı sıfırla",
"button": "Parolayı sıfırla",
"success": "Parolanız başarıyla sıfırlandı! Kısa süre içinde giriş sayfasına yönlendirileceksiniz...",
"invalidToken": "Geçerli bir token bulunamadı. Lütfen e-postanızdaki bağlantıyı kullanın.",
"error": "Parola sıfırlama hatası",
"emailSent": "Parolanızı sıfırlamak için bir bağlantı e-posta adresinize gönderildi.",
"emailError": "E-posta gönderme hatası"
},
"errors": {
"fillAllFields": "Lütfen tüm alanları doldurun",
"invalidEmail": "Lütfen geçerli bir e-posta adresi girin",
"passwordsNotMatch": "Parolalar eşleşmiyor",
"passwordsNotMatchShort": "Parolalar eşleşmiyor",
"enterEmail": "Lütfen e-posta adresinizi girin",
"loginFailed": "Giriş başarısız",
"registerFailed": "Kayıt başarısız",
"googleLoginFailed": "Google ile giriş başarısız",
"emailExists": "Bu e-posta adresiyle zaten bir kullanıcı mevcut. Lütfen başka bir e-posta adresi kullanın veya giriş yapın."
},
"success": {
"registerComplete": "Kayıt başarılı. Artık giriş yapabilirsiniz."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "Devam ediyor", "new": "işlemde",
"pending": "Yeni", "pending": "Yeni",
"processing": "Devam ediyor", "processing": "işlemde",
"paid": "Ödendi",
"cancelled": "İptal edildi", "cancelled": "İptal edildi",
"shipped": "Gönderildi", "shipped": "Gönderildi",
"delivered": "Teslim edildi", "delivered": "Teslim edildi",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Siparişi iptal et" "cancelOrder": "Siparişi iptal et"
}, },
"noOrders": "Henüz sipariş vermediniz.", "noOrders": "Henüz sipariş vermediniz.",
"trackShipment": "Gönderiyi takip et",
"details": { "details": {
"title": "Sipariş detayları: {{orderId}}", "title": "Sipariş detayları: {{orderId}}",
"deliveryAddress": "Teslimat adresi", "deliveryAddress": "Teslimat adresi",
@@ -31,20 +33,19 @@ export default {
"orderDetails": "Sipariş detayları", "orderDetails": "Sipariş detayları",
"deliveryMethod": "Teslimat yöntemi:", "deliveryMethod": "Teslimat yöntemi:",
"paymentMethod": "Ödeme yöntemi:", "paymentMethod": "Ödeme yöntemi:",
"notSpecified": "Belirtilmemiş", "notSpecified": "Belirtilmedi",
"orderedItems": "Sipariş edilen ürünler", "orderedItems": "Sipariş edilen ürünler",
"item": "Ürün", "item": "Ürün",
"quantity": "Adet", "quantity": "Miktar",
"price": "Fiyat", "price": "Fiyat",
"vat": "KDV",
"total": "Toplam", "total": "Toplam",
"cancelOrder": "Siparişi iptal et" "cancelOrder": "Siparişi iptal et"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Siparişi İptal Et", "title": "Siparişi iptal et",
"message": "Bu siparişi iptal etmek istediğinizden emin misiniz?", "message": "Bu siparişi iptal etmek istediğinizden emin misiniz?",
"confirm": "Siparişi İptal Et", "confirm": "İptal et",
"cancelling": "İptal ediliyor..." "cancelling": "İptal ediliyor..."
}, },
"processing": "Sipariş tamamlanıyor...", "processing": "Sipariş tamamlanıyor..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "Профіль", "profile": "Профіль",
"email": "Електронна пошта", "email": "Електронна пошта",
"password": "Пароль", "password": "Пароль",
"newPassword": "Новий пароль",
"confirmPassword": "Підтвердити пароль", "confirmPassword": "Підтвердити пароль",
"forgotPassword": "Забули пароль?", "forgotPassword": "Забули пароль?",
"loginWithGoogle": "Увійти через Google", "loginWithGoogle": "Увійти через Google",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "Політику конфіденційності", "privacyPolicy": "Політику конфіденційності",
"passwordMinLength": "Пароль повинен містити щонайменше 8 символів", "passwordMinLength": "Пароль повинен містити щонайменше 8 символів",
"newPasswordMinLength": "Новий пароль повинен містити щонайменше 8 символів", "newPasswordMinLength": "Новий пароль повинен містити щонайменше 8 символів",
"backToHome": "Повернутися на головну сторінку",
"menu": { "menu": {
"profile": "Профіль", "profile": "Профіль",
"myProfile": "Мій профіль", "myProfile": "Мій профіль",
@@ -21,5 +23,28 @@ export default {
"settings": "Налаштування", "settings": "Налаштування",
"adminDashboard": "Панель адміністратора", "adminDashboard": "Панель адміністратора",
"adminUsers": "Адміністратори" "adminUsers": "Адміністратори"
},
"resetPassword": {
"title": "Скинути пароль",
"button": "Скинути пароль",
"success": "Ваш пароль успішно скинуто! Незабаром ви будете перенаправлені для входу...",
"invalidToken": "Дійсний токен не знайдено. Будь ласка, використовуйте посилання з вашої електронної пошти.",
"error": "Помилка при скиданні пароля",
"emailSent": "Посилання для скидання пароля надіслано на вашу електронну адресу.",
"emailError": "Помилка надсилання електронної пошти"
},
"errors": {
"fillAllFields": "Будь ласка, заповніть усі поля",
"invalidEmail": "Будь ласка, введіть дійсну електронну адресу",
"passwordsNotMatch": "Паролі не співпадають",
"passwordsNotMatchShort": "Паролі не співпадають",
"enterEmail": "Будь ласка, введіть вашу електронну адресу",
"loginFailed": "Не вдалося увійти",
"registerFailed": "Не вдалося зареєструватися",
"googleLoginFailed": "Не вдалося увійти через Google",
"emailExists": "Користувач з цією електронною адресою вже існує. Будь ласка, використовуйте іншу адресу або увійдіть."
},
"success": {
"registerComplete": "Реєстрація успішна. Тепер ви можете увійти."
} }
}; };

View File

@@ -1,8 +1,9 @@
export default { export default {
"status": { "status": {
"new": "В процесі", "new": "в процесі",
"pending": "Новий", "pending": "Новий",
"processing": "В процесі", "processing": "в процесі",
"paid": "Оплачено",
"cancelled": "Скасовано", "cancelled": "Скасовано",
"shipped": "Відправлено", "shipped": "Відправлено",
"delivered": "Доставлено", "delivered": "Доставлено",
@@ -24,6 +25,7 @@ export default {
"cancelOrder": "Скасувати замовлення" "cancelOrder": "Скасувати замовлення"
}, },
"noOrders": "Ви ще не робили замовлень.", "noOrders": "Ви ще не робили замовлень.",
"trackShipment": "Відстежити відправлення",
"details": { "details": {
"title": "Деталі замовлення: {{orderId}}", "title": "Деталі замовлення: {{orderId}}",
"deliveryAddress": "Адреса доставки", "deliveryAddress": "Адреса доставки",
@@ -36,15 +38,14 @@ export default {
"item": "Товар", "item": "Товар",
"quantity": "Кількість", "quantity": "Кількість",
"price": "Ціна", "price": "Ціна",
"vat": "ПДВ",
"total": "Всього", "total": "Всього",
"cancelOrder": "Скасувати замовлення" "cancelOrder": "Скасувати замовлення"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "Скасувати замовлення", "title": "Скасувати замовлення",
"message": "Ви впевнені, що хочете скасувати це замовлення?", "message": "Ви впевнені, що хочете скасувати це замовлення?",
"confirm": "Скасувати замовлення", "confirm": "Скасувати",
"cancelling": "Скасування..." "cancelling": "Скасовується..."
}, },
"processing": "Замовлення обробляється...", "processing": "Замовлення обробляється..."
}; };

View File

@@ -5,6 +5,7 @@ export default {
"profile": "个人资料", "profile": "个人资料",
"email": "电子邮件", "email": "电子邮件",
"password": "密码", "password": "密码",
"newPassword": "新密码",
"confirmPassword": "确认密码", "confirmPassword": "确认密码",
"forgotPassword": "忘记密码?", "forgotPassword": "忘记密码?",
"loginWithGoogle": "使用 Google 登录", "loginWithGoogle": "使用 Google 登录",
@@ -13,6 +14,7 @@ export default {
"privacyPolicy": "隐私政策", "privacyPolicy": "隐私政策",
"passwordMinLength": "密码长度至少为8个字符", "passwordMinLength": "密码长度至少为8个字符",
"newPasswordMinLength": "新密码长度至少为8个字符", "newPasswordMinLength": "新密码长度至少为8个字符",
"backToHome": "返回首页",
"menu": { "menu": {
"profile": "个人资料", "profile": "个人资料",
"myProfile": "我的资料", "myProfile": "我的资料",
@@ -21,5 +23,28 @@ export default {
"settings": "设置", "settings": "设置",
"adminDashboard": "管理员面板", "adminDashboard": "管理员面板",
"adminUsers": "管理员用户" "adminUsers": "管理员用户"
},
"resetPassword": {
"title": "重置密码",
"button": "重置密码",
"success": "您的密码已成功重置!您将很快被重定向到登录页面...",
"invalidToken": "未找到有效的令牌。请使用您邮箱中的链接。",
"error": "重置密码时出错",
"emailSent": "重置密码的链接已发送到您的电子邮件地址。",
"emailError": "发送电子邮件时出错"
},
"errors": {
"fillAllFields": "请填写所有字段",
"invalidEmail": "请输入有效的电子邮件地址",
"passwordsNotMatch": "密码不匹配",
"passwordsNotMatchShort": "密码不匹配",
"enterEmail": "请输入您的电子邮件地址",
"loginFailed": "登录失败",
"registerFailed": "注册失败",
"googleLoginFailed": "Google 登录失败",
"emailExists": "该电子邮件地址已被注册。请使用其他电子邮件地址或登录。"
},
"success": {
"registerComplete": "注册成功。您现在可以登录。"
} }
}; };

View File

@@ -3,6 +3,7 @@ export default {
"new": "进行中", "new": "进行中",
"pending": "新订单", "pending": "新订单",
"processing": "进行中", "processing": "进行中",
"paid": "已付款",
"cancelled": "已取消", "cancelled": "已取消",
"shipped": "已发货", "shipped": "已发货",
"delivered": "已送达", "delivered": "已送达",
@@ -23,27 +24,27 @@ export default {
"viewDetails": "查看详情", "viewDetails": "查看详情",
"cancelOrder": "取消订单" "cancelOrder": "取消订单"
}, },
"noOrders": "您尚未下过任何订单。", "noOrders": "您还没有下过任何订单。",
"trackShipment": "跟踪发货",
"details": { "details": {
"title": "订单详情: {{orderId}}", "title": "订单详情: {{orderId}}",
"deliveryAddress": "收货地址", "deliveryAddress": "收货地址",
"invoiceAddress": "发票地址", "invoiceAddress": "发票地址",
"orderDetails": "订单详情", "orderDetails": "订单详情",
"deliveryMethod": "配送方式:", "deliveryMethod": "配送方式",
"paymentMethod": "支付方式:", "paymentMethod": "支付方式",
"notSpecified": "未指定", "notSpecified": "未指定",
"orderedItems": "订购商品", "orderedItems": "订购商品",
"item": "商品", "item": "商品",
"quantity": "数量", "quantity": "数量",
"price": "价格", "price": "价格",
"vat": "增值税",
"total": "总计", "total": "总计",
"cancelOrder": "取消订单" "cancelOrder": "取消订单"
}, },
"cancelConfirm": { "cancelConfirm": {
"title": "取消订单", "title": "取消订单",
"message": "您确定要取消此订单吗?", "message": "您确定要取消此订单吗?",
"confirm": "取消订单", "confirm": "取消",
"cancelling": "正在取消..." "cancelling": "正在取消..."
}, },
"processing": "订单正在处理..." "processing": "订单正在处理..."

231
src/pages/CategoriesPage.js Normal file
View File

@@ -0,0 +1,231 @@
import React, { Component } from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import CircularProgress from '@mui/material/CircularProgress';
import Paper from '@mui/material/Paper';
import LegalPage from './LegalPage.js';
import CategoryBox from '../components/CategoryBox.js';
import { withI18n } from '../i18n/withTranslation.js';
// Helper function to recursively collect all categories from the tree
const collectAllCategories = (categoryNode, categories = [], level = 0) => {
if (!categoryNode) return categories;
// Add current category (skip root category 209)
if (categoryNode.id !== 209 && categoryNode.seoName) {
categories.push({
id: categoryNode.id,
name: categoryNode.name,
seoName: categoryNode.seoName,
level: level
});
}
// Recursively add children
if (categoryNode.children) {
for (const child of categoryNode.children) {
collectAllCategories(child, categories, level + 1);
}
}
return categories;
};
// Check for cached data - handle both browser and prerender environments
const getProductCache = () => {
if (typeof window !== "undefined" && window.productCache) {
return window.productCache;
}
if (
typeof global !== "undefined" &&
global.window &&
global.window.productCache
) {
return global.window.productCache;
}
return null;
};
// Initialize categories from cache if available (for prerendering)
const initializeCategoryTree = (language = 'de') => {
// Try synchronous get from service first if available
if (typeof window !== "undefined" && window.categoryService) {
const syncData = window.categoryService.getSync(209, language);
if (syncData) return syncData;
}
const productCache = getProductCache();
// Fallback to productCache checks (mostly for prerender context if service isn't init)
const cacheKey = `categoryTree_209_${language}`; // Note: Service uses simpler keys, might mismatch if strictly relying on this
// Check old style cache just in case
if (productCache && productCache[cacheKey]) {
const cached = productCache[cacheKey];
if (cached.categoryTree) return cached.categoryTree;
}
return null;
};
class CategoriesPage extends Component {
constructor(props) {
super(props);
// Use languageContext if available, otherwise fallback to i18n or 'de'
const currentLanguage = props.languageContext?.currentLanguage || props.i18n?.language || 'de';
const initialTree = initializeCategoryTree(currentLanguage);
console.log("CategoriesPage constructor: currentLanguage =", currentLanguage);
this.state = {
categoryTree: initialTree,
loading: !initialTree
};
}
componentDidMount() {
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
// If we don't have data yet, or if we want to ensure freshness/socket connection
if (!this.state.categoryTree) {
this.fetchCategories(currentLanguage);
}
}
componentDidUpdate(prevProps) {
const currentLanguage = this.props.languageContext?.currentLanguage || this.props.i18n?.language || 'de';
const prevLanguage = prevProps.languageContext?.currentLanguage || prevProps.i18n?.language || 'de';
if (currentLanguage !== prevLanguage) {
console.log(`CategoriesPage: Language changed from ${prevLanguage} to ${currentLanguage}. Refetching.`);
this.setState({ loading: true, categoryTree: [] }); // Clear tree to force re-render/loading state
this.fetchCategories(currentLanguage);
}
}
fetchCategories = (language) => {
// Use categoryService which handles caching and translated vs untranslated responses correctly
console.log(`CategoriesPage: Fetching categories for ${language} using categoryService`);
window.categoryService.get(209, language).then((tree) => {
if (tree) {
this.setState({
categoryTree: tree,
loading: false
});
} else {
console.error('Failed to fetch categories via service');
this.setState({ loading: false });
}
}).catch(err => {
console.error("Error in categoryService:", err);
this.setState({ loading: false });
});
};
renderLevel1Section = (l1Node) => {
// Collect all descendants (excluding the L1 node itself, which collectAllCategories would include first)
const descendants = collectAllCategories(l1Node).slice(1);
return (
<Paper
key={l1Node.id}
elevation={1}
sx={{
p: 2,
mb: 3,
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
alignItems: { xs: 'flex-start', md: 'flex-start' },
gap: 3
}}
>
{/* Level 1 Header/Box */}
<Box sx={{
minWidth: '150px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 1
}}>
<CategoryBox
id={l1Node.id}
name={l1Node.name}
seoName={l1Node.seoName}
sx={{
boxShadow: 4,
width: '150px',
height: '150px'
}}
/>
<Typography
variant="h6"
sx={{
textAlign: 'center',
fontWeight: 'bold',
display: { xs: 'block', md: 'none' } // Only show text below box on mobile if needed, or rely on box text
}}
>
{/* Box already has text, so maybe no extra text needed here */}
</Typography>
</Box>
{/* Descendants area */}
<Box sx={{ flex: 1 }}>
<Box sx={{
display: 'flex',
flexWrap: 'wrap',
gap: 2
}}>
{descendants.map((cat) => (
<CategoryBox
key={cat.id}
id={cat.id}
name={cat.name}
seoName={cat.seoName}
sx={{
width: '100px',
height: '100px',
minWidth: '100px',
minHeight: '100px',
boxShadow: 1,
transition: 'transform 0.2s',
'&:hover': { transform: 'scale(1.05)', boxShadow: 3 },
fontSize: '0.9rem' // Smaller text for smaller boxes
}}
/>
))}
</Box>
</Box>
</Paper>
);
};
render() {
const { t } = this.props;
const { categoryTree, loading } = this.state;
const content = (
<Box>
{loading ? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
<CircularProgress />
</Box>
) : (
<Box>
{categoryTree && categoryTree.children && categoryTree.children.map((child) => (
this.renderLevel1Section(child)
))}
{(!categoryTree || !categoryTree.children || categoryTree.children.length === 0) && (
<Typography>Keine Kategorien gefunden.</Typography>
)}
</Box>
)}
</Box>
);
return <LegalPage title={t ? t('navigation.categories') : 'Kategorien'} content={content} />;
}
}
export default withI18n()(CategoriesPage);

View File

@@ -30,28 +30,28 @@ const ResetPassword = () => {
const tokenFromUrl = urlParams.get('token'); const tokenFromUrl = urlParams.get('token');
if (!tokenFromUrl) { if (!tokenFromUrl) {
setError('Kein gültiger Token gefunden. Bitte verwenden Sie den Link aus Ihrer E-Mail.'); setError(t('auth.resetPassword.invalidToken'));
} else { } else {
setToken(tokenFromUrl); setToken(tokenFromUrl);
} }
}, [location]); }, [location, t]);
const handleSubmit = (e) => { const handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
// Validation // Validation
if (!newPassword || !confirmPassword) { if (!newPassword || !confirmPassword) {
setError('Bitte füllen Sie alle Felder aus'); setError(t('auth.errors.fillAllFields'));
return; return;
} }
if (newPassword.length < 8) { if (newPassword.length < 8) {
setError('Das Passwort muss mindestens 8 Zeichen lang sein'); setError(t('auth.passwordMinLength'));
return; return;
} }
if (newPassword !== confirmPassword) { if (newPassword !== confirmPassword) {
setError('Die Passwörter stimmen nicht überein'); setError(t('auth.errors.passwordsNotMatch'));
return; return;
} }
@@ -76,7 +76,7 @@ const ResetPassword = () => {
} }
}, 3000); }, 3000);
} else { } else {
setError(response.message || 'Fehler beim Zurücksetzen des Passworts'); setError(response.message || t('auth.resetPassword.error'));
} }
}); });
}; };
@@ -87,7 +87,7 @@ const ResetPassword = () => {
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}> <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<LockResetIcon sx={{ fontSize: 48, color: 'primary.main', mb: 2 }} /> <LockResetIcon sx={{ fontSize: 48, color: 'primary.main', mb: 2 }} />
<Typography component="h1" variant="h5" gutterBottom> <Typography component="h1" variant="h5" gutterBottom>
Passwort zurücksetzen {t('auth.resetPassword.title')}
</Typography> </Typography>
{!token ? ( {!token ? (
@@ -97,7 +97,7 @@ const ResetPassword = () => {
) : success ? ( ) : success ? (
<Box sx={{ width: '100%', mt: 2 }}> <Box sx={{ width: '100%', mt: 2 }}>
<Alert severity="success" sx={{ mb: 2 }}> <Alert severity="success" sx={{ mb: 2 }}>
Ihr Passwort wurde erfolgreich zurückgesetzt! Sie werden in Kürze zur Anmeldung weitergeleitet... {t('auth.resetPassword.success')}
</Alert> </Alert>
<Box sx={{ display: 'flex', justifyContent: 'center' }}> <Box sx={{ display: 'flex', justifyContent: 'center' }}>
<CircularProgress size={24} /> <CircularProgress size={24} />
@@ -116,7 +116,7 @@ const ResetPassword = () => {
required required
fullWidth fullWidth
name="newPassword" name="newPassword"
label="Neues Passwort" label={t('auth.newPassword')}
type="password" type="password"
id="newPassword" id="newPassword"
autoComplete="new-password" autoComplete="new-password"
@@ -130,7 +130,7 @@ const ResetPassword = () => {
required required
fullWidth fullWidth
name="confirmPassword" name="confirmPassword"
label={t ? t('auth.confirmPassword') : 'Passwort bestätigen'} label={t('auth.confirmPassword')}
type="password" type="password"
id="confirmPassword" id="confirmPassword"
autoComplete="new-password" autoComplete="new-password"
@@ -154,7 +154,7 @@ const ResetPassword = () => {
{loading ? ( {loading ? (
<CircularProgress size={24} color="inherit" /> <CircularProgress size={24} color="inherit" />
) : ( ) : (
'Passwort zurücksetzen' t('auth.resetPassword.button')
)} )}
</Button> </Button>
@@ -164,7 +164,7 @@ const ResetPassword = () => {
onClick={() => navigate('/')} onClick={() => navigate('/')}
sx={{ color: '#2e7d32' }} sx={{ color: '#2e7d32' }}
> >
Zurück zur Startseite {t('auth.backToHome')}
</Button> </Button>
</Box> </Box>
</Box> </Box>