-
Notifications
You must be signed in to change notification settings - Fork 358
Feature/add complete stellarmail features #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,325 @@ | ||||||||
| import React, { useState } from 'react'; | ||||||||
| import { Mail, Lock, User, ArrowRight, Loader2, Eye, EyeOff, ArrowLeft } from 'lucide-react'; | ||||||||
|
|
||||||||
| type AuthView = 'login' | 'register' | 'forgot-password' | 'reset-sent'; | ||||||||
|
|
||||||||
| const Auth: React.FC = () => { | ||||||||
| const [authView, setAuthView] = useState<AuthView>('login'); | ||||||||
| const [isLoading, setIsLoading] = useState(false); | ||||||||
| const [showPassword, setShowPassword] = useState(false); | ||||||||
| const [formData, setFormData] = useState({ | ||||||||
| name: '', | ||||||||
| email: '', | ||||||||
| password: '', | ||||||||
| confirmPassword: '' | ||||||||
| }); | ||||||||
|
|
||||||||
| const handleSubmit = async (e: React.FormEvent) => { | ||||||||
| e.preventDefault(); | ||||||||
| setIsLoading(true); | ||||||||
| setTimeout(() => { | ||||||||
| setIsLoading(false); | ||||||||
| if (authView === 'forgot-password') { | ||||||||
| setAuthView('reset-sent'); | ||||||||
| } | ||||||||
| }, 1500); | ||||||||
| }; | ||||||||
|
Comment on lines
+17
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Authentication handlers are incomplete placeholders. The If this is intentional scaffolding, consider adding a TODO comment. Otherwise, integrate actual authentication logic or callbacks. Would you like me to suggest a pattern for handling auth with callbacks/props or integration with an auth provider? 🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| const renderLogin = () => ( | ||||||||
| <div className="w-full max-w-md mx-auto animate-fadeIn"> | ||||||||
| <div className="text-center mb-8"> | ||||||||
| <h1 className="text-3xl font-bold text-white mb-2">Welcome Back</h1> | ||||||||
| <p className="text-gray-400">Sign in to continue to StellarMail</p> | ||||||||
| </div> | ||||||||
|
|
||||||||
| <div className="bg-[#1a1a1a] rounded-xl border border-gray-800 p-8"> | ||||||||
| <form onSubmit={handleSubmit} className="space-y-6"> | ||||||||
| <div> | ||||||||
| <label className="block text-sm font-medium text-gray-400 mb-2">Email Address</label> | ||||||||
| <div className="relative"> | ||||||||
| <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> | ||||||||
| <Mail size={18} className="text-gray-500" /> | ||||||||
| </div> | ||||||||
| <input | ||||||||
| type="email" | ||||||||
| value={formData.email} | ||||||||
| onChange={(e) => setFormData({ ...formData, email: e.target.value })} | ||||||||
| className="w-full pl-10 pr-4 py-3 bg-gray-950 border border-gray-800 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary-500 focus:ring-1 focus:ring-primary-500 transition-colors" | ||||||||
| placeholder="alex@stellar.io" | ||||||||
| required | ||||||||
| /> | ||||||||
| </div> | ||||||||
| </div> | ||||||||
|
|
||||||||
| <div> | ||||||||
| <label className="block text-sm font-medium text-gray-400 mb-2">Password</label> | ||||||||
| <div className="relative"> | ||||||||
| <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> | ||||||||
| <Lock size={18} className="text-gray-500" /> | ||||||||
| </div> | ||||||||
| <input | ||||||||
| type={showPassword ? 'text' : 'password'} | ||||||||
| value={formData.password} | ||||||||
| onChange={(e) => setFormData({ ...formData, password: e.target.value })} | ||||||||
| className="w-full pl-10 pr-12 py-3 bg-gray-950 border border-gray-800 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary-500 focus:ring-1 focus:ring-primary-500 transition-colors" | ||||||||
| placeholder="••••••••" | ||||||||
| required | ||||||||
| /> | ||||||||
| <button | ||||||||
| type="button" | ||||||||
| onClick={() => setShowPassword(!showPassword)} | ||||||||
| className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-white" | ||||||||
|
||||||||
| className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-white" | |
| className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-white" | |
| aria-label="Toggle password visibility" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Remember me" checkbox state is not tracked.
The checkbox is rendered but its value isn't stored in state or used anywhere. Either add state to track it or remove the checkbox if not needed.
🤖 Prompt for AI Agents
In components/Auth.tsx around lines 78 to 82, the "Remember me" checkbox is
rendered but its checked value isn't tracked; add a React state hook (e.g.,
useState<boolean>) to hold the remember flag, bind the checkbox's checked prop
to that state, add an onChange handler to toggle/update the state, and ensure
the form submission or login handler reads that state (or persist it to
localStorage/cookie as intended); alternatively, if the feature is not required,
remove the checkbox markup to avoid dead UI.
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the login form, this password visibility toggle button is missing an aria-label attribute for screen reader accessibility.
| className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-white" | |
| className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-white" | |
| aria-label={showPassword ? "Hide password" : "Show password"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Password validation is displayed but not enforced.
The UI shows "Must be at least 8 characters" (line 189), and there's a confirmPassword field, but neither constraint is validated before submission. Users could submit weak passwords or mismatched confirmations.
Add validation in handleSubmit for the register flow:
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
+ if (authView === 'register') {
+ if (formData.password.length < 8) {
+ // Show error: password too short
+ return;
+ }
+ if (formData.password !== formData.confirmPassword) {
+ // Show error: passwords don't match
+ return;
+ }
+ }
setIsLoading(true);Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In components/Auth.tsx around lines 189 to 207, the form shows a password rule
and confirmPassword field but there is no enforcement in handleSubmit for the
register flow; update handleSubmit to validate that formData.password is at
least 8 characters and that formData.confirmPassword matches formData.password,
prevent submission if validations fail, and set/display appropriate error
state/messages (e.g., setError or formErrors) so the user sees why submission
was blocked; ensure early return on validation failure and only proceed with the
registration request when checks pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The form submission handler doesn't perform any validation. For the register view, it should validate that the password meets the stated requirement of "at least 8 characters" and that password and confirmPassword match before proceeding. For the login view, it should validate the email format. The lack of validation could lead to poor user experience and security issues.