From b3e6e8d5d073444c44df77ab2d0fa71aebb08a47 Mon Sep 17 00:00:00 2001 From: Dhruwang Jariwala <67850763+Dhruwang@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:53:57 +0530 Subject: [PATCH] feat: multi language UI (#3133) Co-authored-by: Matthias Nannt --- .changeset/config.json | 8 +- .devcontainer/devcontainer.json | 15 +- .github/ISSUE_TEMPLATE/bug_report.yml | 150 +- .prettierrc.js | 7 +- .vscode/launch.json | 18 +- .vscode/settings.json | 4 +- apps/demo-react-native/app.json | 46 +- apps/demo-react-native/tsconfig.json | 4 +- apps/demo/postcss.config.js | 2 +- apps/demo/tsconfig.json | 4 +- .../app/global/question-type/matrix/page.mdx | 7 +- apps/docs/tsconfig.json | 8 +- apps/storybook/src/stories/Configure.mdx | 58 +- apps/storybook/tsconfig.json | 22 +- apps/storybook/tsconfig.node.json | 4 +- .../components/ConnectWithFormbricks.tsx | 17 +- .../components/InviteOrganizationMember.tsx | 13 +- .../OnboardingSetupInstructions.tsx | 16 +- .../[environmentId]/connect/invite/page.tsx | 6 +- .../[environmentId]/connect/page.tsx | 8 +- .../components/XMTemplateList.tsx | 31 +- .../xm-templates/lib/xm-templates.ts | 139 +- .../[environmentId]/xm-templates/page.tsx | 14 +- apps/web/app/(app)/(onboarding)/lib/utils.ts | 6 +- .../organizations/[organizationId]/layout.tsx | 6 +- .../products/new/channel/page.tsx | 24 +- .../products/new/industry/page.tsx | 69 - .../products/new/mode/page.tsx | 12 +- .../settings/components/ProductSettings.tsx | 25 +- .../products/new/settings/page.tsx | 19 +- .../(onboarding)/organizations/actions.ts | 3 +- .../environments/[environmentId]/layout.tsx | 10 +- .../edit/components/AddActionModal.tsx | 10 +- .../edit/components/AddEndingCardButton.tsx | 4 +- .../edit/components/AddQuestionButton.tsx | 20 +- .../edit/components/AddressQuestionForm.tsx | 26 +- .../edit/components/BackgroundStylingCard.tsx | 20 +- .../edit/components/CTAQuestionForm.tsx | 28 +- .../edit/components/CalQuestionForm.tsx | 22 +- .../edit/components/CardStylingSettings.tsx | 62 +- .../edit/components/ConditionalLogic.tsx | 14 +- .../edit/components/ConsentQuestionForm.tsx | 15 +- .../components/ContactInfoQuestionForm.tsx | 23 +- .../edit/components/CreateNewActionTab.tsx | 32 +- .../edit/components/DateQuestionForm.tsx | 15 +- .../edit/components/EditEndingCard.tsx | 27 +- .../edit/components/EditWelcomeCard.tsx | 34 +- .../edit/components/EditorCardMenu.tsx | 30 +- .../edit/components/EndScreenForm.tsx | 26 +- .../components/FileUploadQuestionForm.tsx | 44 +- .../edit/components/FormStylingSettings.tsx | 32 +- .../edit/components/HiddenFieldsCard.tsx | 25 +- .../edit/components/HowToSendCard.tsx | 30 +- .../edit/components/LogicEditor.tsx | 6 +- .../edit/components/LogicEditorActions.tsx | 20 +- .../edit/components/LogicEditorConditions.tsx | 22 +- .../edit/components/MatrixQuestionForm.tsx | 29 +- .../components/MultipleChoiceQuestionForm.tsx | 35 +- .../edit/components/NPSQuestionForm.tsx | 28 +- .../edit/components/OpenQuestionForm.tsx | 28 +- .../edit/components/PictureSelectionForm.tsx | 26 +- .../[surveyId]/edit/components/Placement.tsx | 34 +- .../edit/components/QuestionCard.tsx | 47 +- .../edit/components/QuestionOptionChoice.tsx | 17 +- .../edit/components/QuestionsDroppable.tsx | 4 + .../QuestionsStylingSettingsTabs.tsx | 10 +- .../edit/components/QuestionsView.tsx | 21 +- .../edit/components/RankingQuestionForm.tsx | 22 +- .../edit/components/RatingQuestionForm.tsx | 46 +- .../edit/components/RecontactOptionsCard.tsx | 56 +- .../edit/components/RedirectUrlForm.tsx | 6 +- .../edit/components/ResponseOptionsCard.tsx | 101 +- .../edit/components/SavedActionsTab.tsx | 4 +- .../edit/components/SettingsView.tsx | 9 +- .../edit/components/StylingView.tsx | 27 +- .../edit/components/SurveyBgSelectorTab.tsx | 16 +- .../edit/components/SurveyEditor.tsx | 6 + .../edit/components/SurveyMenuBar.tsx | 47 +- .../edit/components/SurveyPlacementCard.tsx | 22 +- .../edit/components/SurveyVariablesCard.tsx | 8 +- .../components/SurveyVariablesCardItem.tsx | 43 +- .../edit/components/TargetingCard.tsx | 66 +- .../edit/components/UnsplashImages.tsx | 10 +- .../edit/components/UpdateQuestionId.tsx | 8 +- .../edit/components/WhenToSendCard.tsx | 58 +- .../[surveyId]/edit/lib/logicRuleEngine.ts | 140 +- .../surveys/[surveyId]/edit/lib/utils.tsx | 110 +- .../surveys/[surveyId]/edit/lib/validation.ts | 6 +- .../surveys/[surveyId]/edit/page.tsx | 17 +- .../surveys/lib/minimalSurvey.ts | 10 +- .../templates/components/BackButton.tsx | 4 +- .../templates/components/FormbricksAICard.tsx | 10 +- .../components/TemplateContainer.tsx | 16 +- .../surveys/templates/page.tsx | 10 +- .../components/ConfirmationPage.tsx | 10 +- .../components/AttributeActivityTab.tsx | 13 +- .../components/AttributeClassesTable.tsx | 22 +- .../components/AttributeDetailModal.tsx | 8 +- .../components/AttributeRowData.tsx | 8 +- .../components/AttributeSettingsTab.tsx | 26 +- .../components/AttributeTableHeading.tsx | 11 - .../components/HowToAddAttributesButton.tsx | 14 - .../components/UploadAttributesModal.tsx | 16 - .../(people)/attributes/loading.tsx | 12 +- .../(people)/attributes/page.tsx | 14 +- .../components/AttributesSection.tsx | 22 +- .../components/DeletePersonButton.tsx | 5 +- .../[personId]/components/ResponseSection.tsx | 12 +- .../components/ResponseTimeline.tsx | 9 +- .../[personId]/components/ResponsesFeed.tsx | 8 +- .../(people)/people/[personId]/loading.tsx | 34 +- .../(people)/people/[personId]/page.tsx | 12 +- .../people/components/PersonDataView.tsx | 6 +- .../components/PersonSecondaryNavigation.tsx | 9 +- .../people/components/PersonTable.tsx | 16 +- .../people/components/PersonTableColumn.tsx | 13 +- .../(people)/people/loading.tsx | 12 +- .../[environmentId]/(people)/people/page.tsx | 9 +- .../components/BasicCreateSegmentModal.tsx | 44 +- .../components/BasicSegmentSettings.tsx | 45 +- .../segments/components/EditSegmentModal.tsx | 6 +- .../components/SegmentActivityTab.tsx | 10 +- .../segments/components/SegmentTable.tsx | 14 +- .../(people)/segments/loading.tsx | 14 +- .../(people)/segments/page.tsx | 10 +- .../actions/components/ActionActivityTab.tsx | 6 +- .../actions/components/ActionDetailModal.tsx | 6 +- .../actions/components/ActionRowData.tsx | 13 +- .../actions/components/ActionSettingsTab.tsx | 45 +- .../actions/components/ActionTableHeading.tsx | 11 +- .../actions/components/AddActionModal.tsx | 10 +- .../[environmentId]/actions/loading.tsx | 10 +- .../[environmentId]/actions/page.tsx | 10 +- .../components/AddProductButton.tsx | 9 - .../components/EnvironmentLayout.tsx | 14 +- .../components/EnvironmentSwitch.tsx | 4 +- .../components/MainNavigation.tsx | 47 +- .../components/TopControlButtons.tsx | 8 +- .../components/WidgetStatusIndicator.tsx | 10 +- .../components/AddIntegrationModal.tsx | 51 +- .../airtable/components/AirtableWrapper.tsx | 4 + .../components/BaseSelectDropdown.tsx | 4 +- .../airtable/components/ManageIntegration.tsx | 33 +- .../integrations/airtable/page.tsx | 12 +- .../integrations/components/DocsSidebar.tsx | 18 - .../components/IntegrationsPageTitle.tsx | 29 - .../components/AddIntegrationModal.tsx | 51 +- .../components/GoogleSheetWrapper.tsx | 4 + .../components/ManageIntegration.tsx | 37 +- .../integrations/google-sheets/loading.tsx | 14 +- .../integrations/google-sheets/page.tsx | 12 +- .../notion/components/AddIntegrationModal.tsx | 96 +- .../notion/components/ManageIntegration.tsx | 33 +- .../notion/components/NotionWrapper.tsx | 5 + .../integrations/notion/loading.tsx | 10 +- .../integrations/notion/page.tsx | 9 +- .../[environmentId]/integrations/page.tsx | 89 +- .../components/AddChannelMappingModal.tsx | 45 +- .../slack/components/ManageIntegration.tsx | 37 +- .../slack/components/SlackWrapper.tsx | 4 + .../integrations/slack/page.tsx | 11 +- .../webhooks/components/AddWebhookButton.tsx | 4 +- .../webhooks/components/AddWebhookModal.tsx | 47 +- .../webhooks/components/HardcodedTriggers.tsx | 7 - .../components/SurveyCheckboxGroup.tsx | 4 +- .../components/TriggerCheckboxGroup.tsx | 21 +- .../components/WebhookDetailModal.tsx | 6 +- .../components/WebhookOverviewTab.tsx | 28 +- .../webhooks/components/WebhookRowData.tsx | 29 +- .../components/WebhookSettingsTab.tsx | 44 +- .../webhooks/components/WebhookTable.tsx | 5 +- .../components/WebhookTableHeading.tsx | 17 +- .../integrations/webhooks/page.tsx | 10 +- .../environments/[environmentId]/layout.tsx | 10 +- .../environments/[environmentId]/page.tsx | 4 +- .../(setup)/app-connection/loading.tsx | 18 +- .../product/(setup)/app-connection/page.tsx | 20 +- .../(setup)/components/SetupInstructions.tsx | 101 +- .../api-keys/components/AddApiKeyModal.tsx | 17 +- .../api-keys/components/ApiKeyList.tsx | 8 +- .../api-keys/components/EditApiKeys.tsx | 34 +- .../product/api-keys/loading.tsx | 15 +- .../[environmentId]/product/api-keys/page.tsx | 24 +- .../components/ProductConfigNavigation.tsx | 14 +- .../general/components/DeleteProduct.tsx | 8 +- .../components/DeleteProductRender.tsx | 27 +- .../components/EditProductNameForm.tsx | 16 +- .../components/EditWaitingTimeForm.tsx | 10 +- .../product/general/loading.tsx | 17 +- .../[environmentId]/product/general/page.tsx | 26 +- .../product/languages/loading.tsx | 8 +- .../product/languages/page.tsx | 30 +- .../[environmentId]/product/layout.tsx | 8 +- .../product/look/components/EditBranding.tsx | 20 +- .../product/look/components/EditLogo.tsx | 26 +- .../look/components/EditPlacementForm.tsx | 32 +- .../product/look/components/ThemeStyling.tsx | 33 +- .../components/ThemeStylingPreviewSurvey.tsx | 7 +- .../[environmentId]/product/look/loading.tsx | 60 +- .../[environmentId]/product/look/page.tsx | 32 +- .../tags/components/EditTagsWrapper.tsx | 31 +- .../tags/components/MergeTagsCombobox.tsx | 12 +- .../[environmentId]/product/tags/loading.tsx | 14 +- .../[environmentId]/product/tags/page.tsx | 14 +- .../components/AccountSettingsNavbar.tsx | 6 +- .../settings/(account)/layout.tsx | 8 +- .../notifications/components/EditAlerts.tsx | 20 +- .../components/EditWeeklySummary.tsx | 10 +- .../components/IntegrationsTip.tsx | 6 +- .../components/NotificationSwitch.tsx | 29 +- .../(account)/notifications/loading.tsx | 12 +- .../settings/(account)/notifications/page.tsx | 18 +- .../profile/components/AccountSecurity.tsx | 8 +- .../profile/components/DeleteAccount.tsx | 7 +- .../components/DisableTwoFactorModal.tsx | 30 +- .../components/EditProfileAvatarForm.tsx | 17 +- .../components/EditProfileDetailsForm.tsx | 78 +- .../components/EnableTwoFactorModal.tsx | 68 +- .../settings/(account)/profile/loading.tsx | 21 +- .../settings/(account)/profile/page.tsx | 22 +- .../components/OrganizationSettingsNavbar.tsx | 9 +- .../(organization)/enterprise/loading.tsx | 4 +- .../(organization)/enterprise/page.tsx | 59 +- .../(organization)/general/actions.ts | 8 +- .../general/components/AIToggle.tsx | 17 +- .../general/components/AddMemberModal.tsx | 8 +- .../general/components/BulkInviteTab.tsx | 17 +- .../general/components/DeleteOrganization.tsx | 36 +- .../EditMemberships/EditMemberships.tsx | 9 +- .../EditMemberships/MemberActions.tsx | 20 +- .../EditMemberships/OrganizationActions.tsx | 23 +- .../components/EditOrganizationName.tsx | 14 +- .../components/EditOrganizationNameForm.tsx | 12 +- .../components/IndividualInviteTab.tsx | 18 +- .../general/components/ShareInviteModal.tsx | 15 +- .../(organization)/general/loading.tsx | 42 +- .../settings/(organization)/general/page.tsx | 26 +- .../settings/(organization)/layout.tsx | 8 +- .../settings/components/SettingsCard.tsx | 2 +- .../components/EmptyInAppSurveys.tsx | 10 +- .../components/SurveyAnalysisNavigation.tsx | 6 +- .../components/ResponseCardModal.tsx | 5 +- .../responses/components/ResponseDataView.tsx | 19 +- .../responses/components/ResponsePage.tsx | 5 +- .../responses/components/ResponseTable.tsx | 12 +- .../components/ResponseTableColumns.tsx | 58 +- .../[surveyId]/(analysis)/responses/page.tsx | 17 +- .../[surveyId]/(analysis)/summary/actions.ts | 3 +- .../summary/components/AddressSummary.tsx | 16 +- .../summary/components/CTASummary.tsx | 16 +- .../summary/components/CalSummary.tsx | 17 +- .../summary/components/ConsentSummary.tsx | 12 +- .../summary/components/ContactInfoSummary.tsx | 16 +- .../components/DateQuestionSummary.tsx | 18 +- .../components/EnableInsightsBanner.tsx | 13 +- .../summary/components/FileUploadSummary.tsx | 23 +- .../components/HiddenFieldsSummary.tsx | 22 +- .../components/MatrixQuestionSummary.tsx | 8 +- .../components/MultipleChoiceSummary.tsx | 22 +- .../summary/components/NPSSummary.tsx | 23 +- .../summary/components/OpenTextSummary.tsx | 29 +- .../components/PictureChoiceSummary.tsx | 15 +- .../components/QuestionSummaryHeader.tsx | 19 +- .../summary/components/RankingSummary.tsx | 14 +- .../summary/components/RatingSummary.tsx | 18 +- .../summary/components/ShareEmbedSurvey.tsx | 31 +- .../summary/components/ShareSurveyResults.tsx | 22 +- .../summary/components/SuccessMessage.tsx | 6 +- .../summary/components/SummaryDropOffs.tsx | 10 +- .../summary/components/SummaryList.tsx | 33 +- .../summary/components/SummaryMetadata.tsx | 71 +- .../summary/components/SummaryPage.tsx | 5 +- .../summary/components/SurveyAnalysisCTA.tsx | 27 +- .../components/shareEmbedModal/AppTab.tsx | 43 +- .../components/shareEmbedModal/EmailTab.tsx | 25 +- .../components/shareEmbedModal/EmbedView.tsx | 8 +- .../components/shareEmbedModal/LinkTab.tsx | 31 +- .../shareEmbedModal/PanelInfoView.tsx | 57 +- .../components/shareEmbedModal/WebsiteTab.tsx | 33 +- .../(analysis)/summary/lib/utils.ts | 19 +- .../[surveyId]/(analysis)/summary/loading.tsx | 4 +- .../[surveyId]/(analysis)/summary/page.tsx | 16 +- .../[surveyId]/components/CustomFilter.tsx | 41 +- .../components/QuestionFilterComboBox.tsx | 9 +- .../components/QuestionsComboBox.tsx | 6 +- .../[surveyId]/components/ResponseFilter.tsx | 20 +- .../components/ResultsShareButton.tsx | 30 +- .../components/SurveyStatusDropdown.tsx | 29 +- .../surveys/components/CopySurveyForm.tsx | 11 +- .../surveys/components/CopySurveyModal.tsx | 50 +- .../surveys/components/SortOption.tsx | 32 +- .../surveys/components/SurveyCard.tsx | 18 +- .../surveys/components/SurveyDropdownMenu.tsx | 26 +- .../components/SurveyFilterDropdown.tsx | 4 +- .../surveys/components/SurveyFilters.tsx | 40 +- .../surveys/components/SurveyList.tsx | 23 +- .../components/SurveyTypeIndicator.tsx | 11 +- .../[environmentId]/surveys/loading.tsx | 4 +- .../[environmentId]/surveys/page.tsx | 40 +- .../auth/components/BackToLoginButton.tsx | 6 +- .../(auth)/auth/components/Testimonial.tsx | 19 +- .../components/PasswordResetForm/index.tsx | 13 +- .../auth/forgot-password/email-sent/page.tsx | 13 +- .../components/ResetPasswordForm/index.tsx | 16 +- .../forgot-password/reset/success/page.tsx | 10 +- .../auth/login/components/SigninForm.tsx | 56 +- .../auth/login/components/TwoFactor.tsx | 4 +- .../auth/login/components/TwoFactorBackup.tsx | 4 +- .../page.tsx | 11 +- .../auth/signup/components/SignupForm.tsx | 25 +- apps/web/app/(auth)/auth/signup/page.tsx | 6 +- .../components/RequestVerificationEmail.tsx | 6 +- .../auth/verification-requested/page.tsx | 16 +- apps/web/app/(auth)/auth/verify/page.tsx | 16 +- apps/web/app/(auth)/invite/page.tsx | 55 +- apps/web/app/(auth)/layout.tsx | 2 +- .../billing/stripe-webhook/lib/constants.ts | 83 +- .../billing/components/PricingTable.tsx | 41 +- .../(organization)/billing/layout.tsx | 6 +- .../(organization)/billing/loading.tsx | 6 +- .../settings/(organization)/billing/page.tsx | 8 +- apps/web/app/api/(internal)/pipeline/route.ts | 11 +- .../api/cron/weekly-summary/lib/product.ts | 1 + apps/web/app/api/cron/weekly-summary/route.ts | 12 +- .../app/api/v1/users/forgot-password/route.ts | 2 +- .../app/api/v1/users/reset-password/route.ts | 5 + apps/web/app/api/v1/users/route.ts | 2 +- apps/web/app/error.tsx | 6 +- apps/web/app/health/error.tsx | 4 +- apps/web/app/health/page.tsx | 4 +- apps/web/app/layout.tsx | 13 +- .../s/[surveyId]/components/LegalFooter.tsx | 8 +- .../s/[surveyId]/components/LinkSurvey.tsx | 8 +- .../app/s/[surveyId]/components/PinScreen.tsx | 8 +- .../[surveyId]/components/SurveyInactive.tsx | 16 +- .../[surveyId]/components/SurveyLinkUsed.tsx | 8 +- .../s/[surveyId]/components/VerifyEmail.tsx | 31 +- apps/web/app/s/[surveyId]/page.tsx | 5 +- .../app/setup/(fresh-instance)/intro/page.tsx | 25 +- .../setup/(fresh-instance)/signup/page.tsx | 13 +- .../[organizationId]/invite/actions.ts | 4 +- .../invite/components/InviteMembers.tsx | 23 +- .../[organizationId]/invite/page.tsx | 4 +- .../create/components/CreateOrganization.tsx | 8 +- .../components/RemovedFromOrganization.tsx | 15 +- .../app/setup/organization/create/page.tsx | 6 +- .../(analysis)/responses/page.tsx | 11 +- .../[sharingKey]/(analysis)/summary/page.tsx | 11 +- apps/web/app/share/[sharingKey]/not-found.tsx | 10 +- apps/web/i18n/request.ts | 20 + .../components/insight-sheet/index.tsx | 13 +- .../ee/insights/components/insights-view.tsx | 43 +- .../experience/components/dashboard.tsx | 17 +- .../experience/components/greeting.tsx | 8 +- .../experience/components/insight-view.tsx | 29 +- .../experience/components/insights-card.tsx | 10 +- .../insights/experience/components/stats.tsx | 14 +- .../experience/components/templates-card.tsx | 6 +- .../modules/ee/insights/experience/page.tsx | 3 + apps/web/next.config.mjs | 5 +- apps/web/package.json | 1 + apps/web/playwright/action.spec.ts | 2 +- apps/web/playwright/fixtures/users.ts | 1 + apps/web/playwright/organization.spec.ts | 24 +- apps/web/playwright/survey.spec.ts | 53 +- apps/web/playwright/utils/helper.ts | 4 +- apps/web/playwright/utils/mock.ts | 2 + apps/web/postcss.config.js | 2 +- apps/web/public/favicon/site.webmanifest | 34 +- apps/web/tsconfig.json | 8 +- apps/web/vercel.json | 8 +- packages/api/tsconfig.json | 8 +- packages/config-eslint/package.json | 1 + packages/config-prettier/package.json | 3 +- packages/config-typescript/base.json | 2 +- packages/config-typescript/js-library.json | 18 +- packages/config-typescript/nextjs.json | 12 +- packages/config-typescript/node16.json | 14 +- packages/config-typescript/react-library.json | 6 +- .../react-native-library.json | 6 +- packages/database/docker-compose.yml | 5 +- packages/database/json-types.ts | 3 +- .../migration.sql | 2 + packages/database/schema.prisma | 16 +- packages/database/tsconfig.json | 4 +- .../components/add-filter-modal.tsx | 36 +- .../components/advanced-targeting-card.tsx | 56 +- .../components/create-segment-modal.tsx | 38 +- .../components/segment-editor.tsx | 14 +- .../components/segment-filter.tsx | 37 +- .../components/segment-settings.tsx | 33 +- .../components/default-language-select.tsx | 22 +- .../components/edit-language.tsx | 61 +- .../components/language-indicator.tsx | 6 +- .../components/language-labels.tsx | 14 +- .../components/language-row.tsx | 9 +- .../components/language-select.tsx | 16 +- .../components/language-toggle.tsx | 12 +- .../components/localized-editor.tsx | 14 +- .../components/multi-language-card.tsx | 44 +- .../components/secondary-language-select.tsx | 10 +- .../components/add-member-role.tsx | 4 +- .../components/edit-membership-role.tsx | 8 +- .../components/transfer-ownership-modal.tsx | 17 +- packages/ee/tsconfig.json | 6 +- .../emails/auth/forgot-password-email.tsx | 19 +- .../auth/password-reset-notify-email.tsx | 11 +- .../email/emails/auth/verification-email.tsx | 22 +- .../emails/invite/invite-accepted-email.tsx | 10 +- packages/email/emails/invite/invite-email.tsx | 17 +- .../emails/invite/onboarding-invite-email.tsx | 15 +- .../survey/embed-survey-preview-email.tsx | 14 +- .../email/emails/survey/link-survey-email.tsx | 16 +- .../emails/survey/response-finished-email.tsx | 32 +- .../create-reminder-notification-body.tsx | 26 +- .../live-survey-notification.tsx | 37 +- .../no-live-survey-notification-email.tsx | 5 +- .../weekly-summary/notification-footer.tsx | 16 +- .../weekly-summary/notification-header.tsx | 9 +- .../weekly-summary/notification-insight.tsx | 16 +- .../weekly-summary-notification-email.tsx | 8 +- packages/email/index.tsx | 44 +- packages/email/lib/utils.ts | 25 + packages/email/tsconfig.json | 6 +- packages/js-core/tsconfig.json | 12 +- packages/js/index.html | 2 +- packages/js/tsconfig.json | 14 +- packages/lib/.eslintrc.cjs | 17 + packages/lib/actionClient/helper.ts | 2 +- packages/lib/authOptions.ts | 2 + packages/lib/constants.ts | 4 + packages/lib/i18n/utils.ts | 1149 +++++- packages/lib/messages/de-DE.json | 2746 ++++++++++++++ packages/lib/messages/en-US.json | 2746 ++++++++++++++ packages/lib/messages/pt-BR.json | 2746 ++++++++++++++ packages/lib/package.json | 4 +- packages/lib/styling/constants.ts | 220 +- packages/lib/templates.ts | 3294 ++++++++++------- packages/lib/time.ts | 22 +- packages/lib/tsconfig.json | 10 +- packages/lib/user/service.ts | 43 +- packages/lib/utils/locale.ts | 29 + packages/lib/utils/questions.tsx | 279 +- packages/lib/utils/users.ts | 2 + packages/react-native/src/survey-web-view.tsx | 2 +- packages/react-native/tsconfig.json | 8 +- .../src/components/general/LanguageSwitch.tsx | 2 +- packages/surveys/src/styles/date-picker.css | 12 +- packages/surveys/src/styles/global.css | 2 +- packages/surveys/tsconfig.json | 10 +- packages/types/email.ts | 1 + packages/types/tsconfig.json | 8 +- packages/types/user.ts | 6 + packages/types/weekly-summary.ts | 1 + packages/ui/components.json | 20 +- .../AdditionalIntegrationSettings/index.tsx | 14 +- packages/ui/components/AlertDialog/index.tsx | 8 +- .../components/BasicAddFilterModal/index.tsx | 11 +- .../components/AttributeSegmentFilter.tsx | 7 +- .../components/PersonSegmentFilter.tsx | 8 +- .../SegmentFilterItemContextMenu.tsx | 6 +- .../ui/components/BillingSlider/index.tsx | 88 +- .../components/CardArrangementTabs/index.tsx | 20 +- packages/ui/components/ClientLogo/index.tsx | 4 +- packages/ui/components/CodeBlock/index.tsx | 4 +- packages/ui/components/CodeBlock/style.css | 39 +- .../ConfirmDeleteSegmentModal/index.tsx | 14 +- .../components/ConnectIntegration/index.tsx | 13 +- .../ConnectIntegration/lib/utils.ts | 28 +- .../CreateOrganizationModal/index.tsx | 18 +- packages/ui/components/CustomDialog/index.tsx | 6 +- .../components/ColumnSettingsDropdown.tsx | 6 +- .../components/DataTableSettingsModal.tsx | 6 +- .../components/DataTableSettingsModalItem.tsx | 16 +- .../DataTable/components/DataTableToolbar.tsx | 8 +- .../components/SelectedRowSettings.tsx | 18 +- packages/ui/components/DatePicker/index.tsx | 4 +- packages/ui/components/DefaultTag/index.tsx | 5 +- .../components/DeleteAccountModal/index.tsx | 26 +- packages/ui/components/DeleteDialog/index.tsx | 10 +- .../components/DevEnvironmentBanner/index.tsx | 4 +- .../ui/components/Editor/stylesEditor.css | 9 +- .../ui/components/EmptySpaceFiller/index.tsx | 22 +- .../ui/components/EnvironmentNotice/index.tsx | 9 +- .../ui/components/ErrorComponent/index.tsx | 8 +- packages/ui/components/FileInput/index.tsx | 16 +- .../components/FileUploadResponse/index.tsx | 4 +- packages/ui/components/GoBackButton/index.tsx | 4 +- .../ui/components/InputCombobox/index.tsx | 10 +- .../components/LimitsReachedBanner/index.tsx | 20 +- .../ui/components/LoadSegmentModal/index.tsx | 14 +- .../ui/components/MediaBackground/index.tsx | 10 +- .../ui/components/NoMobileOverlay/index.tsx | 4 +- .../ui/components/OptionsSwitch/index.tsx | 5 +- packages/ui/components/PageHeader/index.tsx | 2 +- .../PendingDowngradeBanner/index.tsx | 20 +- .../ui/components/PreviewSurvey/index.tsx | 9 +- packages/ui/components/PricingCard/index.tsx | 31 +- .../ui/components/QuestionFormInput/index.tsx | 18 +- .../ui/components/QuestionFormInput/utils.ts | 6 +- .../components/QuestionToggleTable/index.tsx | 13 +- .../components/ResetProgressButton/index.tsx | 4 +- .../SaveAsNewSegmentModal/index.tsx | 25 +- packages/ui/components/SegmentTitle/index.tsx | 7 +- .../components/LanguageDropdown.tsx | 6 +- .../ui/components/ShareSurveyLink/index.tsx | 30 +- .../components/ShuffleOptionSelect/index.tsx | 4 +- .../SignupOptions/components/AzureButton.tsx | 4 +- .../SignupOptions/components/GithubButton.tsx | 4 +- .../SignupOptions/components/GoogleButton.tsx | 4 +- .../components/IsPasswordValid.tsx | 12 +- .../SignupOptions/components/OpenIdButton.tsx | 4 +- .../ui/components/SignupOptions/index.tsx | 39 +- .../components/HiddenFields.tsx | 4 +- .../components/QuestionSkip.tsx | 8 +- .../components/ResponseNote.tsx | 26 +- .../components/ResponseTagsWrapper.tsx | 8 +- .../components/ResponseVariables.tsx | 4 +- .../components/SingleResponseCardBody.tsx | 7 +- .../components/SingleResponseCardHeader.tsx | 40 +- .../components/VerifiedEmail.tsx | 4 +- .../components/SingleResponseCard/index.tsx | 11 +- .../SurveyStatusIndicator/index.tsx | 10 +- packages/ui/components/TagsCombobox/index.tsx | 12 +- .../components/TargetingIndicator/index.tsx | 13 +- .../components/StartFromScratchTemplate.tsx | 9 +- .../TemplateList/components/Template.tsx | 4 +- .../components/TemplateFilters.tsx | 10 +- .../TemplateList/components/TemplateTags.tsx | 33 +- packages/ui/components/TemplateList/index.tsx | 3 +- .../ui/components/TemplateList/lib/utils.ts | 27 +- .../organisms/CodeActionForm/index.tsx | 15 +- .../components/CssSelector.tsx | 10 +- .../components/InnerHtmlSelector.tsx | 8 +- .../components/PageUrlSelector.tsx | 40 +- .../organisms/NoCodeActionForm/index.tsx | 29 +- packages/ui/tsconfig.json | 12 +- playwright.config.ts | 2 + pnpm-lock.yaml | 176 + turbo.json | 138 +- 540 files changed, 17783 insertions(+), 5661 deletions(-) delete mode 100644 apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/industry/page.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/(people)/attributes/components/AttributeTableHeading.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/(people)/attributes/components/HowToAddAttributesButton.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/(people)/attributes/components/UploadAttributesModal.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/components/AddProductButton.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/integrations/components/DocsSidebar.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/integrations/components/IntegrationsPageTitle.tsx delete mode 100644 apps/web/app/(app)/environments/[environmentId]/integrations/webhooks/components/HardcodedTriggers.tsx create mode 100644 apps/web/i18n/request.ts create mode 100644 packages/database/migrations/20241025105622_add_locale_to_user/migration.sql create mode 100644 packages/lib/messages/de-DE.json create mode 100644 packages/lib/messages/en-US.json create mode 100644 packages/lib/messages/pt-BR.json create mode 100644 packages/lib/utils/locale.ts diff --git a/.changeset/config.json b/.changeset/config.json index 4c67367d41..dea465da34 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,11 +1,11 @@ { "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", + "access": "public", + "baseBranch": "main", "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], + "ignore": ["@formbricks/demo", "@formbricks/web"], "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": ["@formbricks/demo", "@formbricks/web"] + "updateInternalDependencies": "patch" } diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 025b3680f4..79ab91fa99 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,11 +2,6 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/javascript-node-postgres // Update the VARIANT arg in docker-compose.yml to pick a Node.js version { - "name": "Node.js & PostgreSQL", - "dockerComposeFile": "docker-compose.yml", - "service": "app", - "workspaceFolder": "/workspace", - // Configure tool-specific properties. "customizations": { // Configure properties specific to VS Code. @@ -16,14 +11,18 @@ } }, + "dockerComposeFile": "docker-compose.yml", // Use 'forwardPorts' to make a list of ports inside the container available locally. // This can be used to network with other containers or with the host. "forwardPorts": [3000, 5432, 8025], - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "cp .env.example .env && sed -i '/^ENCRYPTION_KEY=/c\\ENCRYPTION_KEY='$(openssl rand -hex 32) .env && sed -i '/^NEXTAUTH_SECRET=/c\\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env && sed -i '/^CRON_SECRET=/c\\CRON_SECRET='$(openssl rand -hex 32) .env && pnpm install && pnpm db:migrate:dev", + "name": "Node.js & PostgreSQL", "postAttachCommand": "pnpm dev --filter=@formbricks/web... --filter=@formbricks/demo...", + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "cp .env.example .env && sed -i '/^ENCRYPTION_KEY=/c\\ENCRYPTION_KEY='$(openssl rand -hex 32) .env && sed -i '/^NEXTAUTH_SECRET=/c\\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env && sed -i '/^CRON_SECRET=/c\\CRON_SECRET='$(openssl rand -hex 32) .env && pnpm install && pnpm db:migrate:dev", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "node" + "remoteUser": "node", + "service": "app", + "workspaceFolder": "/workspace" } diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f158f61f95..a62805b903 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -4,78 +4,78 @@ title: "[BUG]" labels: bug assignees: [] body: -- type: textarea - id: issue-summary - attributes: - label: Issue Summary - description: A summary of the issue. This needs to be a clear detailed-rich summary. - validations: - required: true -- type: textarea - id: steps-to-reproduce - attributes: - label: Steps to Reproduce - value: | - 1. (for example) Went to ... - 2. Clicked on... - 3. ... - validations: - required: true -- type: textarea - id: expected-behavior - attributes: - label: Expected behavior - description: A clear and concise description of what you expected to happen. - validations: - required: true -- type: textarea - id: other-information - attributes: - label: Other information - validations: - required: false -- type: textarea - id: screenshots - attributes: - label: Screenshots - description: If applicable, add screenshots to help explain your problem. - validations: - required: false -- type: checkboxes - id: environment - attributes: - label: Environment - options: - - label: Formbricks Cloud (app.formbricks.com) - - label: Self-hosted Formbricks -- type: textarea - id: desktop-version - attributes: - label: Desktop (please complete the following information) - description: | - examples: - - **OS**: [e.g. iOS] - - **Browser**: [e.g. chrome, safari] - - **Version**: [e.g. 22] - value: | - - OS: - - Node: - - npm: - render: markdown - validations: - required: true -- type: markdown - id: nodejs-version - attributes: - value: | - #### Node.JS version - - [e.g. v18.15.0] -- type: markdown - id: anything-else - attributes: - value: | - #### Anything else? - - - Screen recording, console logs, network requests: You can make a recording with [Loom](https://www.loom.com). - - Anything else that you think could be an issue? + - type: textarea + id: issue-summary + attributes: + label: Issue Summary + description: A summary of the issue. This needs to be a clear detailed-rich summary. + validations: + required: true + - type: textarea + id: steps-to-reproduce + attributes: + label: Steps to Reproduce + value: | + 1. (for example) Went to ... + 2. Clicked on... + 3. ... + validations: + required: true + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. + validations: + required: true + - type: textarea + id: other-information + attributes: + label: Other information + validations: + required: false + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem. + validations: + required: false + - type: checkboxes + id: environment + attributes: + label: Environment + options: + - label: Formbricks Cloud (app.formbricks.com) + - label: Self-hosted Formbricks + - type: textarea + id: desktop-version + attributes: + label: Desktop (please complete the following information) + description: | + examples: + - **OS**: [e.g. iOS] + - **Browser**: [e.g. chrome, safari] + - **Version**: [e.g. 22] + value: | + - OS: + - Node: + - npm: + render: markdown + validations: + required: true + - type: markdown + id: nodejs-version + attributes: + value: | + #### Node.JS version + + [e.g. v18.15.0] + - type: markdown + id: anything-else + attributes: + value: | + #### Anything else? + + - Screen recording, console logs, network requests: You can make a recording with [Loom](https://www.loom.com). + - Anything else that you think could be an issue? diff --git a/.prettierrc.js b/.prettierrc.js index e09241f398..44ad4e4410 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,5 +2,10 @@ const baseConfig = require("./packages/config-prettier/prettier-preset"); module.exports = { ...baseConfig, - plugins: ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"], + plugins: [ + "@trivago/prettier-plugin-sort-imports", + "prettier-plugin-tailwindcss", + "prettier-plugin-sort-json", + ], + jsonRecursiveSort: true, }; diff --git a/.vscode/launch.json b/.vscode/launch.json index 95de9d2df8..5843e73c43 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,21 +1,21 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", "configurations": [ { "name": "Launch localhost:3002", - "type": "firefox", - "request": "launch", "reAttach": true, + "request": "launch", + "type": "firefox", "url": "http://localhost:3002/", "webRoot": "${workspaceFolder}" }, { "name": "Attach", - "type": "firefox", - "request": "attach" + "request": "attach", + "type": "firefox" } - ] + ], + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0d341a005b..48b4d0a2d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.preferences.importModuleSpecifier": "non-relative" + "typescript.preferences.importModuleSpecifier": "non-relative", + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/apps/demo-react-native/app.json b/apps/demo-react-native/app.json index b7701d49b3..66cd17cbb8 100644 --- a/apps/demo-react-native/app.json +++ b/apps/demo-react-native/app.json @@ -1,32 +1,32 @@ { "expo": { - "name": "react-native-demo", - "slug": "react-native-demo", - "version": "1.0.0", - "orientation": "portrait", - "icon": "./assets/icon.png", - "userInterfaceStyle": "light", - "splash": { - "image": "./assets/splash.png", - "resizeMode": "contain", - "backgroundColor": "#ffffff" - }, - "jsEngine": "hermes", - "assetBundlePatterns": ["**/*"], - "ios": { - "supportsTablet": true, - "infoPlist": { - "NSCameraUsageDescription": "Take pictures for certain activities.", - "NSPhotoLibraryUsageDescription": "Select pictures for certain activities.", - "NSMicrophoneUsageDescription": "Need microphone access for recording videos." - } - }, "android": { "adaptiveIcon": { - "foregroundImage": "./assets/adaptive-icon.png", - "backgroundColor": "#ffffff" + "backgroundColor": "#ffffff", + "foregroundImage": "./assets/adaptive-icon.png" } }, + "assetBundlePatterns": ["**/*"], + "icon": "./assets/icon.png", + "ios": { + "infoPlist": { + "NSCameraUsageDescription": "Take pictures for certain activities.", + "NSMicrophoneUsageDescription": "Need microphone access for recording videos.", + "NSPhotoLibraryUsageDescription": "Select pictures for certain activities." + }, + "supportsTablet": true + }, + "jsEngine": "hermes", + "name": "react-native-demo", + "orientation": "portrait", + "slug": "react-native-demo", + "splash": { + "backgroundColor": "#ffffff", + "image": "./assets/splash.png", + "resizeMode": "contain" + }, + "userInterfaceStyle": "light", + "version": "1.0.0", "web": { "favicon": "./assets/favicon.png" } diff --git a/apps/demo-react-native/tsconfig.json b/apps/demo-react-native/tsconfig.json index b9567f6052..1b69c20e54 100644 --- a/apps/demo-react-native/tsconfig.json +++ b/apps/demo-react-native/tsconfig.json @@ -1,6 +1,6 @@ { - "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true - } + }, + "extends": "expo/tsconfig.base" } diff --git a/apps/demo/postcss.config.js b/apps/demo/postcss.config.js index 33ad091d26..12a703d900 100644 --- a/apps/demo/postcss.config.js +++ b/apps/demo/postcss.config.js @@ -3,4 +3,4 @@ module.exports = { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/apps/demo/tsconfig.json b/apps/demo/tsconfig.json index f1063c0342..d000509d66 100644 --- a/apps/demo/tsconfig.json +++ b/apps/demo/tsconfig.json @@ -1,5 +1,5 @@ { + "exclude": ["node_modules"], "extends": "@formbricks/config-typescript/nextjs.json", - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] } diff --git a/apps/docs/app/global/question-type/matrix/page.mdx b/apps/docs/app/global/question-type/matrix/page.mdx index c8f307facc..883c30fa08 100644 --- a/apps/docs/app/global/question-type/matrix/page.mdx +++ b/apps/docs/app/global/question-type/matrix/page.mdx @@ -11,6 +11,7 @@ Matrix questions allow respondents to select a value for each option presented i ## Elements + ### Title + Add a clear title to inform the respondent what information you are asking for. ### Description + Provide an optional description with further instructions. ### Rows + Define the options shown on the left side of the matrix. These represent the items for which users will select a value. ### Columns + Represent the range of values from 0 to X (right side of the screen). Users can choose any value, including 0, using radio buttons. ### Select ordering - Keep current order: This will keep the order of options the same for all respondents. -- Randomize all: This will randomize the options for each respondent. \ No newline at end of file +- Randomize all: This will randomize the options for each respondent. diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index f623ea6a7a..9babd8f0b9 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -1,7 +1,4 @@ { - "extends": "@formbricks/config-typescript/nextjs.json", - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "../../packages/types/*.d.ts"], - "exclude": ["../../.env", "node_modules"], "compilerOptions": { "baseUrl": ".", "paths": { @@ -13,5 +10,8 @@ } ], "strictNullChecks": true - } + }, + "exclude": ["../../.env", "node_modules"], + "extends": "@formbricks/config-typescript/nextjs.json", + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "../../packages/types/*.d.ts"] } diff --git a/apps/storybook/src/stories/Configure.mdx b/apps/storybook/src/stories/Configure.mdx index 51570900ce..6969c2bbd5 100644 --- a/apps/storybook/src/stories/Configure.mdx +++ b/apps/storybook/src/stories/Configure.mdx @@ -1,35 +1,36 @@ import { Meta } from "@storybook/blocks"; -import Github from "./assets/github.svg"; -import Discord from "./assets/discord.svg"; -import Youtube from "./assets/youtube.svg"; -import Tutorials from "./assets/tutorials.svg"; -import Styling from "./assets/styling.png"; -import Context from "./assets/context.png"; -import Assets from "./assets/assets.png"; -import Docs from "./assets/docs.png"; -import Share from "./assets/share.png"; -import FigmaPlugin from "./assets/figma-plugin.png"; -import Testing from "./assets/testing.png"; import Accessibility from "./assets/accessibility.png"; -import Theming from "./assets/theming.png"; import AddonLibrary from "./assets/addon-library.png"; +import Assets from "./assets/assets.png"; +import Context from "./assets/context.png"; +import Discord from "./assets/discord.svg"; +import Docs from "./assets/docs.png"; +import FigmaPlugin from "./assets/figma-plugin.png"; +import Github from "./assets/github.svg"; +import Share from "./assets/share.png"; +import Styling from "./assets/styling.png"; +import Testing from "./assets/testing.png"; +import Theming from "./assets/theming.png"; +import Tutorials from "./assets/tutorials.svg"; +import Youtube from "./assets/youtube.svg"; -export const RightArrow = () => - - +export const RightArrow = () => ( + + + +); @@ -38,6 +39,7 @@ export const RightArrow = () =>
@@ -84,6 +86,7 @@ export const RightArrow = () =>
@@ -203,6 +206,7 @@ export const RightArrow = () => Discover tutorials
+