@@ -11,6 +11,8 @@ export default function SignupPage() {
1111 const [ password , setPassword ] = useState ( "" ) ;
1212 const [ confirmPassword , setConfirmPassword ] = useState ( "" ) ;
1313 const [ username , setUsername ] = useState ( "" ) ;
14+ const [ showPassword , setShowPassword ] = useState ( false ) ;
15+ const [ showConfirmPassword , setShowConfirmPassword ] = useState ( false ) ;
1416 const [ loading , setLoading ] = useState ( false ) ;
1517 const [ error , setError ] = useState < string | null > ( null ) ;
1618 const [ success , setSuccess ] = useState ( false ) ;
@@ -169,32 +171,122 @@ export default function SignupPage() {
169171 < label className = "block text-sm text-gray-400 mb-2" >
170172 PASSWORD
171173 </ label >
172- < input
173- type = "password"
174- value = { password }
175- onChange = { ( e ) => setPassword ( e . target . value ) }
176- className = "w-full bg-black border border-gray-600 px-4 py-3 focus:border-white focus:outline-none transition-colors font-mono"
177- placeholder = "••••••••"
178- required
179- disabled = { loading }
180- minLength = { 6 }
181- />
174+ < div className = "relative" >
175+ < input
176+ type = { showPassword ? "text" : "password" }
177+ value = { password }
178+ onChange = { ( e ) => setPassword ( e . target . value ) }
179+ className = "w-full bg-black border border-gray-600 px-4 py-3 pr-12 focus:border-white focus:outline-none transition-colors font-mono"
180+ placeholder = "••••••••"
181+ required
182+ disabled = { loading }
183+ minLength = { 6 }
184+ />
185+ < button
186+ type = "button"
187+ onClick = { ( ) => setShowPassword ( ! showPassword ) }
188+ className = "absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors"
189+ tabIndex = { - 1 }
190+ >
191+ { showPassword ? (
192+ < svg
193+ xmlns = "http://www.w3.org/2000/svg"
194+ fill = "none"
195+ viewBox = "0 0 24 24"
196+ strokeWidth = { 1.5 }
197+ stroke = "currentColor"
198+ className = "w-5 h-5"
199+ >
200+ < path
201+ strokeLinecap = "round"
202+ strokeLinejoin = "round"
203+ d = "M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
204+ />
205+ </ svg >
206+ ) : (
207+ < svg
208+ xmlns = "http://www.w3.org/2000/svg"
209+ fill = "none"
210+ viewBox = "0 0 24 24"
211+ strokeWidth = { 1.5 }
212+ stroke = "currentColor"
213+ className = "w-5 h-5"
214+ >
215+ < path
216+ strokeLinecap = "round"
217+ strokeLinejoin = "round"
218+ d = "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
219+ />
220+ < path
221+ strokeLinecap = "round"
222+ strokeLinejoin = "round"
223+ d = "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
224+ />
225+ </ svg >
226+ ) }
227+ </ button >
228+ </ div >
182229 < p className = "text-xs text-gray-500 mt-1" > Minimum 6 characters</ p >
183230 </ div >
184231
185232 < div >
186233 < label className = "block text-sm text-gray-400 mb-2" >
187234 CONFIRM_PASSWORD
188235 </ label >
189- < input
190- type = "password"
191- value = { confirmPassword }
192- onChange = { ( e ) => setConfirmPassword ( e . target . value ) }
193- className = "w-full bg-black border border-gray-600 px-4 py-3 focus:border-white focus:outline-none transition-colors font-mono"
194- placeholder = "••••••••"
195- required
196- disabled = { loading }
197- />
236+ < div className = "relative" >
237+ < input
238+ type = { showConfirmPassword ? "text" : "password" }
239+ value = { confirmPassword }
240+ onChange = { ( e ) => setConfirmPassword ( e . target . value ) }
241+ className = "w-full bg-black border border-gray-600 px-4 py-3 pr-12 focus:border-white focus:outline-none transition-colors font-mono"
242+ placeholder = "••••••••"
243+ required
244+ disabled = { loading }
245+ />
246+ < button
247+ type = "button"
248+ onClick = { ( ) => setShowConfirmPassword ( ! showConfirmPassword ) }
249+ className = "absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors"
250+ tabIndex = { - 1 }
251+ >
252+ { showConfirmPassword ? (
253+ < svg
254+ xmlns = "http://www.w3.org/2000/svg"
255+ fill = "none"
256+ viewBox = "0 0 24 24"
257+ strokeWidth = { 1.5 }
258+ stroke = "currentColor"
259+ className = "w-5 h-5"
260+ >
261+ < path
262+ strokeLinecap = "round"
263+ strokeLinejoin = "round"
264+ d = "M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
265+ />
266+ </ svg >
267+ ) : (
268+ < svg
269+ xmlns = "http://www.w3.org/2000/svg"
270+ fill = "none"
271+ viewBox = "0 0 24 24"
272+ strokeWidth = { 1.5 }
273+ stroke = "currentColor"
274+ className = "w-5 h-5"
275+ >
276+ < path
277+ strokeLinecap = "round"
278+ strokeLinejoin = "round"
279+ d = "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
280+ />
281+ < path
282+ strokeLinecap = "round"
283+ strokeLinejoin = "round"
284+ d = "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
285+ />
286+ </ svg >
287+ ) }
288+ </ button >
289+ </ div >
198290 </ div >
199291
200292 < button
0 commit comments