Skip to content

Fix flicker#1143

Merged
elie222 merged 2 commits intomainfrom
fix/time-flicker
Dec 31, 2025
Merged

Fix flicker#1143
elie222 merged 2 commits intomainfrom
fix/time-flicker

Conversation

@elie222
Copy link
Copy Markdown
Owner

@elie222 elie222 commented Dec 31, 2025

Generated description

Below is a concise technical summary of the changes proposed in this PR:

graph LR
TimeDurationSetting_("TimeDurationSetting"):::modified
toastSuccess_("toastSuccess"):::modified
LOADING_MINI_SPINNER_("LOADING_MINI_SPINNER"):::modified
TOAST_("TOAST"):::modified
TimeDurationSetting_ -- "Passes id 'time-duration-saved' when calling toastSuccess." --> toastSuccess_
TimeDurationSetting_ -- "Shows LoadingMiniSpinner inline during form submission." --> LOADING_MINI_SPINNER_
toastSuccess_ -- "Forwards optional id parameter to toast.success for identification." --> TOAST_
classDef added stroke:#15AA7A
classDef removed stroke:#CD5270
classDef modified stroke:#EDAC4C
linkStyle default stroke:#CBD5E1,font-size:13px
Loading

Refactor the TimeDurationSetting component to eliminate UI flicker by removing an unnecessary useEffect hook that caused form state resets, and enhance toast notifications by adding an optional id for better management. Optimize the BriefsOnboarding component by removing unused imports and components, contributing to a cleaner and potentially more performant UI.

TopicDetails
Fix Time Setting Flicker Address UI flicker in the TimeDurationSetting component by removing a useEffect hook that was causing unnecessary form state resets and re-renders, and improve the placement of the LoadingMiniSpinner. Additionally, enhance the toastSuccess utility by allowing an optional id to be passed for better toast management.
Modified files (2)
  • apps/web/components/Toast.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
Latest Contributors(2)
UserCommitDate
elie222fixDecember 15, 2025
eliesteinbock@gmail.comstore-costsAugust 16, 2023
Optimize Onboarding UI Clean up the BriefsOnboarding component by removing unused imports and components, which helps reduce bundle size and potentially improves rendering performance.
Modified files (1)
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
Latest Contributors(1)
UserCommitDate
elie222show-onboarding-in-dis...December 31, 2025
This pull request is reviewed by Baz. Review like a pro on (Baz).

Summary by CodeRabbit

  • New Features

    • Added visual loading indicator when saving time duration settings.
  • Refactor

    • Optimized component imports and dependencies across briefs components.
    • Enhanced toast notification system to prevent duplicate success messages.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
inbox-zero Ready Ready Preview Dec 31, 2025 10:28am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 31, 2025

📝 Walkthrough

Walkthrough

This PR refactors three interconnected components: removes Card wrapper and consolidates imports in Onboarding.tsx, simplifies state management in TimeDurationSetting.tsx by removing useEffect and restructuring the loading indicator, and extends toastSuccess in Toast.tsx to accept an optional id parameter for toast persistence control.

Changes

Cohort / File(s) Summary
Onboarding UI Refactoring
apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
Removed Card component wrapper (kept CardHeader, CardContent, CardFooter, CardTitle, CardDescription); consolidated typography imports; removed lucide-icons barrel imports and filtered to specific icons (UserIcon, MailIcon, LightbulbIcon); removed IconCircle; trimmed Item subcomponents (removed ItemActions).
TimeDurationSetting State & UX
apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
Removed useEffect and form reset logic that synchronized local state with server values; added persistent toast id (id: "time-duration-saved"); relocated LoadingMiniSpinner from form end to new div at form start; simplified useForm destructuring.
Toast Enhancement
apps/web/components/Toast.tsx
Extended toastSuccess function signature to accept optional id?: string parameter, enabling persistent toast identification.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • Add meeting brief onboarding #1142: Directly modifies the BriefsOnboarding component introduced in that PR—this PR's removal of Card wrapper and import consolidation directly impacts the same component.
  • Reorder feature cards on welcome #552: Related through Card-component refactoring patterns—this PR removes Card wrapper usage while the other PR introduces SettingCard as a replacement strategy.

Poem

🐰 A bundled Card now hops away,
State syncs fade with useEffect's delay,
Toast IDs persist, bold and bright,
Spinners spin early, loading done right!
~Whiskers✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Fix flicker' is vague and generic, lacking specificity about which component or feature is affected by the flicker issue. Consider using a more descriptive title such as 'Fix time duration form flicker by removing useEffect sync' or 'Remove useEffect-based state sync to fix UI flicker' to clarify the specific issue and solution.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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

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

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Dec 31, 2025

Move the loading spinner to a fixed leading column and assign toast success id "time-duration-saved" in TimeDurationSetting to fix flicker in briefs settings

Refactor TimeDurationSetting to remove useEffect-based state resets, place the spinner in a fixed-width leading container, and pass an optional id through Toast.toastSuccess.

📍Where to Start

Start with the form submit and state handling in TimeDurationSetting.tsx, then review toastSuccess changes in Toast.tsx.


📊 Macroscope summarized 8a573d2. 2 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted. View details

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

reset({ minutesBefore: initialMinutes });
}, [initialMinutes, reset, isExecuting]);

return (
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.

The UI can show stale values after initialMinutes changes because the useEffect that synced value/unit (and called reset) was removed. Consider re-adding that sync so the input/select reflect server updates; if this is intentional, consider documenting the rationale.

🚀 Want me to fix this? Reply ex: "fix it for me".

Copy link
Copy Markdown
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx (1)

35-100: Critical: CardHeader, CardContent, and CardFooter must be wrapped in a Card component.

The Card subcomponents are being used without their parent Card wrapper, which breaks shadcn/ui's component composition pattern. These subcomponents depend on CSS context from the Card parent, and their absence is likely causing the "flicker" issue mentioned in the PR title.

🔎 Proposed fix: Add Card wrapper

First, add the Card import at the top of the file:

 import {
+  Card,
   CardContent,
   CardHeader,
   CardFooter,
   CardTitle,
   CardDescription,
 } from "@/components/ui/card";

Then wrap the Card subcomponents with the Card component:

   return (
     <div className="mx-4 mt-10 max-w-2xl md:mx-auto">
+      <Card>
         <CardHeader>
           <CardTitle>Meeting Briefs</CardTitle>
           <CardDescription>
             Receive email briefings before meetings with external guests.
           </CardDescription>
         </CardHeader>

         <CardContent>
           <ItemGroup className="grid gap-2">
             <Item variant="outline">
               <ItemMedia variant="icon" className="bg-blue-50">
                 <UserIcon className="text-blue-600" />
               </ItemMedia>
               <ItemContent>
                 <ItemTitle>Attendee research</ItemTitle>
                 <ItemDescription>
                   Who they are, their company, and role
                 </ItemDescription>
               </ItemContent>
             </Item>
             <Item variant="outline">
               <ItemMedia variant="icon" className="bg-blue-50">
                 <MailIcon className="text-blue-600" />
               </ItemMedia>
               <ItemContent>
                 <ItemTitle>Email history</ItemTitle>
                 <ItemDescription>
                   Recent conversations with this person
                 </ItemDescription>
               </ItemContent>
             </Item>
             <Item variant="outline">
               <ItemMedia variant="icon" className="bg-blue-50">
                 <LightbulbIcon className="text-blue-600" />
               </ItemMedia>
               <ItemContent>
                 <ItemTitle>Key context</ItemTitle>
                 <ItemDescription>
                   Important details from past discussions
                 </ItemDescription>
               </ItemContent>
             </Item>
           </ItemGroup>
         </CardContent>

         <CardFooter className="flex flex-col items-center gap-4">
           {hasCalendarConnected ? (
             <>
               <MessageText>
                 You're all set! Enable meeting briefs to get started:
               </MessageText>
               <Button onClick={onEnable} loading={isEnabling}>
                 Enable Meeting Briefs
               </Button>
             </>
           ) : (
             <>
               <MessageText>Connect your calendar to get started:</MessageText>
               <ConnectCalendar
                 onboardingReturnPath={`/${emailAccountId}/briefs`}
               />
             </>
           )}
         </CardFooter>
+      </Card>
     </div>
   );

Based on learnings: shadcn/ui components should be used following their proper composition patterns.

🧹 Nitpick comments (1)
apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx (1)

103-105: Effective flicker fix with reserved spinner space.

The fixed-width container (w-5) prevents layout shift by always reserving space for the loading indicator, directly addressing the PR objective. This is a clean solution to the flicker problem.

Optional: Consider adding accessibility attributes

For screen reader users, consider adding aria-busy to the form when isExecuting is true:

 <form
   className="flex items-center gap-1"
   onSubmit={handleSubmit(onSubmit, onError)}
+  aria-busy={isExecuting}
 >

This would announce the submitting state to assistive technology.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffaf603 and 8a573d2.

📒 Files selected for processing (3)
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/components/Toast.tsx
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)

**/*.{ts,tsx}: For API GET requests to server, use the swr package
Use result?.serverError with toastError from @/components/Toast for error handling in async operations

**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls

**/*.{ts,tsx}: For early access feature flags, create hooks using the naming convention use[FeatureName]Enabled that return a boolean from useFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming convention use[FeatureName]Variant that define variant types, use useFeatureFlagVariantKey() with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g., inbox-cleaner, pricing-options-2)
Always define types for A/B test variant flags (e.g., type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting

**/*.{ts,tsx}: Don't use primitive type aliases or misleading types
Don't use empty type parameters in type aliases and interfaces
Don't use this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions
Don't use TypeScript namespaces
Don't use non-null assertions with the ! postfix operator
Don't use parameter properties in class constructors
Don't use user-defined types
Use as const instead of literal types and type annotations
Use either T[] or Array<T> consistently
Initialize each enum member value explicitly
Use export type for types
Use `impo...

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/app/(app)/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/page-structure.mdc)

apps/web/app/(app)/**/*.{ts,tsx}: Components for the page are either put in page.tsx, or in the apps/web/app/(app)/PAGE_NAME folder
If we're in a deeply nested component we will use swr to fetch via API
If you need to use onClick in a component, that component is a client component and file must start with use client

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)

Always import Prisma enums from @/generated/prisma/enums instead of @/generated/prisma/client to avoid Next.js bundling errors in client components

Import Prisma using the project's centralized utility: import prisma from '@/utils/prisma'

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Do not export types/interfaces that are only used within the same file. Export later if needed

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Use next/image package for images
For API GET requests to server, use the swr package with hooks like useSWR to fetch data
For text inputs, use the Input component with registerProps for form integration and error handling

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Implement responsive design with Tailwind CSS using a mobile-first approach

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.tsx: Use the LoadingContent component to handle loading states instead of manual loading state management
For text areas, use the Input component with type='text', autosizeTextarea prop set to true, and registerProps for form integration

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,jsx,ts,tsx}: Don't use accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like <marquee> or <blink>
Only use the scope prop on <th> elements
Don't assign non-interactive ARIA roles to interactive HTML elements
Make sure label elements have text content and are associated with an input
Don't assign interactive ARIA roles to non-interactive HTML elements
Don't assign tabIndex to non-interactive HTML elements
Don't use positive integers for tabIndex property
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include a title element for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a lang attribute on the html element
Always include a title attribute for iframe elements
Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
Make sure all anchors are valid and navigable
Ensure all ARIA properties (aria-*) are valid
Use valid, non-abstract ARIA roles for elements with ARIA roles
Use valid AR...

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{jsx,tsx}: Don't use unnecessary fragments
Don't pass children as props
Don't use the return value of React.render
Make sure all dependencies are correctly specified in React hooks
Make sure all React hooks are called from the top level of component functions
Don't forget key props in iterators and collection literals
Don't define React components inside other components
Don't use event handlers on non-interactive elements
Don't assign to React component props
Don't use both children and dangerouslySetInnerHTML props on the same element
Don't use dangerous JSX props
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Don't add extra closing tags for components without children
Use <>...</> instead of <Fragment>...</Fragment>
Watch out for possible "wrong" semicolons inside JSX elements
Make sure void (self-closing) elements don't have children
Don't use target="_blank" without rel="noopener"
Don't use <img> elements in Next.js projects
Don't use <head> elements in Next.js projects

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
!(pages/_document).{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

Don't use the next/head module in pages/_document.js on Next.js projects

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)

**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{ts,tsx,js,jsx}: Use @/ path aliases for imports from project root
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
All imports go at the top of files, no mid-file dynamic imports

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Follow NextJS app router structure with (app) directory

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
apps/web/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{tsx,jsx}: Follow tailwindcss patterns with prettier-plugin-tailwindcss for class sorting
Prefer functional components with hooks in React
Use shadcn/ui components when available
Ensure responsive design with mobile-first approach in components
Follow consistent naming conventions using PascalCase for components
Use LoadingContent component for async data with loading and error states
Use React Hook Form with Zod validation for form handling
Use result?.serverError with toastError and toastSuccess for error handling in forms

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/**/*.{ts,tsx,js,jsx,json,css}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Format code with Prettier

Files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
  • apps/web/components/Toast.tsx
apps/web/components/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/fullstack-workflow.mdc)

Use LoadingContent component to consistently handle loading and error states, passing loading, error, and children props

Use PascalCase for component file names (e.g., components/Button.tsx)

Files:

  • apps/web/components/Toast.tsx
**/{pages,routes,components}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/gmail-api.mdc)

Never call Gmail API directly from routes or components - always use wrapper functions from the utils folder

Files:

  • apps/web/components/Toast.tsx
🧠 Learnings (29)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-11-25T14:36:36.276Z
Learning: Applies to **/*.{ts,tsx} : Import error and success toast utilities from '@/components/Toast' for displaying notifications
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/components/**/*Form*.tsx : Handle form submission results using `result?.serverError` to show error toasts and `toastSuccess` to show success messages after server action completion
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/components/**/*Form*.tsx : Handle form submission results using `result?.serverError` to show error toasts and `toastSuccess` to show success messages after server action completion

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/components/Toast.tsx
📚 Learning: 2025-12-21T12:21:37.794Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-21T12:21:37.794Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Use `result?.serverError` with `toastError` and `toastSuccess` for error handling in forms

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/components/Toast.tsx
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/components/**/*Form*.tsx : Use React Hook Form with Zod validation (`zodResolver`) for form handling, with form components using `register`, `handleSubmit`, and error handling from the hook

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*Form.{ts,tsx} : Validate form inputs before submission using React Hook Form and Zod resolver

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*Form.{ts,tsx} : Use React Hook Form with Zod for form validation

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:36:53.147Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:53.147Z
Learning: Applies to **/*Form.{ts,tsx} : Use React Hook Form with Zod for validation in form components

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-12-21T12:21:37.794Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-21T12:21:37.794Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Use React Hook Form with Zod validation for form handling

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-09T19:50:05.292Z
Learnt from: ppranay20
Repo: elie222/inbox-zero PR: 935
File: apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx:367-369
Timestamp: 2025-11-09T19:50:05.292Z
Learning: In React Hook Form, when using `useMemo` or `useEffect` with form errors, always use `formState` as the dependency rather than `errors` or `formState.errors`. This is because React Hook Form uses a Proxy pattern where the errors object is mutable and won't trigger dependency arrays correctly. The formState dependency ensures proper reactivity when form validation state changes.

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : For text inputs in forms, use the `Input` component with `type='email'`, `name`, `label`, `registerProps` from react-hook-form, and `error` props

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : For text areas in forms, use the `Input` component with `type='text'`, `autosizeTextarea` prop, `rows`, `name`, `placeholder`, `registerProps` from react-hook-form, and `error` props

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:38:56.992Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T14:38:56.992Z
Learning: Components with `onClick` handlers must be client components marked with the `use client` directive

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/utils/actions/*.validation.ts : Export types from Zod schemas using `z.infer<>` to maintain type safety between validation and client usage

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:36:53.147Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:53.147Z
Learning: Applies to **/*Form.{ts,tsx} : Validate form inputs before submission

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : Use the `LoadingContent` component to handle loading states

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-12-21T12:21:37.794Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-21T12:21:37.794Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Use LoadingContent component for async data with loading and error states

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/components/**/*.tsx : Use `LoadingContent` component to consistently handle loading and error states, passing `loading`, `error`, and `children` props

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-11-25T14:40:15.063Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:15.063Z
Learning: Applies to **/*.tsx : Use the `LoadingContent` component to handle loading states instead of manual loading state management

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx
📚 Learning: 2025-12-21T12:21:37.794Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-21T12:21:37.794Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Use shadcn/ui components when available

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:38:56.992Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-25T14:38:56.992Z
Learning: Applies to apps/web/components/ui/**/*.tsx : Shadcn UI components are located in `components/ui` directory

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:38:23.265Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/page-structure.mdc:0-0
Timestamp: 2025-11-25T14:38:23.265Z
Learning: Applies to apps/web/app/(app)/**/*.{ts,tsx} : If you need to use `onClick` in a component, that component is a client component and file must start with `use client`

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:38:18.874Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/page-structure.mdc:0-0
Timestamp: 2025-11-25T14:38:18.874Z
Learning: Applies to apps/web/app/(app)/**/*.tsx : If you need to use `onClick` in a component, that component must be a client component and file must start with `use client` directive

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : Use Shadcn UI and Tailwind for components and styling

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.ts : Use `actionClient` when both authenticated user context and a specific emailAccountId are needed, with emailAccountId bound when calling from the client

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:42:11.919Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-11-25T14:42:11.919Z
Learning: Applies to utils/**/*.{js,ts,jsx,tsx} : The `utils` folder contains core app logic such as Next.js Server Actions and Gmail API requests

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:40:15.063Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:15.063Z
Learning: Applies to **/*.{tsx,ts} : Use Shadcn UI and Tailwind for components and styling

Applied to files:

  • apps/web/app/(app)/[emailAccountId]/briefs/Onboarding.tsx
📚 Learning: 2025-11-25T14:36:36.276Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-11-25T14:36:36.276Z
Learning: Applies to **/*.{ts,tsx} : Import error and success toast utilities from '@/components/Toast' for displaying notifications

Applied to files:

  • apps/web/components/Toast.tsx
📚 Learning: 2025-11-25T14:36:40.146Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-11-25T14:36:40.146Z
Learning: Applies to **/*.{ts,tsx} : Use `result?.serverError` with `toastError` from `@/components/Toast` for error handling in async operations

Applied to files:

  • apps/web/components/Toast.tsx
📚 Learning: 2025-11-25T14:36:36.276Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-11-25T14:36:36.276Z
Learning: Applies to **/*.{ts,tsx} : Use `result?.serverError` with `toastError` and `toastSuccess` for error handling in server actions

Applied to files:

  • apps/web/components/Toast.tsx
🧬 Code graph analysis (1)
apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx (2)
apps/web/utils/actions/meeting-briefs.validation.ts (2)
  • UpdateMeetingBriefsMinutesBeforeBody (15-17)
  • updateMeetingBriefsMinutesBeforeBody (11-13)
apps/web/components/Toast.tsx (1)
  • toastSuccess (3-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Baz Reviewer
  • GitHub Check: Macroscope - Correctness Check
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/web/components/Toast.tsx (1)

3-12: LGTM! Clean addition of toast persistence control.

The optional id parameter allows callers to control toast deduplication and persistence. The implementation correctly passes it through to the underlying toast.success() call while maintaining backward compatibility.

apps/web/app/(app)/[emailAccountId]/briefs/TimeDurationSetting.tsx (3)

76-79: Good addition of persistent toast ID.

Using id: "time-duration-saved" prevents duplicate success toasts when users make rapid setting changes. This leverages the enhanced toastSuccess signature from Toast.tsx.


94-94: Clean consolidation of form value update.

The single-line call with explicit shouldValidate: true is clear and maintains proper validation timing before submission.


3-3: Parent component does receive updated initialMinutes after save, but it's not problematic.

The parent uses SWR to fetch settings. When onSaved() calls mutate(), it refetches the API data and the initialMinutes prop updates. However, the local state (value, unit) already reflects the user's input before the save completes, so the component doesn't need to re-sync on prop changes. The PR successfully eliminates the flicker without introducing issues.

@elie222 elie222 merged commit 71635d1 into main Dec 31, 2025
21 checks passed
This was referenced Dec 31, 2025
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.

1 participant