feat: Redesign auth pages (Login/Signup)#217
Conversation
- LoginForm: theme tokens, floating orbs, glassmorphism card - SignupForm: same design + benefits list - use shared Navbar component - indigo accent instead of blue - light/dark mode support - lucide icons (Mail, Lock, etc) - motion animations on mount - GitHub OAuth button placeholder (coming soon)
- remove floating gradient orbs - remove welcome/get started badges - remove glassmorphism blur - remove grid pattern background - remove framer-motion animations - remove benefits checklist - keep: clean form, icon inputs, GitHub button, theme support - Linear/Vercel inspired - just the form, nothing else
|
@DevanshuNEU is attempting to deploy a commit to the Dev's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📝 WalkthroughWalkthroughLoginForm and SignupForm were rewritten to use shared UI components and a landing Navbar, replaced custom icons with lucide-react icons, updated typography and tokens, and preserved existing form control flow (state, validation, submission, navigation, and error handling). Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related Issues
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
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/components/auth/SignupForm.tsx`:
- Around line 136-141: The SignupForm.tsx contains Link components pointing to
"/terms" and "/privacy" which are not defined in the app router; add routes for
these paths or change the links to external URLs. Either create new components
(e.g., TermsPage and PrivacyPage) and register them in the router defined in
App.tsx (or the routing module) with paths "/terms" and "/privacy", or update
the Link targets in SignupForm.tsx to the correct external URLs; ensure the Link
import and route names match existing router conventions so navigation doesn't
produce 404s.
🧹 Nitpick comments (4)
frontend/src/components/auth/LoginForm.tsx (2)
77-82: Non-functional "Forgot password?" button may confuse users.This button has no
onClickhandler and will do nothing when clicked, which could frustrate users. Since the PR notes password reset is planned for a separate PR, consider either disabling the button or making it visually distinct as a placeholder.💡 Option: Disable the button or add a tooltip
<button type="button" + disabled className="text-xs text-muted-foreground hover:text-foreground transition-colors" + title="Coming soon" > Forgot password? </button>Alternatively, convert to plain text until the feature is ready:
- <button - type="button" - className="text-xs text-muted-foreground hover:text-foreground transition-colors" - > - Forgot password? - </button> + <span className="text-xs text-muted-foreground"> + Forgot password? + </span>
27-28: Consider usingunknowntype in catch block.Using
err: anybypasses TypeScript's type checking. A safer pattern isunknownwith a type guard, though this is a common pragmatic choice in React codebases.💡 Type-safe error handling
- } catch (err: any) { - setError(err.message || 'Login failed') + } catch (err: unknown) { + const message = err instanceof Error ? err.message : 'Login failed' + setError(message)frontend/src/components/auth/SignupForm.tsx (2)
38-39: Same type safety consideration as LoginForm.For consistency, consider applying the same
unknowntype pattern if you update LoginForm.💡 Type-safe error handling
- } catch (err: any) { - setError(err.message || 'Signup failed') + } catch (err: unknown) { + const message = err instanceof Error ? err.message : 'Signup failed' + setError(message)
1-175: Consider extracting shared patterns between LoginForm and SignupForm.Both forms share significant structural patterns: the icon input wrapper, the "or" divider, and the GitHub OAuth placeholder button. While acceptable for two files, this could be extracted into shared components if more auth-related forms are planned.
This is a low-priority refactor that could be addressed in a future cleanup PR if the codebase grows:
IconInputcomponent for the icon-prefixed input patternOAuthSectioncomponent for the divider and social login buttons
|
@coderabbitai Good catch! Fixed in e4e8f5f - using placeholder |
|
Tip For best results, initiate chat on the files or code changes.
If you'd like, I can help you create a GitHub issue to track the Terms of Service and Privacy Policy pages for the future PR. Just let me know! |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/components/auth/SignupForm.tsx`:
- Around line 35-40: The catch currently types the error as any and reads
err.message directly; change the catch parameter to err: unknown and narrow it
(e.g., if (err instanceof Error) setError(err.message) else setError(String(err)
|| 'Signup failed')) inside the SignupForm signUp call so setError always
receives a safe string; update the try/catch around signUp(email, password) and
keep navigate('/dashboard') on success.
| try { | ||
| await signUp(email, password); | ||
| navigate('/dashboard'); | ||
| await signUp(email, password) | ||
| navigate('/dashboard') | ||
| } catch (err: any) { | ||
| setError(err.message || 'Signup failed'); | ||
| setError(err.message || 'Signup failed') | ||
| } finally { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "SignupForm.tsx" -type fRepository: OpenCodeIntel/opencodeintel
Length of output: 116
🏁 Script executed:
cat -n ./frontend/src/components/auth/SignupForm.tsxRepository: OpenCodeIntel/opencodeintel
Length of output: 7510
🏁 Script executed:
find . -name "AuthContext*" -type fRepository: OpenCodeIntel/opencodeintel
Length of output: 110
🏁 Script executed:
cat -n ./frontend/src/contexts/AuthContext.tsxRepository: OpenCodeIntel/opencodeintel
Length of output: 2989
🌐 Web query:
TypeScript best practice catch unknown error narrowing pattern
💡 Result:
Best-practice pattern: treat caught values as unknown, then narrow with runtime checks
- Make
catchvariablesunknown(recommended)
- Enable
useUnknownInCatchVariables(enabled by--strict) socatch (err)is typed asunknown, forcing safe narrowing. [1]
- Narrow safely inside
catch
try {
doThing();
} catch (err: unknown) {
if (err instanceof Error) {
// ✅ now you can use err.message, err.stack, etc.
console.error(err.message);
} else {
// ✅ handle non-Error throws (strings, objects, numbers, etc.)
console.error("Non-Error thrown:", err);
}
}TypeScript explicitly recommends instanceof Error as the basic narrowing technique for unknown catch variables. [1]
- For Promise
.catch(): annotate the parameter asunknowntoo
TypeScript’s compiler option doesn’t affectPromise.prototype.catch()callback types, so add an explicit annotation (or enforce it via lint). [2]
Promise.reject("nope").catch((err: unknown) => {
if (err instanceof Error) console.error(err.message);
else console.error(err);
});- (Optional) Enforce the Promise pattern with ESLint
Use@typescript-eslint/use-unknown-in-catch-callback-variableto requireunknownin Promise rejection callbacks. [2]
Sources: TypeScript 4.4 release notes on useUnknownInCatchVariables and narrowing with instanceof Error [1], typescript-eslint rule for Promise catch callbacks [2].
[1] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html
[2] https://typescript-eslint.io/rules/use-unknown-in-catch-callback-variable
Use unknown with type narrowing in catch block to safely handle errors.
The catch clause uses err: any, which bypasses TypeScript's type safety. Since signUp rejects from Supabase and accessing .message directly is unsafe, use proper type narrowing with err: unknown and an instanceof Error check.
🛠️ Suggested fix
- } catch (err: any) {
- setError(err.message || 'Signup failed')
+ } catch (err: unknown) {
+ const message =
+ err instanceof Error
+ ? err.message
+ : typeof err === 'string'
+ ? err
+ : 'Signup failed'
+ setError(message)
} finally {
setLoading(false)
}📝 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.
| try { | |
| await signUp(email, password); | |
| navigate('/dashboard'); | |
| await signUp(email, password) | |
| navigate('/dashboard') | |
| } catch (err: any) { | |
| setError(err.message || 'Signup failed'); | |
| setError(err.message || 'Signup failed') | |
| } finally { | |
| try { | |
| await signUp(email, password) | |
| navigate('/dashboard') | |
| } catch (err: unknown) { | |
| const message = | |
| err instanceof Error | |
| ? err.message | |
| : typeof err === 'string' | |
| ? err | |
| : 'Signup failed' | |
| setError(message) | |
| } finally { |
🤖 Prompt for AI Agents
In `@frontend/src/components/auth/SignupForm.tsx` around lines 35 - 40, The catch
currently types the error as any and reads err.message directly; change the
catch parameter to err: unknown and narrow it (e.g., if (err instanceof Error)
setError(err.message) else setError(String(err) || 'Signup failed')) inside the
SignupForm signUp call so setError always receives a safe string; update the
try/catch around signUp(email, password) and keep navigate('/dashboard') on
success.
Auth Pages Redesign
Summary
Clean, minimal redesign of Login and Signup pages to match the new landing page design system.
Changes
Design Philosophy
Stripped all the "SaaS template" fluff. Inspired by Linear, Vercel, Raycast - developer tools that respect their users' time.
Removed
Kept
Screenshots
Light Mode:
Dark Mode:
Files Changed
frontend/src/components/auth/LoginForm.tsx- Complete rewritefrontend/src/components/auth/SignupForm.tsx- Complete rewriteCode Stats
Testing
Next Steps (separate PR)
Summary by CodeRabbit
Style
Bug Fixes / UX
✏️ Tip: You can customize this high-level summary in your review settings.