Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
TahirMehmood8082 committed Apr 17, 2024
1 parent 4e47617 commit b0e101e
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 22 deletions.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-free": "^6.5.2",
"@reduxjs/toolkit": "^2.2.3",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"axios": "^1.6.8",
"bootstrap": "^5.3.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.1",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.0"
},
Expand Down
14 changes: 12 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import React from 'react'
import {Routes, Route} from "react-router-dom"
import Cart from "./Pages/Cart";
import Header from "./Pages/Header";
import Home from "./Pages/Home";

const App = () => {
return (
<div>App</div>
)
<>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/cart" element={<Cart />} />
</Routes>
</>
);
}

export default App
100 changes: 100 additions & 0 deletions src/Pages/Cart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import { RemoveCartItem } from "../Redux/reducers/ProductSlice";

const Cart = () => {
const dispatch = useDispatch();
const { carts } = useSelector((state) => state.products);

const totalPrice = carts.reduce((acc, a) => {
return acc + a.price;
}, 0);

return (
<>
<section class="h-100 h-custom">
<div class="container py-2 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-12">
<div
class="card card-registration card-registration-2"
style={{ borderRadius: "15px" }}
>
<div class="card-body p-0">
<div class="row g-0">
<div class="col-lg-12">
<div class="p-5">
<div class="d-flex justify-content-between align-items-center mb-5">
<h1 class="fw-bold mb-0 text-black">Shopping Cart</h1>
<h6 class="mb-0 text-muted">{carts.length} items</h6>
</div>
<hr class="my-4" />
{carts && Object.keys(carts).length > 0 ? (
carts.map((item) => {
return (
<>
<div class="row mb-4 d-flex justify-content-between align-items-center">
<div class="col-md-2 col-lg-2 col-xl-2">
<img
src={`${item.image}`}
class="img-fluid rounded-3"
alt="Cotton T-shirt"
/>
</div>
<div class="col-md-3 col-lg-3 col-xl-3">
<h6 class="text-black mb-0">
{item.title}
</h6>
</div>
<div class="col-md-3 col-lg-3 col-xl-2 d-flex">
<h6 class="text-black mb-0">
{item.category}
</h6>
</div>
<div class="col-md-3 col-lg-2 col-xl-2 offset-lg-1">
<h6 class="mb-0">{item.price}</h6>
</div>
<div className="col-md-1 col-lg-1 col-xl-1 text-end">
<a className="text-muted" onClick={() => dispatch(RemoveCartItem(item.id))}>
<i className="fas fa-times" style={{ cursor: "pointer" }}></i>
</a>
</div>

</div>

<hr class="my-4" />
</>
);
})
) : (
<h2 className="text-center">
Cart is Empty! Shop Now
</h2>
)}

<div class="pt-5 d-flex">
<h6 class="mb-0">
<Link to={"/"}>
<i class="fas fa-long-arrow-alt-left me-2"></i>
Back to shop
</Link>
</h6>
<h6 className="mx-auto">
Total Price : {totalPrice}
</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
};

export default Cart;
42 changes: 42 additions & 0 deletions src/Pages/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
const Header = () => {
const { carts } = useSelector((state) => state.products);
return (
<>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand mx-3" href="#">
Ecommerece Shop
</a>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>

<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mx-auto"></ul>
<div className="div-inline my-2 my-lg-0">
<Link to={"/cart"}>
<button
className="btn btn-primary my-2 my-sm-0 mx-3"
type="submit"
>
Cart : {carts.length}
</button>
</Link>
</div>
</div>
</nav>
</>
);
};

export default Header;
47 changes: 47 additions & 0 deletions src/Pages/Home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { AddToCart, fetchAllProducts } from "../Redux/reducers/ProductSlice";
const Home = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAllProducts());
}, []);

const { products, loading } = useSelector((state) => state.products);
return (
<>
<div className="container">
<div className="col-md-12">
<div className="row">
<h1 className="text-center">All Products</h1>
{loading && <h2 className="text-center">Loading..</h2>}
{products &&
products.map((item) => {
return (
<div class="card mx-auto my-4" style={{ width: "18rem" }}>
<img
class="card-img-top img-responsive"
src={`${item.image}`}
alt="Card image cap"
/>
<div class="card-body">
<p class="card-text">{item.title}</p>
<p class="card-text">{item.price}</p>
<button
onClick={() => dispatch(AddToCart(item.id))}
className="btn btn-info"
>
Add to Cart
</button>
</div>
</div>
);
})}
</div>
</div>
</div>
</>
);
};

export default Home;
47 changes: 47 additions & 0 deletions src/Redux/reducers/ProductSlice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const initialState = {
loading: true,
products: [],
carts: [],
};

// fetch all products
export const fetchAllProducts = createAsyncThunk(
"products/fetchProducts",
async () => {
const res = await axios.get("http://fakestoreapi.com/products");
return res.data;
}
);

const ProductSlice = createSlice({
name: "products/allproducts",
initialState,
reducers: {
AddToCart: (state, action) => {
const cartItem = state.products.find((item) => {
return item.id === action.payload;
});

state.carts = [...state.carts, cartItem];
},
RemoveCartItem: (state, action) => {
const remainItems = state.carts.filter((item) => {
return item.id !== action.payload;
});
state.carts = remainItems;
},
},
extraReducers: (builder) => {
builder
.addCase(fetchAllProducts.fulfilled, (state, action) => {
state.loading = false;
state.products = action.payload;
});
},
});

export const { AddToCart, RemoveCartItem } = ProductSlice.actions;
export default ProductSlice.reducer;
10 changes: 10 additions & 0 deletions src/Redux/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { configureStore } from "@reduxjs/toolkit";
import ProductSlice from "./reducers/ProductSlice";

const store = configureStore({
reducer: {
products: ProductSlice,
},
});

export default store;
34 changes: 34 additions & 0 deletions src/Styles/Cart.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@media (min-width: 1025px) {
.h-custom {
height: 100vh !important;
}
}

.card-registration .select-input.form-control[readonly]:not([disabled]) {
font-size: 1rem;
line-height: 2.15;
padding-left: 0.75em;
padding-right: 0.75em;
}

.card-registration .select-arrow {
top: 13px;
}

.bg-grey {
background-color: #eae8e8;
}

@media (min-width: 992px) {
.card-registration-2 .bg-grey {
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
}
}

@media (max-width: 991px) {
.card-registration-2 .bg-grey {
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
}
23 changes: 16 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/js/bootstrap.bundle.js";
import '@fortawesome/fontawesome-free/css/all.min.css';
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "./Redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
);
Loading

0 comments on commit b0e101e

Please sign in to comment.