From d5bec35b3f4c320b0d9c816685e4dcca20ef0988 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Tue, 15 Aug 2023 15:04:40 +0100 Subject: [PATCH 01/10] Split pt translation into pt (EU) and pt_BR (Brazil). --- apps/builder/next.config.mjs | 2 +- .../components/UserPreferencesForm.tsx | 1 + apps/builder/src/locales/index.ts | 9 +- apps/builder/src/locales/pt.ts | 112 +++++----- apps/builder/src/locales/pt_BR.ts | 193 ++++++++++++++++++ 5 files changed, 256 insertions(+), 61 deletions(-) create mode 100644 apps/builder/src/locales/pt_BR.ts diff --git a/apps/builder/next.config.mjs b/apps/builder/next.config.mjs index 094f7a8f60..f842162b34 100644 --- a/apps/builder/next.config.mjs +++ b/apps/builder/next.config.mjs @@ -22,7 +22,7 @@ const nextConfig = { ], i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'pt', 'de'], + locales: ['en', 'fr', 'pt', 'pt_BR', 'de'], }, experimental: { outputFileTracingRoot: join(__dirname, '../../'), diff --git a/apps/builder/src/features/account/components/UserPreferencesForm.tsx b/apps/builder/src/features/account/components/UserPreferencesForm.tsx index 519da2a05a..4a76490e71 100644 --- a/apps/builder/src/features/account/components/UserPreferencesForm.tsx +++ b/apps/builder/src/features/account/components/UserPreferencesForm.tsx @@ -23,6 +23,7 @@ const localeHumanReadable = { fr: 'Français', de: 'Deutsch', pt: 'Português', + pt_BR: 'Português (BR)' } as const export const UserPreferencesForm = () => { diff --git a/apps/builder/src/locales/index.ts b/apps/builder/src/locales/index.ts index 673fa61eae..5c9e686499 100644 --- a/apps/builder/src/locales/index.ts +++ b/apps/builder/src/locales/index.ts @@ -8,8 +8,9 @@ export const { useCurrentLocale, useChangeLocale, } = createI18n({ - en: () => import('./en'), - fr: () => import('./fr'), - pt: () => import('./pt'), - de: () => import('./de'), + en: () => import('./en'), + fr: () => import('./fr'), + pt: () => import('./pt'), + pt_BR: () => import('./pt_BR'), + de: () => import('./de'), }) diff --git a/apps/builder/src/locales/pt.ts b/apps/builder/src/locales/pt.ts index 0848251265..6261ad7e32 100644 --- a/apps/builder/src/locales/pt.ts +++ b/apps/builder/src/locales/pt.ts @@ -1,59 +1,59 @@ export default { back: 'Voltar', - 'confirmModal.defaultTitle': 'Tem certeza?', + 'confirmModal.defaultTitle': 'Tem a certeza?', 'dashboard.header.settingsButton.label': 'Configurações & Membros', - 'dashboard.redirectionMessage': 'Você está sendo redirecionado...', - 'dashboard.title': 'Meus typebots', + 'dashboard.redirectionMessage': 'Está a ser redirecionado...', + 'dashboard.title': 'Os meus typebots', delete: 'Apagar', errorMessage: 'Ocorreu um erro', cancel: 'Cancelar', update: 'Atualizar', - upgrade: 'Upgrade', - downgrade: 'Downgrade', + upgrade: 'Atualizar', + downgrade: 'Desatualizar', remove: 'Remover', pending: 'Pendente', - skip: 'Pular', + skip: 'Saltar', 'folders.createFolderButton.label': 'Criar uma pasta', 'folders.createTypebotButton.label': 'Criar um typebot', 'folders.folderButton.deleteConfirmationMessage': - 'Tem certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)', - 'folders.typebotButton.live': 'Live', + 'Tem a certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)', + 'folders.typebotButton.live': 'Ao Vivo', 'folders.typebotButton.showMoreOptions': 'Mostrar mais opções', 'folders.typebotButton.unpublish': 'Despublicar', 'folders.typebotButton.duplicate': 'Duplicar', 'folders.typebotButton.delete': 'Apagar', 'folders.typebotButton.deleteConfirmationMessage': - 'Tem certeza de que deseja excluir seu typebot {typebotName}?', + 'Tem a certeza de que deseja excluir o seu typebot {typebotName}?', 'folders.typebotButton.deleteConfirmationMessageWarning': 'Todos os dados associados serão excluídos e não poderão ser recuperados.', 'account.apiTokens.heading': 'Tokens de API', 'account.apiTokens.description': - 'Esses tokens permitem que outros aplicativos controlem toda a sua conta e typebots. Tenha cuidado!', + 'Estes tokens permitem que outras aplicações controlem toda a sua conta e typebots. Tenha cuidado!', 'account.apiTokens.createButton.label': 'Criar', 'account.apiTokens.deleteButton.label': 'Excluir', 'account.apiTokens.table.nameHeader': 'Nome', 'account.apiTokens.table.createdHeader': 'Criado', 'account.apiTokens.deleteConfirmationMessage': - 'O token {tokenName} será revogado permanentemente. Tem certeza de que deseja continuar?', + 'O token {tokenName} será revogado permanentemente. Tem a certeza de que deseja continuar?', 'account.apiTokens.createModal.createHeading': 'Criar Token', 'account.apiTokens.createModal.createdHeading': 'Token Criado', 'account.apiTokens.createModal.nameInput.label': - 'Insira um nome único para o seu token para diferenciá-lo de outros tokens.', + 'Insira um nome único para o seu token para o diferenciar de outros tokens.', 'account.apiTokens.createModal.nameInput.placeholder': 'Ex. Zapier, Github, Make.com', 'account.apiTokens.createModal.createButton.label': 'Criar token', 'account.apiTokens.createModal.doneButton.label': 'Concluído', 'account.apiTokens.createModal.copyInstruction': - 'Por favor, copie seu token e guarde-o em um lugar seguro.', + 'Por favor, copie o seu token e guarde-o num lugar seguro.', 'account.apiTokens.createModal.securityWarning': - 'Por motivos de segurança, não podemos mostrá-lo novamente.', + 'Por razões de segurança, não o podemos mostrar novamente.', 'account.preferences.language.heading': 'Idioma', 'account.preferences.language.tooltip': - 'As traduções ainda não estão completas. É um trabalho em andamento. 🤓', + 'As traduções ainda não estão completas. É um trabalho em curso. 🤓', 'account.preferences.graphNavigation.heading': 'Navegação do Editor', - 'account.preferences.graphNavigation.mouse.label': 'Mouse', + 'account.preferences.graphNavigation.mouse.label': 'Rato', 'account.preferences.graphNavigation.mouse.description': - 'Mova arrastando o quadro e amplie/reduza usando a roda de rolagem', + 'Mova arrastando o quadro e amplie/reduza usando a roda de deslocamento', 'account.preferences.graphNavigation.trackpad.label': 'Trackpad', 'account.preferences.graphNavigation.trackpad.description': 'Mova o quadro usando 2 dedos e amplie/reduza fazendo pinça', @@ -65,7 +65,7 @@ export default { 'account.myAccount.changePhotoButton.specification': '.jpg ou.png, máximo 1MB', 'account.myAccount.emailInput.disabledTooltip': - 'A atualização do e-mail não está disponível. Entre em contato com o suporte se quiser alterá-lo.', + 'A atualização do e-mail não está disponível. Entre em contacto com o apoio se quiser alterá-lo.', 'account.myAccount.emailInput.label': 'Endereço de e-mail:', 'account.myAccount.nameInput.label': 'Nome:', 'analytics.viewsLabel': 'Visualizações', @@ -73,120 +73,120 @@ export default { 'analytics.completionRateLabel': 'Taxa de conclusão', 'auth.signin.heading': 'Entrar', 'auth.signin.noAccountLabel.preLink': 'Não tem uma conta?', - 'auth.signin.noAccountLabel.link': 'Registre-se gratuitamente', + 'auth.signin.noAccountLabel.link': 'Registe-se gratuitamente', 'auth.register.heading': 'Criar uma conta', 'auth.register.alreadyHaveAccountLabel.preLink': 'Já tem uma conta?', 'auth.register.alreadyHaveAccountLabel.link': 'Entrar', 'auth.register.aggreeToTerms': - 'Ao se cadastrar, você concorda com nossos {termsOfService} e {privacyPolicy}.', + 'Ao registar-se, concorda com os nossos {termsOfService} e {privacyPolicy}.', 'auth.register.termsOfService': 'termos de serviço', 'auth.register.privacyPolicy': 'política de privacidade', 'auth.error.default': 'Tente entrar com uma conta diferente.', 'auth.error.email': - 'E-mail não encontrado. Tente entrar com um provedor diferente.', + 'E-mail não encontrado. Tente entrar com um fornecedor diferente.', 'auth.error.oauthNotLinked': - 'Para confirmar sua identidade, entre com a mesma conta que você usou originalmente.', + 'Para confirmar a sua identidade, entre com a mesma conta que usou originalmente.', 'auth.error.unknown': 'Ocorreu um erro. Tente novamente.', 'auth.signinErrorToast.title': 'Não autorizado', 'auth.signinErrorToast.description': 'As inscrições estão desativadas.', 'auth.signinErrorToast.tooManyRequests': 'Muitas tentativas. Tente novamente mais tarde.', - 'auth.noProvider.preLink': 'Você precisa', + 'auth.noProvider.preLink': 'Precisa de', 'auth.noProvider.link': - 'configurar pelo menos um provedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).', - 'auth.orEmailLabel': 'Ou com seu email', + 'configurar pelo menos um fornecedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).', + 'auth.orEmailLabel': 'Ou com o seu e-mail', 'auth.emailSubmitButton.label': 'Enviar', - 'auth.magicLink.title': 'Um email com o link mágico foi enviado. 🪄', - 'auth.magicLink.description': 'Certifique-se de verificar sua pasta de spam.', + 'auth.magicLink.title': 'Foi enviado um e-mail com a ligação mágica. 🪄', + 'auth.magicLink.description': 'Certifique-se de verificar a sua pasta de spam.', 'auth.socialLogin.githubButton.label': 'Continuar com GitHub', 'auth.socialLogin.googleButton.label': 'Continuar com Google', 'auth.socialLogin.facebookButton.label': 'Continuar com Facebook', 'auth.socialLogin.azureButton.label': 'Continuar com {azureProviderName}', 'auth.socialLogin.gitlabButton.label': 'Continuar com {gitlabProviderName}', 'auth.socialLogin.customButton.label': 'Continuar com {customProviderName}', - 'billing.billingPortalButton.label': 'Portal de cobrança', + 'billing.billingPortalButton.label': 'Portal de facturação', 'billing.contribution.preLink': - 'A Typebot está contribuindo com 1% da sua assinatura para remover o CO₂ da atmosfera.', + 'A Typebot está a contribuir com 1% da sua subscrição para remover o CO₂ da atmosfera.', 'billing.contribution.link': 'Saiba mais.', 'billing.updateSuccessToast.description': - 'Sua assinatura {plan} foi atualizada com sucesso 🎉', + 'A sua subscrição {plan} foi atualizada com sucesso 🎉', 'billing.customLimit.preLink': - 'Precisa de limites personalizados? Recursos específicos?', - 'billing.customLimit.link': 'Vamos conversar!', + 'Precisa de limites personalizados? Funcionalidades específicas?', + 'billing.customLimit.link': 'Vamos falar!', 'billing.upgradeLimitLabel': - 'Você precisa atualizar sua assinatura para {type}', - 'billing.currentSubscription.heading': 'Assinatura', + 'Precisa de atualizar a sua subscrição para {type}', + 'billing.currentSubscription.heading': 'Subscrição', 'billing.currentSubscription.subheading': - 'Assinatura atual do espaço de trabalho:', - 'billing.currentSubscription.cancelLink': 'Cancelar minha assinatura', - 'billing.invoices.heading': 'Faturas', + 'Subscrição actual do espaço de trabalho:', + 'billing.currentSubscription.cancelLink': 'Cancelar a minha subscrição', + 'billing.invoices.heading': 'Facturas', 'billing.invoices.empty': - 'Nenhuma fatura encontrada para este espaço de trabalho.', + 'Nenhuma factura encontrada para este espaço de trabalho.', 'billing.invoices.paidAt': 'Pago em', 'billing.invoices.subtotal': 'Subtotal', 'billing.preCheckoutModal.companyInput.label': 'Nome da empresa:', 'billing.preCheckoutModal.emailInput.label': 'E-mail:', - 'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (CPF):', + 'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (NIF):', 'billing.preCheckoutModal.taxId.placeholder': 'Tipo de ID', 'billing.preCheckoutModal.submitButton.label': 'Ir para a finalização da compra', 'billing.pricingCard.heading': 'Mudar para {plan}', 'billing.pricingCard.perMonth': '/ mês', 'billing.pricingCard.plus': ', mais:', - 'billing.pricingCard.upgradeButton.current': 'Sua assinatura atual', + 'billing.pricingCard.upgradeButton.current': 'A sua subscrição atual', 'billing.pricingCard.chatsPerMonth': 'chats/mês', 'billing.pricingCard.chatsTooltip': - 'Um chat é contado sempre que um usuário inicia uma discussão. Ele é independente do número de mensagens que ele envia e recebe.', + 'Um chat é contado sempre que um utilizador inicia uma discussão. Ele é independente do número de mensagens que envia e recebe.', 'billing.pricingCard.storageLimit': 'GB de armazenamento', 'billing.pricingCard.storageLimitTooltip': - 'Você acumula armazenamento para cada arquivo que seu usuário carrega em seu bot. Se você excluir o resultado, ele liberará espaço.', + 'Acumula armazenamento para cada ficheiro que o seu utilizador carrega no seu bot. Se excluir o resultado, ele libertará espaço.', 'billing.pricingCard.starter.description': 'Para indivíduos e pequenas empresas.', - 'billing.pricingCard.starter.includedSeats': '2 assentos incluídos', + 'billing.pricingCard.starter.includedSeats': '2 lugares incluídos', 'billing.pricingCard.starter.brandingRemoved': 'Marca removida', - 'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de arquivo', + 'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de ficheiro', 'billing.pricingCard.starter.createFolders': 'Criar pastas', 'billing.pricingCard.pro.mostPopularLabel': 'Mais popular', 'billing.pricingCard.pro.description': 'Para agências e startups em crescimento.', 'billing.pricingCard.pro.everythingFromStarter': 'Tudo em Starter', - 'billing.pricingCard.pro.includedSeats': '5 assentos incluídos', + 'billing.pricingCard.pro.includedSeats': '5 lugares incluídos', 'billing.pricingCard.pro.customDomains': 'Domínios personalizados', 'billing.pricingCard.pro.analytics': 'Análises aprofundadas', 'billing.usage.heading': 'Uso', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': - 'Seus typebots são populares! Você logo alcançará o limite de chats de seu plano. 🚀', + 'Os seus typebots são populares! Vai alcançar em breve o limite de chats do seu plano. 🚀', 'billing.usage.chats.alert.updatePlan': - 'Certifique-se de atualizar seu plano para aumentar esse limite e continuar conversando com seus usuários.', - 'billing.usage.chats.resetInfo': '(reiniciado todo dia 1)', + 'Certifique-se de atualizar o seu plano para aumentar esse limite e continuar a conversar com os seus utilizadores.', + 'billing.usage.chats.resetInfo': '(reiniciado a cada dia 1)', 'billing.usage.storage.heading': 'Armazenamento', 'billing.usage.storage.alert.soonReach': - 'Seus typebots são populares! Você logo alcançará o limite de armazenamento de seu plano. 🚀', + 'Os seus typebots são populares! Vai alcançar em breve o limite de armazenamento do seu plano. 🚀', 'billing.usage.storage.alert.updatePlan': - 'Certifique-se de atualizar seu plano para continuar coletando arquivos enviados. Você também pode excluir arquivos para liberar espaço.', + 'Certifique-se de atualizar o seu plano para continuar a recolher ficheiros enviados. Também pode excluir ficheiros para libertar espaço.', 'billing.limitMessage.brand': 'remover a marca', 'billing.limitMessage.customDomain': 'adicionar domínios personalizados', 'billing.limitMessage.analytics': 'desbloquear análises aprofundadas', - 'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo', + 'billing.limitMessage.fileInput': 'usar blocos de envio de ficheiros', 'billing.limitMessage.folder': 'criar pastas', 'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações', 'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com', 'workspace.membersList.inviteButton.label': 'Convidar', 'workspace.membersList.unlockBanner.label': - 'Atualize seu plano para trabalhar com mais membros da equipe e desbloqueie recursos incríveis 🚀', + 'Atualize o seu plano para trabalhar com mais membros da equipa e desbloquear funcionalidades incríveis 🚀', 'workspace.membersList.title': 'Membros', 'workspace.settings.icon.title': 'Ícone', 'workspace.settings.name.label': 'Nome:', - 'workspace.settings.deleteButton.label': 'Excluir espaço de trabalho', + 'workspace.settings.deleteButton.label': 'Eliminar espaço de trabalho', 'workspace.settings.deleteButton.confirmMessage': - 'Você tem certeza de que deseja excluir o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.', - 'workspace.settings.modal.menu.myAccount.label': 'Minha conta', + 'Tem a certeza de que deseja eliminar o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.', + 'workspace.settings.modal.menu.myAccount.label': 'A minha conta', 'workspace.settings.modal.menu.preferences.label': 'Preferências', 'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho', 'workspace.settings.modal.menu.settings.label': 'Configurações', 'workspace.settings.modal.menu.members.label': 'Membros', - 'workspace.settings.modal.menu.billingAndUsage.label': 'Faturamento e uso', + 'workspace.settings.modal.menu.billingAndUsage.label': 'Faturação e uso', 'workspace.settings.modal.menu.version.label': 'Versão: {version}', 'workspace.dropdown.newButton.label': 'Novo espaço de trabalho', 'workspace.dropdown.logoutButton.label': 'Sair', diff --git a/apps/builder/src/locales/pt_BR.ts b/apps/builder/src/locales/pt_BR.ts new file mode 100644 index 0000000000..0848251265 --- /dev/null +++ b/apps/builder/src/locales/pt_BR.ts @@ -0,0 +1,193 @@ +export default { + back: 'Voltar', + 'confirmModal.defaultTitle': 'Tem certeza?', + 'dashboard.header.settingsButton.label': 'Configurações & Membros', + 'dashboard.redirectionMessage': 'Você está sendo redirecionado...', + 'dashboard.title': 'Meus typebots', + delete: 'Apagar', + errorMessage: 'Ocorreu um erro', + cancel: 'Cancelar', + update: 'Atualizar', + upgrade: 'Upgrade', + downgrade: 'Downgrade', + remove: 'Remover', + pending: 'Pendente', + skip: 'Pular', + 'folders.createFolderButton.label': 'Criar uma pasta', + 'folders.createTypebotButton.label': 'Criar um typebot', + 'folders.folderButton.deleteConfirmationMessage': + 'Tem certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)', + 'folders.typebotButton.live': 'Live', + 'folders.typebotButton.showMoreOptions': 'Mostrar mais opções', + 'folders.typebotButton.unpublish': 'Despublicar', + 'folders.typebotButton.duplicate': 'Duplicar', + 'folders.typebotButton.delete': 'Apagar', + 'folders.typebotButton.deleteConfirmationMessage': + 'Tem certeza de que deseja excluir seu typebot {typebotName}?', + 'folders.typebotButton.deleteConfirmationMessageWarning': + 'Todos os dados associados serão excluídos e não poderão ser recuperados.', + 'account.apiTokens.heading': 'Tokens de API', + 'account.apiTokens.description': + 'Esses tokens permitem que outros aplicativos controlem toda a sua conta e typebots. Tenha cuidado!', + 'account.apiTokens.createButton.label': 'Criar', + 'account.apiTokens.deleteButton.label': 'Excluir', + 'account.apiTokens.table.nameHeader': 'Nome', + 'account.apiTokens.table.createdHeader': 'Criado', + 'account.apiTokens.deleteConfirmationMessage': + 'O token {tokenName} será revogado permanentemente. Tem certeza de que deseja continuar?', + 'account.apiTokens.createModal.createHeading': 'Criar Token', + 'account.apiTokens.createModal.createdHeading': 'Token Criado', + 'account.apiTokens.createModal.nameInput.label': + 'Insira um nome único para o seu token para diferenciá-lo de outros tokens.', + 'account.apiTokens.createModal.nameInput.placeholder': + 'Ex. Zapier, Github, Make.com', + 'account.apiTokens.createModal.createButton.label': 'Criar token', + 'account.apiTokens.createModal.doneButton.label': 'Concluído', + 'account.apiTokens.createModal.copyInstruction': + 'Por favor, copie seu token e guarde-o em um lugar seguro.', + 'account.apiTokens.createModal.securityWarning': + 'Por motivos de segurança, não podemos mostrá-lo novamente.', + 'account.preferences.language.heading': 'Idioma', + 'account.preferences.language.tooltip': + 'As traduções ainda não estão completas. É um trabalho em andamento. 🤓', + 'account.preferences.graphNavigation.heading': 'Navegação do Editor', + 'account.preferences.graphNavigation.mouse.label': 'Mouse', + 'account.preferences.graphNavigation.mouse.description': + 'Mova arrastando o quadro e amplie/reduza usando a roda de rolagem', + 'account.preferences.graphNavigation.trackpad.label': 'Trackpad', + 'account.preferences.graphNavigation.trackpad.description': + 'Mova o quadro usando 2 dedos e amplie/reduza fazendo pinça', + 'account.preferences.appearance.heading': 'Aparência', + 'account.preferences.appearance.systemLabel': 'Sistema', + 'account.preferences.appearance.lightLabel': 'Claro', + 'account.preferences.appearance.darkLabel': 'Escuro', + 'account.myAccount.changePhotoButton.label': 'Alterar foto', + 'account.myAccount.changePhotoButton.specification': + '.jpg ou.png, máximo 1MB', + 'account.myAccount.emailInput.disabledTooltip': + 'A atualização do e-mail não está disponível. Entre em contato com o suporte se quiser alterá-lo.', + 'account.myAccount.emailInput.label': 'Endereço de e-mail:', + 'account.myAccount.nameInput.label': 'Nome:', + 'analytics.viewsLabel': 'Visualizações', + 'analytics.startsLabel': 'Inícios', + 'analytics.completionRateLabel': 'Taxa de conclusão', + 'auth.signin.heading': 'Entrar', + 'auth.signin.noAccountLabel.preLink': 'Não tem uma conta?', + 'auth.signin.noAccountLabel.link': 'Registre-se gratuitamente', + 'auth.register.heading': 'Criar uma conta', + 'auth.register.alreadyHaveAccountLabel.preLink': 'Já tem uma conta?', + 'auth.register.alreadyHaveAccountLabel.link': 'Entrar', + 'auth.register.aggreeToTerms': + 'Ao se cadastrar, você concorda com nossos {termsOfService} e {privacyPolicy}.', + 'auth.register.termsOfService': 'termos de serviço', + 'auth.register.privacyPolicy': 'política de privacidade', + 'auth.error.default': 'Tente entrar com uma conta diferente.', + 'auth.error.email': + 'E-mail não encontrado. Tente entrar com um provedor diferente.', + 'auth.error.oauthNotLinked': + 'Para confirmar sua identidade, entre com a mesma conta que você usou originalmente.', + 'auth.error.unknown': 'Ocorreu um erro. Tente novamente.', + 'auth.signinErrorToast.title': 'Não autorizado', + 'auth.signinErrorToast.description': 'As inscrições estão desativadas.', + 'auth.signinErrorToast.tooManyRequests': + 'Muitas tentativas. Tente novamente mais tarde.', + 'auth.noProvider.preLink': 'Você precisa', + 'auth.noProvider.link': + 'configurar pelo menos um provedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).', + 'auth.orEmailLabel': 'Ou com seu email', + 'auth.emailSubmitButton.label': 'Enviar', + 'auth.magicLink.title': 'Um email com o link mágico foi enviado. 🪄', + 'auth.magicLink.description': 'Certifique-se de verificar sua pasta de spam.', + 'auth.socialLogin.githubButton.label': 'Continuar com GitHub', + 'auth.socialLogin.googleButton.label': 'Continuar com Google', + 'auth.socialLogin.facebookButton.label': 'Continuar com Facebook', + 'auth.socialLogin.azureButton.label': 'Continuar com {azureProviderName}', + 'auth.socialLogin.gitlabButton.label': 'Continuar com {gitlabProviderName}', + 'auth.socialLogin.customButton.label': 'Continuar com {customProviderName}', + 'billing.billingPortalButton.label': 'Portal de cobrança', + 'billing.contribution.preLink': + 'A Typebot está contribuindo com 1% da sua assinatura para remover o CO₂ da atmosfera.', + 'billing.contribution.link': 'Saiba mais.', + 'billing.updateSuccessToast.description': + 'Sua assinatura {plan} foi atualizada com sucesso 🎉', + 'billing.customLimit.preLink': + 'Precisa de limites personalizados? Recursos específicos?', + 'billing.customLimit.link': 'Vamos conversar!', + 'billing.upgradeLimitLabel': + 'Você precisa atualizar sua assinatura para {type}', + 'billing.currentSubscription.heading': 'Assinatura', + 'billing.currentSubscription.subheading': + 'Assinatura atual do espaço de trabalho:', + 'billing.currentSubscription.cancelLink': 'Cancelar minha assinatura', + 'billing.invoices.heading': 'Faturas', + 'billing.invoices.empty': + 'Nenhuma fatura encontrada para este espaço de trabalho.', + 'billing.invoices.paidAt': 'Pago em', + 'billing.invoices.subtotal': 'Subtotal', + 'billing.preCheckoutModal.companyInput.label': 'Nome da empresa:', + 'billing.preCheckoutModal.emailInput.label': 'E-mail:', + 'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (CPF):', + 'billing.preCheckoutModal.taxId.placeholder': 'Tipo de ID', + 'billing.preCheckoutModal.submitButton.label': + 'Ir para a finalização da compra', + 'billing.pricingCard.heading': 'Mudar para {plan}', + 'billing.pricingCard.perMonth': '/ mês', + 'billing.pricingCard.plus': ', mais:', + 'billing.pricingCard.upgradeButton.current': 'Sua assinatura atual', + 'billing.pricingCard.chatsPerMonth': 'chats/mês', + 'billing.pricingCard.chatsTooltip': + 'Um chat é contado sempre que um usuário inicia uma discussão. Ele é independente do número de mensagens que ele envia e recebe.', + 'billing.pricingCard.storageLimit': 'GB de armazenamento', + 'billing.pricingCard.storageLimitTooltip': + 'Você acumula armazenamento para cada arquivo que seu usuário carrega em seu bot. Se você excluir o resultado, ele liberará espaço.', + 'billing.pricingCard.starter.description': + 'Para indivíduos e pequenas empresas.', + 'billing.pricingCard.starter.includedSeats': '2 assentos incluídos', + 'billing.pricingCard.starter.brandingRemoved': 'Marca removida', + 'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de arquivo', + 'billing.pricingCard.starter.createFolders': 'Criar pastas', + 'billing.pricingCard.pro.mostPopularLabel': 'Mais popular', + 'billing.pricingCard.pro.description': + 'Para agências e startups em crescimento.', + 'billing.pricingCard.pro.everythingFromStarter': 'Tudo em Starter', + 'billing.pricingCard.pro.includedSeats': '5 assentos incluídos', + 'billing.pricingCard.pro.customDomains': 'Domínios personalizados', + 'billing.pricingCard.pro.analytics': 'Análises aprofundadas', + 'billing.usage.heading': 'Uso', + 'billing.usage.chats.heading': 'Chats', + 'billing.usage.chats.alert.soonReach': + 'Seus typebots são populares! Você logo alcançará o limite de chats de seu plano. 🚀', + 'billing.usage.chats.alert.updatePlan': + 'Certifique-se de atualizar seu plano para aumentar esse limite e continuar conversando com seus usuários.', + 'billing.usage.chats.resetInfo': '(reiniciado todo dia 1)', + 'billing.usage.storage.heading': 'Armazenamento', + 'billing.usage.storage.alert.soonReach': + 'Seus typebots são populares! Você logo alcançará o limite de armazenamento de seu plano. 🚀', + 'billing.usage.storage.alert.updatePlan': + 'Certifique-se de atualizar seu plano para continuar coletando arquivos enviados. Você também pode excluir arquivos para liberar espaço.', + 'billing.limitMessage.brand': 'remover a marca', + 'billing.limitMessage.customDomain': 'adicionar domínios personalizados', + 'billing.limitMessage.analytics': 'desbloquear análises aprofundadas', + 'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo', + 'billing.limitMessage.folder': 'criar pastas', + 'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações', + 'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com', + 'workspace.membersList.inviteButton.label': 'Convidar', + 'workspace.membersList.unlockBanner.label': + 'Atualize seu plano para trabalhar com mais membros da equipe e desbloqueie recursos incríveis 🚀', + 'workspace.membersList.title': 'Membros', + 'workspace.settings.icon.title': 'Ícone', + 'workspace.settings.name.label': 'Nome:', + 'workspace.settings.deleteButton.label': 'Excluir espaço de trabalho', + 'workspace.settings.deleteButton.confirmMessage': + 'Você tem certeza de que deseja excluir o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.', + 'workspace.settings.modal.menu.myAccount.label': 'Minha conta', + 'workspace.settings.modal.menu.preferences.label': 'Preferências', + 'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho', + 'workspace.settings.modal.menu.settings.label': 'Configurações', + 'workspace.settings.modal.menu.members.label': 'Membros', + 'workspace.settings.modal.menu.billingAndUsage.label': 'Faturamento e uso', + 'workspace.settings.modal.menu.version.label': 'Versão: {version}', + 'workspace.dropdown.newButton.label': 'Novo espaço de trabalho', + 'workspace.dropdown.logoutButton.label': 'Sair', +} as const From c173e67e5c26f83022d845402b941adb16b9ee22 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Tue, 15 Aug 2023 15:14:32 +0100 Subject: [PATCH 02/10] Fix identation. --- .../features/account/components/UserPreferencesForm.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/builder/src/features/account/components/UserPreferencesForm.tsx b/apps/builder/src/features/account/components/UserPreferencesForm.tsx index 4a76490e71..b38fc7c1fe 100644 --- a/apps/builder/src/features/account/components/UserPreferencesForm.tsx +++ b/apps/builder/src/features/account/components/UserPreferencesForm.tsx @@ -19,10 +19,10 @@ import { ChevronDownIcon } from '@/components/icons' import { MoreInfoTooltip } from '@/components/MoreInfoTooltip' const localeHumanReadable = { - en: 'English', - fr: 'Français', - de: 'Deutsch', - pt: 'Português', + en: 'English', + fr: 'Français', + de: 'Deutsch', + pt: 'Português', pt_BR: 'Português (BR)' } as const From 0d0158fb91c2aad0fa0b5b98e65af7a4bab49df7 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Wed, 16 Aug 2023 16:39:25 +0100 Subject: [PATCH 03/10] Fix terms. --- apps/builder/src/locales/pt.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/builder/src/locales/pt.ts b/apps/builder/src/locales/pt.ts index 6261ad7e32..4fa1821045 100644 --- a/apps/builder/src/locales/pt.ts +++ b/apps/builder/src/locales/pt.ts @@ -8,8 +8,8 @@ export default { errorMessage: 'Ocorreu um erro', cancel: 'Cancelar', update: 'Atualizar', - upgrade: 'Atualizar', - downgrade: 'Desatualizar', + upgrade: 'Upgrade', + downgrade: 'Downgrade', remove: 'Remover', pending: 'Pendente', skip: 'Saltar', From 7674f3d737ce673ea1a3ee5288ac49a3ec93923f Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Tue, 15 Aug 2023 21:30:10 +0100 Subject: [PATCH 04/10] Add en language fallback, improve editor translations pt, pt_BR. --- .../components/CurrentSubscriptionSummary.tsx | 2 +- .../billing/components/UsageProgressBars.tsx | 4 ++-- .../editor/components/BlocksSideBar.tsx | 10 ++++---- .../editor/components/TypebotHeader.tsx | 18 +++++++------- .../components/CreateNewTypebotButtons.tsx | 10 ++++---- .../ImportTypebotFromFileButton.tsx | 4 +++- .../templates/components/TemplatesModal.tsx | 16 +++++++------ apps/builder/src/locales/de.ts | 2 ++ apps/builder/src/locales/en.ts | 24 +++++++++++++++++++ apps/builder/src/locales/fr.ts | 2 ++ apps/builder/src/locales/pt.ts | 2 ++ apps/builder/src/locales/pt_BR.ts | 20 ++++++++++++++++ apps/builder/src/pages/_app.tsx | 3 ++- 13 files changed, 89 insertions(+), 28 deletions(-) diff --git a/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx b/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx index d31bd474b0..277574ceaa 100644 --- a/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx +++ b/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx @@ -30,7 +30,7 @@ export const CurrentSubscriptionSummary = ({ workspace }: Props) => { {data?.subscription?.cancelDate && ( - (Will be cancelled on {data.subscription.cancelDate.toDateString()}) + ({scopedT('cancelDate')} {data.subscription.cancelDate.toDateString()}) )} diff --git a/apps/builder/src/features/billing/components/UsageProgressBars.tsx b/apps/builder/src/features/billing/components/UsageProgressBars.tsx index 06ba08367b..30b5c9fdc6 100644 --- a/apps/builder/src/features/billing/components/UsageProgressBars.tsx +++ b/apps/builder/src/features/billing/components/UsageProgressBars.tsx @@ -88,7 +88,7 @@ export const UsageProgressBars = ({ workspace }: Props) => { /{' '} {workspaceChatsLimit === -1 - ? 'Unlimited' + ? scopedT('unlimited') : parseNumberWithCommas(workspaceChatsLimit)} @@ -141,7 +141,7 @@ export const UsageProgressBars = ({ workspace }: Props) => { /{' '} {workspaceStorageLimit === -1 - ? 'Unlimited' + ? scopedT('unlimited') : `${workspaceStorageLimit} GB`} diff --git a/apps/builder/src/features/editor/components/BlocksSideBar.tsx b/apps/builder/src/features/editor/components/BlocksSideBar.tsx index ad87d155c8..45c1952df8 100644 --- a/apps/builder/src/features/editor/components/BlocksSideBar.tsx +++ b/apps/builder/src/features/editor/components/BlocksSideBar.tsx @@ -23,8 +23,10 @@ import { BlockCard } from './BlockCard' import { LockedIcon, UnlockedIcon } from '@/components/icons' import { BlockCardOverlay } from './BlockCardOverlay' import { headerHeight } from '../constants' +import { useScopedI18n } from '@/locales' export const BlocksSideBar = () => { + const scopedT = useScopedI18n('editor.sidebarBlocks') const { setDraggedBlockType, draggedBlockType } = useBlockDnd() const [position, setPosition] = useState({ x: 0, @@ -114,7 +116,7 @@ export const BlocksSideBar = () => { - Bubbles + {scopedT('blockType.bubbles.heading')} {Object.values(BubbleBlockType).map((type) => ( @@ -125,7 +127,7 @@ export const BlocksSideBar = () => { - Inputs + {scopedT('blockType.inputs.heading')} {Object.values(InputBlockType).map((type) => ( @@ -136,7 +138,7 @@ export const BlocksSideBar = () => { - Logic + {scopedT('blockType.logic.heading')} {Object.values(LogicBlockType).map((type) => ( @@ -147,7 +149,7 @@ export const BlocksSideBar = () => { - Integrations + {scopedT('blockType.integrations.heading')} {Object.values(IntegrationBlockType).map((type) => ( diff --git a/apps/builder/src/features/editor/components/TypebotHeader.tsx b/apps/builder/src/features/editor/components/TypebotHeader.tsx index 26b83f6c7f..cc92ea2078 100644 --- a/apps/builder/src/features/editor/components/TypebotHeader.tsx +++ b/apps/builder/src/features/editor/components/TypebotHeader.tsx @@ -30,8 +30,10 @@ import { RightPanel, useEditor } from '../providers/EditorProvider' import { useTypebot } from '../providers/TypebotProvider' import { SupportBubble } from '@/components/SupportBubble' import { isCloudProdInstance } from '@/helpers/isCloudProdInstance' +import { useScopedI18n } from '@/locales' export const TypebotHeader = () => { + const scopedT = useScopedI18n('editor.headers') const router = useRouter() const { typebot, @@ -103,7 +105,7 @@ export const TypebotHeader = () => { variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'} size="sm" > - Flow + {scopedT('flowButton.label')} {isDefined(publishedTypebot) && ( )} @@ -219,14 +221,14 @@ export const TypebotHeader = () => { {isSavingLoading && ( - Saving... + {scopedT('SavingSpinner.label')} )} @@ -241,7 +243,7 @@ export const TypebotHeader = () => { isLoading={isNotDefined(typebot)} size="sm" > - Preview + {scopedT('previewButton.label')} )} diff --git a/apps/builder/src/features/templates/components/CreateNewTypebotButtons.tsx b/apps/builder/src/features/templates/components/CreateNewTypebotButtons.tsx index fa32d730ec..707995c52c 100644 --- a/apps/builder/src/features/templates/components/CreateNewTypebotButtons.tsx +++ b/apps/builder/src/features/templates/components/CreateNewTypebotButtons.tsx @@ -16,8 +16,10 @@ import { useWorkspace } from '@/features/workspace/WorkspaceProvider' import { useUser } from '@/features/account/hooks/useUser' import { useToast } from '@/hooks/useToast' import { trpc } from '@/lib/trpc' +import { useScopedI18n } from '@/locales' export const CreateNewTypebotButtons = () => { + const scopedT = useScopedI18n('templates.buttons') const { workspace } = useWorkspace() const { user } = useUser() const router = useRouter() @@ -70,7 +72,7 @@ export const CreateNewTypebotButtons = () => { return ( - Create a new typebot + {scopedT('heading')} { isLoading={isLoading} onNewTypebot={handleCreateSubmit} > - Import a file + {scopedT('importFileButton.label')} void @@ -13,6 +14,7 @@ export const ImportTypebotFromFileButton = ({ onNewTypebot, ...props }: Props) => { + const scopedT = useScopedI18n('templates.importFromFileButon') const { showToast } = useToast() const handleInputChange = async (e: ChangeEvent) => { @@ -27,7 +29,7 @@ export const ImportTypebotFromFileButton = ({ } catch (err) { console.error(err) showToast({ - description: "Failed to parse the file. Are you sure it's a typebot?", + description: scopedT('toastError.description'), details: { content: JSON.stringify(err, null, 2), lang: 'json', diff --git a/apps/builder/src/features/templates/components/TemplatesModal.tsx b/apps/builder/src/features/templates/components/TemplatesModal.tsx index 80283e1090..5f6e93f16b 100644 --- a/apps/builder/src/features/templates/components/TemplatesModal.tsx +++ b/apps/builder/src/features/templates/components/TemplatesModal.tsx @@ -19,6 +19,7 @@ import { templates } from '../data' import { TemplateProps } from '../types' import { useToast } from '@/hooks/useToast' import { sendRequest } from '@typebot.io/lib' +import { useScopedI18n } from '@/locales' type Props = { isOpen: boolean @@ -27,6 +28,7 @@ type Props = { } export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { + const scopedT = useScopedI18n('templates.modal') const templateCardBackgroundColor = useColorModeValue('white', 'gray.800') const [typebot, setTypebot] = useState() const [selectedTemplate, setSelectedTemplate] = useState( @@ -88,7 +90,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { pl="1" color="gray.500" > - Marketing + {scopedT('menuHeading.marketing')} {templates .filter((template) => template.category === 'marketing') @@ -110,7 +112,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { {template.name} {template.isNew && ( - New + {scopedT('menuHeading.new.tag')} )} @@ -124,7 +126,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { pl="1" color="gray.500" > - Product + {scopedT('menuHeading.product')} {templates .filter((template) => template.category === 'product') @@ -146,7 +148,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { {template.name} {template.isNew && ( - New + {scopedT('menuHeading.new.tag')} )} @@ -160,7 +162,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { pl="1" color="gray.500" > - Other + {scopedT('menuHeading.other')} {templates .filter((template) => template.category === undefined) @@ -182,7 +184,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { {template.name} {template.isNew && ( - New + {scopedT('menuHeading.new.tag')} )} @@ -229,7 +231,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => { onClick={onUseThisTemplateClick} isLoading={isLoading} > - Use this template + {scopedT('useTemplateButton.label')} diff --git a/apps/builder/src/locales/de.ts b/apps/builder/src/locales/de.ts index 32c4fb3474..0f752759ee 100644 --- a/apps/builder/src/locales/de.ts +++ b/apps/builder/src/locales/de.ts @@ -120,6 +120,7 @@ export default { 'billing.currentSubscription.heading': 'Abonnement', 'billing.currentSubscription.subheading': 'Aktuelles Workspace-Abonnement:', 'billing.currentSubscription.cancelLink': 'Mein Abonnement kündigen', + 'billing.currentSubscription.cancelDate': 'Wird storniert am', 'billing.invoices.heading': 'Rechnungen', 'billing.invoices.empty': 'Keine Rechnungen für diesen Workspace gefunden.', 'billing.invoices.paidAt': 'Bezahlt am', @@ -152,6 +153,7 @@ export default { 'billing.pricingCard.pro.customDomains': 'Eigene Domains', 'billing.pricingCard.pro.analytics': 'Detaillierte Analysen', 'billing.usage.heading': 'Nutzung', + 'billing.usage.unlimited': 'Unbegrenzt', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': 'Deine Typebots sind beliebt! Du wirst bald das Chat-Limit deines Tarifs erreichen. 🚀', diff --git a/apps/builder/src/locales/en.ts b/apps/builder/src/locales/en.ts index 79e9e72cfc..5cd782fb4f 100644 --- a/apps/builder/src/locales/en.ts +++ b/apps/builder/src/locales/en.ts @@ -115,6 +115,7 @@ export default { 'billing.currentSubscription.heading': 'Subscription', 'billing.currentSubscription.subheading': 'Current workspace subscription:', 'billing.currentSubscription.cancelLink': 'Cancel my subscription', + 'billing.currentSubscription.cancelDate': 'Will be cancelled on', 'billing.invoices.heading': 'Invoices', 'billing.invoices.empty': 'No invoices found for this workspace.', 'billing.invoices.paidAt': 'Paid at', @@ -147,6 +148,7 @@ export default { 'billing.pricingCard.pro.customDomains': 'Custom domains', 'billing.pricingCard.pro.analytics': 'In-depth analytics', 'billing.usage.heading': 'Usage', + 'billing.usage.unlimited': 'Unlimited', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': "Your typebots are popular! You will soon reach your plan's chats limit. 🚀", @@ -183,4 +185,26 @@ export default { 'workspace.settings.modal.menu.version.label': 'Version: {version}', 'workspace.dropdown.newButton.label': 'New workspace', 'workspace.dropdown.logoutButton.label': 'Log out', + 'templates.buttons.heading': 'Create a new typebot', + 'templates.buttons.fromScratchButton.label': 'Start from scratch', + 'templates.buttons.fromTemplateButton.label': 'Start from a template', + 'templates.buttons.importFileButton.label': 'Import a file', + 'templates.modal.menuHeading.marketing': 'Marketing', + 'templates.modal.menuHeading.product': 'Product', + 'templates.modal.menuHeading.other': 'Other', + 'templates.modal.menuHeading.new.tag': 'New', + 'templates.modal.useTemplateButton.label': 'Use this template', + 'templates.importFromFileButon.toastError.description': 'Failed to parse the file. Are you sure it\'s a typebot?', + 'editor.headers.flowButton.label': 'Flow', + 'editor.headers.themeButton.label': 'Theme', + 'editor.headers.settingsButton.label': 'Settings', + 'editor.headers.shareButton.label': 'Share', + 'editor.headers.resultsButton.label': 'Results', + 'editor.headers.helpButton.label': 'Help', + 'editor.headers.savingSpinner.label': 'Saving...', + 'editor.headers.previewButton.label': 'Preview', + 'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles', + 'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs', + 'editor.sidebarBlocks.blockType.logic.heading': 'Logic', + 'editor.sidebarBlocks.blockType.integrations.heading': 'Integrations', } as const diff --git a/apps/builder/src/locales/fr.ts b/apps/builder/src/locales/fr.ts index f7fb9620ad..130db039b5 100644 --- a/apps/builder/src/locales/fr.ts +++ b/apps/builder/src/locales/fr.ts @@ -117,6 +117,7 @@ export default { 'billing.currentSubscription.heading': 'Abonnement', 'billing.currentSubscription.subheading': 'Abonnement actuel du workspace :', 'billing.currentSubscription.cancelLink': "Annuler l'abonnement", + 'billing.currentSubscription.cancelDate': 'Sera annulé le', 'billing.invoices.heading': 'Factures', 'billing.invoices.empty': 'Aucune facture trouvée pour ce workspace.', 'billing.invoices.paidAt': 'Payé le', @@ -151,6 +152,7 @@ export default { 'billing.pricingCard.pro.customDomains': 'Domaines personnalisés', 'billing.pricingCard.pro.analytics': 'Analyses approfondies', 'billing.usage.heading': 'Utilisation', + 'billing.usage.unlimited': 'Illimité', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': 'Tes typebots sont populaires ! Tu atteindras bientôt la limite de chats de votre abonnement. 🚀', diff --git a/apps/builder/src/locales/pt.ts b/apps/builder/src/locales/pt.ts index 4fa1821045..0ffc4ea30a 100644 --- a/apps/builder/src/locales/pt.ts +++ b/apps/builder/src/locales/pt.ts @@ -119,6 +119,7 @@ export default { 'billing.currentSubscription.subheading': 'Subscrição actual do espaço de trabalho:', 'billing.currentSubscription.cancelLink': 'Cancelar a minha subscrição', + 'billing.currentSubscription.cancelDate': 'Será cancelado em', 'billing.invoices.heading': 'Facturas', 'billing.invoices.empty': 'Nenhuma factura encontrada para este espaço de trabalho.', @@ -154,6 +155,7 @@ export default { 'billing.pricingCard.pro.customDomains': 'Domínios personalizados', 'billing.pricingCard.pro.analytics': 'Análises aprofundadas', 'billing.usage.heading': 'Uso', + 'billing.usage.unlimited': 'Ilimitado', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': 'Os seus typebots são populares! Vai alcançar em breve o limite de chats do seu plano. 🚀', diff --git a/apps/builder/src/locales/pt_BR.ts b/apps/builder/src/locales/pt_BR.ts index 0848251265..ce773bc065 100644 --- a/apps/builder/src/locales/pt_BR.ts +++ b/apps/builder/src/locales/pt_BR.ts @@ -119,6 +119,7 @@ export default { 'billing.currentSubscription.subheading': 'Assinatura atual do espaço de trabalho:', 'billing.currentSubscription.cancelLink': 'Cancelar minha assinatura', + 'billing.currentSubscription.cancelDate': 'Será cancelado em', 'billing.invoices.heading': 'Faturas', 'billing.invoices.empty': 'Nenhuma fatura encontrada para este espaço de trabalho.', @@ -154,6 +155,7 @@ export default { 'billing.pricingCard.pro.customDomains': 'Domínios personalizados', 'billing.pricingCard.pro.analytics': 'Análises aprofundadas', 'billing.usage.heading': 'Uso', + 'billing.usage.unlimited': 'Ilimitado', 'billing.usage.chats.heading': 'Chats', 'billing.usage.chats.alert.soonReach': 'Seus typebots são populares! Você logo alcançará o limite de chats de seu plano. 🚀', @@ -190,4 +192,22 @@ export default { 'workspace.settings.modal.menu.version.label': 'Versão: {version}', 'workspace.dropdown.newButton.label': 'Novo espaço de trabalho', 'workspace.dropdown.logoutButton.label': 'Sair', + 'templates.buttons.heading': 'Create a new typebot', + 'templates.buttons.fromScratchButton.label': 'Start from scratch', + 'templates.buttons.fromTemplateButton.label': 'Start from a template', + 'templates.buttons.importFileButton.label': 'Import a file', + 'templates.modal.menuHeading.marketing': 'Marketing', + 'templates.modal.menuHeading.product': 'Product', + 'templates.modal.menuHeading.other': 'Other', + 'templates.modal.menuHeading.new.tag': 'Novo', + 'templates.modal.useTemplateButton.label': 'Use this template', + 'templates.importFromFileButon.toastError.description': 'Falha ao carregar arquivo. Tem certeza que é um template no formato typebot?', + 'editor.headers.flowButton.label': 'Fluxo', + 'editor.headers.themeButton.label': 'Tema', + 'editor.headers.settingsButton.label': 'Configurações', + 'editor.headers.shareButton.label': 'Compartilhar', + 'editor.headers.resultsButton.label': 'Resultados', + 'editor.headers.helpButton.label': 'Ajuda', + 'editor.headers.savingSpinner.label': 'Salvando...', + 'editor.headers.previewButton.label': 'Visualizar', } as const diff --git a/apps/builder/src/pages/_app.tsx b/apps/builder/src/pages/_app.tsx index 134c338d66..c3a730f9c9 100644 --- a/apps/builder/src/pages/_app.tsx +++ b/apps/builder/src/pages/_app.tsx @@ -16,6 +16,7 @@ import { Plan } from '@typebot.io/prisma' import { trpc } from '@/lib/trpc' import { NewVersionPopup } from '@/components/NewVersionPopup' import { I18nProvider } from '@/locales' +import en from '@/locales/en' import { TypebotProvider } from '@/features/editor/providers/TypebotProvider' import { WorkspaceProvider } from '@/features/workspace/WorkspaceProvider' import { isCloudProdInstance } from '@/helpers/isCloudProdInstance' @@ -55,7 +56,7 @@ const App = ({ Component, pageProps }: AppProps) => { return ( <> - + From 5972dbdb92c6e6112e03b130da0ae98f4d013ed3 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Fri, 18 Aug 2023 13:16:57 +0100 Subject: [PATCH 05/10] wip --- .../features/editor/components/BlockLabel.tsx | 71 ++++++++++--------- apps/builder/src/locales/en.ts | 33 +++++++++ apps/builder/src/locales/pt.ts | 55 ++++++++++++++ apps/builder/src/locales/pt_BR.ts | 37 ++++++++++ 4 files changed, 162 insertions(+), 34 deletions(-) diff --git a/apps/builder/src/features/editor/components/BlockLabel.tsx b/apps/builder/src/features/editor/components/BlockLabel.tsx index dfe59a3986..52f7c26a3a 100644 --- a/apps/builder/src/features/editor/components/BlockLabel.tsx +++ b/apps/builder/src/features/editor/components/BlockLabel.tsx @@ -7,79 +7,82 @@ import { BlockType, } from '@typebot.io/schemas' import React from 'react' +import { useScopedI18n } from '@/locales' type Props = { type: BlockType } export const BlockLabel = ({ type }: Props): JSX.Element => { + const scopedT = useScopedI18n('editor.sidebarBlock') + switch (type) { case 'start': - return Start + return {scopedT('start.label')} case BubbleBlockType.TEXT: case InputBlockType.TEXT: - return Text + return {scopedT('text.label')} case BubbleBlockType.IMAGE: - return Image + return {scopedT('image.label')} case BubbleBlockType.VIDEO: - return Video + return {scopedT('video.label')} case BubbleBlockType.EMBED: - return Embed + return {scopedT('embed.label')} case BubbleBlockType.AUDIO: - return Audio + return {scopedT('audio.label')} case InputBlockType.NUMBER: - return Number + return {scopedT('number.label')} case InputBlockType.EMAIL: - return Email + return {scopedT('email.label')} case InputBlockType.URL: - return Website + return {scopedT('website.label')} case InputBlockType.DATE: - return Date + return {scopedT('date.label')} case InputBlockType.PHONE: - return Phone + return {scopedT('phone.label')} case InputBlockType.CHOICE: - return Button + return {scopedT('button.label')} case InputBlockType.PICTURE_CHOICE: - return Pic choice + return {scopedT('picChoice.label')} case InputBlockType.PAYMENT: - return Payment + return {scopedT('payment.label')} case InputBlockType.RATING: - return Rating + return {scopedT('rating.label')} case InputBlockType.FILE: - return File + return {scopedT('file.label')} case LogicBlockType.SET_VARIABLE: - return Set variable + return {scopedT('setVariable.label')} case LogicBlockType.CONDITION: - return Condition + return {scopedT('condition.label')} case LogicBlockType.REDIRECT: - return Redirect + return {scopedT('redirect.label')} case LogicBlockType.SCRIPT: - return Script + return {scopedT('script.label')} case LogicBlockType.TYPEBOT_LINK: - return Typebot + return {scopedT('typebot.label')} case LogicBlockType.WAIT: - return Wait + return {scopedT('wait.label')} case LogicBlockType.JUMP: - return Jump + return {scopedT('jump.label')} case LogicBlockType.AB_TEST: - return AB Test + return {scopedT('abTest.label')} case IntegrationBlockType.GOOGLE_SHEETS: - return Sheets + return {scopedT('sheets.label')} case IntegrationBlockType.GOOGLE_ANALYTICS: - return Analytics + return {scopedT('analytics.label')} case IntegrationBlockType.WEBHOOK: - return Webhook + return {scopedT('webhook.label')} case IntegrationBlockType.ZAPIER: - return Zapier + return {scopedT('zapier.label')} case IntegrationBlockType.MAKE_COM: - return Make.com + return {scopedT('makecom.label')} case IntegrationBlockType.PABBLY_CONNECT: - return Pabbly + return {scopedT('pabbly.label')} case IntegrationBlockType.EMAIL: - return Email + return {scopedT('email.label')} case IntegrationBlockType.CHATWOOT: - return Chatwoot + return {scopedT('chatwoot.label')} case IntegrationBlockType.OPEN_AI: - return OpenAI + return {scopedT('openai.label')} case IntegrationBlockType.PIXEL: - return Pixel + return {scopedT('pixel.label')} } } diff --git a/apps/builder/src/locales/en.ts b/apps/builder/src/locales/en.ts index 5cd782fb4f..2bc476bb45 100644 --- a/apps/builder/src/locales/en.ts +++ b/apps/builder/src/locales/en.ts @@ -207,4 +207,37 @@ export default { 'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs', 'editor.sidebarBlocks.blockType.logic.heading': 'Logic', 'editor.sidebarBlocks.blockType.integrations.heading': 'Integrations', + 'editor.sidebarBlock.start.label': 'Start', + 'editor.sidebarBlock.text.label': 'Text', + 'editor.sidebarBlock.image.label': 'Image', + 'editor.sidebarBlock.video.label': 'Video', + 'editor.sidebarBlock.embed.label': 'Embed', + 'editor.sidebarBlock.audio.label': 'Audio', + 'editor.sidebarBlock.number.label': 'Number', + 'editor.sidebarBlock.email.label': 'Email', + 'editor.sidebarBlock.website.label': 'Website', + 'editor.sidebarBlock.date.label': 'Date', + 'editor.sidebarBlock.phone.label': 'Phone', + 'editor.sidebarBlock.button.label': 'Button', + 'editor.sidebarBlock.picChoice.label': 'Pic choice', + 'editor.sidebarBlock.payment.label': 'Payment', + 'editor.sidebarBlock.rating.label': 'Rating', + 'editor.sidebarBlock.file.label': 'File', + 'editor.sidebarBlock.setVariable.label': 'Set variable', + 'editor.sidebarBlock.condition.label': 'Condition', + 'editor.sidebarBlock.redirect.label': 'Redirect', + 'editor.sidebarBlock.script.label': 'Script', + 'editor.sidebarBlock.typebot.label': 'Typebot', + 'editor.sidebarBlock.wait.label': 'Wait', + 'editor.sidebarBlock.jump.label': 'Jump', + 'editor.sidebarBlock.abTest.label': 'AB Test', + 'editor.sidebarBlock.sheets.label': 'Sheets', + 'editor.sidebarBlock.analytics.label': 'Analytics', + 'editor.sidebarBlock.webhook.label': 'Webhook', + 'editor.sidebarBlock.zapier.label': 'Zapier', + 'editor.sidebarBlock.makecom.label': 'Make.com', + 'editor.sidebarBlock.pabbly.label': 'Pabbly', + 'editor.sidebarBlock.chatwoot.label': 'Chatwoot', + 'editor.sidebarBlock.openai.label': 'OpenAI', + 'editor.sidebarBlock.pixel.label': 'Pixel', } as const diff --git a/apps/builder/src/locales/pt.ts b/apps/builder/src/locales/pt.ts index 0ffc4ea30a..9db15e4601 100644 --- a/apps/builder/src/locales/pt.ts +++ b/apps/builder/src/locales/pt.ts @@ -192,4 +192,59 @@ export default { 'workspace.settings.modal.menu.version.label': 'Versão: {version}', 'workspace.dropdown.newButton.label': 'Novo espaço de trabalho', 'workspace.dropdown.logoutButton.label': 'Sair', + 'templates.buttons.heading': 'Create a new typebot', + 'templates.buttons.fromScratchButton.label': 'Start from scratch', + 'templates.buttons.fromTemplateButton.label': 'Start from a template', + 'templates.buttons.importFileButton.label': 'Import a file', + 'templates.modal.menuHeading.marketing': 'Marketing', + 'templates.modal.menuHeading.product': 'Product', + 'templates.modal.menuHeading.other': 'Other', + 'templates.modal.menuHeading.new.tag': 'Novo', + 'templates.modal.useTemplateButton.label': 'Use this template', + 'templates.importFromFileButon.toastError.description': 'Falha ao carregar arquivo. Tem certeza que é um template no formato typebot?', + 'editor.headers.flowButton.label': 'Fluxo', + 'editor.headers.themeButton.label': 'Tema', + 'editor.headers.settingsButton.label': 'Configurações', + 'editor.headers.shareButton.label': 'Compartilhar', + 'editor.headers.resultsButton.label': 'Resultados', + 'editor.headers.helpButton.label': 'Ajuda', + 'editor.headers.savingSpinner.label': 'Salvando...', + 'editor.headers.previewButton.label': 'Visualizar', + 'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles', + 'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs', + 'editor.sidebarBlocks.blockType.logic.heading': 'Condicionais', + 'editor.sidebarBlocks.blockType.integrations.heading': 'Integrações', + 'editor.sidebarBlock.start.label': 'Início', + 'editor.sidebarBlock.text.label': 'Texto', + 'editor.sidebarBlock.image.label': 'Imagem', + 'editor.sidebarBlock.video.label': 'Vídeo', + 'editor.sidebarBlock.embed.label': 'Embed', + 'editor.sidebarBlock.audio.label': 'Áudio', + 'editor.sidebarBlock.number.label': 'Número', + 'editor.sidebarBlock.email.label': 'Email', + 'editor.sidebarBlock.website.label': 'Website', + 'editor.sidebarBlock.date.label': 'Data', + 'editor.sidebarBlock.phone.label': 'Telefone', + 'editor.sidebarBlock.button.label': 'Botão', + 'editor.sidebarBlock.picChoice.label': 'Seleção de Imagem', + 'editor.sidebarBlock.payment.label': 'Pagamento', + 'editor.sidebarBlock.rating.label': 'Classificação', + 'editor.sidebarBlock.file.label': 'Ficheiro', + 'editor.sidebarBlock.setVariable.label': 'Variável', + 'editor.sidebarBlock.condition.label': 'Condição', + 'editor.sidebarBlock.redirect.label': 'Redirecionar', + 'editor.sidebarBlock.script.label': 'Script', + 'editor.sidebarBlock.typebot.label': 'Typebot', + 'editor.sidebarBlock.wait.label': 'Espera', + 'editor.sidebarBlock.jump.label': 'Saltar', + 'editor.sidebarBlock.abTest.label': 'Teste AB', + 'editor.sidebarBlock.sheets.label': 'Sheets', + 'editor.sidebarBlock.analytics.label': 'Analytics', + 'editor.sidebarBlock.webhook.label': 'Webhook', + 'editor.sidebarBlock.zapier.label': 'Zapier', + 'editor.sidebarBlock.makecom.label': 'Make.com', + 'editor.sidebarBlock.pabbly.label': 'Pabbly', + 'editor.sidebarBlock.chatwoot.label': 'Chatwoot', + 'editor.sidebarBlock.openai.label': 'OpenAI', + 'editor.sidebarBlock.pixel.label': 'Pixel', } as const diff --git a/apps/builder/src/locales/pt_BR.ts b/apps/builder/src/locales/pt_BR.ts index ce773bc065..00028a999a 100644 --- a/apps/builder/src/locales/pt_BR.ts +++ b/apps/builder/src/locales/pt_BR.ts @@ -210,4 +210,41 @@ export default { 'editor.headers.helpButton.label': 'Ajuda', 'editor.headers.savingSpinner.label': 'Salvando...', 'editor.headers.previewButton.label': 'Visualizar', + 'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles', + 'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs', + 'editor.sidebarBlocks.blockType.logic.heading': 'Condicionais', + 'editor.sidebarBlocks.blockType.integrations.heading': 'Integrações', + 'editor.sidebarBlock.start.label': 'Início', + 'editor.sidebarBlock.text.label': 'Texto', + 'editor.sidebarBlock.image.label': 'Imagem', + 'editor.sidebarBlock.video.label': 'Vídeo', + 'editor.sidebarBlock.embed.label': 'Embed', + 'editor.sidebarBlock.audio.label': 'Áudio', + 'editor.sidebarBlock.number.label': 'Número', + 'editor.sidebarBlock.email.label': 'Email', + 'editor.sidebarBlock.website.label': 'Website', + 'editor.sidebarBlock.date.label': 'Data', + 'editor.sidebarBlock.phone.label': 'Telefone', + 'editor.sidebarBlock.button.label': 'Botão', + 'editor.sidebarBlock.picChoice.label': 'Seleção de Imagem', + 'editor.sidebarBlock.payment.label': 'Pagamento', + 'editor.sidebarBlock.rating.label': 'Avaliação', + 'editor.sidebarBlock.file.label': 'Arquivo', + 'editor.sidebarBlock.setVariable.label': 'Variável', + 'editor.sidebarBlock.condition.label': 'Condição', + 'editor.sidebarBlock.redirect.label': 'Redirecionar', + 'editor.sidebarBlock.script.label': 'Script', + 'editor.sidebarBlock.typebot.label': 'Typebot', + 'editor.sidebarBlock.wait.label': 'Espera', + 'editor.sidebarBlock.jump.label': 'Pular', + 'editor.sidebarBlock.abTest.label': 'Teste AB', + 'editor.sidebarBlock.sheets.label': 'Sheets', + 'editor.sidebarBlock.analytics.label': 'Analytics', + 'editor.sidebarBlock.webhook.label': 'Webhook', + 'editor.sidebarBlock.zapier.label': 'Zapier', + 'editor.sidebarBlock.makecom.label': 'Make.com', + 'editor.sidebarBlock.pabbly.label': 'Pabbly', + 'editor.sidebarBlock.chatwoot.label': 'Chatwoot', + 'editor.sidebarBlock.openai.label': 'OpenAI', + 'editor.sidebarBlock.pixel.label': 'Pixel', } as const From 25bf904e3a8799cca2632674a3a1b002c4957966 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Sat, 19 Aug 2023 00:29:29 +0100 Subject: [PATCH 06/10] wip --- apps/builder/src/locales/pt.ts | 2 +- apps/builder/src/locales/pt_BR.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/builder/src/locales/pt.ts b/apps/builder/src/locales/pt.ts index 9db15e4601..67f486bcbb 100644 --- a/apps/builder/src/locales/pt.ts +++ b/apps/builder/src/locales/pt.ts @@ -218,7 +218,7 @@ export default { 'editor.sidebarBlock.text.label': 'Texto', 'editor.sidebarBlock.image.label': 'Imagem', 'editor.sidebarBlock.video.label': 'Vídeo', - 'editor.sidebarBlock.embed.label': 'Embed', + 'editor.sidebarBlock.embed.label': 'Incorporar', 'editor.sidebarBlock.audio.label': 'Áudio', 'editor.sidebarBlock.number.label': 'Número', 'editor.sidebarBlock.email.label': 'Email', diff --git a/apps/builder/src/locales/pt_BR.ts b/apps/builder/src/locales/pt_BR.ts index 00028a999a..c193d34ba1 100644 --- a/apps/builder/src/locales/pt_BR.ts +++ b/apps/builder/src/locales/pt_BR.ts @@ -218,7 +218,7 @@ export default { 'editor.sidebarBlock.text.label': 'Texto', 'editor.sidebarBlock.image.label': 'Imagem', 'editor.sidebarBlock.video.label': 'Vídeo', - 'editor.sidebarBlock.embed.label': 'Embed', + 'editor.sidebarBlock.embed.label': 'Incorporar', 'editor.sidebarBlock.audio.label': 'Áudio', 'editor.sidebarBlock.number.label': 'Número', 'editor.sidebarBlock.email.label': 'Email', From 1ba7ed1920d9da2c1ecf43c571728aee0390137b Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Mon, 21 Aug 2023 11:06:41 +0100 Subject: [PATCH 07/10] Improve pt-br translation. --- apps/builder/src/locales/pt_BR.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/builder/src/locales/pt_BR.ts b/apps/builder/src/locales/pt_BR.ts index c193d34ba1..e4edccc9e0 100644 --- a/apps/builder/src/locales/pt_BR.ts +++ b/apps/builder/src/locales/pt_BR.ts @@ -85,7 +85,7 @@ export default { 'auth.error.email': 'E-mail não encontrado. Tente entrar com um provedor diferente.', 'auth.error.oauthNotLinked': - 'Para confirmar sua identidade, entre com a mesma conta que você usou originalmente.', + 'Já existe uma conta vinculada a esse E-mail, entre com a mesma conta que você usou originalmente.', 'auth.error.unknown': 'Ocorreu um erro. Tente novamente.', 'auth.signinErrorToast.title': 'Não autorizado', 'auth.signinErrorToast.description': 'As inscrições estão desativadas.', From 42a872cca2c5e121ea8cc9190510c44b7c7de978 Mon Sep 17 00:00:00 2001 From: Daniel Oliveira Date: Tue, 22 Aug 2023 14:02:25 +0100 Subject: [PATCH 08/10] Add i18n type func. --- .../features/editor/components/BlockCard.tsx | 16 +++++----- .../editor/components/BlocksSideBar.tsx | 4 +-- .../editor/components/EditableTypebotName.tsx | 4 ++- .../editor/components/GettingStartedModal.tsx | 30 +++++++++---------- .../editor/providers/TypebotProvider.tsx | 6 +++- .../editor/providers/typebotActions/groups.ts | 7 +++-- apps/builder/src/locales/en.ts | 26 ++++++++++++++++ apps/builder/src/locales/pt.ts | 26 ++++++++++++++++ apps/builder/src/locales/pt_BR.ts | 26 ++++++++++++++++ 9 files changed, 115 insertions(+), 30 deletions(-) diff --git a/apps/builder/src/features/editor/components/BlockCard.tsx b/apps/builder/src/features/editor/components/BlockCard.tsx index d742b0bd53..044e299268 100644 --- a/apps/builder/src/features/editor/components/BlockCard.tsx +++ b/apps/builder/src/features/editor/components/BlockCard.tsx @@ -14,6 +14,7 @@ import { Plan } from '@typebot.io/prisma' import { useWorkspace } from '@/features/workspace/WorkspaceProvider' import { BlockLabel } from './BlockLabel' import { LockTag } from '@/features/billing/components/LockTag' +import { useScopedI18n } from '@/locales' type Props = { type: DraggableBlockType @@ -26,6 +27,7 @@ type Props = { export const BlockCard = ( props: Pick ): JSX.Element => { + const scopedT = useScopedI18n('editor.blockCard') const { workspace } = useWorkspace() switch (props.type) { @@ -33,7 +35,7 @@ export const BlockCard = ( return ( @@ -41,7 +43,7 @@ export const BlockCard = ( ) case InputBlockType.FILE: return ( - + @@ -51,14 +53,14 @@ export const BlockCard = ( ) case LogicBlockType.SCRIPT: return ( - + ) case LogicBlockType.TYPEBOT_LINK: return ( - + @@ -67,7 +69,7 @@ export const BlockCard = ( return ( @@ -75,14 +77,14 @@ export const BlockCard = ( ) case IntegrationBlockType.GOOGLE_SHEETS: return ( - + ) case IntegrationBlockType.GOOGLE_ANALYTICS: return ( - + diff --git a/apps/builder/src/features/editor/components/BlocksSideBar.tsx b/apps/builder/src/features/editor/components/BlocksSideBar.tsx index 45c1952df8..67a9d5cd0c 100644 --- a/apps/builder/src/features/editor/components/BlocksSideBar.tsx +++ b/apps/builder/src/features/editor/components/BlocksSideBar.tsx @@ -104,10 +104,10 @@ export const BlocksSideBar = () => { className="hide-scrollbar" > - + : } - aria-label={isLocked ? 'Unlock' : 'Lock'} + aria-label={isLocked ? scopedT('sidebar.icon.unlock.label') : scopedT('sidebar.icon.lock.label') } size="sm" onClick={handleLockClick} /> diff --git a/apps/builder/src/features/editor/components/EditableTypebotName.tsx b/apps/builder/src/features/editor/components/EditableTypebotName.tsx index 4a91488cd8..ecf3445270 100644 --- a/apps/builder/src/features/editor/components/EditableTypebotName.tsx +++ b/apps/builder/src/features/editor/components/EditableTypebotName.tsx @@ -6,6 +6,7 @@ import { useColorModeValue, } from '@chakra-ui/react' import React, { useState } from 'react' +import { useScopedI18n } from '@/locales' type EditableProps = { defaultName: string @@ -15,6 +16,7 @@ export const EditableTypebotName = ({ defaultName, onNewName, }: EditableProps) => { + const scopedT = useScopedI18n('editor.editableTypebotName') const emptyNameBg = useColorModeValue('gray.100', 'gray.700') const [currentName, setCurrentName] = useState(defaultName) @@ -25,7 +27,7 @@ export const EditableTypebotName = ({ } return ( - + { + const scopedT = useScopedI18n('editor.gettingStartedModal') const { query } = useRouter() const { isOpen, onOpen, onClose } = useDisclosure() @@ -38,7 +40,7 @@ export const GettingStartedModal = () => { - Editor basics + {scopedT('editorBasics.heading')} { flexShrink={0} fontSize="13px" > - 1 + {scopedT('editorBasics.list.one.number')} - The left side bar contains blocks that you can drag and drop - to the board. + {scopedT('editorBasics.list.one.label')} @@ -71,11 +72,10 @@ export const GettingStartedModal = () => { fontWeight="bold" flexShrink={0} > - 2 + {scopedT('editorBasics.list.two.number')} - You can group blocks together by dropping them below or above - each other + {scopedT('editorBasics.list.two.label')} @@ -90,9 +90,9 @@ export const GettingStartedModal = () => { flexShrink={0} fontSize="13px" > - 3 + {scopedT('editorBasics.list.three.number')} - Connect the groups together + {scopedT('editorBasics.list.three.label')} { flexShrink={0} fontSize="13px" > - 4 + {scopedT('editorBasics.list.four.number')} - Preview your bot by clicking the preview button on the top - right + {scopedT('editorBasics.list.four.label')} - Feel free to use the bottom-right bubble to reach out if you have - any question. I usually answer within the next 24 hours. 😃 + {scopedT('editorBasics.list.label')} - See it in action ({`<`} 5 minutes) + {scopedT('seeAction.label')} ({`<`} {scopedT('seeAction.time')})