Vous êtes sur la page 1sur 18

Application web de Online Shopping

développé avec React Js

L’objectif de ce projet est créé une application web de Online Shopping avec React JS.

Le travail est organisé en deux parties :

BackEnd et le FrontEnd.
BackEnd
Etape 1 :

Installer le serveur JSON

npm install -g json-server

Créer un fichier db.json avec quelques données

{
"users": [
{
"name": "adil adil",
"username": "adil",
"email": "adil@ofppt-edu.ma",
"password": "123",
"id": 1
},
{
"name": "nada nada",
"username": "nada",
"email": "nada@ofppt-edu.ma",
"password": "123",
"id": 2
},
{
"name": "nabil",
"username": "nabil",
"email": "email1@gmail.com",
"password": "123",
"id": 3
}
],
"products": [
{
"id": 1,
"name": "Sony",
"desc": "pc sony vio",
"price": 56,
"img": "https://res.cloudinary.com/image1.jpg"
},
{
"id": 2,
"name": "Hp",
"desc": "pc Note book",
"price": 70,
"img": "https://res.cloudinary.com/image1.jpg"
},
{
"id": 3,
"name": "Dell",
"desc": "pc dell",
"price": 56,
"img": "https://res.cloudinary.com/image1.jpg"
}
]
}

package.json
{
"dependencies": {
"json-server": "^0.17.0"
},
"scripts": {
"start":"json-server -p 3006 -w db.json"
}

Etape 2 :

Mettez vos images dans le cloud Cloudinary

-s’authentifier par ton email.

- Créer un nouveau dossier onlineShopping danslequel vous importez quelques exemples d’images.
FrontEnd
Dans cette partie on veut développer une application web à l’aide de ReactJS qui gère les achats
en ligne via API.

Dans cet application, vous allez utiliser Axios pour accéder à API JSON dans une application
React et le middleware Redux-Thunk pour gérer les événements asynchrones

Etape 1 :

- Créer un nouveau projet Recat Js

npx create-react-app onlineshop

- Installer les bibliothèques suivantes

npm i @reduxjs/toolkit react-redux axios

npm i react-router-dom@6

La structure du dossier :
Etape 2 :

1- Créer le store avec la fonction configureStore.

2- Créer le slice usersSlice contenant le state et les extraReducers. Vous pouvez utiliser
l'option extraReducers dans createSlice pour écouter ces types d'action (pending, fulfilled
et rejected)) et mettre à jour l'état.

3- Créer la fonction login à l’aide de createAsyncThunk pour récupérer les données à partir
du serveur JSON. Définir les actions correspondantes (pending, fulfilled et rejected).

usersSlice.js

import { createAsyncThunk,createSlice } from "@reduxjs/toolkit";


import axios from "axios";
const initialState={
connectedUser:null,
error:null,
isLoading:null
}
export const login=createAsyncThunk('users/login',async ()
try {
// code ………
} catch (error) {
// code ………

}
})
export const addUser=createAsyncThunk('users/addUser',async ()=>{
try {
// code ………
} catch (error) {
// code ………
}
})
const usersSlice=createSlice({
name:"users",
initialState,
reducers:{

logout:(state)=>{
// code ………
},
},
extraReducers:{
[login.pending]:(state,action)=>{
// code ………
},
[login.fulfilled]:(state,action)=>{
// code ………
},
[login.rejected]:(state,action)=>{
// code ………

},
[addUser.pending]:(state,action)=>{
// code ………

},
[addUser.fulfilled]:(state,action)=>{
// code ………

},
[addUser.rejected]:(state,action)=>{
// code ………
}

}
})
export default usersSlice.reducer
export const {logout}=usersSlice.actions

Etape 3 :

- Créer le component <Login/>

- Login.js : qui authentifie l'utilisateur. Elle contient un formulaire renfermant une zone de texte,
une zone de mot de passe et un bouton d'envoi. Si l’authentification échoue alors un message
d’erreur s’affiche.

-
Si le client tente d'accéder directement à la page checkout alors qu'il n'est pas authentifié, il sera
aussitôt redirigé vers la page login. Si'il fournit un bon login et un bon mot de passe alors il sera redirigé
vers la page Home.

La propriété isLoading permet d’indiquer le statut de la requête asynchrone. Elle prend la valeur True
dans pending et false dans fulfilled et rejected.

La propriété error stocke l’erreur retournée par le serveur en cas d’échec.

Etape 4 :

Dans le component App vous configurez le router de l’application et aussi le Provider.

<BrowserRouter>
<NavBar/>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/login" element={<Login/>}/>
<Route path="/cart" element={<Cart/>}/>
<Route path ="*" element={<NotFound/>}/>
<Route path ="/register" element={<Register/>}/>
</Routes>
</BrowserRouter>
Etape 5 :

Maintenant implémenter le navbar conteant :

 un titre Online Shop h2 sous fome d’un NavLink qui redirige vers la page home.
 Un icon et le nombre des articles commandés sous fome d’un Navlink qui redirige vers la page
cart
 Dex Navlink Login et Register

Si le client s’authentifie donc les deux links Login et Register seront masqués et on affichera le nom de
l’utilisateur et le bouton Logout.

Etape 6 :

1- Créer le slice productsSlice contenant le state et les extraReducers. Vous pouvez utiliser
l'option extraReducers dans createSlice pour écouter ces types d'action (pending, fulfilled
et rejected)) et mettre à jour l'état.

2- Créer la fonction getProducts à l’aide de createAsyncThunk pour récupérer les données


à partir du serveur JSON. Définir les actions correspondantes (pending, fulfilled et
rejected).

3- Ajouter le reducer products au store.

productsSlice.js

import { createSlice,createAsyncThunk } from "@reduxjs/toolkit";


import axios from "axios";
const initialState={
items:[],
isLaoding:null,
error:null
}
export const getProducts=createAsyncThunk('products/getProducts',
async(_,{rejectWithValue})=>{
try {
const resp=await axios.get("http://localhost:3006/products")
return resp.data
} catch (error) {

return rejectWithValue(error.message)
}

})
const productsSlice=createSlice({
name:"products",
initialState,
reducers:{

},
extraReducers:{
[getProducts.pending]:(state,action)=>{
//code…..
},
[getProducts.fulfilled]:(state,action)=>{
//code…..
},
[getProducts.rejected]:(state,action)=>{
//code…..
}

})

export default productsSlice.reducer

Etape 7 : Home.js
Ce component affiche tous les produits stockées items du state products.
La focntion getProducts est déclenchée dans le hook useEffect du component Home afin
d’initialiser la propriété items et aussi créer les actions asynchrones.
Ici on itère sur le tableau retourné par useSelector en passant chaque item comme props dans
le component child <Product/>.
Au moment de récupération des donnés ( pending) on affiche le message ‘is Loading…’
Etape 8 : Product.js

Ce component affiche les détails d’un seul produit en plus un bouton Add to Cart (ajouter au
panier). Après le client sera redirigée vers la page cart.

Etape 10 : Cart.js

Ce component affiche notre panier sous forme d’une grille qui contienne dans chaque ligne le
produit avec le bouton remove. Le prix et aussi la quantité qui peut être modifié avec les
boutons + et – et enfin le total qui égale au prix unitaire multiplié par la quantité.

En bas à gauche on a un bouton clearCart pour vider le panier.


En bas à droite il y a le prix total de la facture et deux NavLinks Log to check out (si le client
n’est pas encore s’authentifié) et continue Shopping

Si le panier est vide on affiche le rendu suivant :

Start shopping redirige le client vers la page Home pour commencer ses achats.

Etape 9 : cartSlice.js
Ce slice contient la logique des achats effectués par le client. Lorsqu’on clique sur Add to
cart on insère un nouveau produit dans cartItems.

1- Créer le slice cartSlice contenant le state et les reducers.

2- Créer les actions suivantes :

 addToCart qui permet d’ajouter un produit à notre panier (cart) en spécifiant une
nouvelle propriété productQuantity qui indique le nombre de même produit
ajouté au panier.

 computeTotalQuantity calcule le nombre des articles choisis par le client. Cette


valeur est affichée dans le navbar.
 computeTotalAmount calcule le prix total.
 increase qui incrémente le nombre du produit c.-à-d. incrémenter la propriété
productQuantity.
 decrease qui décrémente le nombre du produit c.-à-d. décrémenter la propriété
productQuantity.
 removeItem qui supprime le produit du panier.
 clearCart qui vide le panier.

3- cartTotalQuantity contient le nombre des articles ajoutés au panier.

4- cartTotalAmount contient le prix total.

5- Ajouter le reducer products au store.

catSlice.js
import { createSlice } from "@reduxjs/toolkit";
import { toast } from "react-toastify";
const initialState={cartItems:[],
cartTotalQuantity:0,
cartTotalAmount:0
}
const cartSlice=createSlice({
name:"cart",
initialState,
reducers:{
addToCart:(state,action)=>{
//code ………..

},
computeTotalQuantity:(state)=>{
//code ………..
},
computeTotalAmount:(state)=>{
//code ………..
},
removeItem:(state,action)=>{
//code ………..
toast.warning(`${action.payload.name} removed from cart`)
},
increase:(state,action)=>{
//code ………..

},
decrease:(state,action)=>{
//code ………..
},
clearCart:(state)=>{
//code ………..
}
}
})
export default cartSlice.reducer
export const
{addToCart,computeTotalQuantity,removeItem,increase,decrease,clearCart,compute
TotalAmount}=cartSlice.actions

Etape 12 :

Lorsqu’on clique sur Add to Cart ou remove il est recommandé d’afficher un message
informatif qui indique au client que l’opération a été bien effectuée. Dans ce projet on
utilisera la bibliothèque toastify.
npm i react-toastify
pour profiter de toastify il faut tout d’abord ajouter le component <ToastContainer/> Dans
App.js

import {ToastContainer} from 'react-toastify'

<BrowserRouter>
<ToastContainer/>
<NavBar/>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/login" element={<Login/>}/>
<Route path="/cart" element={<Cart/>}/>
<Route path ="*" element={<NotFound/>}/>
<Route path ="/register" element={<Register/>}/>
</Routes>
</BrowserRouter>

Dans l’action addToCart vous insérez la ligne suivante :

toast.success('product added to cart')

Dans l’action remove vous insérer la ligne suivante :

toast.warning(`prodcut removed from cart`)


Etape 12 : Register.js

Dans le slice usersSlice définir une fonction addUser à l’aide de createAsyncThunk pour poster
un nouvel utilisateur au serveur JSON. Définir les actions correspondantes (pending, fulfilled
et rejected).

Vous aimerez peut-être aussi