diff --git a/content/building-a-login-screen-with-react-and-bootstrap/email-error-login-form.png b/content/building-a-login-screen-with-react-and-bootstrap/email-error-login-form.png new file mode 100644 index 00000000..63757ed2 Binary files /dev/null and b/content/building-a-login-screen-with-react-and-bootstrap/email-error-login-form.png differ diff --git a/content/building-a-login-screen-with-react-and-bootstrap/error-login-form.png b/content/building-a-login-screen-with-react-and-bootstrap/error-login-form.png new file mode 100644 index 00000000..d19aabca Binary files /dev/null and b/content/building-a-login-screen-with-react-and-bootstrap/error-login-form.png differ diff --git a/content/building-a-login-screen-with-react-and-bootstrap/focused-login-form.png b/content/building-a-login-screen-with-react-and-bootstrap/focused-login-form.png new file mode 100644 index 00000000..0cb5eeac Binary files /dev/null and b/content/building-a-login-screen-with-react-and-bootstrap/focused-login-form.png differ diff --git a/content/building-a-login-screen-with-react-and-bootstrap/index.md b/content/building-a-login-screen-with-react-and-bootstrap/index.md index ded96f1d..05b40464 100644 --- a/content/building-a-login-screen-with-react-and-bootstrap/index.md +++ b/content/building-a-login-screen-with-react-and-bootstrap/index.md @@ -1,309 +1,614 @@ --- title: Building a login screen with React and Bootstrap -date: "2022-03-14" +date: "2024-07-15" description: "Build an elegant login screen super fast using React and Bootstrap" cover: "building-a-login-screen-with-react-and-bootstrap.png" category: "programming" -author: "Nemi Shah" -discord_button_id: "discord_building_a_login_screen_with_react_and_bootstrap" +author: "Mostafa Ibrahim" --- -Most web applications today require users to register in order to use certain features or visit specific pages, but building a login form is one of the most tedious things to do. In this article we will build a simple and elegant sign in screen using React and Bootstrap 5. +## Table of Contents + +- [Introduction](#introduction) +- [Prerequisites](#prerequisites) +- [Step 1: Setting Up the Project](#step-1-setting-up-the-project) +- [Step 2: Creating the Login Component](#step-2-creating-the-login-component) +- [Step 3: Styling the Login Page](#step-3-styling-the-login-page) +- [Step 4: Handling User Input](#step-4-handling-user-input) +- [Step 5: Adding Form Validation](#step-5-adding-form-validation) +- [Step 6: Connecting to a Backend](#step-6-connecting-to-a-backend) +- [Step 7: Implementing Authentication](#step-7-implementing-authentication) +- [Conclusion](#conclusion) + +## Introduction + +In this comprehensive guide, we'll walk you through the process of building a login page using React and Bootstrap. Whether you're a seasoned developer or just starting out, this tutorial will help you create a professional-looking login component that's both responsive and user-friendly. ## Prerequisites -- A basic understanding of HTML, CSS and Javascript -- A basic understanding of React -- Setup [NodeJS](https://nodejs.org/en/) on your machine +Before we dive in, make sure you have the following: -## Setup the React app +- **Basic Understanding of React**: You should be familiar with React's component-based architecture, JSX syntax, and how to manage state and props. Understanding React hooks, particularly useState and useEffect, will be beneficial as we'll be using them extensively in our login component. +- **Familiarity with Bootstrap**: A general understanding of Bootstrap's grid system, utility classes, and component library will help you follow along more easily. We'll be leveraging Bootstrap's pre-built components to create a responsive and visually appealing login page. +- **Development Environment**: Ensure you have Node.js and npm (Node Package Manager) installed on your machine. These tools are essential for creating and managing React projects. Additionally, having a code editor like Visual Studio Code will make the development process smoother. +- **Command Line Basics**: You should be comfortable using the command line interface to run npm commands and navigate your project directory. +- **HTML/CSS Knowledge**: While we'll be using React and Bootstrap, a good grasp of HTML structure and CSS styling principles will help you understand and customize the login page design. -Run the following command to create a fresh react project: +## Step 1: Setting Up the Project -```sh -npx create-react-app react-login -``` +Let's start by creating a new React project and setting up Bootstrap. -Navigate into the project and start the app +**1. Open your terminal and run the following command to create a new React project:** -```sh -cd react-login -npm start +```bash +npx create-react-app react-login-page +cd react-login-page ``` -Once the build is ready, the app should look like this: +**2. Install Bootstrap and its dependencies:** -![Default React App](./default-react-app.png) +```bash +npm install bootstrap react-bootstrap +``` -## Install Bootstrap -Install bootstrap using npm: +**3. Open src/index.js and import Bootstrap CSS:** -```sh -npm install –save bootstrap +```bash +import 'bootstrap/dist/css/bootstrap.min.css'; ``` -Edit `App.js` and add an import statement for bootstrap +**4. Create a new file src/components/Login.js for our login component.** -```jsx -import "bootstrap/dist/css/bootstrap.min.css" -``` +## Step 2: Creating the Login Component -We will also go ahead and remove the boilerplate code that the default React app adds to App.js. The file should now look like this: +Now we'll dive into the heart of our login page – the Login component. This React component will contain all the necessary elements for user authentication. We'll use React's `useState` hook to manage the form's state, allowing us to capture and control user input efficiently. The component will include input fields for email and password, along with a submit button, all styled using Bootstrap classes for a clean, professional look. -```jsx -import "bootstrap/dist/css/bootstrap.min.css" -import "./App.css" +In `src/components/Login.js`, add the following code: -function App() { - return
+```javascript +// Login.js: +import React, { useState } from 'react'; +import { Form, Button, Container, Row, Col } from 'react-bootstrap'; + +function Login() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + + const handleSubmit = (event) => { + event.preventDefault(); + console.log('Login attempted with:', { email, password }); + // Here you would typically send a request to your server + }; + + return ( + + + +

Login

+
+ + Email address + setEmail(e.target.value)} + /> + + + + Password + setPassword(e.target.value)} + /> + + + +
+ +
+
+ ); } -export default App +export default Login; ``` -## Setup Routes +This creates a basic login form with email and password fields using React Bootstrap components. + +![login form](./login-form.png) + -First we will create a new component Auth in Auth.js. We will work on the actual Auth component later for now we need this to set up routes. +## Step 3: Styling the Login Page -```jsx -import React from "react" +Bootstrap provides pre-styled components, but let's add some custom CSS to make our login page stand out. Create a new file `src/components/Login.css` and add the following styles: -export default function (props) { - return
Auth Screen
+```css +.login-wrapper { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + padding: 20px; +} + +.login-form-container { + width: 100%; + max-width: 400px; + padding: 20px; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + background-color: #fff; +} + +.login-title { + text-align: center; + margin-bottom: 20px; +} + +.login-form { + margin-bottom: 15px; +} + +.login-button { + width: 100%; } ``` -In a real world application you would redirect users to your login screen if they were not already logged in. This is where routing comes into the picture, run the following command to install `react-router-dom`, restart the react app after the installation is complete. +Now, update your `Login.js` to import and use these styles: + +```js +import React, { useState } from 'react'; +import { Form, Button, Container } from 'react-bootstrap'; +import './Login.css'; + +function Login() { + // ... (previous state and handleSubmit code) + + return ( +
+
+

Login

+
+ {/* ... */} + + +
+
+
+ ); +} -```sh -npm install --save react-router-dom +export default Login; ``` -Modify the `App.js` file to set up the default and login routes. We will show the login UI on the `/auth` route. +![focused login form](./focused-login-form.png) + +## Step 4: Handling User Input + +We've already set up state variables for email and password, and we're updating them on input change. Let's add some basic validation to improve user experience. +Update your `Login.js` with the following changes: + +```js +import React, { useState } from 'react'; +import { Form, Button, Container, Alert } from 'react-bootstrap'; +import './Login.css'; + + +function Login() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [error, setError] = useState(''); + + + const handleSubmit = (event) => { + event.preventDefault(); + setError(''); + if (!email || !password) { + setError('Please enter both email and password.'); + return; + } + console.log('Login attempted with:', { email, password }); + // Here you would typically send a request to your server + }; -```jsx -import "bootstrap/dist/css/bootstrap.min.css" -import "./App.css" -import { BrowserRouter, Routes, Route } from "react-router-dom" -import Auth from "./Auth" -function App() { return ( - - - } /> - - - ) +
+
+

Login

+ {error && {error}} +
+ Login + +
+
+
+ + + ); } -export default App + +export default Login; + ``` -## Create the Login form +This adds basic validation for empty fields and a simple email format check. + +![error login form](./error-login-form.png) + +## Step 5: Adding Form Validation + +Proper input handling is crucial for any form, especially a login form. We'll implement onChange handlers to update our component's state as the user types. This step lays the groundwork for form validation and submission, ensuring we have access to the most up-to-date user input at all times. + +Update `src/components/Login.js`: + +```js +import React, { useState } from 'react'; +import { Form, Button, Alert } from 'react-bootstrap'; +import './Login.css'; + + +function Login() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [errors, setErrors] = useState({}); + -Modify `Auth.js` that we created earlier + const validateForm = () => { + const newErrors = {}; + if (!email) newErrors.email = 'Email is required'; + else if (!/\S+@\S+\.\S+/.test(email)) newErrors.email = 'Email is invalid'; + if (!password) newErrors.password = 'Password is required'; + else if (password.length < 6) newErrors.password = 'Password must be at least 6 characters'; + return newErrors; + }; + + + const handleSubmit = (event) => { + event.preventDefault(); + const formErrors = validateForm(); + if (Object.keys(formErrors).length > 0) { + setErrors(formErrors); + } else { + setErrors({}); + console.log('Login attempted with:', { email, password }); + // Here you would typically send a request to your server + } + }; -```jsx -import React from "react" -export default function (props) { return ( -
-
-
-

Sign In

-
- - +
+

Login

+ + + Email address + setEmail(e.target.value)} + isInvalid={!!errors.email} /> -
-
- - + {errors.email} + + + + + + Password + setPassword(e.target.value)} + isInvalid={!!errors.password} /> -
-
- -
-

- Forgot password? -

-
- + + {errors.password} + + + + + + +
- ) + ); } + + +export default Login; ``` -Also modify `App.css` to include: +![email error login form](./email-error-login-form.png) -```css -.App { - background-color: white; -} +## Step 6: Connecting to a Backend -.Auth-form-container { - display: flex; - justify-content: center; - align-items: center; - width: 100vw; - height: 100vh; -} +For this tutorial, we'll simulate a backend response.In a real-world application, your login form would communicate with a backend server to authenticate users. We'll simulate this process using a mock API. This step introduces you to the concept of asynchronous API calls in React and how to handle responses, setting the stage for integration with a real authentication system in the future. + +```js +import axios from 'axios'; + + +const API_URL = 'https://jsonplaceholder.typicode.com'; // Mock API -.Auth-form { - width: 420px; - box-shadow: rgb(0 0 0 / 16%) 1px 1px 10px; - padding-top: 30px; - padding-bottom: 20px; - border-radius: 8px; - background-color: white; -} -.Auth-form-content { - padding-left: 12%; - padding-right: 12%; +export const login = async (email, password) => { + try { + const response = await axios.post(`${API_URL}/users`, { email, password }); + return response.data; + } catch (error) { + throw error; + } +}; +Update src/components/Login.js: + + +import React, { useState } from 'react'; +import { Form, Button, Container, Alert } from 'react-bootstrap'; +import { login } from '../services/api'; +import './Login.css'; + + +function Login() { + // ... (previous state and validation code) + + + const handleSubmit = async (event) => { + event.preventDefault(); + const formErrors = validateForm(); + if (Object.keys(formErrors).length > 0) { + setErrors(formErrors); + } else { + setErrors({}); + try { + const userData = await login(email, password); + console.log('Login successful:', userData); + // Here you would typically store the user data and redirect + } catch (error) { + setErrors({ form: 'Login failed. Please try again.' }); + } + } + }; + + + // ... (rest of the component) } -.Auth-form-title { - text-align: center; - margin-bottom: 1em; - font-size: 24px; - color: rgb(34, 34, 34); - font-weight: 800; + +export default Login; +``` + +![successful login](./successfull-login.png) + +### Step 7: Implementing Authentication + +In a real application, you'd want to manage authentication state across your app. Here's a simple example using React Context: + +Create a new file `src/context/AuthContext.js`: + +```js +import React, { createContext, useState, useContext } from 'react'; + + +const AuthContext = createContext(null); + + +export const AuthProvider = ({ children }) => { + const [user, setUser] = useState(null); + + + const login = (userData) => { + setUser(userData); + localStorage.setItem('user', JSON.stringify(userData)); + }; + + + const logout = () => { + setUser(null); + localStorage.removeItem('user'); + }; + + + return ( + + {children} + + ); +}; + + +export const useAuth = () => useContext(AuthContext); +``` + +**Update `src/App.js` to use the AuthProvider:** + +```js +Update src/App.js to use the AuthProvider: + + +import React from 'react'; +import { AuthProvider } from './context/AuthContext'; +import Login from './components/Login'; + + +function App() { + return ( + +
+ +
+
+ ); } -label { - font-size: 14px; - font-weight: 600; - color: rgb(34, 34, 34); + +export default App; +Step 8: Adding Navigation +Install React Router: +npm install react-router-dom +Create a new file src/components/Navigation.js: +import React from 'react'; +import { Navbar, Nav, Container } from 'react-bootstrap'; +import { Link } from 'react-router-dom'; +import { useAuth } from '../context/AuthContext'; + + +function Navigation() { + const { user, logout } = useAuth(); + + + return ( + + + My App + + + + + + + + ); } + + +export default Navigation; ``` -If you open the `/auth` route you should see the form +**Create placeholder components for Home and Profile:** -![Sign in Form](./initial-sign-in.png) +```js +src/components/Home.js: -## Add the signup form -Typically you want to allow users to register if they haven’t already. Modify the `Auth.js` component +import React from 'react'; +import { Container } from 'react-bootstrap'; -```jsx -import React, { useState } from "react" -export default function (props) { - let [authMode, setAuthMode] = useState("signin") +function Home() { + return ( + +

Welcome to My App

+
+ ); +} + + +export default Home; + - const changeAuthMode = () => { - setAuthMode(authMode === "signin" ? "signup" : "signin") - } - if (authMode === "signin") { - return ( -
-
-
-

Sign In

-
- Not registered yet?{" "} - - Sign Up - -
-
- - -
-
- - -
-
- -
-

- Forgot password? -

-
-
-
- ) - } + +src/components/Profile.js: + + +import React from 'react'; +import { Container } from 'react-bootstrap'; +import { useAuth } from '../context/AuthContext'; + + +function Profile() { + const { user } = useAuth(); + return ( -
-
-
-

Sign In

-
- Already registered?{" "} - - Sign In - -
-
- - -
-
- - -
-
- - -
-
- -
-

- Forgot password? -

-
-
-
- ) + +

Profile

+

Welcome, {user.email}!

+
+ ); } + + +export default Profile; ``` -We use `useState` to change between signing in and signing up. Now when you visit `/auth` you can toggle between sign in and sign up. -![Sign In Form](./final-sign-in.png) -![Sign In Form](./final-sign-up.png) +**Now user shall navigate to /profile on successful login.** + +```js +function Login() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [errors, setErrors] = useState({}); + const { login } = useAuth(); + const navigate = useNavigate(); + + + const validateForm = () => { + const newErrors = {}; + if (!email) newErrors.email = 'Email is required'; + else if (!/\S+@\S+\.\S+/.test(email)) newErrors.email = 'Email is invalid'; + if (!password) newErrors.password = 'Password is required'; + else if (password.length < 6) newErrors.password = 'Password must be at least 6 characters'; + return newErrors; + }; + + + const handleSubmit = async (event) => { + event.preventDefault(); + const formErrors = validateForm(); + if (Object.keys(formErrors).length > 0) { + setErrors(formErrors); + } else { + setErrors({}); + try { + const userData = await login(email, password); + + + navigate('/profile'); + console.log('Login successful:', userData); + // Here you would typically store the user data and redirect + } catch (error) { + setErrors({ form: 'Login failed. Please try again.' }); + } + } + }; +``` ## Conclusion -We have created a sign in / up UI using React with Bootstrap. However, there is still work needed to actually get it to function - to make API calls and to do session management. To quickly get those setup, checkout [SuperTokens](https://supertokens.com) +You've successfully built a login page using React and Bootstrap. This login component includes: +- A responsive design using Bootstrap +- Form validation +- Simulated API interaction + +- Basic authentication state management +Remember, this is just the beginning. In a production application, you'd want to add more features like: + +- Proper error handling and user feedback +- Password strength requirements +- Remember me functionality +- Password reset option +- Multi-factor authentication + +Building secure login pages is crucial for protecting user data and ensuring a smooth user experience. With React and Bootstrap, you have powerful tools at your disposal to create professional, responsive, and secure login interfaces. diff --git a/content/building-a-login-screen-with-react-and-bootstrap/login-form.png b/content/building-a-login-screen-with-react-and-bootstrap/login-form.png new file mode 100644 index 00000000..a85d091a Binary files /dev/null and b/content/building-a-login-screen-with-react-and-bootstrap/login-form.png differ diff --git a/content/building-a-login-screen-with-react-and-bootstrap/successfull-login.png b/content/building-a-login-screen-with-react-and-bootstrap/successfull-login.png new file mode 100644 index 00000000..82091f1f Binary files /dev/null and b/content/building-a-login-screen-with-react-and-bootstrap/successfull-login.png differ