Skip to content

feat: Introduce Formbricks CX#3152

Merged
jobenjada merged 34 commits intomainfrom
356-feature-introduce-formbricks-cx
Sep 20, 2024
Merged

feat: Introduce Formbricks CX#3152
jobenjada merged 34 commits intomainfrom
356-feature-introduce-formbricks-cx

Conversation

@gupta-piyush19
Copy link
Contributor

@gupta-piyush19 gupta-piyush19 commented Sep 17, 2024

What does this PR do?

Introduce Formbricks CX

Fixes https://github.com/formbricks/internal/issues/356

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read How we Code at Formbricks
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand bits
  • Ran pnpm build
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues
  • First PR at Formbricks? Please sign the CLA! Without it we wont be able to merge it 🙏

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Formbricks Docs if changes were necessary

Summary by CodeRabbit

Release Notes

  • New Features

    • Added multiple survey templates for enhanced survey creation, including NPS, CSAT, and more.
    • Introduced a new interface for selecting between "Web app" and "Mobile app" embedding options.
    • Enhanced survey embedding options with static iframe and dynamic pop-up choices.
  • Improvements

    • Improved user experience with clear guidance and instructions tailored to different application types.
    • Enhanced flexibility in onboarding options and question type selections, including conditional rendering based on "CX mode."
    • Added utility functions for customizing survey templates with product names.
  • Bug Fixes

    • Corrected URL path for notifications settings to ensure proper routing.

@vercel
Copy link

vercel bot commented Sep 17, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
formbricks-cloud ⬜️ Ignored (Inspect) Visit Preview Sep 20, 2024 7:39am
formbricks-docs ⬜️ Ignored (Inspect) Visit Preview Sep 20, 2024 7:39am

@github-actions
Copy link
Contributor

github-actions bot commented Sep 17, 2024

Thank you for following the naming conventions for pull request titles! 🙏

@gupta-piyush19
Copy link
Contributor Author

@jobenjada Please review the new onboarding and the changes in the survey editor.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 18, 2024

Walkthrough

The changes introduce new survey templates and utility functions for managing them, along with components for embedding surveys in web and mobile applications. Notable additions include the AppTab and WebsiteTab components, which facilitate user interactions for embedding options. Additionally, existing components have been enhanced to support conditional rendering based on the isCxMode property, expanding the application's survey capabilities and improving user experience.

Changes

File Path Change Summary
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts Introduced various survey templates including NPS, CSAT, and others, with a default template exported.
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts Added utility functions for replacing placeholders in survey templates with actual product names.
apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/AppTab.tsx Added AppTab component for selecting between web and mobile app embedding options.
apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/WebsiteTab.tsx Created WebsiteTab component with options for static iframe and pop-up embedding.
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddQuestionButton.tsx Modified AddQuestionButton to include isCxMode for conditional question type rendering.
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx Added isCxMode to toggle question type mappings in EditorCardMenu.
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx Introduced isCxMode to QuestionCard for conditional rendering based on mode.
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyMenuBar.tsx Updated SurveyMenuBar to conditionally render buttons based on isCxMode.
packages/lib/utils/questions.tsx Added CXQuestionTypes and CX_QUESTIONS_NAME_MAP for focused handling of specific question types.

Possibly related PRs

Suggested labels

🙋🏻‍♂️help wanted, 🕹️ oss.gg, 🕹️ 50 points, 🕹️ Level 1

🐰 Hopping through the code with glee,
New features sprout like leaves on a tree.
Templates and surveys, all in a line,
With each little change, our app will shine!
So let's celebrate this joyful spree,
For every new line, there's a hop from me! 🐇✨


Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 76fafb1 and 08d4ce6.

Files selected for processing (1)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/page.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/page.tsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Member

@jobenjada jobenjada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey Piyush!

Looks great :) Really like the stripped down survey editor, makes it a lot easier to get to the first finalized survey 💪

A few things:

Here, please use the toggle we're also using in the Survey Editor e.g. to determine which validation a text input has:
image

image

As discussed on Discord: Is it possible here to set the toggle to default on and hide the toggle and the two text links below the background color?
image


And pls review my code changes and resolve the merge conflict :)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Outside diff range and nitpick comments (9)
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts (1)

12-12: Consider using a configuration or environment variable for the default language code.

Using a hardcoded default language code might cause issues with localization. Consider using a configuration or environment variable to set the default language code.

apps/web/app/page.tsx (1)

42-42: LGTM! Ensure thorough testing and documentation.

The change in the redirect URL aligns with the PR objective of introducing Formbricks CX and the shift in the product creation process.

Please ensure that:

  1. The new "mode" creation page is thoroughly tested, especially the scenarios mentioned in the PR description (Test A and Test B).
  2. The Formbricks documentation is updated to reflect the changes in the user flow and the introduction of the "mode" creation page, if necessary.
apps/web/package.json (1)

42-42: Consider using the latest version of file-loader.

The added file-loader dependency is using version ^6.2.0. However, the latest version of file-loader is 6.2.1.

Unless there are specific compatibility requirements, it's generally recommended to use the latest stable version of a package to ensure you have access to the latest bug fixes and improvements.

Consider updating the version to ^6.2.1:

-    "file-loader": "^6.2.0",
+    "file-loader": "^6.2.1",
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/components/XMTemplateList.tsx (2)

17-21: Consider adding PropTypes or TypeScript types for the component props.

To improve type safety and provide better documentation for the component's props, consider adding PropTypes or TypeScript types. This will help catch potential type-related issues during development and make the component more self-explanatory.


1-100: Add tests to cover the component's functionality.

To ensure the reliability and maintainability of the XMTemplateList component, it's important to add tests that cover its core functionality and edge cases. Consider writing unit tests to verify the behavior of the createSurvey and handleTemplateClick functions, as well as integration tests to ensure the component renders correctly with different prop values and user interactions.

Do you want me to generate some test cases or open a GitHub issue to track this task?

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx (2)

Line range hint 179-199: Fix the typo in the variable name.

The logic for rendering the dropdown items for changing the question type based on the availbleQuestionTypes is correct. It handles the case when the question has logic by showing a warning modal. However, the variable name availbleQuestionTypes has a typo. It should be availableQuestionTypes.

Apply this diff to fix the typo:

-{Object.entries(availbleQuestionTypes).map(([type, name]) => {
+{Object.entries(availableQuestionTypes).map(([type, name]) => {

Line range hint 224-237: Fix the typo in the variable name.

The logic for rendering the dropdown items for adding a new question below the current question based on the availbleQuestionTypes is correct. However, the variable name availbleQuestionTypes has a typo. It should be availableQuestionTypes.

Apply this diff to fix the typo:

-{Object.entries(availbleQuestionTypes).map(([type, name]) => {
+{Object.entries(availableQuestionTypes).map(([type, name]) => {
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx (1)

57-57: Approve the addition of isCxMode prop, but request more information.

The addition of the isCxMode boolean prop to the QuestionCardProps interface is approved. However, it would be helpful to provide more context about the purpose and intended usage of this prop, either through code comments or in the PR description. This will help with maintainability and understanding of the code.

apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/page.tsx (1)

43-48: Consider a more responsive layout for the survey button.

The survey button is positioned absolutely, which may cause layout issues on smaller screens. Consider using a more responsive layout approach to ensure that the button remains accessible and visually appealing across different screen sizes.

One possible solution is to use a media query to adjust the button's position or layout based on the screen size. For example:

-<Button
-  className="absolute right-5 top-5 !mt-0 text-slate-500 hover:text-slate-700"
-  variant="minimal"
-  href={`/environments/${environment.id}/surveys`}>
+<Button
+  className="md:absolute md:right-5 md:top-5 !mt-0 text-slate-500 hover:text-slate-700"
+  variant="minimal"
+  href={`/environments/${environment.id}/surveys`}>
   <XIcon className="h-7 w-7" strokeWidth={1.5} />
 </Button>

In this example, the md: prefix is used to apply the absolute positioning only on medium-sized screens and above. On smaller screens, the button will follow the normal flow of the document.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ebf35ea and 227eabc.

Files ignored due to path filters (3)
  • apps/web/images/tooltips/change-survey-type-app.mp4 is excluded by !**/*.mp4
  • apps/web/images/tooltips/change-survey-type.mp4 is excluded by !**/*.mp4
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (42)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/connect/page.tsx (1 hunks)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/components/XMTemplateList.tsx (1 hunks)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts (1 hunks)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts (1 hunks)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/page.tsx (1 hunks)
  • apps/web/app/(app)/(onboarding)/lib/utils.ts (1 hunks)
  • apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/channel/page.tsx (1 hunks)
  • apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/mode/page.tsx (1 hunks)
  • apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/settings/components/ProductSettings.tsx (3 hunks)
  • apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/settings/page.tsx (3 hunks)
  • apps/web/app/(app)/(onboarding)/organizations/components/OnboardingOptionsContainer.tsx (1 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddQuestionButton.tsx (3 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditEndingCard.tsx (2 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx (6 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/HowToSendCard.tsx (1 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx (3 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsDroppable.tsx (3 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsStylingSettingsTabs.tsx (2 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsView.tsx (5 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyEditor.tsx (5 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyMenuBar.tsx (5 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx (3 hunks)
  • apps/web/app/(app)/environments/[environmentId]/components/MainNavigation.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/components/WidgetStatusIndicator.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/product/(setup)/components/SetupInstructions.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/product/(setup)/website-connection/page.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareEmbedSurvey.tsx (4 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/AppTab.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/EmbedView.tsx (3 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/WebpageTab.tsx (2 hunks)
  • apps/web/app/lib/questions.tsx (2 hunks)
  • apps/web/app/page.tsx (1 hunks)
  • apps/web/next.config.mjs (1 hunks)
  • apps/web/package.json (1 hunks)
  • packages/lib/templates.ts (1 hunks)
  • packages/types/product.ts (1 hunks)
  • packages/types/templates.ts (1 hunks)
  • packages/types/video.d.ts (1 hunks)
  • packages/ui/Header/index.tsx (1 hunks)
  • packages/ui/OptionCard/index.tsx (2 hunks)
  • packages/ui/OptionsSwitch/index.tsx (1 hunks)
  • packages/ui/ShareSurveyLink/components/SurveyLinkDisplay.tsx (1 hunks)
Files skipped from review due to trivial changes (2)
  • apps/web/app/(app)/environments/[environmentId]/product/(setup)/website-connection/page.tsx
  • packages/types/video.d.ts
Additional context used
Biome
apps/web/app/(app)/(onboarding)/organizations/components/OnboardingOptionsContainer.tsx

[error] 49-49: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/AppTab.tsx

[error] 31-31: Unexpected empty object pattern.

(lint/correctness/noEmptyPattern)

apps/web/app/lib/questions.tsx

[error] 261-261: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

Additional comments not posted (95)
packages/ui/Header/index.tsx (2)

5-5: LGTM!

Making the subtitle property optional is a good change that enhances the flexibility of the Header component. This allows the component to be used in more scenarios without requiring a subtitle to be provided every time.


12-12: LGTM!

Conditionally rendering the subtitle paragraph based on the presence of a subtitle value is a good improvement. It prevents the display of an empty paragraph when no subtitle is provided, resulting in a cleaner output.

packages/ui/ShareSurveyLink/components/SurveyLinkDisplay.tsx (1)

11-11: LGTM! The changes improve responsiveness and usability.

The modifications to the className prop of the Input component enhance the responsiveness and visual clarity of the input field:

  • Changing the width from a fixed w-96 to a flexible w-full with a minimum width of min-w-96 allows the input to expand to fill the available space while ensuring it doesn't shrink below a certain size. This improves the responsiveness of the input field.
  • Updating the background color from bg-slate-50 to bg-white may impact the visual appearance and contrast of the input field, potentially improving readability.
  • Slightly increasing the padding from px-3 to px-4 could enhance usability by providing more space around the text within the input.

These changes align with the goal of improving the user experience, as mentioned in the PR objectives.

apps/web/app/(app)/(onboarding)/lib/utils.ts (1)

3-3: Verify the function usage throughout the codebase.

Making the channel and industry parameters optional enhances the function's flexibility. However, it's crucial to ensure that the function is called with the expected arguments throughout the codebase to avoid any unintended behavior.

Run the following script to verify the function usage:

Verification successful

Function usage verified: No issues found

After thorough examination, I can confirm that the getCustomHeadline function is being used correctly throughout the codebase. All identified instances of the function call provide both the channel and industry parameters, which aligns with the best practice for using this function.

The change to make the parameters optional hasn't introduced any issues in the current usage. However, it's important to maintain the practice of providing both parameters in future usage to ensure consistent behavior.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `getCustomHeadline` provide the expected arguments.

# Test: Search for the function usage. Expect: Only occurrences with both arguments provided.
rg --type typescript -A 5 $'getCustomHeadline'

Length of output: 80


Script:

#!/bin/bash
# Description: Verify all function calls to `getCustomHeadline` provide the expected arguments.

# Search using rg without specifying file type
echo "Searching with rg:"
rg -n -A 5 'getCustomHeadline'

# Search using fd and grep
echo "Searching with fd and grep:"
fd -e ts -e tsx | xargs grep -n -A 5 'getCustomHeadline'

Length of output: 12237

packages/types/templates.ts (1)

28-34: LGTM!

The new ZXMTemplate structure is defined correctly using Zod, with appropriately typed properties referencing existing types for questions and endings. The corresponding TypeScript type, TXMTemplate, is inferred correctly from the ZXMTemplate object.

This change expands the functionality of the module by adding a new template type, allowing for more complex survey configurations or data handling, while leaving the existing ZTemplate and its type TTemplate unchanged.

packages/ui/OptionCard/index.tsx (3)

15-17: LGTM!

The changes to the sizeClasses object are consistent and follow a logical pattern based on the card sizes. The maximum width constraints are suitable for the respective sizes.


38-38: LGTM!

Adding the text-center class to the div containing the title and description improves the visual layout and readability of the card by centering the text.


40-40: Please clarify the purpose of the text-balance class.

The text-balance class is not a standard Tailwind CSS class. Can you provide more context on what this class does and how it affects the text styling or weight of the description?

apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts (2)

6-26: LGTM!

The function implementation looks good. It correctly handles the case when the product is not provided, creates a deep copy of the question object, and replaces the placeholder in the headline and subheader.


29-36: LGTM!

The function implementation looks good. It correctly creates a deep copy of the template object, replaces the placeholder in the template name, iterates over the questions to apply the replaceQuestionPresetPlaceholders function, and returns a new object that merges the original template with the modified survey data.

apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/mode/page.tsx (4)

1-11: LGTM!

The imports and the ModePageProps interface are properly defined and follow a consistent naming convention.


13-45: LGTM!

The Page component is well-structured and follows a logical flow. It correctly fetches the products based on the organizationId and renders the onboarding options and navigation button accordingly.


47-47: LGTM!

The Page component is correctly exported as the default export of the module.


1-47: Great work!

The page.tsx file is well-structured, follows best practices, and effectively implements the onboarding page for product selection within an organization. The code is readable, maintainable, and adheres to consistent naming conventions.

No issues or potential improvements were identified during the review.

apps/web/app/(app)/(onboarding)/organizations/components/OnboardingOptionsContainer.tsx (4)

4-4: LGTM!

The import statement for the cn function is correct.


12-15: LGTM!

The addition of optional properties to the OnboardingOptionsContainerProps interface enhances the flexibility and functionality of the onboarding options. The properties are well-defined and serve clear purposes.


20-40: LGTM!

The getOptionCard function is a well-structured helper function that encapsulates the rendering logic for an individual option card. It correctly handles the optional properties and conditionally renders the icon text and loading state. Extracting this logic into a separate function improves code organization and reusability.


43-47: LGTM!

The layout logic in the OnboardingOptionsContainer component is well-implemented. The conditional application of class names based on the number of options allows for a responsive layout. The grid layout is appropriately used for three or more options, while the flex layout is used for fewer options. The class names are correctly applied using the cn function.

apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/channel/page.tsx (3)

20-20: LGTM! The URL path change aligns with the new functionality.

The change in the URL path from /industry to /settings suggests that users will now be directed to a settings page instead of an industry selection page when accessing the "Public website" channel. The addition of the channel query parameter indicates that the settings page may have different behavior based on the selected channel.


27-27: LGTM! The URL path change aligns with the new functionality.

Similar to the previous change, the URL path has been updated from /industry to /settings for the "App with sign up" channel. This suggests that users will now be directed to a settings page instead of an industry selection page when accessing this channel. The channel query parameter with the value app has been added to differentiate the behavior of the settings page based on the selected channel.


35-35: LGTM! The URL path change aligns with the new functionality.

The URL path for the "Link & email surveys" channel has also been updated from /industry to /settings, consistent with the changes made to the other channel options. This change suggests that users will now be directed to a settings page instead of an industry selection page when accessing this channel. The channel query parameter with the value link has been added to differentiate the behavior of the settings page based on the selected channel.

apps/web/app/(app)/(onboarding)/environments/[environmentId]/connect/page.tsx (1)

28-29: LGTM!

The changes correctly handle the case where product.config.channel or product.config.industry might be undefined by providing a fallback value of null. This ensures that channel and industry variables always have a value, preventing potential errors downstream.

Additionally, removing the previous check that returned a "not found" response allows the code to proceed to generate a custom headline regardless of whether channel or industry are defined, potentially allowing for more flexible handling of these values.

Overall, these changes enhance the robustness of the code and modify the flow of execution based on the presence of these properties.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsStylingSettingsTabs.tsx (4)

34-34: LGTM!

The addition of the isCxMode property to the QuestionsAudienceTabsProps interface is a valid change that enhances the component's flexibility.


41-41: LGTM!

The addition of the isCxMode property to the destructured props in the QuestionsAudienceTabs component is consistent with the changes made to the QuestionsAudienceTabsProps interface.


50-52: LGTM!

The introduction of the tabsToDisplay variable and the conditional filtering of the "settings" tab based on the value of isCxMode is a valid change that enhances the component's flexibility.


56-56: LGTM!

The replacement of tabsComputed with tabsToDisplay in the JSX is consistent with the introduction of the tabsToDisplay variable and ensures that the tabs displayed in the UI are based on the value of isCxMode.

packages/ui/OptionsSwitch/index.tsx (5)

7-7: LGTM!

The addition of the disabled property to the TOption interface is a good way to enable more granular control over user interactions with individual options. The property is appropriately marked as optional and the boolean type is suitable for representing the disabled state.


21-35: LGTM!

The use of React hooks useState and useEffect to manage the highlight style dynamically based on the currently selected option is a good practice. The highlight effect is calculated correctly by referencing the position and width of the active option within the container. The useEffect hook has the appropriate dependency on currentOption to ensure the highlight style is updated whenever the selected option changes.


48-56: LGTM!

The click handler for each option correctly checks the disabled state of the individual option, preventing interaction with disabled options. The styling logic appropriately reflects the disabled state visually by applying the cursor-not-allowed and opacity-50 classes. The cursor-pointer and hover:bg-slate-50 classes provide visual feedback for non-disabled options on hover.


59-59: LGTM!

The icon rendering logic correctly checks for the presence of the icon property using the && operator, as it is optional in the TOption interface. The icon is rendered within a div element with appropriate classes for styling. Rendering the icon as a React node allows for flexibility in the type of icon that can be passed.


Line range hint 1-66: Overall, the changes made to the OptionsSwitch component are excellent!

The addition of the disabled property for individual options allows for more granular control over user interactions, improving the flexibility and usability of the component. The use of React hooks to manage state and side effects is implemented correctly and follows best practices. The component now provides clear visual feedback based on the disabled and currentOption states, enhancing the user experience.

Great job on these enhancements! The OptionsSwitch component is now more robust and user-friendly.

apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/settings/page.tsx (4)

7-7: LGTM!

The import statement for TProductMode is syntactically correct and the type is likely used in the subsequent changes.


18-18: LGTM!

The addition of the optional mode property to the searchParams object in the ProductSettingsPageProps interface is syntactically correct and uses the imported TProductMode type.


23-25: LGTM!

The initialization of the channel, industry, and mode variables from the searchParams object is syntactically correct. Using the || operator to provide default values ensures that the variables have a fallback value if the corresponding properties are not present in the searchParams object. The default value of "surveys" for mode suggests that it is the default mode for the product settings page.


Line range hint 32-45: LGTM!

The changes to the rendering logic for the Header component and the addition of the productMode prop to the ProductSettings component are syntactically correct and align with the overall functionality of the product settings page.

The rendering logic for the Header component now includes a condition that checks if mode is equal to "cx" in addition to checking if channel is "link", which broadens the scenarios under which the specific header is displayed.

The ProductSettings component receives the productMode prop, which is set to the value of mode, allowing it to adapt its behavior based on the selected mode.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsDroppable.tsx (3)

23-23: LGTM!

The addition of the isCxMode property to the QuestionsDraggableProps interface is a clean way to extend the component's functionality without introducing any breaking changes. The naming convention is clear and follows the existing code style.


42-42: LGTM!

The addition of isCxMode to the destructured props in the QuestionsDroppable component is consistent with the changes made to the QuestionsDraggableProps interface. This change allows the property to be used within the component and maintains the code's readability.


67-67: Verify the usage of isCxMode in the QuestionCard component.

Passing down the isCxMode property to the QuestionCard component is a logical step to propagate the "Cx mode" functionality to the individual question cards. The code change is consistent with the existing structure and style.

To ensure that the "Cx mode" functionality is correctly implemented, please verify that the isCxMode property is being used appropriately within the QuestionCard component. Look for conditional rendering or behavior modifications based on the value of isCxMode.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddQuestionButton.tsx (5)

3-8: LGTM!

The imports are necessary to support the changes made in the file. The code segment looks good.


19-19: LGTM!

The new prop isCxMode is necessary to support the conditional logic introduced in the component. The code segment looks good.


22-22: LGTM!

The modification to the AddQuestionButton component declaration is necessary to support the usage of the new prop isCxMode in the component. The code segment looks good.


25-25: LGTM!

The conditional logic to select the set of question types based on the value of isCxMode is necessary to support the different sets of question types based on the mode. The code segment looks good.


50-50: LGTM!

The modification to use the availableQuestionTypes constant in the mapping of question types is necessary to support the conditional selection of question types based on the mode. The code segment looks good.

packages/types/product.ts (1)

18-19: LGTM!

The introduction of the ZProductMode enumeration and the corresponding TProductMode type alias is a great addition to the codebase. It enhances the product configuration capabilities and aligns with the PR objective of introducing Formbricks CX.

The changes are additive and do not break existing functionality. The new enumeration and type alias can be used to improve the type safety and readability of the codebase.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/page.tsx (2)

73-73: LGTM!

The introduction of the isCxMode variable enhances the overall functionality of the component by enabling it to respond to different modes based on the URL's query parameters. This could affect how the survey editor behaves or is rendered.


92-92: Verify the isCxMode prop usage in the SurveyEditor component.

Passing the isCxMode variable as a prop to the SurveyEditor component allows the component to adapt its behavior or rendering based on the mode.

Run the following script to verify the prop usage:

Verification successful

The isCxMode prop is correctly implemented and used throughout the survey editor components.

The isCxMode prop is properly passed down from the SurveyEditor component to its child components and is used consistently to modify the behavior and UI of the survey editor based on the mode. This implementation allows for a flexible editor experience that can adapt to different use cases (standard mode vs. "cx" mode).

Key points:

  • The prop is determined based on the URL search parameter in the page component.
  • It affects available question types, UI rendering, button text, and available tabs.
  • The implementation is consistent across multiple components.

No issues were found with the usage of the isCxMode prop.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `isCxMode` prop is correctly handled in the `SurveyEditor` component.

# Test: Search for the prop usage. Expect: Occurrences of the prop being used to conditionally render or modify behavior.
rg --type typescript -A 5 $'isCxMode'

Length of output: 71


Script:

#!/bin/bash
# Description: Verify the `isCxMode` prop is correctly handled in the `SurveyEditor` component.

# Find TypeScript files and search for isCxMode
fd -e ts -e tsx | xargs rg -n -A 5 'isCxMode'

Length of output: 28801

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/EmbedView.tsx (3)

6-6: LGTM!

The import statement for the AppTab component is correctly added.


29-29: LGTM!

The environmentId prop is correctly passed to the EmbedView and WebsiteTab components. The AppTab component is also correctly rendered based on the activeId value.

Also applies to: 73-73, 81-82


16-16: Verify the component prop change in the codebase.

The environmentId prop has been correctly added to the EmbedViewProps interface. However, ensure that all usages of the EmbedView component have been updated to pass the environmentId prop.

Run the following script to verify the component usage:

Verification successful

Verification successful: EmbedView component usage is up-to-date

The EmbedView component usage has been correctly updated to include the new environmentId prop. The search across all TypeScript, TSX, JavaScript, and JSX files in the codebase revealed only one instance of the EmbedView component being used, and it properly includes the environmentId prop:

<EmbedView
  handleInitialPageButton={handleInitialPageButton}
  tabs={tabs}
  activeId={activeId}
  environmentId={environmentId}
  setActiveId={setActiveId}
/>

This usage is found in the file:
apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareEmbedSurvey.tsx

The changes have been correctly implemented, and no further updates are required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all usages of `EmbedView` pass the `environmentId` prop.

# Test: Search for the component usage. Expect: All occurrences to pass the prop.
rg --type typescript -A 5 $'<EmbedView'

Length of output: 75


Script:

#!/bin/bash
# Description: Verify all usages of `EmbedView` pass the `environmentId` prop.

# Find TypeScript, TSX, JavaScript, and JSX files and search for EmbedView usage
fd -e ts -e tsx -e js -e jsx | xargs rg -A 5 '<EmbedView'

Length of output: 986

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/AppTab.tsx (3)

10-29: LGTM!

The AppTab component is well-structured and provides a clear user interface for selecting between web and mobile app options. The use of the useState hook to manage the selectedTab state and the conditional rendering of the WebAppTab or MobileAppTab component based on the selected tab is a good approach.


32-55: LGTM!

The MobileAppTab component provides clear instructions for embedding a survey in a React Native application. The link to the setup instructions and the alert indicating ongoing work on SDKs for other platforms are helpful for users.


57-94: LGTM!

The WebAppTab component provides clear instructions for embedding a survey in a web application. The links to the setup instructions and user identification documentation are helpful for users. The video that visually demonstrates how to change the survey type to "App Survey" is a nice addition to guide users through the process.

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/shareEmbedModal/WebpageTab.tsx (3)

13-36: LGTM!

The WebsiteTab component is well-structured and provides a clear way for users to toggle between the two embedding options. The use of the OptionsSwitch component makes the code more readable and maintainable. The selected tab state is managed correctly using the useState hook, and the appropriate child component is rendered based on the selection.

The component is receiving the necessary props (surveyUrl and environmentId) and passing them down to the respective child components.

Overall, the code changes in this component are implemented correctly and enhance the user experience by providing different embedding options.


Line range hint 38-82: Code looks good!

The StaticTab component is functioning as expected and remains largely unchanged, as mentioned in the AI-generated summary. The component correctly generates the iframe code based on the surveyUrl prop and the embedModeEnabled state.

The use of the AdvancedOptionToggle component allows users to easily enable or disable the embed mode, providing flexibility in how the survey is embedded.

The "Copy code" button is implemented correctly, copying the generated iframe code to the clipboard when clicked, enhancing the user experience.

Overall, the StaticTab component is implemented correctly and maintains its existing functionality.


84-112: Great addition!

The new PopupTab component is a valuable addition to the codebase, providing users with clear and detailed instructions on how to embed a pop-up survey on their website. The component is well-structured and easy to understand.

The link to the setup instructions is generated correctly using the environmentId prop, ensuring that users can easily access the necessary information to connect their website with Formbricks.

The inclusion of a video demonstration is a great way to provide a visual guide on how to change the survey type and define the pop-up behavior. This enhances the user experience and makes it easier for users to understand and implement the pop-up survey functionality.

Overall, the PopupTab component is a well-designed and informative addition that improves the usability and user experience of the Formbricks platform.

apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/components/XMTemplateList.tsx (1)

1-100: Excellent work on the XMTemplateList component!

The component is well-structured, follows best practices, and provides a seamless onboarding experience for creating surveys based on predefined templates. The use of appropriate hooks, libraries, and reusable components enhances the code quality and maintainability.

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareEmbedSurvey.tsx (4)

3-11: LGTM!

The icons are imported correctly from the "lucide-react" library and used appropriately in the component.


38-41: LGTM!

The new tab object for embedding surveys in an app is added correctly with appropriate properties. The labels for existing tabs are also modified for better consistency and clarity.


86-86: LGTM!

The correction in the URL path for notifications settings is necessary to ensure proper routing. The double slash is fixed appropriately.


113-113: LGTM!

Adding the environmentId as a prop to the EmbedView component is a good practice for sharing data between components. It may facilitate further functionality related to the environment context within the EmbedView component.

apps/web/next.config.mjs (1)

93-108: LGTM!

The webpack configuration for handling video files looks good:

  • The test regular expression correctly matches the desired video file extensions.
  • Using file-loader is a suitable choice for processing and outputting video files.
  • The loader options are properly configured to set the public path, output path, and naming convention for the generated video files.

This configuration will allow the Next.js application to import and use video files with the specified extensions, and the files will be accessible via the /_next/static/videos/ path.

apps/web/app/(app)/(onboarding)/organizations/[organizationId]/products/new/settings/components/ProductSettings.tsx (3)

16-16: LGTM!

The import statement for TProductMode is syntactically correct and the type is likely used in the component.


36-36: LGTM!

The productMode prop is correctly typed using the imported TProductMode type and is likely used to handle different product modes in the component.


44-44: LGTM!

The updated routing logic correctly handles different product modes and channels:

  • The previous condition checking if the channel was not "link" has been replaced with a check for whether the channel is either "app" or "website".
  • A new condition has been added to handle the case when productMode is "cx", which redirects the user to the correct route.

These changes enhance the routing logic based on the product mode, thereby affecting the navigation flow within the application.

Also applies to: 74-79

apps/web/app/(app)/environments/[environmentId]/product/(setup)/components/SetupInstructions.tsx (1)

26-26: LGTM!

The conditional initialization of activeTab based on the type prop is a nice enhancement. It improves the user experience by dynamically setting the initial active tab to the most relevant one based on the context.

apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts (7)

6-10: LGTM!

The XMSurveyDefault template provides a good base structure for the survey templates. The empty name and questions properties can be overridden by specific templates, and the default ending card is appropriately retrieved from the library.


12-33: LGTM!

The NPSSurvey template is well-structured and follows the standard NPS format. The questions flow logically from the NPS rating to the open text feedback. The use of {{productName}} allows for customization of the survey for different products.


35-73: LGTM!

The StarRatingSurvey template effectively uses the star rating question type and provides different paths based on the rating value. The CTA question encourages satisfied users to write a review, while the open text question collects feedback from dissatisfied users. The use of the logic property to control the question flow is a good approach.


75-109: LGTM!

The CSATSurvey template effectively measures customer satisfaction using a rating question with a smiley scale. The follow-up questions are well-tailored to the user's satisfaction level, asking for improvement suggestions in a friendly tone. The use of the logic property to control the question flow based on the rating value is a good approach.


111-135: LGTM!

The CESSurvey template effectively measures the effort required by customers to achieve a specific goal using a rating question with a number scale. The follow-up question appropriately asks for suggestions to make it easier for customers to achieve the goal. The use of the [ADD GOAL] placeholder allows for customization of the survey based on the specific use case.


137-175: The SmileysRatingSurvey template is very similar to the StarRatingSurvey template, with the only difference being the use of a smiley scale instead of a star scale. The overall structure and logic of the template are the same.


177-198: The eNPSSurvey template is very similar to the NPSSurvey template, with the only difference being the question text tailored for employee recommendation likelihood. The overall structure and logic of the template are the same as the NPSSurvey template.

apps/web/app/lib/questions.tsx (2)

232-240: LGTM!

The new CXQuestionTypes constant provides a focused list of question types that can be used in subsequent logic. This change enhances the clarity and usability of question type handling within the application.


258-264: LGTM!

The new CX_QUESTIONS_NAME_MAP constant provides a convenient way to access the labels of the filtered question types. This change facilitates the use of the filtered question types in the application without needing to reference the full questionTypes array.

Regarding the static analysis hint:
The hint suggests avoiding the use of spread syntax on accumulators in the reduce method. However, this is a false positive because the spread syntax is not used on the accumulator object itself, but on the new object being returned in each iteration. The spread syntax is used to create a new object that includes all the properties of the accumulator object and the new property being added in the current iteration. This does not cause a time complexity of O(n^2) because the spread syntax is not used on the accumulator object directly.

Tools
Biome

[error] 261-261: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyEditor.tsx (4)

40-40: LGTM!

The addition of the isCxMode property to the SurveyEditorProps interface is a valid change that introduces a new configuration option for the SurveyEditor component.


59-59: LGTM!

The destructuring of the isCxMode property from the SurveyEditorProps object and the assignment of a default value of false is a valid implementation that ensures the property is available within the SurveyEditor component.


149-149: Verify the usage of the isCxMode prop in the SurveyMenuBar component.

The isCxMode property is being correctly passed to the SurveyMenuBar component. However, it is important to ensure that the SurveyMenuBar component properly handles this prop and adapts its behavior based on the value of isCxMode.

Verification successful

The isCxMode prop is correctly used in the SurveyMenuBar component.

The verification process confirms that the isCxMode prop is properly handled in the SurveyMenuBar component:

  • It's defined in the component's props interface.
  • It's used for conditional rendering of UI elements:
    • Two buttons are only shown when not in CX mode.
    • The main action button text changes from "Publish" to "Save & Close" in CX mode.

This implementation ensures that the SurveyMenuBar adapts its behavior and appearance based on the CX mode as intended.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `isCxMode` prop in the `SurveyMenuBar` component.

# Test: Search for the usage of the `isCxMode` prop in the `SurveyMenuBar` component.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
rg --type tsx -A 5 $'isCxMode' $(fd SurveyMenuBar.tsx)

Length of output: 200


Script:

#!/bin/bash
# Description: Verify the usage of the `isCxMode` prop in the SurveyMenuBar component using alternative methods.

# Attempt 1: Use grep to search for isCxMode
echo "Searching for isCxMode using grep:"
grep -n -C 5 "isCxMode" $(fd SurveyMenuBar.tsx)

# Attempt 2: If grep doesn't find anything, display the entire file content
if [ $? -ne 0 ]; then
    echo "isCxMode not found. Displaying entire file content:"
    cat $(fd SurveyMenuBar.tsx)
fi

Length of output: 2212


158-158: Verify the usage of the isCxMode prop in the QuestionsAudienceTabs and QuestionsView components.

The isCxMode property is being correctly passed to the QuestionsAudienceTabs and QuestionsView components. However, it is important to ensure that these components properly handle this prop and adapt their behavior based on the value of isCxMode.

Also applies to: 177-177

Verification successful

The isCxMode prop is being used correctly in the QuestionsAudienceTabs and QuestionsView components, as well as other related components.

After thorough analysis of the codebase, it's clear that the isCxMode prop is being properly passed down from the SurveyEditor component and used consistently across multiple components, including QuestionsAudienceTabs and QuestionsView. The prop is used to conditionally render certain elements, modify available question types, and adjust the behavior of components based on whether the application is in "CX mode" or not.

Some key observations:

  • In QuestionsAudienceTabs, it's used to filter out the "settings" tab when in CX mode.
  • In QuestionsView, it affects the rendering of welcome cards and other UI elements.
  • Other components like QuestionCard, QuestionsDroppable, and AddQuestionButton also utilize the prop to modify their behavior appropriately.

No issues or inconsistencies were found in the usage of the isCxMode prop. The implementation appears to be correct and in line with the intended functionality of differentiating between CX mode and regular mode.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `isCxMode` prop in the `QuestionsAudienceTabs` and `QuestionsView` components.

# Test: Search for the usage of the `isCxMode` prop in the `QuestionsAudienceTabs` component.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
rg --type tsx -A 5 $'isCxMode' $(fd QuestionsAudienceTabs.tsx)

# Test: Search for the usage of the `isCxMode` prop in the `QuestionsView` component.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
rg --type tsx -A 5 $'isCxMode' $(fd QuestionsView.tsx)

Length of output: 290


Script:

#!/bin/bash
# Description: Verify the usage of the `isCxMode` prop in the `QuestionsAudienceTabs` and `QuestionsView` components.

# Test: Search for the usage of the `isCxMode` prop in the `QuestionsAudienceTabs` component.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
fd -e tsx QuestionsAudienceTabs | xargs rg -t typescript -A 5 'isCxMode'

# Test: Search for the usage of the `isCxMode` prop in the `QuestionsView` component.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
fd -e tsx QuestionsView | xargs rg -t typescript -A 5 'isCxMode'

Length of output: 207


Script:

#!/bin/bash
# Description: Verify the usage of the `isCxMode` prop in the `QuestionsAudienceTabs` and `QuestionsView` components.

# Test: Search for the usage of the `isCxMode` prop in all TSX files, focusing on QuestionsAudienceTabs.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
fd -e tsx | xargs rg -A 5 'isCxMode.*QuestionsAudienceTabs'

# Test: Search for the usage of the `isCxMode` prop in all TSX files, focusing on QuestionsView.
# Expect: The `isCxMode` prop should be used to conditionally render or modify the behavior of the component.
fd -e tsx | xargs rg -A 5 'isCxMode.*QuestionsView'

# Test: If the above searches don't yield results, search for `isCxMode` prop usage in all TSX files.
# Expect: To find any usage of `isCxMode` prop in the codebase.
fd -e tsx | xargs rg -A 5 'isCxMode'

Length of output: 28274

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/HowToSendCard.tsx (1)

234-234: LGTM!

The change in the URL path for creating a new product is consistent with the AI-generated summary. The path segment channel is replaced with mode, which may indicate a shift in the functionality or categorization of the product creation process.

Can you provide more context on the reason for this change? Is it related to a new feature or organizational structure?

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditEndingCard.tsx (3)

50-53: LGTM!

The logic for disabling the "Redirect to Url" option for free plan users on Formbricks Cloud is implemented correctly. It also handles the case where the current ending card type is already "redirectToUrl" to keep it enabled.


55-58: Nice refactor!

Moving the endingCardTypes array inside the EditEndingCard component is a good refactor as it is only used within this component. Setting the disabled property based on isRedirectToUrlDisabled correctly propagates the disabling logic to the UI.


209-217: Good enhancement to the control flow!

Checking if the selected option is disabled before allowing the change prevents users from selecting the "Redirect to Url" option when it is disabled. Updating the survey type only when the selected option is not disabled ensures data consistency. This change enhances the control flow and improves the user experience.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx (3)

3-8: LGTM!

The import statements are syntactically correct and add the necessary constants for the feature.


45-45: LGTM!

The new optional prop isCxMode is added correctly to the EditorCardMenuProps interface. The type and optional nature of the prop are appropriate for a feature flag.


60-60: LGTM!

Setting a default value of false for the isCxMode prop is a good practice. It ensures that the component behaves predictably when the prop is not provided.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyMenuBar.tsx (3)

42-42: LGTM!

The addition of the isCxMode property to the SurveyMenuBarProps interface is a valid change. It enables new functionality to be added to the component based on the value of isCxMode.


301-312: LGTM!

The conditional rendering of the "Back" button based on the value of isCxMode is a valid change. It improves the user experience in CX mode by hiding the "Back" button when it is not needed.


348-359: LGTM!

The conditional rendering of the "Save" button and the modification of the "Publish" button text based on the value of isCxMode are valid changes. They improve the user experience in CX mode by:

  • Hiding the "Save" button when it is not needed.
  • Using a more appropriate label of "Save & Close" for the "Publish" button.

Also applies to: 389-389

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionsView.tsx (2)

52-52: LGTM!

The addition of the isCxMode prop to the QuestionsViewProps interface is a good way to introduce a new mode to the survey editor.


Line range hint 364-469: LGTM!

The usage of the isCxMode prop to conditionally render UI elements is a clean way to streamline the survey editor UI for the new CX mode. The changes are well-contained and do not affect the overall functionality of the survey editor.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx (1)

78-78: Approve passing isCxMode prop, but review its usage in EditorCardMenu.

The isCxMode prop is being correctly passed from the QuestionCard component to its child EditorCardMenu component. This is approved.

However, to fully understand the impact of this change, the usage of isCxMode within the EditorCardMenu component should also be reviewed. Please ensure that the behavior of EditorCardMenu based on the value of isCxMode aligns with the intended functionality of the "CX mode".

Also applies to: 211-211

apps/web/app/(app)/environments/[environmentId]/components/MainNavigation.tsx (1)

172-172: Verify the impact of the URL path change on the codebase.

The change in the URL path for adding a new product looks good. However, please ensure that:

  • The new path /organizations/${organizationId}/products/new/mode is handled correctly in the corresponding route handler.
  • Any other parts of the codebase that rely on the old path /organizations/${organizationId}/products/new/channel are updated accordingly.

Run the following script to verify the usage of the old and new paths:

Verification successful

Path change successfully verified across the codebase

The verification process confirms that:

  • The old path '/organizations/${organizationId}/products/new/channel' has been completely removed from the codebase.
  • The new path '/organizations/${organizationId}/products/new/mode' is consistently used in two locations:
    1. MainNavigation.tsx (the file we initially reviewed)
    2. HowToSendCard.tsx (in a href attribute for navigation)

These findings suggest that the change has been applied consistently. However, as an extra precaution, it's recommended to perform a quick manual check to ensure no edge cases were missed, particularly in any configuration files or documentation that might not have been covered by our search.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the old and new paths for adding a new product.

# Test 1: Search for the old path usage. Expect: No occurrences of the old path.
rg --type typescript --type javascript --type jsx --type tsx $'/organizations/\$\{organizationId\}/products/new/channel'

# Test 2: Search for the new path usage. Expect: Only occurrences of the new path.
rg --type typescript --type javascript --type jsx --type tsx $'/organizations/\$\{organizationId\}/products/new/mode'

Length of output: 310


Script:

#!/bin/bash
# Description: Verify the usage of the old and new paths for adding a new product.

# Test 1: Search for the old path usage. Expect: No occurrences of the old path.
rg -t js -t jsx -t tsx -g '*.ts' '/organizations/\$\{organizationId\}/products/new/channel'

# Test 2: Search for the new path usage. Expect: Only occurrences of the new path.
rg -t js -t jsx -t tsx -g '*.ts' '/organizations/\$\{organizationId\}/products/new/mode'

Length of output: 240


Script:

#!/bin/bash
# Description: Verify the usage of the old and new paths for adding a new product.

# Test 1: Search for the old path usage. Expect: No occurrences of the old path.
find . -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) -exec grep -H '/organizations/${organizationId}/products/new/channel' {} +

# Test 2: Search for the new path usage. Expect: Only occurrences of the new path.
find . -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) -exec grep -H '/organizations/${organizationId}/products/new/mode' {} +

Length of output: 674

packages/lib/templates.ts (2)

Line range hint 44-51: Verify if surveyDefault should be exported.

Exporting surveyDefault makes it accessible to other modules. Ensure this is intentional and aligns with the desired usage and encapsulation of this constant. If surveyDefault is meant to be an internal implementation detail of this module, consider keeping it unexported.


Line range hint 1-1: LGTM!

The removal of the empty line in the "Net Promoter Score (NPS)" template object improves the consistency and readability of the code. This minor formatting change does not introduce any functional issues.

apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/page.tsx (1)

1-53: LGTM!

The Page component is well-structured and follows a logical flow. It effectively retrieves the necessary data (user session, environment details, and associated product) and handles error cases appropriately by throwing errors when the required data is not found.

The use of the XMTemplateList component to render the list of XM templates is a good approach, promoting code reusability and maintainability.

Overall, the component provides a clear and user-friendly interface for interacting with XM templates within a specific environment.

Copy link
Member

@jobenjada jobenjada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last tweaks, some merge conflicts, then LGTM 🚀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this duplicate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, atleast the replacePresetPlaceholders handler, as the XM templates have a different schema than the normal templates

<div className="flex min-h-full min-w-full flex-col items-center justify-center space-y-12">
<Header title="What kind of feedback would you like to get?" />
<XMTemplateList product={product} user={user} environmentId={environment.id} />
<Button
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's missing the condition checking for product.length !== 0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{products.length >= 1 && (

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this check here? We are only fetching a single product and throwing an error if it doesn't exist.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cc3e3e8 and 76fafb1.

Files selected for processing (6)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts (1 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddQuestionButton.tsx (3 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx (6 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx (3 hunks)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyMenuBar.tsx (5 hunks)
  • packages/lib/utils/questions.tsx (2 hunks)
Files skipped from review as they are similar to previous changes (5)
  • apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/utils.ts
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddQuestionButton.tsx
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu.tsx
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/QuestionCard.tsx
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyMenuBar.tsx
Additional context used
Biome
packages/lib/utils/questions.tsx

[error] 263-263: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

Additional comments not posted (1)
packages/lib/utils/questions.tsx (1)

232-242: LGTM!

The filtering logic is correct and the specified question types are relevant for the Formbricks CX functionality. The code segment is well-structured and follows best practices.

Copy link
Member

@jobenjada jobenjada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoopwhooop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants