Skip to content

Comments

Add Intercom support and enhance phishing detection in AI search#1184

Merged
MrgSub merged 1 commit intostagingfrom
06-02-interom
Jun 3, 2025
Merged

Add Intercom support and enhance phishing detection in AI search#1184
MrgSub merged 1 commit intostagingfrom
06-02-interom

Conversation

@MrgSub
Copy link
Collaborator

@MrgSub MrgSub commented Jun 3, 2025

Add Intercom integration and enhance phishing detection in mail display

Description

This PR adds Intercom integration for customer support and enhances the phishing detection capabilities in the mail display component. The changes include:

  1. Integrating Intercom messenger for user support with secure JWT authentication
  2. Enhancing the AI web search query to better identify suspicious domains and potential phishing attempts
  3. Reorganizing the help and feedback UI elements in the navigation sidebar

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🔒 Security enhancement
  • 🎨 UI/UX improvement

Areas Affected

  • User Interface/Experience
  • Authentication/Authorization
  • Security

Testing Done

  • Manual testing performed

Security Considerations

  • No sensitive data is exposed
  • Authentication checks are in place
  • JWT implementation for secure Intercom authentication

Checklist

  • I have performed a self-review of my code
  • My changes generate no new warnings

Additional Notes

The phishing detection enhancement improves security by adding domain validation to the AI search query, helping users identify suspicious email domains more effectively. The Intercom integration provides a direct support channel for users within the application.

By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.

Summary by CodeRabbit

  • New Features

    • Added Intercom messenger integration, allowing users to access help via a new "Help" button in the sidebar.
    • Introduced a "Feedback" navigation item in the sidebar for quick access to external feedback submission.
  • Enhancements

    • Improved person background search to include phishing detection and domain validity context.
  • Chores

    • Updated dependencies to support new features.
    • Adjusted navigation configuration for sidebar items.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Walkthrough

This update introduces Intercom messenger integration into the mail application's navigation sidebar, including UI changes for help and feedback access. It adds backend support for generating JWT tokens for Intercom via a new TRPC route, updates navigation configuration, and manages related dependencies and environment variables.

Changes

File(s) Change Summary
apps/mail/components/mail/mail-display.tsx Enhanced AI query in MoreAboutPerson to include phishing detection context.
apps/mail/components/ui/nav-main.tsx Integrated Intercom messenger, added Help/Feedback sidebar UI, and refactored related logic.
apps/mail/config/navigation.ts Removed "feedback" item from bottom navigation configuration.
apps/mail/package.json Added @intercom/messenger-js-sdk dependency.
apps/server/package.json Added @tsndr/cloudflare-worker-jwt dependency.
apps/server/src/trpc/routes/user.ts Added getIntercomToken TRPC query for Intercom JWT token generation.
apps/server/wrangler.jsonc Added JWT_SECRET environment variable for local environment.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant NavMain (Frontend)
    participant TRPC (Backend)
    participant Intercom SDK

    User->>NavMain (Frontend): Clicks Help button
    NavMain (Frontend)->>TRPC (Backend): getIntercomToken query
    TRPC (Backend)->>NavMain (Frontend): Returns JWT token
    NavMain (Frontend)->>Intercom SDK: Initialize with JWT token
    NavMain (Frontend)->>Intercom SDK: Show Intercom Messenger UI
Loading

Possibly related PRs

  • Mail-0/Zero#1182: Introduced the MoreAboutPerson component and AI search dialogs, which are directly built upon by the main PR’s changes.

Suggested reviewers

  • ahmetskilinc

Poem

In the warren of code, a new friend hops in,
Intercom now listens, let the chats begin!
With tokens secure and a sidebar so bright,
Help and feedback buttons are now in sight.
A hop, a skip, and a click or two—
The rabbit approves these updates for you!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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
Collaborator Author

MrgSub commented Jun 3, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@MrgSub MrgSub marked this pull request as ready for review June 3, 2025 02:21
@MrgSub MrgSub changed the title Interom Add Intercom support and enhance phishing detection in AI search Jun 3, 2025
Copy link
Collaborator Author

MrgSub commented Jun 3, 2025

Merge activity

  • Jun 3, 2:24 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 3, 2:24 AM UTC: @MrgSub merged this pull request with Graphite.

@MrgSub MrgSub merged commit 57b1f4f into staging Jun 3, 2025
2 of 3 checks passed
@MrgSub MrgSub deleted the 06-02-interom branch June 3, 2025 02:24
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: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a66a0f and 10450b4.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/mail/components/mail/mail-display.tsx (1 hunks)
  • apps/mail/components/ui/nav-main.tsx (4 hunks)
  • apps/mail/config/navigation.ts (0 hunks)
  • apps/mail/package.json (1 hunks)
  • apps/server/package.json (1 hunks)
  • apps/server/src/trpc/routes/user.ts (2 hunks)
  • apps/server/wrangler.jsonc (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/mail/config/navigation.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/server/src/trpc/routes/user.ts (1)
apps/server/src/trpc/trpc.ts (1)
  • privateProcedure (21-29)
apps/mail/components/ui/nav-main.tsx (4)
apps/mail/components/ui/sidebar.tsx (1)
  • SidebarMenuButton (605-605)
apps/mail/config/navigation.ts (2)
  • MessageKey (25-25)
  • NavItem (27-38)
apps/mail/components/icons/icons.tsx (1)
  • MessageSquare (491-508)
apps/mail/types/index.ts (1)
  • NavItem (36-42)
🔇 Additional comments (7)
apps/mail/package.json (1)

24-24:

Details

❓ Verification inconclusive

Verify package version and security status.

The version 0.0.14 suggests this might be an early or beta release. Please ensure this is the latest stable version and check for any known security vulnerabilities.


🏁 Script executed:

#!/bin/bash
# Check the latest version and security advisories for @intercom/messenger-js-sdk

# Get latest version from npm
npm view @intercom/messenger-js-sdk version

# Check for security advisories
npm audit --package-lock-only --audit-level=low

Length of output: 907


🏁 Script executed:

#!/bin/bash
# Generate a lockfile in the mail app and run an audit to check for vulnerabilities
cd apps/mail
npm install --package-lock-only
npm audit --audit-level=low

Length of output: 632


Confirmed latest version; manual security audit required

  • File: apps/mail/package.json
  • The version 0.0.14 matches the latest release on npm.
  • Automated npm audit failed due to an unsupported “catalog:” URL protocol in your registry config.

Please perform a manual security review (for example, run npm audit with a valid lockfile or use a third-party tool like Snyk) to ensure there are no known vulnerabilities in @intercom/messenger-js-sdk.

apps/server/package.json (1)

37-37:

Details

❓ Verification inconclusive

Verify JWT library version and security.

Please ensure this is the latest version of the JWT library and check for any known security vulnerabilities.


🏁 Script executed:

#!/bin/bash
# Check the latest version of @tsndr/cloudflare-worker-jwt
npm view @tsndr/cloudflare-worker-jwt version

# Check for security advisories
npm audit --package-lock-only --audit-level=low

Length of output: 908


🏁 Script executed:

#!/bin/bash
# Generate a lockfile and re-run audit to catch any vulnerabilities
cd apps/server
npm install --package-lock-only
npm audit --audit-level=low

Length of output: 634


JWT library version confirmed, manual security review needed

npm view shows that @tsndr/cloudflare-worker-jwt@3.2.0 is the current latest stable release. Attempts to run npm audit in the sandbox failed due to missing lockfiles and unsupported protocols. Please perform a manual security check for known vulnerabilities (e.g., via npmjs.com/package/@tsndr/cloudflare-worker-jwt, Snyk, or your preferred advisory database).

• Location: apps/server/package.json (line 37)

apps/mail/components/mail/mail-display.tsx (1)

646-648: Excellent security enhancement for phishing detection.

This addition to the search query enhances user security by helping identify potentially suspicious email domains. The examples provided (x.io vs x.com, paypalcom.com vs paypal.com) effectively illustrate common phishing tactics.

apps/server/src/trpc/routes/user.ts (1)

2-2: LGTM - Clean import addition

The import for the Cloudflare Worker JWT library is properly added.

apps/mail/components/ui/nav-main.tsx (3)

21-23: LGTM - Clean import additions

The new imports for react-query, Intercom SDK, and icons are properly organized and support the new functionality.


199-199: LGTM - Proper translation hook usage

Good addition of the translation hook for internationalization support.


202-207: LGTM - Simplified toast usage

The change to use toast.promise directly is cleaner and more readable than the previous implementation.

"COOKIE_DOMAIN": "localhost",
"VITE_PUBLIC_BACKEND_URL": "http://localhost:8787",
"VITE_PUBLIC_APP_URL": "http://localhost:3000",
"JWT_SECRET": "secret",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical security issue: weak JWT secret and missing production configuration.

Two critical issues identified:

  1. Security vulnerability: Using "secret" as the JWT secret is extremely insecure and predictable.
  2. Missing configuration: JWT_SECRET is only defined for the local environment but missing from staging and production.

For the local environment, use a stronger secret:

-        "JWT_SECRET": "secret",
+        "JWT_SECRET": "your-strong-local-jwt-secret-here",

You also need to add JWT_SECRET to staging and production environments with appropriate secure values. Consider using environment-specific secrets management.

🤖 Prompt for AI Agents
In apps/server/wrangler.jsonc at line 69, replace the weak JWT_SECRET value
"secret" with a strong, complex secret for the local environment. Additionally,
add JWT_SECRET entries with secure, environment-specific values for the staging
and production configurations to ensure proper security across all environments.
Use environment-specific secrets management practices to handle these sensitive
values safely.

Comment on lines +15 to +24
getIntercomToken: privateProcedure.query(async ({ ctx }) => {
const token = await jwt.sign(
{
user_id: ctx.session.user.id,
email: ctx.session.user.email,
},
ctx.c.env.JWT_SECRET,
);
return token;
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and security improvements for JWT generation

The JWT token generation implementation needs several improvements:

  1. Missing token expiration: JWT tokens should have an expiration time for security
  2. No error handling: JWT signing could fail and should be wrapped in try-catch
  3. Environment variable validation: Should validate that JWT_SECRET exists

Apply this diff to improve security and error handling:

  getIntercomToken: privateProcedure.query(async ({ ctx }) => {
+   if (!ctx.c.env.JWT_SECRET) {
+     throw new TRPCError({
+       code: 'INTERNAL_SERVER_ERROR',
+       message: 'JWT_SECRET not configured',
+     });
+   }
+   
+   try {
      const token = await jwt.sign(
        {
          user_id: ctx.session.user.id,
          email: ctx.session.user.email,
+         exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1 hour expiration
        },
        ctx.c.env.JWT_SECRET,
      );
      return token;
+   } catch (error) {
+     throw new TRPCError({
+       code: 'INTERNAL_SERVER_ERROR',
+       message: 'Failed to generate Intercom token',
+     });
+   }
  }),

Don't forget to import TRPCError at the top of the file:

-import { privateProcedure, router } from '../trpc';
+import { privateProcedure, router } from '../trpc';
+import { TRPCError } from '@trpc/server';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
getIntercomToken: privateProcedure.query(async ({ ctx }) => {
const token = await jwt.sign(
{
user_id: ctx.session.user.id,
email: ctx.session.user.email,
},
ctx.c.env.JWT_SECRET,
);
return token;
}),
// At the top of apps/server/src/trpc/routes/user.ts
import { privateProcedure, router } from '../trpc';
import { TRPCError } from '@trpc/server';
getIntercomToken: privateProcedure.query(async ({ ctx }) => {
// Validate that the secret is present
if (!ctx.c.env.JWT_SECRET) {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'JWT_SECRET not configured',
});
}
try {
const token = await jwt.sign(
{
user_id: ctx.session.user.id,
email: ctx.session.user.email,
// 1 hour expiration
exp: Math.floor(Date.now() / 1000) + 60 * 60,
},
ctx.c.env.JWT_SECRET,
);
return token;
} catch (error) {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'Failed to generate Intercom token',
});
}
}),
🤖 Prompt for AI Agents
In apps/server/src/trpc/routes/user.ts around lines 15 to 24, improve the JWT
token generation by adding an expiration time to the token payload, wrapping the
signing process in a try-catch block to handle potential errors, and validating
that the JWT_SECRET environment variable exists before signing. If JWT_SECRET is
missing, throw a TRPCError with an appropriate message. Also, ensure TRPCError
is imported at the top of the file.

Comment on lines +84 to +93
const { data: intercomToken } = useQuery(trpc.user.getIntercomToken.queryOptions());

React.useEffect(() => {
if (intercomToken) {
Intercom({
app_id: 'aavenrba',
intercom_user_jwt: intercomToken,
});
}
}, [intercomToken]);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Move hardcoded configuration to environment variables and add error handling

The Intercom integration has several issues:

  1. Hardcoded app_id: The Intercom app ID 'aavenrba' should be an environment variable
  2. No error handling: Missing error handling for token fetch failures
  3. No loading state: No handling for when the token is still loading

Consider this improved implementation:

- const { data: intercomToken } = useQuery(trpc.user.getIntercomToken.queryOptions());
+ const { data: intercomToken, error: tokenError, isLoading: tokenLoading } = useQuery(
+   trpc.user.getIntercomToken.queryOptions()
+ );

  React.useEffect(() => {
-   if (intercomToken) {
+   if (intercomToken && !tokenError && !tokenLoading) {
      Intercom({
-       app_id: 'aavenrba',
+       app_id: process.env.NEXT_PUBLIC_INTERCOM_APP_ID || 'aavenrba',
        intercom_user_jwt: intercomToken,
      });
+   } else if (tokenError) {
+     console.error('Failed to load Intercom token:', tokenError);
    }
- }, [intercomToken]);
+ }, [intercomToken, tokenError, tokenLoading]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data: intercomToken } = useQuery(trpc.user.getIntercomToken.queryOptions());
React.useEffect(() => {
if (intercomToken) {
Intercom({
app_id: 'aavenrba',
intercom_user_jwt: intercomToken,
});
}
}, [intercomToken]);
const { data: intercomToken, error: tokenError, isLoading: tokenLoading } = useQuery(
trpc.user.getIntercomToken.queryOptions()
);
React.useEffect(() => {
if (intercomToken && !tokenError && !tokenLoading) {
Intercom({
app_id: process.env.NEXT_PUBLIC_INTERCOM_APP_ID || 'aavenrba',
intercom_user_jwt: intercomToken,
});
} else if (tokenError) {
console.error('Failed to load Intercom token:', tokenError);
}
}, [intercomToken, tokenError, tokenLoading]);
🤖 Prompt for AI Agents
In apps/mail/components/ui/nav-main.tsx around lines 84 to 93, replace the
hardcoded Intercom app_id 'aavenrba' with a value read from an environment
variable. Add error handling to manage failures when fetching the intercomToken,
such as logging or displaying an error message. Also, implement a loading state
to handle the period when the token is being fetched before it is available.
Update the React.useEffect to only initialize Intercom when the token is
successfully fetched and handle cases where the token fetch fails or is loading.

Comment on lines +212 to +232
{isBottomNav ? (
<>
<SidebarMenuButton
onClick={() => show()}
tooltip={state === 'collapsed' ? t('help' as MessageKey) : undefined}
className="flex cursor-pointer items-center"
>
<MessageSquare className="relative mr-2.5 h-3 w-3.5" />
<p className="mt-0.5 truncate text-[13px]">Help</p>
</SidebarMenuButton>
<NavItem
key={'feedback'}
isActive={isUrlActive('https://feedback.0.email')}
href={'https://feedback.0.email'}
url={'https://feedback.0.email'}
icon={MessageSquare}
target={'_blank'}
title={'navigation.sidebar.feedback'}
/>
</>
) : null}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve consistency and configuration management in bottom navigation

Several inconsistencies and hardcoded values in the new bottom navigation:

  1. Inconsistent translation usage: "Help" is hardcoded while "Feedback" uses translation key
  2. Hardcoded feedback URL: Should be configurable
  3. No error handling: show() call could fail

Apply this diff to improve consistency:

            <SidebarMenuButton
              onClick={() => show()}
              tooltip={state === 'collapsed' ? t('help' as MessageKey) : undefined}
              className="flex cursor-pointer items-center"
            >
              <MessageSquare className="relative mr-2.5 h-3 w-3.5" />
-             <p className="mt-0.5 truncate text-[13px]">Help</p>
+             <p className="mt-0.5 truncate text-[13px]">{t('navigation.sidebar.help' as MessageKey)}</p>
            </SidebarMenuButton>
            <NavItem
              key={'feedback'}
-             isActive={isUrlActive('https://feedback.0.email')}
-             href={'https://feedback.0.email'}
-             url={'https://feedback.0.email'}
+             isActive={isUrlActive(process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email')}
+             href={process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email'}
+             url={process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email'}
              icon={MessageSquare}
              target={'_blank'}
              title={'navigation.sidebar.feedback'}
            />

Also consider wrapping the show() call in error handling:

-             onClick={() => show()}
+             onClick={() => {
+               try {
+                 show();
+               } catch (error) {
+                 console.error('Failed to show Intercom:', error);
+               }
+             }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{isBottomNav ? (
<>
<SidebarMenuButton
onClick={() => show()}
tooltip={state === 'collapsed' ? t('help' as MessageKey) : undefined}
className="flex cursor-pointer items-center"
>
<MessageSquare className="relative mr-2.5 h-3 w-3.5" />
<p className="mt-0.5 truncate text-[13px]">Help</p>
</SidebarMenuButton>
<NavItem
key={'feedback'}
isActive={isUrlActive('https://feedback.0.email')}
href={'https://feedback.0.email'}
url={'https://feedback.0.email'}
icon={MessageSquare}
target={'_blank'}
title={'navigation.sidebar.feedback'}
/>
</>
) : null}
{isBottomNav ? (
<>
<SidebarMenuButton
- onClick={() => show()}
+ onClick={() => {
+ try {
+ show();
+ } catch (error) {
+ console.error('Failed to show Intercom:', error);
+ }
+ }}
tooltip={state === 'collapsed' ? t('help' as MessageKey) : undefined}
className="flex cursor-pointer items-center"
>
<MessageSquare className="relative mr-2.5 h-3 w-3.5" />
- <p className="mt-0.5 truncate text-[13px]">Help</p>
+ <p className="mt-0.5 truncate text-[13px]">
+ {t('navigation.sidebar.help' as MessageKey)}
+ </p>
</SidebarMenuButton>
<NavItem
key={'feedback'}
- isActive={isUrlActive('https://feedback.0.email')}
- href={'https://feedback.0.email'}
- url={'https://feedback.0.email'}
+ isActive={isUrlActive(process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email')}
+ href={process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email'}
+ url={process.env.NEXT_PUBLIC_FEEDBACK_URL || 'https://feedback.0.email'}
icon={MessageSquare}
target={'_blank'}
title={'navigation.sidebar.feedback'}
/>
</>
) : null}
🤖 Prompt for AI Agents
In apps/mail/components/ui/nav-main.tsx around lines 212 to 232, fix
inconsistencies by replacing the hardcoded "Help" text with a translation key
similar to "Feedback" using the t() function. Make the feedback URL configurable
by moving it to a constant or config variable instead of hardcoding it. Wrap the
show() call inside a try-catch block to handle potential errors gracefully,
logging or managing errors as appropriate.

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.

2 participants