@designcrowd/fe-shared-lib 1.2.1-rr-7 → 1.2.2-ast-disabled-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +2 -0
- package/index.js +2 -0
- package/nodemon.translation.json +7 -0
- package/package.json +7 -2
- package/{dist → public}/css/tailwind-brandCrowd.css +510 -592
- package/{dist → public}/css/tailwind-brandPage.css +434 -512
- package/{dist → public}/css/tailwind-crazyDomains.css +510 -592
- package/{dist → public}/css/tailwind-designCom.css +510 -592
- package/{dist → public}/css/tailwind-designCrowd.css +510 -592
- package/src/atoms/components/ButtonGroup/ButtonGroup.stories.js +1 -0
- package/src/atoms/components/ButtonGroup/ButtonGroup.vue +24 -12
- package/src/atoms/components/FormControl/FormControl.mixin.js +1 -10
- package/src/atoms/components/Icon/Icon.vue +3 -3
- package/src/atoms/components/TextInput/TextInput.vue +1 -5
- package/src/bundleTranslation.js +89 -0
- package/src/bundles/bundled-translations.de-DE.json +5 -0
- package/src/bundles/bundled-translations.es-ES.json +5 -0
- package/src/bundles/bundled-translations.fr-FR.json +5 -0
- package/src/bundles/bundled-translations.json +5 -0
- package/src/bundles/bundled-translations.pt-PT.json +5 -0
- package/src/experiences/components/PaymentConfigList/PaymentConfig.mixin.js +1 -1
- package/src/experiences/components/PublishBrandPageModal/PublishBrandPageModal.vue +22 -9
- package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.de-DE.json +5 -0
- package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.es-ES.json +5 -0
- package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.fr-FR.json +5 -0
- package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.json +5 -0
- package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.pt-PT.json +5 -0
- package/src/experiences/components/SellDomainNameList/SellDomainNameList.vue +1 -0
- package/src/experiences/components/SellDomainNameSearchResult/SellDomainNameListSearchResult.vue +4 -0
- package/src/experiences/components/SellDomainNameSearchWithResults/SellDomainNameSearchWithResults.vue +4 -0
- package/src/useSharedLibTranslate.js +38 -0
|
@@ -10,11 +10,14 @@
|
|
|
10
10
|
<button
|
|
11
11
|
class="button-group-item tw-text-xs tw-shadow-inner tw-w-full tw-py-2"
|
|
12
12
|
:class="{
|
|
13
|
-
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
|
|
14
|
-
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200
|
|
13
|
+
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
|
|
14
|
+
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
|
|
15
|
+
'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
|
|
16
|
+
'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
|
|
15
17
|
}"
|
|
18
|
+
:disabled="option.disabled"
|
|
16
19
|
v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
|
|
17
|
-
@click="$emit('on-select', option)"
|
|
20
|
+
@click="!option.disabled && $emit('on-select', option)"
|
|
18
21
|
>
|
|
19
22
|
<slot name="content" :option="option"></slot>
|
|
20
23
|
</button>
|
|
@@ -35,8 +38,10 @@
|
|
|
35
38
|
<button
|
|
36
39
|
v-if="variant === 'icon'"
|
|
37
40
|
:class="{
|
|
38
|
-
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
|
|
39
|
-
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200
|
|
41
|
+
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
|
|
42
|
+
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
|
|
43
|
+
'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
|
|
44
|
+
'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
|
|
40
45
|
'tw-px-2': !option.iconViewBox,
|
|
41
46
|
'tw-px-px':
|
|
42
47
|
option.iconViewBox && !option.isSelected && !option.iconName.includes('display-style') && btnStyleVariant, // TODO - move style logic to computed prop
|
|
@@ -45,9 +50,10 @@
|
|
|
45
50
|
'tw-px-0 tw-py-0': option.iconName.includes('display-style') || btnStyleVariant === 'compressed',
|
|
46
51
|
}"
|
|
47
52
|
:style="option.iconName.includes('display-style') ? { lineHeight: 0 } : {}"
|
|
53
|
+
:disabled="option.disabled"
|
|
48
54
|
class="tw-text-xs button-group-icon-button tw-shadow-inner"
|
|
49
55
|
v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
|
|
50
|
-
@click="$emit('on-select', option)"
|
|
56
|
+
@click="!option.disabled && $emit('on-select', option)"
|
|
51
57
|
>
|
|
52
58
|
<div
|
|
53
59
|
:class="{
|
|
@@ -67,12 +73,15 @@
|
|
|
67
73
|
<button
|
|
68
74
|
v-else
|
|
69
75
|
:class="{
|
|
70
|
-
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
|
|
71
|
-
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200
|
|
76
|
+
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
|
|
77
|
+
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
|
|
78
|
+
'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
|
|
79
|
+
'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
|
|
72
80
|
}"
|
|
81
|
+
:disabled="option.disabled"
|
|
73
82
|
class="tw-text-xs button-group-image-button tw-shadow-inner"
|
|
74
83
|
v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
|
|
75
|
-
@click="$emit('on-select', option)"
|
|
84
|
+
@click="!option.disabled && $emit('on-select', option)"
|
|
76
85
|
>
|
|
77
86
|
<img :src="option.src" :alt="option.alt" class="tw-w-full tw-h-full" />
|
|
78
87
|
</button>
|
|
@@ -90,11 +99,14 @@
|
|
|
90
99
|
:key="`button-${option.value}`"
|
|
91
100
|
:class="{
|
|
92
101
|
'tw-ml-2': idx > 0 && !columns,
|
|
93
|
-
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
|
|
94
|
-
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200
|
|
102
|
+
'!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
|
|
103
|
+
'!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
|
|
104
|
+
'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
|
|
105
|
+
'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
|
|
95
106
|
}"
|
|
107
|
+
:disabled="option.disabled"
|
|
96
108
|
class="tw-text-xs button-group-button tw-shadow-inner"
|
|
97
|
-
@click="$emit('on-select', option)"
|
|
109
|
+
@click="!option.disabled && $emit('on-select', option)"
|
|
98
110
|
>
|
|
99
111
|
{{ option.label }}
|
|
100
112
|
</button>
|
|
@@ -97,20 +97,11 @@ export default {
|
|
|
97
97
|
required: false,
|
|
98
98
|
default: false,
|
|
99
99
|
},
|
|
100
|
-
requiredMessage: {
|
|
101
|
-
type: String,
|
|
102
|
-
required: false,
|
|
103
|
-
default: 'Please fill in this field.',
|
|
104
|
-
},
|
|
105
100
|
},
|
|
106
101
|
methods: {
|
|
107
|
-
input(modelValue
|
|
102
|
+
input(modelValue) {
|
|
108
103
|
this.$emit('update:modelValue', modelValue);
|
|
109
104
|
this.$emit('input', modelValue);
|
|
110
|
-
|
|
111
|
-
if (event?.target) {
|
|
112
|
-
event.target.setCustomValidity('');
|
|
113
|
-
}
|
|
114
105
|
},
|
|
115
106
|
keyup(modelValue) {
|
|
116
107
|
this.$emit('keyup', modelValue);
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
aria-labelledby="title"
|
|
21
21
|
aria-describedby="desc"
|
|
22
22
|
>
|
|
23
|
-
<title :id="`${name}-${id}-title`" lang="en">{{ title }}</title>
|
|
24
|
-
<desc :id="`${name}-${id}-desc`" lang="en">{{ description }}</desc>
|
|
23
|
+
<title v-if="title" :id="`${name}-${id}-title`" lang="en">{{ title }}</title>
|
|
24
|
+
<desc v-if="description" :id="`${name}-${id}-desc`" lang="en">{{ description }}</desc>
|
|
25
25
|
<component :is="`icon-${iconName}`"></component>
|
|
26
26
|
</svg>
|
|
27
27
|
</div>
|
|
@@ -799,7 +799,7 @@ export default {
|
|
|
799
799
|
return css || null;
|
|
800
800
|
},
|
|
801
801
|
title() {
|
|
802
|
-
return this.altText
|
|
802
|
+
return this.altText;
|
|
803
803
|
},
|
|
804
804
|
description() {
|
|
805
805
|
return `${this.title} Icon`;
|
|
@@ -73,8 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
]"
|
|
75
75
|
class="tw-text-grayscale-600 tw-box-border tw-w-full tw-text-base tw-px-4 tw-border tw-border-solid focus:tw-outline-none tw-transition-colors tw-duration-300 tw-ease-out tw-shadow-inner"
|
|
76
|
-
@
|
|
77
|
-
@input.stop="input($event.target.value, $event)"
|
|
76
|
+
@input.stop="input($event.target.value)"
|
|
78
77
|
@keyup.stop="keyup($event.target.value)"
|
|
79
78
|
@keydown.stop="keydown($event.target.value, $event)"
|
|
80
79
|
@focus="focus($event.target.value)"
|
|
@@ -152,9 +151,6 @@ export default {
|
|
|
152
151
|
this.$emit('on-clear-confirmation');
|
|
153
152
|
}
|
|
154
153
|
},
|
|
155
|
-
setValidationMessage(event) {
|
|
156
|
-
event.target.setCustomValidity(this.requiredMessage);
|
|
157
|
-
},
|
|
158
154
|
},
|
|
159
155
|
};
|
|
160
156
|
</script>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
const localeSuffixes = ['.de-DE', '.fr-FR', '.es-ES', '.pt-PT', ''];
|
|
5
|
+
|
|
6
|
+
const findTranslationFiles = (dir, localeString) => {
|
|
7
|
+
const files = [];
|
|
8
|
+
const entries = fs.readdirSync(dir);
|
|
9
|
+
|
|
10
|
+
entries.forEach((entry) => {
|
|
11
|
+
const fullPath = path.join(dir, entry);
|
|
12
|
+
|
|
13
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
14
|
+
if (entry === 'i18n') {
|
|
15
|
+
files.push(
|
|
16
|
+
...fs
|
|
17
|
+
.readdirSync(fullPath)
|
|
18
|
+
.filter((file) => {
|
|
19
|
+
if (localeString === '') {
|
|
20
|
+
return (
|
|
21
|
+
!file.includes('.de-DE') &&
|
|
22
|
+
!file.includes('.fr-FR') &&
|
|
23
|
+
!file.includes('.es-ES') &&
|
|
24
|
+
!file.includes('.pt-PT')
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return file.endsWith(`${localeString}.json`);
|
|
28
|
+
})
|
|
29
|
+
.map((file) => path.join(fullPath, file)),
|
|
30
|
+
);
|
|
31
|
+
} else {
|
|
32
|
+
// Recursively find translation files in nested folders
|
|
33
|
+
files.push(...findTranslationFiles(fullPath, localeString));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return files;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const bundle = () => {
|
|
42
|
+
console.log('Bundling translations...', __dirname);
|
|
43
|
+
|
|
44
|
+
const bundlesDir = path.resolve(__dirname, './bundles');
|
|
45
|
+
|
|
46
|
+
console.log('bundlesDir', bundlesDir);
|
|
47
|
+
|
|
48
|
+
if (!fs.existsSync(bundlesDir)) {
|
|
49
|
+
console.log('Creating bundles dir');
|
|
50
|
+
fs.mkdirSync(bundlesDir);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rootDir = path.resolve(__dirname, '../src');
|
|
54
|
+
|
|
55
|
+
localeSuffixes.forEach((locale) => {
|
|
56
|
+
const outputFile = path.resolve(bundlesDir, `bundled-translations${locale}.json`);
|
|
57
|
+
|
|
58
|
+
const translationFiles = findTranslationFiles(rootDir, locale);
|
|
59
|
+
|
|
60
|
+
console.log(
|
|
61
|
+
`Found ${translationFiles.length} translation files in BrandPage for file prefix: ${`bundled-translations${locale}.json`}`,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const translations = {};
|
|
65
|
+
|
|
66
|
+
translationFiles.forEach((file) => {
|
|
67
|
+
const fileContent = fs.readFileSync(file, 'utf-8');
|
|
68
|
+
|
|
69
|
+
Object.assign(translations, JSON.parse(fileContent));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
console.log(`Writing bundled translations to: ${outputFile}`);
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const potentiallyExistingFile = fs.readFileSync(outputFile, 'utf-8');
|
|
76
|
+
|
|
77
|
+
if (potentiallyExistingFile === JSON.stringify(translations, null, 2)) {
|
|
78
|
+
console.log('Current translations are the same as the existing file - skipping write');
|
|
79
|
+
} else {
|
|
80
|
+
fs.writeFileSync(outputFile, JSON.stringify(translations, null, 2));
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.log("Translation file doesn't exist, creating new one");
|
|
84
|
+
fs.writeFileSync(outputFile, JSON.stringify(translations, null, 2));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
bundle();
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<div v-if="isNotPublished || isSlugEditMode" class="tw-mt-4">
|
|
51
51
|
<PublishBrandPageCard
|
|
52
52
|
v-if="!hasPurchasedDomains"
|
|
53
|
-
:
|
|
53
|
+
:img-url="iconUrl"
|
|
54
54
|
title="Free Address"
|
|
55
55
|
description="Choose a free address to publish now. You can always edit the URL later"
|
|
56
56
|
:is-design-com="isDesignCom"
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
data-test-brand-page-publish-button
|
|
85
85
|
variant="primary"
|
|
86
86
|
size="small-medium"
|
|
87
|
-
@on-click="onPublish"
|
|
88
87
|
:full-width="isMobile"
|
|
89
88
|
:class="{
|
|
90
89
|
'tw-uppercase': !isDesignCom,
|
|
91
90
|
}"
|
|
91
|
+
@on-click="onPublish"
|
|
92
92
|
/>
|
|
93
93
|
</div>
|
|
94
94
|
</template>
|
|
@@ -196,6 +196,7 @@
|
|
|
196
196
|
:display-result-limit="4"
|
|
197
197
|
:domain-search-location="sitePublishedModal"
|
|
198
198
|
@on-change-search="onSearchTextChanged"
|
|
199
|
+
@on-buy-now-click="onBuyNowClick"
|
|
199
200
|
/>
|
|
200
201
|
</div>
|
|
201
202
|
<Button
|
|
@@ -245,19 +246,21 @@
|
|
|
245
246
|
</div>
|
|
246
247
|
</template>
|
|
247
248
|
<script>
|
|
248
|
-
import
|
|
249
|
+
import { computed } from 'vue';
|
|
250
|
+
import Modal from '../../../atoms/components/Modal/Modal.vue';
|
|
249
251
|
import PublishBrandPageCard from './PublishBrandPageCard.vue';
|
|
250
|
-
import TextInput from '
|
|
251
|
-
import Dropdown from '
|
|
252
|
-
import DropdownItem from '
|
|
253
|
-
import Button from '
|
|
254
|
-
import TextCopyField from '
|
|
252
|
+
import TextInput from '../../../atoms/components/TextInput/TextInput.vue';
|
|
253
|
+
import Dropdown from '../../../atoms/components/Dropdown/Dropdown.vue';
|
|
254
|
+
import DropdownItem from '../../../atoms/components/Dropdown/DropdownItem.vue';
|
|
255
|
+
import Button from '../../../atoms/components/Button/Button.vue';
|
|
256
|
+
import TextCopyField from '../../../atoms/components/TextCopyField/TextCopyField.vue';
|
|
255
257
|
|
|
256
258
|
import SellDomainNameSearchWithResults from '../SellDomainNameSearchWithResults/SellDomainNameSearchWithResults.vue';
|
|
257
259
|
import SellDomainNameListModal from '../SellDomainNameListModal/SellDomainNameListModal.vue';
|
|
258
260
|
import brandCrowdApiClient from '../../clients/brand-crowd-api.client';
|
|
259
261
|
import Events, { sitePublishedModal } from '../../constants/event-constants';
|
|
260
262
|
import mediaQueryMixin from '../../mixins/mediaQueryMixin';
|
|
263
|
+
import { tr } from '../../../useSharedLibTranslate';
|
|
261
264
|
|
|
262
265
|
const headerSubtitle = 'Buy matching domain name for your brand';
|
|
263
266
|
|
|
@@ -412,6 +415,12 @@ export default {
|
|
|
412
415
|
'on-view-more-domains',
|
|
413
416
|
'on-slug-changed',
|
|
414
417
|
],
|
|
418
|
+
setup() {
|
|
419
|
+
return {
|
|
420
|
+
tr,
|
|
421
|
+
testMessage: computed(() => tr('publishModal.test')),
|
|
422
|
+
};
|
|
423
|
+
},
|
|
415
424
|
data() {
|
|
416
425
|
return {
|
|
417
426
|
DOMAIN_TYPES,
|
|
@@ -489,7 +498,7 @@ export default {
|
|
|
489
498
|
this.$emit('on-hide-domain-modal');
|
|
490
499
|
},
|
|
491
500
|
onCopyUrlClick() {
|
|
492
|
-
this.$emit('copy-url-
|
|
501
|
+
this.$emit('copy-url-clicked');
|
|
493
502
|
},
|
|
494
503
|
onSlugChanged(e) {
|
|
495
504
|
this.searchText = e;
|
|
@@ -509,6 +518,7 @@ export default {
|
|
|
509
518
|
},
|
|
510
519
|
onSearchTextChanged(val) {
|
|
511
520
|
this.searchText = val;
|
|
521
|
+
this.$emit('on-change-search', val);
|
|
512
522
|
},
|
|
513
523
|
onSelectPurchasedDomain(newVal) {
|
|
514
524
|
this.selectedCustomDomain = newVal;
|
|
@@ -524,6 +534,9 @@ export default {
|
|
|
524
534
|
onSellDomainNameListCloseModal() {
|
|
525
535
|
this.$emit('on-hide-domain-modal');
|
|
526
536
|
},
|
|
537
|
+
onBuyNowClick() {
|
|
538
|
+
this.$emit('on-buy-now-clicked');
|
|
539
|
+
},
|
|
527
540
|
async searchDomainName(isUserTriggered) {
|
|
528
541
|
this.isLoading = true;
|
|
529
542
|
let searchSlug = '';
|
|
@@ -114,6 +114,7 @@ export default {
|
|
|
114
114
|
if (typeof this.domainSearchLocation !== 'undefined') {
|
|
115
115
|
request.domainSearchLocation = this.domainSearchLocation;
|
|
116
116
|
}
|
|
117
|
+
this.$emit('on-buy-now-click');
|
|
117
118
|
window.dispatchEvent(
|
|
118
119
|
new CustomEvent(Events.DomainSelectedEvent, {
|
|
119
120
|
detail: request,
|
package/src/experiences/components/SellDomainNameSearchResult/SellDomainNameListSearchResult.vue
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
:load-more-domains-button-text="loadMoreDomainsButtonText"
|
|
26
26
|
:domain-search-location="domainSearchLocation"
|
|
27
27
|
@load-more-domains="onLoadMoreDomains"
|
|
28
|
+
@on-buy-now-click="onBuyNowClick"
|
|
28
29
|
/>
|
|
29
30
|
<div v-else-if="shouldShowDomainNameNotFound" class="tw-flex tw-justify-center tw-text-center">
|
|
30
31
|
Sorry, we couldn't find any domain for "{{ previousSearchText }}".
|
|
@@ -145,6 +146,9 @@ export default {
|
|
|
145
146
|
window.dispatchEvent(new CustomEvent(Events.DomainLoadMoreEvent));
|
|
146
147
|
this.domainNameItemsInView += this.domainNameItemsPerPage;
|
|
147
148
|
},
|
|
149
|
+
onBuyNowClick() {
|
|
150
|
+
this.$emit('on-buy-now-click');
|
|
151
|
+
},
|
|
148
152
|
resetDomainNameItemsInView() {
|
|
149
153
|
this.domainNameItemsInView = this.domainNameItemsPerPage;
|
|
150
154
|
},
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
:domain-name-items-per-page="domainNameItemsPerPage"
|
|
21
21
|
:load-more-domains-button-text="loadMoreDomainsButtonText"
|
|
22
22
|
:domain-search-location="domainSearchLocation"
|
|
23
|
+
@on-buy-now-click="onBuyNowClick"
|
|
23
24
|
/>
|
|
24
25
|
</div>
|
|
25
26
|
</template>
|
|
@@ -170,6 +171,9 @@ export default {
|
|
|
170
171
|
this.isBusy = false;
|
|
171
172
|
}
|
|
172
173
|
},
|
|
174
|
+
onBuyNowClick() {
|
|
175
|
+
this.$emit('on-buy-now-click');
|
|
176
|
+
},
|
|
173
177
|
cleanText(inputText) {
|
|
174
178
|
// In this function, we use the Unicode property escapes \p{L} and \p{N} to match any Unicode letters (characters from various scripts) and Unicode numbers, respectively.
|
|
175
179
|
const cleanedText = inputText.replace(/[^\p{L}\p{N}\-.]+/gu, '');
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import i18next from 'i18next';
|
|
3
|
+
|
|
4
|
+
const fallbackLocale = 'en-US';
|
|
5
|
+
|
|
6
|
+
const relativePathsToTranslationFiles = {
|
|
7
|
+
'en-US': () => import('./bundles/bundled-translations.json'),
|
|
8
|
+
'de-DE': () => import('./bundles/bundled-translations.de-DE.json'),
|
|
9
|
+
'fr-FR': () => import('./bundles/bundled-translations.fr-FR.json'),
|
|
10
|
+
'es-ES': () => import('./bundles/bundled-translations.es-ES.json'),
|
|
11
|
+
'pt-PT': () => import('./bundles/bundled-translations.pt-PT.json'),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const setLocaleAsync = async (locale = 'en-US') => {
|
|
15
|
+
const localeToUse = locale;
|
|
16
|
+
|
|
17
|
+
if (!i18next.isInitialized) {
|
|
18
|
+
await i18next.init({
|
|
19
|
+
debug: false,
|
|
20
|
+
fallbackLng: fallbackLocale,
|
|
21
|
+
lng: localeToUse,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const languageFile = (await relativePathsToTranslationFiles[localeToUse]()).default;
|
|
26
|
+
|
|
27
|
+
await i18next.addResourceBundle(localeToUse, 'fe-shared-lib', {
|
|
28
|
+
...languageFile,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const tr = (key, valuesToInterpolate = {}) => {
|
|
33
|
+
const translated = i18next.t(key, { ns: 'fe-shared-lib', ...valuesToInterpolate });
|
|
34
|
+
|
|
35
|
+
return translated;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { setLocaleAsync, tr };
|