Created
November 11, 2025 17:44
-
-
Save saltukalakus/0687dc0e224720226398c5f9bb700ab2 to your computer and use it in GitHub Desktop.
Login test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useState, useMemo } from 'react'; | |
| import Login from '@auth0/auth0-acul-js/login'; | |
| // Error Messages Component | |
| const ErrorMessages: React.FC<{ errors: any[] }> = ({ errors }) => ( | |
| <div className="mt-4 p-3 bg-red-50 border border-red-200 rounded-md"> | |
| <div className="text-sm text-red-800"> | |
| {errors.map((error, index) => ( | |
| <div key={index} className="mb-1"> | |
| {error.message || error.code || 'An error occurred'} | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| const LoginScreen: React.FC = () => { | |
| const [username, setUsername] = useState(''); | |
| const [password, setPassword] = useState(''); | |
| const [error, setError] = useState(''); | |
| const loginManager = new Login(); | |
| const { transaction } = loginManager; | |
| const activeIdentifiers = useMemo(() => (loginManager.getLoginIdentifiers?.() ?? loginManager.getActiveIdentifiers?.() ?? ['email']), []); | |
| const errors = transaction.errors || []; | |
| const getIdentifierLabel = () => { | |
| if (activeIdentifiers?.length === 1) return `Enter your ${activeIdentifiers[0]}`; | |
| return `Enter your ${activeIdentifiers?.join(" or ")}`; | |
| }; | |
| const handleSubmit = async (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| setError(''); | |
| try { | |
| await loginManager.login({ | |
| username, | |
| password | |
| }); | |
| } catch (error) { | |
| setError('Login failed. Please check your credentials.'); | |
| } | |
| }; | |
| const handleSocialLogin = async (connection: string) => { | |
| try { | |
| await loginManager.federatedLogin({ connection }); | |
| } catch (error) { | |
| setError('Social login failed. Please try again.'); | |
| } | |
| }; | |
| return ( | |
| <div className="min-h-screen bg-gray-100 flex flex-col justify-center py-12 sm:px-6 lg:px-8"> | |
| <div className="sm:mx-auto sm:w-full sm:max-w-md"> | |
| <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900"> | |
| Sign in to your account | |
| </h2> | |
| </div> | |
| <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> | |
| <div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10"> | |
| <form className="space-y-6" onSubmit={handleSubmit}> | |
| <div> | |
| <label htmlFor="username" className="block text-sm font-medium text-gray-700"> | |
| {getIdentifierLabel()} | |
| </label> | |
| <div className="mt-1"> | |
| <input | |
| id="username" | |
| name="username" | |
| type="text" | |
| required | |
| value={username} | |
| onChange={(e) => setUsername(e.target.value)} | |
| placeholder= {getIdentifierLabel()} | |
| className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500" | |
| /> | |
| </div> | |
| </div> | |
| <div> | |
| <label htmlFor="password" className="block text-sm font-medium text-gray-700"> | |
| Password | |
| </label> | |
| <div className="mt-1"> | |
| <input | |
| id="password" | |
| name="password" | |
| type="password" | |
| required | |
| value={password} | |
| onChange={(e) => setPassword(e.target.value)} | |
| className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500" | |
| /> | |
| </div> | |
| </div> | |
| {error && ( | |
| <div className="text-red-600 text-sm"> | |
| {error} | |
| </div> | |
| )} | |
| {loginManager.transaction.hasErrors && errors && errors.length > 0 && ( | |
| <ErrorMessages errors={errors} /> | |
| )} | |
| <div> | |
| <button | |
| type="submit" | |
| className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" | |
| > | |
| Sign in | |
| </button> | |
| </div> | |
| </form> | |
| {transaction.alternateConnections && transaction.alternateConnections.length > 0 && ( | |
| <div className="mt-6"> | |
| <div className="relative"> | |
| <div className="absolute inset-0 flex items-center"> | |
| <div className="w-full border-t border-gray-300" /> | |
| </div> | |
| <div className="relative flex justify-center text-sm"> | |
| <span className="px-2 bg-white text-gray-500"> | |
| Or continue with | |
| </span> | |
| </div> | |
| </div> | |
| <div className="mt-6 grid grid-cols-3 gap-3"> | |
| {transaction.alternateConnections.map((connection) => ( | |
| <button | |
| key={connection.name} | |
| onClick={() => handleSocialLogin(connection.name)} | |
| className="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50" | |
| > | |
| {connection.name} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default LoginScreen; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment