feat(Translation): enhance product dialogs and update translation model
- Added new translation files for product dialogs to support additional languages. - Refactored various components to utilize translation functions for error messages, labels, and placeholders, enhancing localization support.
This commit is contained in:
@@ -79,7 +79,7 @@ class ArticleAvailabilityForm extends Component {
|
||||
} else {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: response.error || 'Ein Fehler ist aufgetreten'
|
||||
error: response.error || this.props.t("productDialogs.errorGeneric")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -114,20 +114,21 @@ class ArticleAvailabilityForm extends Component {
|
||||
|
||||
render() {
|
||||
const { name, email, telegramId, notificationMethod, message, loading, success, error } = this.state;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<Paper id="availability-form" sx={{ p: 3, mt: 4, borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)" }}>
|
||||
<Typography variant="h5" gutterBottom sx={{ fontWeight: 600, color: '#333' }}>
|
||||
Verfügbarkeit anfragen
|
||||
{t("productDialogs.availabilityTitle")}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Dieser Artikel ist derzeit nicht verfügbar. Gerne informieren wir Sie, sobald er wieder lieferbar ist.
|
||||
{t("productDialogs.availabilitySubtitle")}
|
||||
</Typography>
|
||||
|
||||
{success && (
|
||||
<Alert severity="success" sx={{ mb: 3 }}>
|
||||
Vielen Dank für Ihre Anfrage! Wir werden Sie {notificationMethod === 'email' ? 'per E-Mail' : 'über Telegram'} informieren, sobald der Artikel wieder verfügbar ist.
|
||||
{notificationMethod === 'email' ? t("productDialogs.availabilitySuccessEmail") : t("productDialogs.availabilitySuccessTelegram")}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
@@ -139,18 +140,18 @@ class ArticleAvailabilityForm extends Component {
|
||||
|
||||
<Box component="form" onSubmit={this.handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<TextField
|
||||
label="Name"
|
||||
label={t("productDialogs.nameLabel")}
|
||||
value={name}
|
||||
onChange={this.handleInputChange('name')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="Ihr Name"
|
||||
placeholder={t("productDialogs.namePlaceholder")}
|
||||
/>
|
||||
|
||||
<FormControl component="fieldset" disabled={loading}>
|
||||
<FormLabel component="legend" sx={{ mb: 1 }}>
|
||||
Wie möchten Sie benachrichtigt werden?
|
||||
{t("productDialogs.notificationMethodLabel")}
|
||||
</FormLabel>
|
||||
<RadioGroup
|
||||
value={notificationMethod}
|
||||
@@ -160,51 +161,51 @@ class ArticleAvailabilityForm extends Component {
|
||||
<FormControlLabel
|
||||
value="email"
|
||||
control={<Radio />}
|
||||
label="E-Mail"
|
||||
label={t("productDialogs.emailLabel")}
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="telegram"
|
||||
control={<Radio />}
|
||||
label="Telegram Bot"
|
||||
label={t("productDialogs.telegramBotLabel")}
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
|
||||
{notificationMethod === 'email' && (
|
||||
<TextField
|
||||
label="E-Mail"
|
||||
label={t("productDialogs.emailLabel")}
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={this.handleInputChange('email')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="ihre.email@example.com"
|
||||
placeholder={t("productDialogs.emailPlaceholder")}
|
||||
/>
|
||||
)}
|
||||
|
||||
{notificationMethod === 'telegram' && (
|
||||
<TextField
|
||||
label="Telegram ID"
|
||||
label={t("productDialogs.telegramIdLabel")}
|
||||
value={telegramId}
|
||||
onChange={this.handleInputChange('telegramId')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="@IhrTelegramName oder Telegram ID"
|
||||
helperText="Geben Sie Ihren Telegram-Benutzernamen (mit @) oder Ihre Telegram-ID ein"
|
||||
placeholder={t("productDialogs.telegramPlaceholder")}
|
||||
helperText={t("productDialogs.telegramHelper")}
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextField
|
||||
label="Nachricht (optional)"
|
||||
label={t("productDialogs.messageLabel")}
|
||||
value={message}
|
||||
onChange={this.handleInputChange('message')}
|
||||
fullWidth
|
||||
multiline
|
||||
rows={3}
|
||||
disabled={loading}
|
||||
placeholder="Zusätzliche Informationen oder Fragen..."
|
||||
placeholder={t("productDialogs.messagePlaceholder")}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -225,10 +226,10 @@ class ArticleAvailabilityForm extends Component {
|
||||
{loading ? (
|
||||
<>
|
||||
<CircularProgress size={20} sx={{ mr: 1 }} />
|
||||
Wird gesendet...
|
||||
{t("productDialogs.sending")}
|
||||
</>
|
||||
) : (
|
||||
'Verfügbarkeit anfragen'
|
||||
t("productDialogs.submitAvailability")
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -98,7 +98,7 @@ class ArticleQuestionForm extends Component {
|
||||
} else {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: response.error || 'Ein Fehler ist aufgetreten'
|
||||
error: response.error || this.props.t("productDialogs.errorGeneric")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class ArticleQuestionForm extends Component {
|
||||
} catch {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: 'Fehler beim Verarbeiten der Fotos'
|
||||
error: this.props.t("productDialogs.errorPhotos")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,20 +140,21 @@ class ArticleQuestionForm extends Component {
|
||||
|
||||
render() {
|
||||
const { name, email, question, loading, success, error } = this.state;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<Paper sx={{ p: 3, mt: 4, borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)" }}>
|
||||
<Typography variant="h5" gutterBottom sx={{ fontWeight: 600, color: '#333' }}>
|
||||
Frage zum Artikel
|
||||
{t("productDialogs.questionTitle")}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Haben Sie eine Frage zu diesem Artikel? Wir helfen Ihnen gerne weiter.
|
||||
{t("productDialogs.questionSubtitle")}
|
||||
</Typography>
|
||||
|
||||
{success && (
|
||||
<Alert severity="success" sx={{ mb: 3 }}>
|
||||
Vielen Dank für Ihre Frage! Wir werden uns schnellstmöglich bei Ihnen melden.
|
||||
{t("productDialogs.questionSuccess")}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
@@ -165,28 +166,28 @@ class ArticleQuestionForm extends Component {
|
||||
|
||||
<Box component="form" onSubmit={this.handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<TextField
|
||||
label="Name"
|
||||
label={t("productDialogs.nameLabel")}
|
||||
value={name}
|
||||
onChange={this.handleInputChange('name')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="Ihr Name"
|
||||
placeholder={t("productDialogs.namePlaceholder")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="E-Mail"
|
||||
label={t("productDialogs.emailLabel")}
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={this.handleInputChange('email')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="ihre.email@example.com"
|
||||
placeholder={t("productDialogs.emailPlaceholder")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Ihre Frage"
|
||||
label={t("productDialogs.questionLabel")}
|
||||
value={question}
|
||||
onChange={this.handleInputChange('question')}
|
||||
required
|
||||
@@ -194,7 +195,7 @@ class ArticleQuestionForm extends Component {
|
||||
multiline
|
||||
rows={4}
|
||||
disabled={loading}
|
||||
placeholder="Beschreiben Sie Ihre Frage zu diesem Artikel..."
|
||||
placeholder={t("productDialogs.questionPlaceholder")}
|
||||
/>
|
||||
|
||||
<PhotoUpload
|
||||
@@ -202,7 +203,7 @@ class ArticleQuestionForm extends Component {
|
||||
onChange={this.handlePhotosChange}
|
||||
disabled={loading}
|
||||
maxFiles={3}
|
||||
label="Fotos zur Frage anhängen (optional)"
|
||||
label={t("productDialogs.photosLabelQuestion")}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -219,10 +220,10 @@ class ArticleQuestionForm extends Component {
|
||||
{loading ? (
|
||||
<>
|
||||
<CircularProgress size={20} sx={{ mr: 1 }} />
|
||||
Wird gesendet...
|
||||
{t("productDialogs.sending")}
|
||||
</>
|
||||
) : (
|
||||
'Frage senden'
|
||||
t("productDialogs.submitQuestion")
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -106,7 +106,7 @@ class ArticleRatingForm extends Component {
|
||||
} else {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: response.error || 'Ein Fehler ist aufgetreten'
|
||||
error: response.error || this.props.t("productDialogs.errorGeneric")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ class ArticleRatingForm extends Component {
|
||||
} catch {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: 'Fehler beim Verarbeiten der Fotos'
|
||||
error: this.props.t("productDialogs.errorPhotos")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,20 +149,21 @@ class ArticleRatingForm extends Component {
|
||||
|
||||
render() {
|
||||
const { name, email, rating, review, loading, success, error } = this.state;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<Paper sx={{ p: 3, mt: 4, borderRadius: 2, boxShadow: "0 2px 8px rgba(0,0,0,0.08)" }}>
|
||||
<Typography variant="h5" gutterBottom sx={{ fontWeight: 600, color: '#333' }}>
|
||||
Artikel Bewerten
|
||||
{t("productDialogs.ratingTitle")}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Teilen Sie Ihre Erfahrungen mit diesem Artikel und helfen Sie anderen Kunden bei der Entscheidung.
|
||||
{t("productDialogs.ratingSubtitle")}
|
||||
</Typography>
|
||||
|
||||
{success && (
|
||||
<Alert severity="success" sx={{ mb: 3 }}>
|
||||
Vielen Dank für Ihre Bewertung! Sie wird nach Prüfung veröffentlicht.
|
||||
{t("productDialogs.ratingSuccess")}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
@@ -174,30 +175,30 @@ class ArticleRatingForm extends Component {
|
||||
|
||||
<Box component="form" onSubmit={this.handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<TextField
|
||||
label="Name"
|
||||
label={t("productDialogs.nameLabel")}
|
||||
value={name}
|
||||
onChange={this.handleInputChange('name')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="Ihr Name"
|
||||
placeholder={t("productDialogs.namePlaceholder")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="E-Mail"
|
||||
label={t("productDialogs.emailLabel")}
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={this.handleInputChange('email')}
|
||||
required
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
placeholder="ihre.email@example.com"
|
||||
helperText="Ihre E-Mail wird nicht veröffentlicht"
|
||||
placeholder={t("productDialogs.emailPlaceholder")}
|
||||
helperText={t("productDialogs.emailHelper")}
|
||||
/>
|
||||
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
<Typography variant="body2" sx={{ fontWeight: 500 }}>
|
||||
Bewertung *
|
||||
{t("productDialogs.ratingLabel")}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<Rating
|
||||
@@ -209,20 +210,20 @@ class ArticleRatingForm extends Component {
|
||||
emptyIcon={<StarIcon style={{ opacity: 0.55 }} fontSize="inherit" />}
|
||||
/>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{rating > 0 ? `${rating} von 5 Sternen` : 'Bitte bewerten'}
|
||||
{rating > 0 ? t("productDialogs.ratingStars", { rating }) : t("productDialogs.pleaseRate")}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<TextField
|
||||
label="Ihre Bewertung (optional)"
|
||||
label={t("productDialogs.reviewLabel")}
|
||||
value={review}
|
||||
onChange={this.handleInputChange('review')}
|
||||
fullWidth
|
||||
multiline
|
||||
rows={4}
|
||||
disabled={loading}
|
||||
placeholder="Beschreiben Sie Ihre Erfahrungen mit diesem Artikel..."
|
||||
placeholder={t("productDialogs.reviewPlaceholder")}
|
||||
/>
|
||||
|
||||
<PhotoUpload
|
||||
@@ -230,7 +231,7 @@ class ArticleRatingForm extends Component {
|
||||
onChange={this.handlePhotosChange}
|
||||
disabled={loading}
|
||||
maxFiles={5}
|
||||
label="Fotos zur Bewertung anhängen (optional)"
|
||||
label={t("productDialogs.photosLabelRating")}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -247,10 +248,10 @@ class ArticleRatingForm extends Component {
|
||||
{loading ? (
|
||||
<>
|
||||
<CircularProgress size={20} sx={{ mr: 1 }} />
|
||||
Wird gesendet...
|
||||
{t("productDialogs.sending")}
|
||||
</>
|
||||
) : (
|
||||
'Bewertung abgeben'
|
||||
t("productDialogs.submitRating")
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import Delete from '@mui/icons-material/Delete';
|
||||
import CloudUpload from '@mui/icons-material/CloudUpload';
|
||||
import { withI18n } from '../i18n/withTranslation.js';
|
||||
|
||||
class PhotoUpload extends Component {
|
||||
constructor(props) {
|
||||
@@ -30,7 +31,7 @@ class PhotoUpload extends Component {
|
||||
// Validate file count
|
||||
if (this.state.files.length + selectedFiles.length > maxFiles) {
|
||||
this.setState({
|
||||
error: `Maximal ${maxFiles} Dateien erlaubt`
|
||||
error: this.props.t("productDialogs.photoUploadErrorMaxFiles", { max: maxFiles })
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -43,14 +44,14 @@ class PhotoUpload extends Component {
|
||||
for (const file of selectedFiles) {
|
||||
if (!validTypes.includes(file.type)) {
|
||||
this.setState({
|
||||
error: 'Nur Bilddateien (JPEG, PNG, GIF, WebP) sind erlaubt'
|
||||
error: this.props.t("productDialogs.photoUploadErrorFileType")
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.size > maxSize) {
|
||||
this.setState({
|
||||
error: `Datei zu groß. Maximum: ${Math.round(maxSize / (1024 * 1024))}MB`
|
||||
error: this.props.t("productDialogs.photoUploadErrorFileSize", { maxSize: Math.round(maxSize / (1024 * 1024)) })
|
||||
});
|
||||
continue;
|
||||
}
|
||||
@@ -167,12 +168,12 @@ class PhotoUpload extends Component {
|
||||
|
||||
render() {
|
||||
const { files, previews, error } = this.state;
|
||||
const { disabled, label } = this.props;
|
||||
const { disabled, label, t } = this.props;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="body2" sx={{ mb: 1, fontWeight: 500 }}>
|
||||
{label || 'Fotos anhängen (optional)'}
|
||||
{label || t("productDialogs.photoUploadLabelDefault")}
|
||||
</Typography>
|
||||
|
||||
<input
|
||||
@@ -192,7 +193,7 @@ class PhotoUpload extends Component {
|
||||
disabled={disabled}
|
||||
sx={{ mb: 2 }}
|
||||
>
|
||||
Fotos auswählen
|
||||
{t("productDialogs.photoUploadSelect")}
|
||||
</Button>
|
||||
|
||||
{error && (
|
||||
@@ -228,7 +229,7 @@ class PhotoUpload extends Component {
|
||||
size="small"
|
||||
onClick={() => this.handleRemoveFile(index)}
|
||||
disabled={disabled}
|
||||
aria-label="Bild entfernen"
|
||||
aria-label={t("productDialogs.photoUploadRemove")}
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 4,
|
||||
@@ -269,10 +270,10 @@ class PhotoUpload extends Component {
|
||||
|
||||
{files.length > 0 && (
|
||||
<Typography variant="caption" color="text.secondary" sx={{ mt: 1, display: 'block' }}>
|
||||
{files.length} Datei(en) ausgewählt
|
||||
{t("productDialogs.photoUploadSelectedFiles", { count: files.length })}
|
||||
{previews.length > 0 && previews.some(p => p.originalSize && p.compressedSize) && (
|
||||
<span style={{ marginLeft: '8px' }}>
|
||||
(komprimiert für Upload)
|
||||
{t("productDialogs.photoUploadCompressed")}
|
||||
</span>
|
||||
)}
|
||||
</Typography>
|
||||
@@ -282,4 +283,4 @@ class PhotoUpload extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default PhotoUpload;
|
||||
export default withI18n()(PhotoUpload);
|
||||
@@ -762,7 +762,7 @@ class ProductDetailPage extends Component {
|
||||
handleEmbedShare = () => {
|
||||
const embedCode = `<iframe src="${this.getProductUrl()}" width="100%" height="600" frameborder="0"></iframe>`;
|
||||
navigator.clipboard.writeText(embedCode).then(() => {
|
||||
this.showSnackbar("Einbettungscode wurde in die Zwischenablage kopiert!");
|
||||
this.showSnackbar(this.props.t ? this.props.t("productDialogs.shareSuccessEmbed") : "Einbettungscode wurde in die Zwischenablage kopiert!");
|
||||
}).catch(() => {
|
||||
// Fallback for older browsers
|
||||
try {
|
||||
@@ -772,9 +772,9 @@ class ProductDetailPage extends Component {
|
||||
textArea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textArea);
|
||||
this.showSnackbar("Einbettungscode wurde in die Zwischenablage kopiert!");
|
||||
this.showSnackbar(this.props.t ? this.props.t("productDialogs.shareSuccessEmbed") : "Einbettungscode wurde in die Zwischenablage kopiert!");
|
||||
} catch {
|
||||
this.showSnackbar("Fehler beim Kopieren des Einbettungscodes", "error");
|
||||
this.showSnackbar(this.props.t ? this.props.t("productDialogs.shareErrorEmbed") : "Fehler beim Kopieren des Einbettungscodes", "error");
|
||||
}
|
||||
});
|
||||
this.handleShareClose();
|
||||
@@ -782,7 +782,10 @@ class ProductDetailPage extends Component {
|
||||
|
||||
handleWhatsAppShare = () => {
|
||||
const url = this.getProductUrl();
|
||||
const text = `Schau dir dieses Produkt an: ${cleanProductName(this.state.product.name)}`;
|
||||
const productName = cleanProductName(this.state.product.name);
|
||||
const text = this.props.t
|
||||
? this.props.t("productDialogs.shareWhatsAppText", { name: productName })
|
||||
: `Schau dir dieses Produkt an: ${productName}`;
|
||||
const whatsappUrl = `https://wa.me/?text=${encodeURIComponent(text + ' ' + url)}`;
|
||||
window.open(whatsappUrl, '_blank');
|
||||
this.handleShareClose();
|
||||
@@ -797,7 +800,10 @@ class ProductDetailPage extends Component {
|
||||
|
||||
handleTelegramShare = () => {
|
||||
const url = this.getProductUrl();
|
||||
const text = `Schau dir dieses Produkt an: ${cleanProductName(this.state.product.name)}`;
|
||||
const productName = cleanProductName(this.state.product.name);
|
||||
const text = this.props.t
|
||||
? this.props.t("productDialogs.shareTelegramText", { name: productName })
|
||||
: `Schau dir dieses Produkt an: ${productName}`;
|
||||
const telegramUrl = `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`;
|
||||
window.open(telegramUrl, '_blank');
|
||||
this.handleShareClose();
|
||||
@@ -805,8 +811,18 @@ class ProductDetailPage extends Component {
|
||||
|
||||
handleEmailShare = () => {
|
||||
const url = this.getProductUrl();
|
||||
const subject = `Produktempfehlung: ${cleanProductName(this.state.product.name)}`;
|
||||
const body = `Hallo,\n\nich möchte dir dieses Produkt empfehlen:\n\n${cleanProductName(this.state.product.name)}\n${url}\n\nViele Grüße`;
|
||||
const productName = cleanProductName(this.state.product.name);
|
||||
const subject = this.props.t
|
||||
? `${this.props.t("productDialogs.shareEmailSubject")}: ${productName}`
|
||||
: `Produktempfehlung: ${productName}`;
|
||||
|
||||
const body = this.props.t
|
||||
? this.props.t("productDialogs.shareEmailBody", {
|
||||
name: productName,
|
||||
url: url
|
||||
})
|
||||
: `Hallo,\n\nich möchte dir dieses Produkt empfehlen:\n\n${productName}\n${url}\n\nViele Grüße`;
|
||||
|
||||
const emailUrl = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
|
||||
window.location.href = emailUrl;
|
||||
this.handleShareClose();
|
||||
@@ -815,7 +831,7 @@ class ProductDetailPage extends Component {
|
||||
handleLinkCopy = () => {
|
||||
const url = this.getProductUrl();
|
||||
navigator.clipboard.writeText(url).then(() => {
|
||||
this.showSnackbar("Link wurde in die Zwischenablage kopiert!");
|
||||
this.showSnackbar(this.props.t ? this.props.t("productDialogs.shareSuccessLink") : "Link wurde in die Zwischenablage kopiert!");
|
||||
}).catch(() => {
|
||||
// Fallback for older browsers
|
||||
try {
|
||||
@@ -825,7 +841,7 @@ class ProductDetailPage extends Component {
|
||||
textArea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textArea);
|
||||
this.showSnackbar("Link wurde in die Zwischenablage kopiert!");
|
||||
this.showSnackbar(this.props.t ? this.props.t("productDialogs.shareSuccessLink") : "Link wurde in die Zwischenablage kopiert!");
|
||||
} catch {
|
||||
this.showSnackbar("Fehler beim Kopieren des Links", "error");
|
||||
}
|
||||
@@ -968,7 +984,7 @@ class ProductDetailPage extends Component {
|
||||
}).format(productData.price)}
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
inkl. MwSt.
|
||||
{this.props.t ? this.props.t('product.inclVatSimple') : 'inkl. MwSt.'}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -1331,7 +1347,7 @@ class ProductDetailPage extends Component {
|
||||
whiteSpace: "nowrap"
|
||||
}}
|
||||
>
|
||||
Frage zum Artikel
|
||||
{this.props.t ? this.props.t('productDialogs.questionTitle') : "Frage zum Artikel"}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
@@ -1345,7 +1361,7 @@ class ProductDetailPage extends Component {
|
||||
whiteSpace: "nowrap"
|
||||
}}
|
||||
>
|
||||
Artikel Bewerten
|
||||
{this.props.t ? this.props.t('productDialogs.ratingTitle') : "Artikel Bewerten"}
|
||||
</Button>
|
||||
{(product.available !== 1 && product.availableSupplier !== 1) && (
|
||||
<Button
|
||||
@@ -1366,7 +1382,7 @@ class ProductDetailPage extends Component {
|
||||
}
|
||||
}}
|
||||
>
|
||||
Verfügbarkeit anfragen
|
||||
{this.props.t ? this.props.t('productDialogs.availabilityTitle') : "Verfügbarkeit anfragen"}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
@@ -1595,7 +1611,7 @@ class ProductDetailPage extends Component {
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
Teilen
|
||||
{this.props.t ? this.props.t("productDialogs.shareTitle") : "Teilen"}
|
||||
</Button>
|
||||
<Box
|
||||
sx={{
|
||||
@@ -1669,7 +1685,7 @@ class ProductDetailPage extends Component {
|
||||
<ListItemIcon>
|
||||
<CodeIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Einbetten" />
|
||||
<ListItemText primary={this.props.t ? this.props.t("productDialogs.shareEmbed") : "Einbetten"} />
|
||||
</MenuItem>
|
||||
<MenuItem onClick={this.handleWhatsAppShare}>
|
||||
<ListItemIcon>
|
||||
@@ -1699,7 +1715,7 @@ class ProductDetailPage extends Component {
|
||||
<ListItemIcon>
|
||||
<LinkIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Link kopieren" />
|
||||
<ListItemText primary={this.props.t ? this.props.t("productDialogs.shareCopyLink") : "Link kopieren"} />
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user