Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR refactors the authentication system by extracting form handling logic from page components into dedicated, reusable form components (ForgotPasswordForm, LoginForm, RegisterForm). Auth pages are converted to lightweight server-side components that render these forms. The AuthContext no longer displays a loading UI, and the auth/loading route is removed. A new AuthFormMotion component adds entrance animations to forms. Landing page imports are consolidated via a ClientDynamics barrel export. Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (4)
src/components/landing/ClientDynamics.tsx (1)
6-24: Consider adding loading fallbacks for content-heavy components.The dynamic imports work correctly, but
LookaheadDashboardandShowcaseSectionappear to be content-heavy sections. Without aloadingfallback, users may see empty space or layout shifts while these components load on the client.For decorative components like
HeroOrbsandScrollAnimations, omitting the fallback is fine.💡 Optional: Add skeleton/placeholder for content components
export const LookaheadDashboard = dynamic( () => import("./LookaheadPreview").then((m) => m.LookaheadDashboard), - { ssr: false }, + { ssr: false, loading: () => <div className="h-96 animate-pulse bg-white/5 rounded-xl" /> }, ); export const ShowcaseSection = dynamic( () => import("./ShowcaseSection").then((m) => m.ShowcaseSection), - { ssr: false }, + { ssr: false, loading: () => <div className="h-96 animate-pulse bg-white/5 rounded-xl" /> }, );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/ClientDynamics.tsx` around lines 6 - 24, LookaheadDashboard and ShowcaseSection are dynamically imported without a loading fallback, causing empty space/layout shifts while they load; update the dynamic(...) calls for LookaheadDashboard and ShowcaseSection to include a loading prop that returns a lightweight skeleton/placeholder component (or simple placeholder element) to render during client load, e.g., add loading: () => <YourSkeleton /> to the dynamic options and create or reuse a small Skeleton/Placeholder component to keep layout stable while LookaheadDashboard and ShowcaseSection hydrate.src/components/auth/RegisterForm.tsx (1)
112-131: Consider making inputs fully controlled by addingvalueprop.The Input components use
onChangeto update state but don't bind thevalueprop back toformData. This makes them partially uncontrolled, which can lead to state sync issues (e.g., if state is reset programmatically, the UI won't reflect it).Proposed fix to make inputs controlled
<Input id="firstName" name="firstName" placeholder="John" + value={formData.firstName} onChange={handleChange} required className="h-11 border-slate-200 focus-visible:ring-[var(--navy)]" /> </div> <div className="space-y-2"> <Label htmlFor="lastName">Last Name</Label> <Input id="lastName" name="lastName" placeholder="Doe" + value={formData.lastName} onChange={handleChange} required className="h-11 border-slate-200 focus-visible:ring-[var(--navy)]" />Apply the same pattern to all other inputs (
phone,password,confirmPassword).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/auth/RegisterForm.tsx` around lines 112 - 131, The Input elements (e.g., the Input with id/name "firstName" and "lastName") are currently updated via onChange/handleChange but lack a bound value, making them partially uncontrolled; update each Input to include value={formData.firstName} and value={formData.lastName} respectively (and similarly bind value for email, phone, password, confirmPassword) so the components are fully controlled by the formData state managed by handleChange and any programmatic resets will reflect in the UI.src/components/auth/LoginForm.tsx (1)
37-40: Consider refactoring to avoid eslint-disable.The suppressed
react-hooks/exhaustive-depswarning indicates a potential issue. The effect readserrorand callsclearErrorbut neither is in the dependency array. While the intent (clear error on input change) is valid, this can be achieved more cleanly.Alternative approach without eslint-disable
- // eslint-disable-next-line react-hooks/exhaustive-deps - useEffect(() => { - if (error) clearError(); - }, [email, password]); + const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => { + setEmail(e.target.value); + if (error) clearError(); + }; + + const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => { + setPassword(e.target.value); + if (error) clearError(); + };Then use
handleEmailChangeandhandlePasswordChangein the respective InputonChangehandlers instead of inline setters.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/auth/LoginForm.tsx` around lines 37 - 40, The useEffect currently reads error and calls clearError but suppresses react-hooks/exhaustive-deps; refactor by removing the effect and instead clear errors inside the input change handlers: add or update handleEmailChange and handlePasswordChange to call setEmail/setPassword and then call clearError() when error is present, and wire those handlers to the Input onChange props; remove the useEffect and the eslint-disable comment so clearError is invoked deterministically without missing dependencies.src/components/auth/ForgotPasswordForm.tsx (1)
60-65: Consider allowing retry after error.Currently, the form remains functional after an error, which is good. However, after success, the form is permanently disabled. Consider whether users should be able to request another email if they didn't receive the first one (perhaps after a delay/cooldown).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/auth/ForgotPasswordForm.tsx` around lines 60 - 65, The success branch in ForgotPasswordForm currently shows a success Alert and leaves the form permanently disabled because the UI relies on status.type === "success"; change the behavior so users can request another email by (1) removing permanent disablement tied directly to status.type === "success" in the submit/button disabled logic (update the condition in the component where form submission is blocked), (2) implement a cooldown/resend flow by adding a resend action or timer that resets status (use setStatus or the existing status state) after a configurable delay, and (3) optionally surface a "Resend email" button that calls the same submit handler (or a dedicated resendEmail function) and respects the cooldown to prevent spamming; reference the ForgotPasswordForm component, status (and setStatus) state, and the submit handler to locate and update the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/components/auth/ForgotPasswordForm.tsx`:
- Around line 60-65: The success branch in ForgotPasswordForm currently shows a
success Alert and leaves the form permanently disabled because the UI relies on
status.type === "success"; change the behavior so users can request another
email by (1) removing permanent disablement tied directly to status.type ===
"success" in the submit/button disabled logic (update the condition in the
component where form submission is blocked), (2) implement a cooldown/resend
flow by adding a resend action or timer that resets status (use setStatus or the
existing status state) after a configurable delay, and (3) optionally surface a
"Resend email" button that calls the same submit handler (or a dedicated
resendEmail function) and respects the cooldown to prevent spamming; reference
the ForgotPasswordForm component, status (and setStatus) state, and the submit
handler to locate and update the code.
In `@src/components/auth/LoginForm.tsx`:
- Around line 37-40: The useEffect currently reads error and calls clearError
but suppresses react-hooks/exhaustive-deps; refactor by removing the effect and
instead clear errors inside the input change handlers: add or update
handleEmailChange and handlePasswordChange to call setEmail/setPassword and then
call clearError() when error is present, and wire those handlers to the Input
onChange props; remove the useEffect and the eslint-disable comment so
clearError is invoked deterministically without missing dependencies.
In `@src/components/auth/RegisterForm.tsx`:
- Around line 112-131: The Input elements (e.g., the Input with id/name
"firstName" and "lastName") are currently updated via onChange/handleChange but
lack a bound value, making them partially uncontrolled; update each Input to
include value={formData.firstName} and value={formData.lastName} respectively
(and similarly bind value for email, phone, password, confirmPassword) so the
components are fully controlled by the formData state managed by handleChange
and any programmatic resets will reflect in the UI.
In `@src/components/landing/ClientDynamics.tsx`:
- Around line 6-24: LookaheadDashboard and ShowcaseSection are dynamically
imported without a loading fallback, causing empty space/layout shifts while
they load; update the dynamic(...) calls for LookaheadDashboard and
ShowcaseSection to include a loading prop that returns a lightweight
skeleton/placeholder component (or simple placeholder element) to render during
client load, e.g., add loading: () => <YourSkeleton /> to the dynamic options
and create or reuse a small Skeleton/Placeholder component to keep layout stable
while LookaheadDashboard and ShowcaseSection hydrate.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
src/app/(auth)/forgot-password/page.tsxsrc/app/(auth)/loading.tsxsrc/app/(auth)/login/page.tsxsrc/app/(auth)/register/page.tsxsrc/app/(dashboard)/layout.tsxsrc/app/context/AuthContext.tsxsrc/components/auth/AuthFormMotion.tsxsrc/components/auth/ForgotPasswordForm.tsxsrc/components/auth/LoginForm.tsxsrc/components/auth/RegisterForm.tsxsrc/components/landing/ClientDynamics.tsxsrc/components/landing/LandingPage.tsx
💤 Files with no reviewable changes (2)
- src/app/(auth)/loading.tsx
- src/app/context/AuthContext.tsx
Summary by CodeRabbit
New Features
Improvements