+
+
{t('featuresBanner.label')}
-
+
+ {t('featuresBanner.title')}
+
+
+
-
-
-
{translate('lifetimeBanner.guarantee')}
+
+
+
{t('featuresBanner.guarantee')}
+
+
{t('featuresBanner.lastCta')}
-
- {features.map((item) => (
-
-
-
{item.title}
+
+
+
+ {features.map((card) => (
+
+ ))}
- ))}
+
);
};
+
export default FeaturesBanner;
diff --git a/src/app/i18n/locales/de.json b/src/app/i18n/locales/de.json
index 199d16982..ca0a9e9f7 100644
--- a/src/app/i18n/locales/de.json
+++ b/src/app/i18n/locales/de.json
@@ -4,18 +4,19 @@
"logOut": "Log-out"
},
"featuresBanner": {
- "header": "Spare 70%!",
- "title": "Bereiten Sie sich auf die Datenschutzwoche vor",
- "cta": "Plan auswählen",
- "guarantee": "30-tägige Geld-zurück-Garantie",
- "features": {
- "discount": "Sparen Sie bei monatlichen und jährlichen Plänen",
- "safeCloud": "Sicherer und geschützter Cloud-Speicher",
- "openSource": "Open Source und transparent",
- "endToEnd": "Ende-zu-Ende-verschlüsselte Übertragungen",
- "unauthorized": "Kein unberechtigter Zugriff",
- "offerEnds": "Angebot endet am 29. Februar"
- }
+ "label": "Spare 75%",
+ "title": "Starten Sie Ihre digitale Frühjahrsputz",
+ "cta": "Wähle einen Plan",
+ "guarantee": "30 Tage Geld-zurück-Garantie",
+ "lastCta": "*Angebot gilt für kostenlose Konten oder neue Kunden",
+ "features": [
+ "Sparen Sie bei allen unseren Plänen",
+ "Sicherer Cloud-Speicher",
+ "Backup privater Dateien und Fotos",
+ "End-to-end verschlüsselte Übertragungen",
+ "Kein unbefugter Zugriff",
+ "Angebot endet am 18. März"
+ ]
},
"valentinesBanner": {
"title": "Liebe ohne grenzen!",
diff --git a/src/app/i18n/locales/en.json b/src/app/i18n/locales/en.json
index 415a6a223..c4e31c8f9 100644
--- a/src/app/i18n/locales/en.json
+++ b/src/app/i18n/locales/en.json
@@ -4,19 +4,19 @@
"logOut": "Log Out"
},
"featuresBanner": {
- "header": "Save 70%!",
- "title": "Get ready for Data Privacy Week",
+ "label": "Save 75%",
+ "title": "Start your digital spring cleaning",
"cta": "Choose plan",
"guarantee": "30-day money-back guarantee",
"lastCta": "*Offer is for free accounts or new customers",
- "features": {
- "discount": "Save on monthly & annual plans",
- "safeCloud": "Safe and secure cloud storage",
- "openSource": "Open source and transparent",
- "endToEnd": "End-to-end encrypted transfers",
- "unauthorized": "No unauthorized access",
- "offerEnds": "Offer ends February 29th"
- }
+ "features": [
+ "Save on all of our plans",
+ "Safe and secure cloud storage",
+ "Open source and transparent",
+ "End-to-end encrypted transfers",
+ "No unauthorized access",
+ "Offer ends March 18th"
+ ]
},
"valentinesBanner": {
"title": "Love without limits!",
diff --git a/src/app/i18n/locales/es.json b/src/app/i18n/locales/es.json
index d2fc32040..4eeb6f068 100644
--- a/src/app/i18n/locales/es.json
+++ b/src/app/i18n/locales/es.json
@@ -4,19 +4,19 @@
"logOut": "Cerrar sesión"
},
"featuresBanner": {
- "header": "¡Ahorra un 70%!",
- "title": "Prepárate para la Semana de la Privacidad de Datos",
+ "label": "Ahorra un 75%",
+ "title": "Comienza a ahorrar esta primavera",
"cta": "Elige un plan",
"guarantee": "Garantía de devolución de 30 días",
"lastCta": "*La oferta es para cuentas gratuitas o nuevos clientes",
- "features": {
- "discount": "Ahorra en suscripciones mensuales y anuales",
- "safeCloud": "Almacenamiento seguro en la nube",
- "openSource": "Código abierto y transparente",
- "endToEnd": "Transferencias cifradas de extremo a extremo",
- "unauthorized": "Sin acceso no autorizado",
- "offerEnds": "La oferta finaliza el 29 de febrero"
- }
+ "features": [
+ "Ahorra en todos nuestros planes",
+ "Almacenamiento seguro en la nube",
+ "Código abierto y auditado",
+ "Transferencias cifradas de extremo a extremo",
+ "Sin accesos no autorizados",
+ "La oferta finaliza el 18 de marzo"
+ ]
},
"valentinesBanner": {
"title": "¡Amor sin limites!",
diff --git a/src/app/i18n/locales/fr.json b/src/app/i18n/locales/fr.json
index f520eb3de..f7d8e10e7 100644
--- a/src/app/i18n/locales/fr.json
+++ b/src/app/i18n/locales/fr.json
@@ -4,19 +4,19 @@
"logOut": "Déconnexion"
},
"featuresBanner": {
- "header": "Économisez 70% !",
- "title": "Préparez-vous pour la Semaine de la Protection des Données",
+ "label": "Économisez 75%",
+ "title": "Profitez de votre offre de printemps",
"cta": "Choisissez un plan",
"guarantee": "Garantie de remboursement de 30 jours",
"lastCta": "*L'offre est valable pour les comptes gratuits ou les nouveaux clients",
- "features": {
- "discount": "Économisez sur les plans mensuels et annuels",
- "safeCloud": "Stockage cloud sûr et sécurisé",
- "openSource": "Open source et transparent",
- "endToEnd": "Transferts chiffrés de bout en bout",
- "unauthorized": "Aucun accès non autorisé",
- "offerEnds": "L'offre se termine le 29 février"
- }
+ "features": [
+ "Économisez sur tous nos plans",
+ "Stockage cloud sûr et sécurisé",
+ "Open source et transparent",
+ "Transferts chiffrés de bout en bout",
+ "Aucun accès non autorisé",
+ "L'offre se termine le 18 mars"
+ ]
},
"valentinesBanner": {
"title": "L'amour sans limites !",
diff --git a/src/app/i18n/locales/it.json b/src/app/i18n/locales/it.json
index 31d287ded..54b64f9b8 100644
--- a/src/app/i18n/locales/it.json
+++ b/src/app/i18n/locales/it.json
@@ -9,19 +9,19 @@
"cta": "Get the deal"
},
"featuresBanner": {
- "header": "Risparmia il 70%!",
- "title": "Preparati per la Settimana della Privacy dei Dati",
+ "label": "Risparmia il 75%",
+ "title": "Inizia la tua pulizia digitale di primavera",
"cta": "Scegli un piano",
"guarantee": "Garanzia di rimborso entro 30 giorni",
"lastCta": "*L'offerta è valida solo per account gratuiti o nuovi clienti",
- "features": {
- "discount": "Risparmia su piani mensili e annuali",
- "safeCloud": "Archiviazione cloud sicura e protetta",
- "openSource": "Open source e trasparente",
- "endToEnd": "Trasferimenti crittografati end-to-end",
- "unauthorized": "Nessun accesso non autorizzato",
- "offerEnds": "L'offerta termina il 29 febbraio"
- }
+ "features": [
+ "Risparmia su tutti i nostri piani",
+ "Archiviazione cloud sicura e protetta",
+ "Open source e trasparente",
+ "Trasferimenti crittografati end-to-end",
+ "Nessun accesso non autorizzato",
+ "L'offerta termina il 18 marzo"
+ ]
},
"lifetimeBanner": {
"label": "Cercate uno spazio sicuro per i vostri dati per tutta la vita?",
diff --git a/src/app/i18n/locales/ru.json b/src/app/i18n/locales/ru.json
index ed04b362d..a65073863 100644
--- a/src/app/i18n/locales/ru.json
+++ b/src/app/i18n/locales/ru.json
@@ -9,19 +9,19 @@
"cta": "Получить скидку"
},
"featuresBanner": {
- "label": "Сэкономьте 70%!",
- "title": "Приготовьтесь к Неделе конфиденциальности данных",
+ "label": "Скидка 75%",
+ "title": "Получите своё весеннее предложение",
"cta": "Выбрать план",
- "guarantee": "30-дневная гарантия возврата денег",
+ "guarantee": "Гарантия возврата денег в течение 30 дней",
"lastCta": "*Предложение действует только для бесплатных аккаунтов или новых клиентов",
- "features": {
- "discount": "Скидка на годовые и месячные планы",
- "safeCloud": "Надежное и безопасное облачное хранилище",
- "openSource": "Открытый исходный код и прозрачность",
- "endToEnd": "Передача данных в зашифрованном виде",
- "unauthorized": "Отсутствие несанкционированного доступа",
- "offerEnds": "Предложение действует до 29 февраля"
- }
+ "features": [
+ "Экономьте на всех наших планах",
+ "Надежное и безопасное облачное хранилище",
+ "Открытый исходный код и прозрачность",
+ "Передача данных в зашифрованном виде",
+ "Отсутствие несанкционированного доступа",
+ "Предложение заканчивается 18 марта"
+ ]
},
"lifetimeBanner": {
"label": "Ищите надежное хранилище данных на всю жизнь?",
diff --git a/src/app/i18n/locales/zh.json b/src/app/i18n/locales/zh.json
index 66d8e96a3..137e2b783 100644
--- a/src/app/i18n/locales/zh.json
+++ b/src/app/i18n/locales/zh.json
@@ -4,19 +4,19 @@
"logOut": "登出"
},
"featuresBanner": {
- "header": "省 70%!",
- "title": "为数据隐私周做好准备",
+ "label": "省75%",
+ "title": "开始您的数字春季大扫除",
"cta": "选择计划",
- "guarantee": "30 天内退款保证",
- "lastCta": "*此优惠仅适用于免费账户或新客户",
- "features": {
- "discount": "在月度和年度计划上节省",
- "safeCloud": "安全可靠的云存储",
- "openSource": "开源和透明",
- "endToEnd": "端到端加密传输",
- "unauthorized": "无未经授权访问",
- "offerEnds": "优惠截止日期为2月29日"
- }
+ "guarantee": "30天退款保证",
+ "lastCta": "*优惠仅适用于免费帐户或新客户",
+ "features": [
+ "在我们所有的计划上节省",
+ "安全可靠的云存储",
+ "开源和透明",
+ "端到端加密传输",
+ "没有未经授权的访问",
+ "优惠截至日期为3月18日"
+ ]
},
"valentinesBanner": {
"title": "爱无极限!",
From 4090ee8a32629fbc6f0ca94a7ff137d8a9f3983b Mon Sep 17 00:00:00 2001
From: Xavier Abad <77491413+masterprog-cmd@users.noreply.github.com>
Date: Mon, 4 Mar 2024 18:19:55 +0100
Subject: [PATCH 2/6] fix: remove unused import
---
src/app/banners/BannerWrapper.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/app/banners/BannerWrapper.tsx b/src/app/banners/BannerWrapper.tsx
index 0f08c4db8..86e8ab3f1 100644
--- a/src/app/banners/BannerWrapper.tsx
+++ b/src/app/banners/BannerWrapper.tsx
@@ -7,7 +7,6 @@ import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { UserSettings } from '@internxt/sdk/dist/shared/types/userSettings';
-import Banner from './Banner';
import FeaturesBanner from './FeaturesBanner';
const SHOW_BANNER_COOKIE_NAME = 'show_spring_banner';
From da4ac46043d93fbb7427484031049f4e8bf82b66 Mon Sep 17 00:00:00 2001
From: Xavier Abad <77491413+masterprog-cmd@users.noreply.github.com>
Date: Mon, 4 Mar 2024 18:25:14 +0100
Subject: [PATCH 3/6] feat: use custom hook (translations)
---
src/app/banners/FeaturesBanner.tsx | 16 ++++++++--------
src/app/i18n/provider/TranslationProvider.tsx | 2 +-
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/app/banners/FeaturesBanner.tsx b/src/app/banners/FeaturesBanner.tsx
index 0f00682a6..3be02ed85 100644
--- a/src/app/banners/FeaturesBanner.tsx
+++ b/src/app/banners/FeaturesBanner.tsx
@@ -1,10 +1,10 @@
import { CheckCircle, Flower, X } from '@phosphor-icons/react';
-import { useTranslation } from 'react-i18next';
+import { useTranslationContext } from 'app/i18n/provider/TranslationProvider';
const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose: () => void }): JSX.Element => {
- const { t } = useTranslation();
+ const { translate } = useTranslationContext();
- const features = t('featuresBanner.features', { returnObjects: true }) as string[];
+ const features = translate('featuresBanner.features', { returnObjects: true }) as string[];
const handleOnClick = () => {
window.open('https://internxt.com/pricing', '_blank', 'nofollow noreferrer');
@@ -28,10 +28,10 @@ const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose:
-
{t('featuresBanner.label')}
+
{translate('featuresBanner.label')}
- {t('featuresBanner.title')}
+ {translate('featuresBanner.title')}
@@ -39,14 +39,14 @@ const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose:
onClick={handleOnClick}
className="flex w-max items-center rounded-lg bg-primary px-5 py-3 text-lg font-medium text-white hover:bg-primary-dark"
>
- {t('featuresBanner.cta')}
+ {translate('featuresBanner.cta')}
-
{t('featuresBanner.guarantee')}
+
{translate('featuresBanner.guarantee')}
-
{t('featuresBanner.lastCta')}
+
{translate('featuresBanner.lastCta')}
diff --git a/src/app/i18n/provider/TranslationProvider.tsx b/src/app/i18n/provider/TranslationProvider.tsx
index 573534e8c..30192e10a 100644
--- a/src/app/i18n/provider/TranslationProvider.tsx
+++ b/src/app/i18n/provider/TranslationProvider.tsx
@@ -2,7 +2,7 @@ import React, { createContext, useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
interface TranslationContextProps {
- translate: (key: string, props?: Record
) => string;
+ translate: (key: string, props?: Record) => string | string[] | undefined;
}
const TranslationContext = createContext({ translate: () => '' });
From 6ee23e572f7156bf784e2131665f1531aafc74eb Mon Sep 17 00:00:00 2001
From: Xavier Abad <77491413+masterprog-cmd@users.noreply.github.com>
Date: Mon, 4 Mar 2024 18:30:08 +0100
Subject: [PATCH 4/6] fix: error in translations provider
---
src/app/banners/FeaturesBanner.tsx | 2 +-
src/app/i18n/provider/TranslationProvider.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/banners/FeaturesBanner.tsx b/src/app/banners/FeaturesBanner.tsx
index 3be02ed85..36219ab1c 100644
--- a/src/app/banners/FeaturesBanner.tsx
+++ b/src/app/banners/FeaturesBanner.tsx
@@ -7,7 +7,7 @@ const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose:
const features = translate('featuresBanner.features', { returnObjects: true }) as string[];
const handleOnClick = () => {
- window.open('https://internxt.com/pricing', '_blank', 'nofollow noreferrer');
+ window.open('https://internxt.com/pricing', '_blank', 'noopener noreferrer');
};
return (
diff --git a/src/app/i18n/provider/TranslationProvider.tsx b/src/app/i18n/provider/TranslationProvider.tsx
index 30192e10a..af02d67b0 100644
--- a/src/app/i18n/provider/TranslationProvider.tsx
+++ b/src/app/i18n/provider/TranslationProvider.tsx
@@ -2,7 +2,7 @@ import React, { createContext, useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
interface TranslationContextProps {
- translate: (key: string, props?: Record) => string | string[] | undefined;
+ translate: (key: string, props?: Record) => string | string[] | any;
}
const TranslationContext = createContext({ translate: () => '' });
From 2b7b19f18aea1e39255dcbbd5925ec1d10f5ff22 Mon Sep 17 00:00:00 2001
From: Xavier Abad <77491413+masterprog-cmd@users.noreply.github.com>
Date: Mon, 4 Mar 2024 18:43:55 +0100
Subject: [PATCH 5/6] feat: adding space between components
---
src/app/banners/FeaturesBanner.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/banners/FeaturesBanner.tsx b/src/app/banners/FeaturesBanner.tsx
index 36219ab1c..3b41523c9 100644
--- a/src/app/banners/FeaturesBanner.tsx
+++ b/src/app/banners/FeaturesBanner.tsx
@@ -25,7 +25,7 @@ const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose:
-
+
{translate('featuresBanner.label')}
From 7cdba8515d9e3a4ee9badd574946cee60a05d2eb Mon Sep 17 00:00:00 2001
From: Xavier Abad <77491413+masterprog-cmd@users.noreply.github.com>
Date: Tue, 5 Mar 2024 11:19:11 +0100
Subject: [PATCH 6/6] feat: create new function to get arrays from json
---
src/app/banners/FeaturesBanner.tsx | 4 ++--
src/app/i18n/provider/TranslationProvider.tsx | 10 +++++++---
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/app/banners/FeaturesBanner.tsx b/src/app/banners/FeaturesBanner.tsx
index 3b41523c9..3183ce2e7 100644
--- a/src/app/banners/FeaturesBanner.tsx
+++ b/src/app/banners/FeaturesBanner.tsx
@@ -2,9 +2,9 @@ import { CheckCircle, Flower, X } from '@phosphor-icons/react';
import { useTranslationContext } from 'app/i18n/provider/TranslationProvider';
const FeaturesBanner = ({ showBanner, onClose }: { showBanner: boolean; onClose: () => void }): JSX.Element => {
- const { translate } = useTranslationContext();
+ const { translate, translateList } = useTranslationContext();
- const features = translate('featuresBanner.features', { returnObjects: true }) as string[];
+ const features = translateList('featuresBanner.features');
const handleOnClick = () => {
window.open('https://internxt.com/pricing', '_blank', 'noopener noreferrer');
diff --git a/src/app/i18n/provider/TranslationProvider.tsx b/src/app/i18n/provider/TranslationProvider.tsx
index af02d67b0..1a91f3e1c 100644
--- a/src/app/i18n/provider/TranslationProvider.tsx
+++ b/src/app/i18n/provider/TranslationProvider.tsx
@@ -2,17 +2,21 @@ import React, { createContext, useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
interface TranslationContextProps {
- translate: (key: string, props?: Record
) => string | string[] | any;
+ translate: (key: string, props?: Record) => string;
+ translateList: (key: string) => string[];
}
-const TranslationContext = createContext({ translate: () => '' });
+const TranslationContext = createContext({ translate: () => '', translateList: () => [] });
interface TranslationProviderProps {
children: React.ReactNode;
}
export const TranslationProvider: React.FC = ({ children }) => {
const { t } = useTranslation();
- const value = useMemo(() => ({ translate: t }), [t]);
+
+ const translateList = (key: string) => t(key, { returnObjects: true }) as string[];
+
+ const value = useMemo(() => ({ translate: t, translateList }), [t]);
return {children};
};