Skip to content

[PB-5978]: feat(mail)/frozen account state#53

Open
jzunigax2 wants to merge 4 commits into
masterfrom
feat/disabled-account-state
Open

[PB-5978]: feat(mail)/frozen account state#53
jzunigax2 wants to merge 4 commits into
masterfrom
feat/disabled-account-state

Conversation

@jzunigax2
Copy link
Copy Markdown
Contributor

@jzunigax2 jzunigax2 commented May 8, 2026

Added account suspended notification to the sidebar. Locked some actions when account status is suspended

@jzunigax2 jzunigax2 self-assigned this May 8, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 11, 2026

Deploying mail-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: 05bbaea
Status: ✅  Deploy successful!
Preview URL: https://33c4d3d3.mail-web-ea0.pages.dev
Branch Preview URL: https://feat-disabled-account-state.mail-web-ea0.pages.dev

View logs

@jzunigax2 jzunigax2 force-pushed the feat/disabled-account-state branch from 65b05ed to 99d313d Compare May 12, 2026 15:57
@jzunigax2 jzunigax2 marked this pull request as ready for review May 12, 2026 16:28
@jzunigax2 jzunigax2 requested a review from xabg2 as a code owner May 12, 2026 16:28
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack

Warning

Rate limit exceeded

@jzunigax2 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2d6fa17d-6f59-4fce-b869-a5ae6c52ace6

📥 Commits

Reviewing files that changed from the base of the PR and between 99d313d and 05bbaea.

📒 Files selected for processing (3)
  • src/components/Sidenav/index.tsx
  • src/components/Sidenav/useSidenavData.ts
  • src/utils/days-until/index.ts
📝 Walkthrough

Walkthrough

This PR implements mail account suspension detection and UI handling. It fetches the current mail account status via a new service method, calculates days until account deletion, displays a suspension notification in the sidenav with the countdown, and provides translated messages across four languages. The sidenav disables the compose button when mail is suspended.

Changes

Mail Account Status & Suspension Handling

Layer / File(s) Summary
Mail Service & Type Definitions
src/services/sdk/mail/index.ts, src/services/sdk/mail/mail.service.test.ts
MailService.getMe() method and MailMeResponse type alias fetch the current mail account; tests verify behavior for active and suspended accounts.
Days-Until-Deletion Utility
src/utils/days-until/index.ts, src/utils/days-until/daysUntil.test.ts
getDaysUntil calculates remaining days until a target date with ceiling rounding and edge-case handling.
Error Type for Status Fetch Failures
src/errors/mail/index.ts
FetchMailMeError class provides typed error handling for mail status query failures.
RTK Query Endpoint & Hook
src/store/api/base.ts, src/store/api/mail/index.ts, src/store/api/mail/mail.api.test.ts
getMailMe endpoint wires MailService.getMe() into RTK Query, maps failures to FetchMailMeError, exports useGetMailMeQuery hook, and includes MailMe cache tag.
Sidenav UI & Multi-Language Notifications
src/components/Sidenav/index.tsx, src/hooks/navigation/useSidenavNavigation.tsx, src/i18n/locales/*
Sidenav queries mail status via hook, disables compose button when suspended, renders notification with days-until-deletion, and displays translated mailDowngraded message across four languages. Simplified SidenavOption import path.
Dependency Version Updates
package.json
Bumped @internxt/sdk and @internxt/ui to newer patch/minor versions.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested Reviewers

  • xabg2
  • larryrider
  • CandelR
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(mail)/frozen account state' clearly describes the main change: adding functionality to handle a frozen/suspended mail account state.
Description check ✅ Passed The description is directly related to the changeset, explaining that account suspended notifications were added to the sidebar and actions are locked when the account is suspended.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/disabled-account-state

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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.

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Sidenav/index.tsx`:
- Around line 24-27: Extract the data fetching and derived UI state from Sidenav
into a hook (e.g., create useMailAccountState or useSidenavData) so the
component remains presentational: move the useGetMailMeQuery() call and derived
values isMailDisabled, daysUntilDeletion (derived via
getDaysUntil(mailMe?.deletionAt)), and storagePercentage (derived from planUsage
and planLimit) into that hook, have the hook return plain values/booleans
(mailMe, isMailDisabled, daysUntilDeletion, storagePercentage, planUsage,
planLimit) and any callbacks, then replace the in-component logic in Sidenav
with a single call to the new hook and pass the returned values as props to the
render layer; update any other similar logic around lines 76-85 into the same or
another focused use... hook following the same pattern.
- Around line 79-82: The CTA's onAction is currently a no-op and should invoke
the real upgrade flow; replace the empty handler assigned to onAction with a
call that opens your app's upgrade UI (for example call an existing helper like
openUpgradeModal(), openBillingPortal(), or dispatch a navigation such as
router.push('/settings/billing')), ensuring you import or access that function
inside the Sidenav component and pass any required params; update the onAction
reference (the handler on the message created with
translate('mailDowngraded.message'...)) to invoke that real upgrade function
instead of () => {} so the warning button actually starts the upgrade flow.

In `@src/utils/days-until/index.ts`:
- Around line 3-4: The getDaysUntil function currently computes days for any
string and can return NaN for unparseable dates; update getDaysUntil to first
parse the input (e.g., const ts = Date.parse(date) or new Date(date).getTime()),
check Number.isFinite(ts) or !Number.isNaN(ts), and if the parse fails return
undefined; otherwise use ts and MS_PER_DAY in the Math.max/Math.ceil calculation
so invalid date strings do not propagate NaN to callers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b187cb78-a03d-40ee-b0cf-5170ddddf4e1

📥 Commits

Reviewing files that changed from the base of the PR and between c2fa38a and 99d313d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • package.json
  • src/components/Sidenav/index.tsx
  • src/errors/mail/index.ts
  • src/hooks/navigation/useSidenavNavigation.tsx
  • src/i18n/locales/en.json
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/it.json
  • src/services/sdk/mail/index.ts
  • src/services/sdk/mail/mail.service.test.ts
  • src/store/api/base.ts
  • src/store/api/mail/index.ts
  • src/store/api/mail/mail.api.test.ts
  • src/utils/days-until/daysUntil.test.ts
  • src/utils/days-until/index.ts

Comment thread src/components/Sidenav/index.tsx Outdated
Comment thread src/components/Sidenav/index.tsx
Comment thread src/utils/days-until/index.ts Outdated
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
57.1% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

isLoadingPlanLimit,
isLoadingPlanUsage,
storagePercentage,
} = useSidenavData();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀

expect(mockMailClient.getMailAccount).toHaveBeenCalledOnce();
});

test('When fetching the mail account and it is suspended, then suspendedAt and deletionAt should be present', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid using technical descriptions. When fetching the mail account and it is suspended, then the date when it was suspended and it will be deleted are present

expect(result.data).toStrictEqual(mockAccount);
});

test('When fetching the mail account fails, then a FetchMailMeError should be returned', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can use an error indicating so is thrown

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