├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── index.html
├── logo.jpeg
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.css
├── App.js
├── Components
├── Body
│ ├── About
│ │ ├── About.js
│ │ └── style.css
│ ├── BooksList
│ │ ├── BooksList.js
│ │ └── style.css
│ ├── Buy
│ │ ├── Buy.js
│ │ └── style.css
│ ├── Contact
│ │ └── Contact.js
│ ├── Filter
│ │ └── Filter.js
│ ├── Home
│ │ ├── Home.js
│ │ └── style.css
│ ├── Loading
│ │ └── Loading.js
│ ├── Login
│ │ ├── Login.js
│ │ └── style.css
│ ├── NotFound
│ │ ├── BookNotFound.js
│ │ └── NotFound.js
│ ├── Profile
│ │ ├── Pages
│ │ │ ├── Profile.js
│ │ │ └── Reviews.js
│ │ ├── Profile.js
│ │ └── style.css
│ ├── Rating
│ │ ├── Rating.js
│ │ ├── RatingBook.js
│ │ └── style.css
│ ├── Register
│ │ ├── Register.js
│ │ └── style.css
│ ├── Sales_list
│ │ ├── SalesList.js
│ │ └── SingleItem.js
│ ├── Services
│ │ ├── Services.js
│ │ └── style.css
│ └── SingleBook
│ │ ├── SingleBook.js
│ │ └── style.css
├── Footer
│ ├── Footer.js
│ └── style.css
├── Header
│ ├── Header.js
│ ├── Sections
│ │ ├── BasketShop.js
│ │ ├── Menu.js
│ │ ├── Search.js
│ │ └── SearchModal.js
│ └── style.css
└── utils
│ └── BooksApi.js
├── Context
├── ContextReview.js
├── ContextShopping.js
├── SearchContext.js
└── style.css
├── Data
├── Books.js
├── Contacts.js
├── Rates.js
├── Reviews.js
├── SalesList.js
└── Users.js
├── assets
└── images
│ ├── background1.jpg
│ ├── background2.jpg
│ ├── background3.jpg
│ ├── background4.jpg
│ ├── background5.jpg
│ ├── booksLib.jpeg
│ ├── bookswall.jpg
│ ├── download.jpeg
│ ├── logo.jpeg
│ ├── profile.png
│ ├── review.jpg
│ ├── reviews.jpg
│ ├── reviews.png
│ └── tobuybook.jpg
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
72 |
73 |
74 | # About This Awesome Project:
75 |
76 | ## tools :
77 | 1. I choose mui to create the Front Design.
78 | -mui is a library of UI components designers and developers can use to build React applications.
79 | 2. REACTJS is an open-source JavaScript framework and library developed by Facebook.
80 |
81 | ## Books Library Description :
82 | 1. Get an api list of books (from the Google Books api) using axios and Filter the list by book category (fantasy, horror, romance, sci-fi, ...) .
83 | 2. Customer can login and logout
84 | 3. Customer can buy a book and give it a rating, if he is not logged in, he is redirected to the login page
85 | 4. When he adds a book, the basket is update (increment).
86 | 5. He can remove a book from the added list and the basket will be updated(decrement).
87 | 6. Also, Filter book by creator, title, publisher ...
88 | 7. When user login redirect him to Profile page.
89 | 8. User can add Review on book & Update his reviews.
90 | 9. User can add contact us message & Update his messages.
91 |
92 | => In this project, I Covered (context api to Easily share data between components).
93 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@emotion/react": "^11.10.6",
7 | "@emotion/styled": "^11.10.6",
8 | "@mui/icons-material": "^5.11.11",
9 | "@mui/material": "^5.11.11",
10 | "@testing-library/jest-dom": "^5.16.5",
11 | "@testing-library/react": "^13.4.0",
12 | "@testing-library/user-event": "^13.5.0",
13 | "axios": "^1.3.4",
14 | "react": "^18.2.0",
15 | "react-dom": "^18.2.0",
16 | "react-router-dom": "^6.8.2",
17 | "react-scripts": "5.0.1",
18 | "web-vitals": "^2.1.4"
19 | },
20 | "scripts": {
21 | "start": "react-scripts start",
22 | "build": "react-scripts build",
23 | "test": "react-scripts test",
24 | "eject": "react-scripts eject"
25 | },
26 | "eslintConfig": {
27 | "extends": [
28 | "react-app",
29 | "react-app/jest"
30 | ]
31 | },
32 | "browserslist": {
33 | "production": [
34 | ">0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/public/logo.jpeg
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/App.css
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Routes, Route } from 'react-router-dom';
3 | import Home from './Components/Body/Home/Home';
4 | import About from './Components/Body/About/About';
5 | import Services from './Components/Body/Services/Services';
6 | import Footer from './Components/Footer/Footer';
7 | import Header from './Components/Header/Header';
8 | import BooksList from './Components/Body/BooksList/BooksList';
9 | import Filter from './Components/Body/Filter/Filter';
10 | import Login from './Components/Body/Login/Login';
11 | import Register from './Components/Body/Register/Register';
12 | import Buy from './Components/Body/Buy/Buy';
13 | import NotFound from './Components/Body/NotFound/NotFound';
14 | import Profile from './Components/Body/Profile/Profile';
15 | import ProfileUpdate from './Components/Body/Profile/Pages/Profile';
16 | import Review from './Components/Body/Profile/Pages/Reviews';
17 | import Ratings from './Components/Body/Rating/Rating';
18 | import RatingBook from './Components/Body/Rating/RatingBook';
19 | import Contact from './Components/Body/Contact/Contact';
20 | import SalesList from './Components/Body/Sales_list/SalesList';
21 | import SingleItem from './Components/Body/Sales_list/SingleItem';
22 | import './App.css';
23 |
24 | function App() {
25 | return (
26 |
27 |
28 |
29 | } exact />
30 | } />
31 | } />
32 | } />
33 | } />
34 | } />
35 | } />
36 | } />
37 | } />
38 | } />
39 | } />
40 | } />
41 | } />
42 | } />
43 | } />
44 | } />
45 | } />
46 |
47 |
48 |
49 |
50 | );
51 | }
52 |
53 | export default App;
54 |
--------------------------------------------------------------------------------
/src/Components/Body/About/About.js:
--------------------------------------------------------------------------------
1 | import { Typography, createTheme, Box, CssBaseline, Avatar } from '@mui/material';
2 | import React from 'react';
3 | import wallpaper from "../../../assets/images/background4.jpg";
4 |
5 |
6 | const theme = createTheme();
7 |
8 | function About() {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | ABOUT US
16 |
17 |
18 | Our Books Library Created in January 2023 We offre of users books
19 | with the best price.
20 | our Team are working for making The best Services for Clients.
21 |
22 |
23 | A home for your books :
24 |
25 |
26 | Enter what you're reading or your whole library. It's an easy, library-quality catalog.
27 |
28 |
29 | A community of 2,800 book lovers
30 |
31 |
32 | LibraryThing connects you to people who read what you do.
33 |
34 |
35 |
36 |
37 | );
38 | }
39 |
40 | export default About
--------------------------------------------------------------------------------
/src/Components/Body/About/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Body/About/style.css
--------------------------------------------------------------------------------
/src/Components/Body/BooksList/BooksList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import CssBaseline from '@mui/material/CssBaseline';
3 | import Grid from '@mui/material/Grid';
4 | import Box from '@mui/material/Box';
5 | import Typography from '@mui/material/Typography';
6 | import Container from '@mui/material/Container';
7 | import { useParams } from "react-router-dom";
8 | import SingleBook from '../SingleBook/SingleBook';
9 | import Loading from '../Loading/Loading';
10 | import { getBooks } from '../../utils/BooksApi';
11 |
12 | function BooksList() {
13 | const [books, setBooks] = useState([]);
14 | const [loading, setLoading] = useState(false);
15 | let { BookID } = useParams();
16 |
17 | useEffect(() => {
18 | setLoading(true);
19 | getBooks(BookID, '').then(data => setBooks(data));
20 | setLoading(false);
21 | }, [BookID]);
22 |
23 |
24 | return (
25 |
26 |
27 | {books.length > 0 && loading === false ?
28 |
29 | (
30 |
31 |
32 |
33 |
34 |
35 |
41 |
42 |
49 | Books List
50 |
51 |
52 | This is a Collection of {BookID} Books List :
53 |
54 |
55 |
56 |
57 |
58 |
59 | {books.map((book) => (
60 |
61 |
62 |
63 | ))}
64 |
65 |
66 |
67 |
68 |
69 | )
70 | :
71 | (
72 |
73 |
74 |
75 | )
76 | }
77 |
78 | )}
79 |
80 | export default BooksList
--------------------------------------------------------------------------------
/src/Components/Body/BooksList/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Body/BooksList/style.css
--------------------------------------------------------------------------------
/src/Components/Body/Buy/Buy.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState, useContext } from 'react';
2 | import axios from 'axios';
3 | import { useNavigate, useParams } from "react-router-dom";
4 | import Loading from '../Loading/Loading';
5 | import BookNotFound from '../NotFound/BookNotFound';
6 | import { ShoppingContext } from '../../../Context/ContextShopping';
7 | import './style.css';
8 |
9 | function Buy() {
10 | const {book, setBook, BookData} = useContext(ShoppingContext);
11 | const [loading, setLoading] = useState(true);
12 | const navigate = useNavigate();
13 | const params = useParams();
14 |
15 | const getBook = async () => {
16 | setLoading(true);
17 | await axios.get(`https://www.googleapis.com/books/v1/volumes?q=${params.idBook}&key=AIzaSyDKG8AN_GKcPk-V3AaA0DXYvuJ2kpdXUG8`)
18 | .then(res => {
19 | setBook(res.data.items[0])
20 | })
21 | .catch(error => {
22 | //setBook(null)
23 | console.log(error)
24 | })
25 | setLoading(false);
26 | }
27 |
28 | useEffect(() => {
29 | if (!localStorage.getItem("getFirstName")) {
30 | navigate('/Login');
31 | } else {
32 | getBook();
33 | }
34 | }, []);
35 |
36 | return (
37 |
38 | {loading ?
39 | (
40 |
41 | )
42 | : book.length !== 0 ?
43 |
44 | :
45 |
46 | }
47 |
48 | )
49 | }
50 |
51 | export default Buy;
--------------------------------------------------------------------------------
/src/Components/Body/Buy/style.css:
--------------------------------------------------------------------------------
1 | #imga{
2 | height: 450px;
3 | width: 550px;
4 |
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/src/Components/Body/Contact/Contact.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef,useContext } from 'react';
2 | import { Grid, Box, Typography, Button, TextField} from '@mui/material';
3 | import { ReviewContext } from '../../../Context/ContextReview';
4 | import { Link } from 'react-router-dom';
5 |
6 | import Contacts from '../../../Data/Contacts.js';
7 |
8 | function Contact() {
9 | const [contact, setContact] = useState(Contacts.filter(contact => contact.user_id == localStorage.getItem('getID')));
10 | const [ShowModal] = useContext(ReviewContext);
11 | const [open, setOpen] = useState(false);
12 |
13 | const handleOpen = () => setOpen(true);
14 |
15 | const opinionRef = useRef(null);
16 | const errorDescription = useRef(null);
17 |
18 | const handleSubmit = (e) => {
19 | e.preventDefault();
20 |
21 | const message = opinionRef.current.value;
22 |
23 | const verify_message = contact.filter(contact => contact.content === message);
24 |
25 |
26 |
27 | if (message.length < 8) {
28 | return errorDescription.current.innerHTML = "Your Message Must Contain over 7 Caracters";
29 | } else if (verify_message.length > 0) {
30 | return errorDescription.current.innerHTML = "You Write This Contact before";
31 | }else{
32 | errorDescription.current.innerHTML= "";
33 | }
34 |
35 | const date = new Date();
36 | const newContact = {
37 | id: contact.length + 1,
38 | user_id: localStorage.getItem('getID'),
39 | content: message,
40 | published_date: `${date.getDate()} / ${date.getMonth()} / ${date.getFullYear()}`
41 | }
42 |
43 | setContact([...contact, newContact])
44 |
45 | }
46 | const HandleDeleteContact = (e) => {
47 | /* Add Code Here To Delete is From Databse,
48 | if not when The Page Reload The Deleted Element Will Show Again */
49 | setContact(contact.filter(cont => cont.id !== parseInt(e.target.value) ));
50 | }
51 |
52 | return (
53 |
54 |
55 | Profile
56 |
67 | Add Contact :
68 |
69 |
78 |
79 |
80 |
81 |
88 | add Contact
89 |
90 |
91 |
92 |
93 | {contact.map(cont => (
94 |
95 | Contact Message : {cont.content}.
96 | Date Of Publication : {cont.published_date}.
97 |
98 |
99 | Delete
100 | Update
101 |
102 |
103 |
104 | ))}
105 |
106 |
107 | )
108 | }
109 |
110 | export default Contact;
--------------------------------------------------------------------------------
/src/Components/Body/Filter/Filter.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import axios from 'axios';
3 | import { Button, Box, InputLabel, Select, MenuItem, FormControl, Typography, Paper, Container, Grid } from '@mui/material';
4 | import { createTheme, ThemeProvider } from '@mui/material/styles';
5 | import { Alert, AlertTitle, CircularProgress, TextField } from '@mui/material';
6 | import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
7 | import MoodBadIcon from '@mui/icons-material/MoodBad';
8 | import SingleBook from "../SingleBook/SingleBook"
9 | import Loading from '../Loading/Loading';
10 | import wallpaper from "../../../assets/images/background4.jpg";
11 | import { getBooks } from '../../utils/BooksApi';
12 |
13 | const theme = createTheme();
14 | function Filter() {
15 | const [filter, setFilter] = useState('');
16 | const [search, setSearch] = useState('');
17 | const [result, setResult] = useState([]);
18 | const [loading, setLoading] = useState(false);
19 | const handleChangeSelect = (event) => {
20 | setFilter(event.target.value);
21 | };
22 |
23 | const handleChangeSearch = (e) => {
24 | setSearch(e.target.value);
25 | }
26 |
27 | const getFilterdResult = async () => {
28 | setLoading(true)
29 |
30 | if (filter === "author" && search.length > 3) {
31 |
32 | getBooks(search, 'inauthor:%22').then(data => setResult(data));
33 |
34 | } else if (filter === "title" && search.length > 3) {
35 |
36 | getBooks(search, 'intitle:%22').then(data => setResult(data));
37 |
38 | } else if (filter === "publisher" && search.length > 3) {
39 |
40 | getBooks(search, 'inpublisher:%22').then(data => setResult(data));
41 |
42 | } else if (filter === "subject" && search.length > 3) {
43 | getBooks(search, 'subject:%22').then(data => setResult(data));
44 |
45 | } else if (search.length < 4) {
46 | document.getElementById("attention").innerHTML = "Search Must Contain More Than 3 Caracters";
47 | } else if (result.length === 0) {
48 | document.getElementById('attention').innerHTML = `There is no results That mutch ${search} !`;
49 | }
50 | if (filter === '') {
51 | document.getElementById("attention").innerHTML = "You Must Select one Field of The List";
52 | }
53 | if (search.length > 3) {
54 | document.getElementById("attention").innerHTML = "";
55 |
56 | }
57 | setLoading(false);
58 |
59 | console.log(result);
60 | }
61 |
62 | return (
63 |
64 |
65 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | Find & Buy Books :
84 |
85 | Filter:
86 |
95 |
96 | None
97 |
98 | authors
99 | title
100 | publisher
101 | subject
102 |
103 | {filter !== "" ?
104 | ( ) :
112 | ''
113 | }
114 |
115 | Search
116 | Books Result Down
117 |
118 |
119 |
120 |
121 |
122 |
123 | {loading && search.length > 3 && result ? (
124 |
125 | ) :
126 | (result ?
127 | (
128 |
129 |
130 | {result.map((book, index) => (
131 |
132 |
133 |
134 | ))}
135 |
136 |
137 |
138 | ) :
139 | (
140 |
141 | Books
142 | There is no Books That Match [ {search} ] String — Enter a Correct Information Next Time ....
143 |
144 | )
145 | )
146 |
147 | }
148 |
149 |
150 |
151 | )
152 | }
153 |
154 | export default Filter;
--------------------------------------------------------------------------------
/src/Components/Body/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Grid, Typography, Paper, Box, Button } from '@mui/material';
3 | import { useNavigate } from 'react-router-dom';
4 | import Background1 from '../../../assets/images/background2.jpg';
5 | import './style.css';
6 | function Home() {
7 | const navigate = useNavigate()
8 | return (
9 |
21 |
32 |
33 |
34 |
43 |
44 | Welcome To Our Books Library
45 |
46 |
47 | In our Library we offre you the ability to recommend Books, Rate, Review on Books & Sort List Of Books and Mutch More Services
48 |
49 | {!localStorage.getItem('getID') ?
50 |
51 | { navigate('/Login') }}>Login Page
52 |
53 | { navigate('/Register') }} >Register Page
54 |
55 | :
56 |
57 | { navigate('/Filter') }}>Buy Book
58 | { navigate('/Profile') }}>Profile
59 | { navigate('/Contacts') }}>Contact US
60 |
61 | }
62 |
63 |
64 |
65 |
66 | );
67 | }
68 |
69 |
70 | export default Home;
--------------------------------------------------------------------------------
/src/Components/Body/Home/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Body/Home/style.css
--------------------------------------------------------------------------------
/src/Components/Body/Loading/Loading.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import CircularProgress from '@mui/material/CircularProgress';
3 | import {Typography, Paper, Container } from '@mui/material';
4 |
5 |
6 | function Loading() {
7 | return (
8 |
16 |
17 |
18 | Loading From Book's Data ...
19 |
20 |
21 | )
22 | }
23 |
24 | export default Loading
--------------------------------------------------------------------------------
/src/Components/Body/Login/Login.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from 'react';
2 | import Avatar from '@mui/material/Avatar';
3 | import Button from '@mui/material/Button';
4 | import CssBaseline from '@mui/material/CssBaseline';
5 | import TextField from '@mui/material/TextField';
6 | import {Link} from 'react-router-dom';
7 | import Grid from '@mui/material/Grid';
8 | import Paper from '@mui/material/Paper';
9 | import Box from '@mui/material/Box';
10 | import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
11 | import Typography from '@mui/material/Typography';
12 | import { useNavigate } from 'react-router-dom';
13 | import wallpaper from "../../../assets/images/background5.jpg";
14 | import Users from '../../../Data/Users';
15 | import './style.css';
16 |
17 |
18 | export default function Login() {
19 | const navigate = useNavigate();
20 | const handleSubmit = (event) => {
21 | event.preventDefault();
22 | const data = new FormData(event.currentTarget);
23 | console.log({
24 | email: data.get('email'),
25 | password: data.get('password'),
26 | });
27 | const email = data.get('email')
28 | const password = data.get('password')
29 | const FindUser = Users.filter(user => user.email === email && user.password === password);
30 |
31 | // if user Found then Login else Send an error Message.
32 |
33 | console.log(FindUser[0])
34 | if (FindUser[0]) {
35 | localStorage.setItem("getID", FindUser[0].id);
36 | localStorage.setItem("getFirstName", FindUser[0].Firstname);
37 | localStorage.setItem("getSecondName", FindUser[0].Secondname);
38 | localStorage.setItem("getAddress", FindUser[0].address);
39 | window.location.replace('/profile');
40 | } else if(!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) || !(/^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{6,16}$/.test(password))) {
41 | document.getElementById("errormsg").innerHTML = "Please, Verify Your email and Password";
42 | }else{
43 | document.getElementById("errormsg").innerHTML = "Email or Password Incorrect ";
44 | }
45 |
46 | };
47 | /*
48 | useEffect(() => {
49 | if(localStorage.getItem("getUsername")){
50 | navigate('/Profile');
51 | }
52 | },[])
53 | */
54 | return (
55 |
67 |
68 |
81 |
82 |
83 |
84 |
85 |
86 | Sign in
87 |
88 |
89 |
101 |
102 |
103 |
115 |
116 |
117 |
118 |
119 |
125 | Sign In
126 |
127 |
128 |
129 |
130 | Don't have an account? Click Here Sign Up
131 |
132 |
133 |
134 |
135 |
136 |
137 | );
138 | }
--------------------------------------------------------------------------------
/src/Components/Body/Login/style.css:
--------------------------------------------------------------------------------
1 | #email, #password {
2 | color: white;
3 | }
--------------------------------------------------------------------------------
/src/Components/Body/NotFound/BookNotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Box from '@mui/material/Box';
3 | import Typography from '@mui/material/Typography';
4 | import Button from '@mui/material/Button';
5 | import Alert from '@mui/material/Alert';
6 | import { useNavigate } from "react-router-dom";
7 | import { Grid } from '@mui/material';
8 | import { Container } from '@mui/system';
9 | import SentimentVeryDissatisfiedIcon from '@mui/icons-material/SentimentVeryDissatisfied';
10 | import bookswall from "../../../assets/images/bookswall.jpg";
11 |
12 | function BookNotFound() {
13 | const navigate = useNavigate();
14 |
15 | return (
16 |
25 |
26 |
27 |
28 |
29 | 400
30 |
31 |
32 |
33 |
34 | This Book Is not available for rating right now
35 |
36 | navigate('/Rate')} sx={{ margin: "30px", ml:10 }}>Go Back
37 |
38 |
39 |
40 |
41 | )
42 | }
43 |
44 | export default BookNotFound
--------------------------------------------------------------------------------
/src/Components/Body/NotFound/NotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Box, Button, Container, Typography } from '@mui/material';
3 | import Grid from '@mui/material/Grid';
4 | import { useNavigate } from 'react-router-dom';
5 |
6 | function NotFound() {
7 | const navigate = useNavigate();
8 |
9 | return (
10 |
21 |
22 |
23 |
24 |
25 | 404
26 |
27 |
28 | The page you’re looking for doesn’t exist.
29 |
30 | navigate('/')}>Back Home
31 |
32 |
33 |
34 |
35 |
36 |
37 | )
38 | }
39 |
40 | export default NotFound;
--------------------------------------------------------------------------------
/src/Components/Body/Profile/Pages/Profile.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link } from 'react-router-dom';
3 |
4 | function ProfileUpdate() {
5 | return (
6 | <>
7 | Profile Update
8 | Profile
9 | >
10 | )
11 | }
12 |
13 | export default ProfileUpdate;
--------------------------------------------------------------------------------
/src/Components/Body/Profile/Pages/Reviews.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef, useContext } from 'react'
2 | import { Grid, Box, Typography, Button, TextField } from '@mui/material';
3 | import { Link } from 'react-router-dom';
4 | import { ReviewContext } from '../../../../Context/ContextReview';
5 | import Books from '../../../../Data/Books.js';
6 | import Reviews from '../../../../Data/Reviews.js';
7 |
8 | function Review() {
9 | const [review, setReview] = useState(Reviews.filter(review => review.user_id == localStorage.getItem('getID')));
10 | const [ShowModal] = useContext(ReviewContext);
11 | const [open, setOpen] = useState(false);
12 |
13 | const bookRef = useRef(null);
14 | const opinionRef = useRef(null);
15 | const errorBook = useRef(null);
16 | const errorDescription = useRef(null);
17 |
18 | const handleOpen = () => setOpen(true);
19 |
20 | const handleSubmit = (e) => {
21 | e.preventDefault();
22 | const book = bookRef.current.value;
23 | const opinion = opinionRef.current.value;
24 |
25 | if (book.trim() === "") {
26 | errorBook.current.innerHTML = 'Empty Field Please Enter Book Name !';
27 | return;
28 | } else {
29 | errorBook.current.innerHTML = ''
30 | }
31 |
32 | if (opinion.trim().length < 8) {
33 | errorDescription.current.innerHTML = 'This Field Must Contain at Least 8 Caracters ! ';
34 | return;
35 | } else {
36 | errorDescription.current.innerHTML = ''
37 | }
38 |
39 | let bookID = Books.filter(booky => booky.name.toLowerCase().trim() == book.toLowerCase().trim());
40 |
41 | if (bookID.length !== 0) {
42 | bookID = bookID[0].id;
43 | const test = review.filter(rev => rev.book_id == bookID)
44 | console.log(test)
45 | if (test.length !== 0) {
46 | return errorBook.current.innerHTML = 'This book has already been rated';
47 | }
48 | else {
49 | errorBook.current.innerHTML = '';
50 | }
51 | }
52 | else {
53 | return errorBook.current.innerHTML = 'This book is not available in our list right now'
54 | }
55 |
56 | const newReview =
57 | {
58 | id: review.length + 1,
59 | user_id: localStorage.getItem('getID'),
60 | review: opinionRef.current.value,
61 | book_id: bookID,
62 | };
63 |
64 | console.log(newReview)
65 | setReview([newReview, ...review]);
66 | }
67 |
68 | const HandleDelete = (e) => {
69 | /* Add Code Here To Delete is From Databse,
70 | if not when The Page Reload The Deleted Element Will Show Again */
71 | console.log(e.target.value)
72 | setReview(review.filter(rev => rev.id != e.target.value));
73 | }
74 | const BookNames = [];
75 | review.map(rev => Books.map(book => book.id == rev.book_id && BookNames.push(book.name)));
76 |
77 | return (
78 |
79 |
80 | Profile
81 |
92 | Add Review
93 |
94 |
107 |
108 |
117 |
118 |
119 |
120 |
127 | add Review
128 |
129 |
130 |
131 |
132 | {review.map((rev, index) => (
133 |
134 | Name : {BookNames[index]}.
135 | Review : {rev.review}.
136 |
137 | Delete
138 | Update
139 |
140 |
141 |
142 | ))}
143 |
144 |
145 | )
146 | }
147 |
148 | export default Review;
--------------------------------------------------------------------------------
/src/Components/Body/Profile/Profile.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react'
2 | import { createTheme, ThemeProvider } from '@mui/material/styles';
3 | import { styled } from '@mui/material/styles';
4 | import Box from '@mui/material/Box';
5 | import Paper from '@mui/material/Paper';
6 | import Grid from '@mui/material/Grid';
7 | import { Link, useNavigate } from 'react-router-dom';
8 | import { Card, CardActions, CardContent, CardMedia, Typography } from '@mui/material';
9 | import Divider from '@mui/material/Divider';
10 | import Avatar from '@mui/material/Avatar';
11 | import StarHalfIcon from '@mui/icons-material/StarHalf';
12 | import RemoveRedEyeIcon from '@mui/icons-material/RemoveRedEye';
13 | import PersonIcon from '@mui/icons-material/Person';
14 | import List from '@mui/material/List';
15 | import ListItem from '@mui/material/ListItem';
16 | import ListItemButton from '@mui/material/ListItemButton';
17 | import ListItemIcon from '@mui/material/ListItemIcon';
18 | import ListItemText from '@mui/material/ListItemText';
19 | import CallIcon from '@mui/icons-material/Call';
20 | import VisibilityIcon from '@mui/icons-material/Visibility';
21 | import PeopleAltIcon from '@mui/icons-material/PeopleAlt';
22 | import GradeIcon from '@mui/icons-material/Grade';
23 | import MenuBookIcon from '@mui/icons-material/MenuBook';
24 |
25 | import download from "../../../assets/images/download.jpeg";
26 | import review from "../../../assets/images/review.jpg";
27 | import profile from "../../../assets/images/profile.png";
28 | import "./style.css"
29 |
30 | const mdTheme = createTheme();
31 | const Item = styled(Paper)(({ theme }) => ({
32 | backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
33 | ...theme.typography.body2,
34 | padding: theme.spacing(1),
35 | textAlign: 'center',
36 | color: theme.palette.text.secondary,
37 | }));
38 | function Profile() {
39 |
40 | const [open, setOpen] = React.useState(true);
41 | const toggleDrawer = () => {
42 | setOpen(!open);
43 | };
44 |
45 | const navigate = useNavigate();
46 | useEffect(() => {
47 | if (!localStorage.getItem("getFirstName")) {
48 | navigate("/login")
49 | }
50 | }, []);
51 |
52 | return (
53 |
54 |
55 |
56 |
57 |
58 | {localStorage.getItem("getFirstName")} {localStorage.getItem("getSecondName")}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
134 |
145 |
146 |
147 |
148 | Update & add Contacts
149 |
150 |
151 |
152 |
153 |
154 |
155 | Contact US
156 |
157 |
158 |
159 |
160 |
161 |
162 |
165 |
176 |
177 |
178 |
179 | Update & add Reviews
180 |
181 |
182 |
183 |
184 |
185 |
186 | Reviews
187 |
188 |
189 |
190 |
191 |
192 |
193 |
196 |
207 |
208 |
209 |
210 | Update Profile
211 |
212 |
213 |
214 |
215 | Profile
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 | )
225 | }
226 |
227 | export default Profile;
--------------------------------------------------------------------------------
/src/Components/Body/Profile/style.css:
--------------------------------------------------------------------------------
1 | .fixedbtn{
2 | text-decoration: none;
3 | position: fixed;
4 | right:0px;
5 | top : 50%;
6 | background: #3f51b5;;
7 | color: aliceblue;
8 | padding: 15px;
9 | border-bottom-left-radius: 5px;
10 | border-top-left-radius: 5px;
11 | font-weight: bold;
12 | }
13 |
14 | .fixedbtn:hover{
15 | background: #5563b8;
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/Components/Body/Rating/Rating.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import axios from 'axios';
3 | import Box from '@mui/material/Box';
4 | import Rating from '@mui/material/Rating';
5 | import GradeIcon from '@mui/icons-material/Grade';
6 | import Typography from '@mui/material/Typography';
7 | import Button from '@mui/material/Button';
8 | import Modal from '@mui/material/Modal';
9 | import Alert from '@mui/material/Alert';
10 | import { useNavigate, useParams } from "react-router-dom";
11 | import { FormControl } from '@mui/material';
12 | import { Container } from '@mui/system';
13 |
14 | import { getBooks } from '../../utils/BooksApi';
15 | import Loading from '../Loading/Loading';
16 | import BookNotFound from '../NotFound/BookNotFound';
17 | import './style.css'
18 |
19 | const style = {
20 | position: 'absolute',
21 | top: '50%',
22 | left: '50%',
23 | transform: 'translate(-50%, -50%)',
24 | bgcolor: 'rgb(0 0 0 / 0.9)',
25 | textAlign: "center",
26 | boxShadow: 24,
27 | width: '450px',
28 | py: 10,
29 | };
30 |
31 | const boxSX = {
32 | "&:hover": {
33 | border: "1px solid #ffcdd2",
34 | color: 'red',
35 | backgroundColor: '#757575'
36 | },
37 | };
38 |
39 | export default function Ratings() {
40 | const navigate = useNavigate();
41 | const [value, setValue] = useState(null);
42 | const [open, setOpen] = useState(false);
43 | const [book, setBook] = useState([]);
44 | const [add, setAdd] = useState(false);
45 | const [loading, setLoading] = useState(true);
46 | const [exist, setExist] = useState(false);
47 | const handleOpen = () => setOpen(true);
48 | const handleClose = () => setOpen(false);
49 |
50 | const params = useParams();
51 |
52 |
53 | const handleClick = (e) => {
54 | setValue(Number(e.target.value));
55 | }
56 |
57 | const addRateValue = async () => {
58 | // verify id user add a rate on this movie once
59 | // if yes set the state of exist true
60 | if (!exist && value) {
61 | setAdd(true);
62 | await setInterval(() => {
63 | setValue(null);
64 | setAdd(false);
65 | window.location.replace('/');
66 | //navigate('/', { replace: false });
67 | }, 2000);
68 | }
69 | }
70 |
71 | const getBook = async () => {
72 | setLoading(true);
73 |
74 | await axios.get(`https://www.googleapis.com/books/v1/volumes?q=${params.idBook}&key=AIzaSyDKG8AN_GKcPk-V3AaA0DXYvuJ2kpdXUG8`)
75 | .then(res => {
76 | setBook(res.data.items[0])
77 | })
78 | .catch(error => {
79 | //setBook(null)
80 | console.log(error)
81 | })
82 | setLoading(false);
83 | }
84 | useEffect(() => {
85 | if (!localStorage.getItem("getFirstName")) {
86 | navigate('/Login');
87 | } else {
88 | getBook();
89 | }
90 | }, [])
91 |
92 | return (
93 |
94 | {loading ?
95 | (
96 |
97 | )
98 | : book.length !== 0 ?
99 | (
100 |
101 |
105 |
106 |
107 | Click The Link Bellow For Rating Book
108 | title : {book.volumeInfo.title}
109 | Author : {book.volumeInfo.authors}
110 | Rate Book
111 |
112 |
118 |
119 |
120 | Rate This Book
121 | Book : {book.volumeInfo.title}
122 | e.preventDefault()}>
123 |
124 | Rate
125 |
126 | {value && book.length !== 0 && add ?
127 |
128 | This Book was rated Successfully
129 |
130 | : exist ?
131 | Error you rate this number once
132 | : !value && add ?
133 | add rate number please ...
134 | : ''
135 | }
136 |
137 |
138 |
139 | )
140 | :
141 |
142 | }
143 |
144 |
145 | );
146 | }
--------------------------------------------------------------------------------
/src/Components/Body/Rating/RatingBook.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import Box from '@mui/material/Box';
3 | import { Button, FormControl, Typography, TextField, Paper, Container, Grid, Alert, AlertTitle } from '@mui/material';
4 | import MoodBadIcon from '@mui/icons-material/MoodBad';
5 | import { useNavigate } from 'react-router-dom';
6 | import { getBooks } from '../../utils/BooksApi';
7 | import wallpaper from "../../../assets/images/background4.jpg";
8 | import SingleBook from '../SingleBook/SingleBook';
9 | import Loading from '../Loading/Loading';
10 |
11 | function RatingBook() {
12 | const [value, setValue] = useState('');
13 | const [book, setBook] = useState([]);
14 | const [loading, setLoading] = useState(false);
15 |
16 | const navigate = useNavigate();
17 |
18 | const handleChange = (e) => {
19 | setValue(e.target.value)
20 | }
21 |
22 | const SearchBook = async () => {
23 | setLoading(true);
24 | if(value.length < 3 ){
25 | return
26 | }
27 | getBooks(value, 'intitle:%22').then(data => setBook(data));
28 | setLoading(false);
29 | }
30 |
31 | useEffect(() => {
32 | if (!localStorage.getItem("getFirstName")) {
33 | navigate('/Login');
34 | }
35 | }, [])
36 | console.log(book)
37 | return (
38 |
39 |
40 |
52 |
53 |
54 |
55 | Search Book To Rate :
56 |
57 |
58 | Search
59 |
60 |
61 |
62 | {loading & book ?
63 | (
64 |
65 | )
66 | : book ?
67 | (
68 |
69 | Books List :
70 |
71 |
72 | {book.map((item, index) => (
73 |
74 |
75 |
76 | ))}
77 |
78 |
79 |
80 | )
81 | :
82 | (
83 |
84 |
85 | Book Not Found
86 | There is no Books That Match [ {value} ] String — Enter a Correct Information Next Time ....
87 |
88 |
89 | )
90 | }
91 |
92 |
93 | )
94 | }
95 |
96 | export default RatingBook
--------------------------------------------------------------------------------
/src/Components/Body/Rating/style.css:
--------------------------------------------------------------------------------
1 | #inputseart{
2 | font-size: 25px;
3 | color :white
4 | }
--------------------------------------------------------------------------------
/src/Components/Body/Register/Register.js:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import Avatar from '@mui/material/Avatar';
3 | import Button from '@mui/material/Button';
4 | import CssBaseline from '@mui/material/CssBaseline';
5 | import TextField from '@mui/material/TextField';
6 | import {Link} from 'react-router-dom';
7 | import Grid from '@mui/material/Grid';
8 | import Box from '@mui/material/Box';
9 | import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
10 | import Typography from '@mui/material/Typography';
11 | import Paper from '@mui/material/Paper';
12 | import wallpaper from "../../../assets/images/background5.jpg";
13 |
14 | import { useNavigate } from 'react-router-dom';
15 | import Users from '../../../Data/Users'
16 | import './style.css'
17 |
18 |
19 |
20 | export default function Register() {
21 | const navigate = useNavigate();
22 | const handleSubmit = (event) => {
23 | event.preventDefault();
24 | const data = new FormData(event.currentTarget);
25 | console.log({
26 | email: data.get('email'),
27 | password: data.get('password'),
28 | });
29 | const email = data.get('email');
30 | const password = data.get('password');
31 | const First_name = data.get('firstName');
32 | const Last_name = data.get('lastName');
33 | const username = data.get('username');
34 | const verify_username = Users.filter(user => { return user.Username === username })
35 | const verify_email = Users.filter(user => { return user.email === email })
36 |
37 | if (email.length === 0 || First_name.length === 0 || password.length === 0 || Last_name.length === 0 || username.length === 0 ) {
38 | document.getElementById("Register_Error").innerHTML = "Empty Field, Verify Your Inputs";
39 | }else if (!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email))){
40 | document.getElementById("Register_Error").innerHTML = "email must mutch this form xxxxxx@xxxx.xxs";
41 | }/*else if(!(/^[A-Z][a-z][0-9]{8,20}$/.test(email))){
42 | document.getElementById("Register_Error").innerHTML = "password must contain over 7 caracter, numbers and letters";
43 | }*/
44 | else if(verify_email.length !== 0){
45 | document.getElementById("Register_Error").innerHTML = "This Email is Used by another Person";
46 | }else if (verify_username.length !== 0) {
47 | document.getElementById("Register_Error").innerHTML = "This Username is Used by another Person";
48 |
49 | }else{
50 | document.getElementById("Register_Error").innerHTML = "";
51 | const created = true;
52 | if(created){
53 | // add user informations to localstorage
54 | localStorage.setItem("getUsername", username);
55 | localStorage.setItem("getEmail", email);
56 | localStorage.setItem("getFirstName", First_name);
57 | localStorage.setItem("getSirstName", Last_name);
58 | window.location.replace('/profile');
59 | }else{
60 | document.getElementById("Register_Error").innerHTML = "Account cannot be created for some reasons";
61 | }
62 | }
63 |
64 |
65 | // add user to the database.
66 |
67 |
68 | };
69 |
70 | return (
71 |
84 |
85 |
98 |
99 |
100 |
101 |
102 | Sign up
103 |
104 |
105 |
106 |
107 |
108 |
117 |
118 |
119 |
128 |
129 |
130 |
139 |
140 |
141 |
150 |
151 |
152 |
162 |
163 |
164 |
165 |
171 | Sign Up
172 |
173 |
174 |
175 |
176 | Already have an account? Sign in
177 |
178 |
179 |
180 |
181 |
182 |
183 | );
184 | }
--------------------------------------------------------------------------------
/src/Components/Body/Register/style.css:
--------------------------------------------------------------------------------
1 | #firstName, #lastName, #username, #email, #password {
2 | color: white;
3 | font-size: 18px;
4 | font-weight: bold;
5 | }
--------------------------------------------------------------------------------
/src/Components/Body/Sales_list/SalesList.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react'
2 | import { Typography, Box, Paper, Container, Button, Grid, Card, CardMedia, CardContent } from '@mui/material';
3 | import { ShoppingContext } from '../../../Context/ContextShopping';
4 | import backgroundImg from '../../../assets/images/background1.jpg';
5 |
6 | function SalesList(e) {
7 | const {listbooks, UpdateBasket} = useContext(ShoppingContext);
8 |
9 | return (
10 |
17 |
18 | List Of Sales
19 | {listbooks.length > 0 ?
20 |
21 |
22 | {listbooks.map((itembook, index) => (
23 |
24 |
27 |
38 |
39 |
40 | {itembook.volumeInfo.title}
41 |
42 | Delete recumendation
43 |
44 |
45 |
46 |
47 | ))}
48 |
49 |
50 | :
51 | You have not Recommande Books Yet ...
52 | }
53 |
54 |
55 |
56 | )
57 | }
58 |
59 | export default SalesList
--------------------------------------------------------------------------------
/src/Components/Body/Sales_list/SingleItem.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react'
2 | import { Typography, Box, Card, CardMedia, CardContent, Grid, Container, Paper, Button } from '@mui/material';
3 | import { ShoppingContext } from '../../../Context/ContextShopping';
4 | import { useParams } from 'react-router-dom';
5 | import backgroundImg from '../../../assets/images/background1.jpg';
6 |
7 | function SingleItem() {
8 | const {book, listbooks, UpdateBasket} = useContext(ShoppingContext);
9 |
10 | // the useCallback for prevent bookItem/qbrgAAAAMAAJ, whene listbooks && BookItem undefined.
11 | const bookid = useParams();
12 |
13 | let BookItem = listbooks.filter(book => book.id == bookid.ItemID)[0];
14 |
15 | console.log(BookItem)
16 | let Thumbnail = BookItem.volumeInfo.imageLinks && BookItem.volumeInfo.imageLinks.smallThumbnail;
17 |
18 | return (
19 |
26 |
27 | List Of Sales
28 |
29 |
30 |
31 |
32 |
33 |
36 |
47 |
48 |
49 | {BookItem.volumeInfo.title}
50 |
51 | Delete recumendation
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | )
62 | }
63 |
64 | export default SingleItem
--------------------------------------------------------------------------------
/src/Components/Body/Services/Services.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Services() {
4 | return (
5 | Services
6 | )
7 | }
8 |
9 | export default Services
--------------------------------------------------------------------------------
/src/Components/Body/Services/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Body/Services/style.css
--------------------------------------------------------------------------------
/src/Components/Body/SingleBook/SingleBook.js:
--------------------------------------------------------------------------------
1 | import React, {useState } from 'react'
2 | import Card from '@mui/material/Card';
3 | import CardActions from '@mui/material/CardActions';
4 | import CardContent from '@mui/material/CardContent';
5 | import CardMedia from '@mui/material/CardMedia';
6 | import Button from '@mui/material/Button';
7 | import Typography from '@mui/material/Typography';
8 | import Box from '@mui/material/Box';
9 | import Modal from '@mui/material/Modal';
10 | import { Link } from 'react-router-dom';
11 | import StarBorderIcon from '@mui/icons-material/StarBorder';
12 |
13 | import "./style.css";
14 |
15 | const style = {
16 | position: 'absolute',
17 | top: '50%',
18 | left: '50%',
19 | transform: 'translate(-50%, -50%)',
20 | bgcolor: 'rgb(0 0 0 / 0.9)',
21 | color: 'white',
22 | border: '0.5px solid #000',
23 | boxShadow: 24,
24 | pt: 5,
25 | px: 4,
26 | display:'flex',
27 | width: {md:750, xs:500},
28 | height: 400,
29 |
30 | };
31 |
32 | function CardBook({ Databook }) {
33 | const [open, setOpen] = useState(false);
34 |
35 | let Thumbnail = Databook.volumeInfo.imageLinks && Databook.volumeInfo.imageLinks.smallThumbnail;
36 |
37 | const handleOpen = () => {
38 | setOpen(true);
39 | };
40 |
41 | const handleClose = () => {
42 | setOpen(false);
43 | };
44 |
45 | return (
46 |
49 |
60 |
61 |
62 | {Databook.volumeInfo.title}
63 |
64 |
65 |
66 |
67 | Show
68 |
75 |
76 |
77 |
78 | Title : {Databook.volumeInfo.title}
79 | Authors : {Databook.volumeInfo.authors}
80 | Publisher :{Databook.volumeInfo.publisher}
81 | Published Date : {Databook.volumeInfo.publishedDate}
82 | Number Of Pages : {Databook.volumeInfo.pageCount}
83 | Close
84 | Buy
85 | Rate
86 |
87 |
88 |
89 | Buy
90 |
91 |
92 |
93 | )
94 | }
95 |
96 | export default CardBook;
--------------------------------------------------------------------------------
/src/Components/Body/SingleBook/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Body/SingleBook/style.css
--------------------------------------------------------------------------------
/src/Components/Footer/Footer.js:
--------------------------------------------------------------------------------
1 | import { Box, Typography } from '@mui/material';
2 | import React from 'react'
3 | import Grid from '@mui/material/Grid';
4 | import IconButton from '@mui/material/IconButton';
5 | import FacebookIcon from '@mui/icons-material/Facebook';
6 | import InstagramIcon from '@mui/icons-material/Instagram';
7 | import TwitterIcon from '@mui/icons-material/Twitter';
8 | import YouTubeIcon from '@mui/icons-material/YouTube';
9 | import LinkedInIcon from '@mui/icons-material/LinkedIn';
10 | function Footer() {
11 | return (
12 |
13 |
14 | Books Library
15 |
16 |
22 | We Hope You Found What You Need
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | )
54 | }
55 |
56 | export default Footer;
--------------------------------------------------------------------------------
/src/Components/Footer/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Footer/style.css
--------------------------------------------------------------------------------
/src/Components/Header/Header.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from 'react'
2 | import { Modal, Container, Button, AppBar, Typography, Box, Avatar, Toolbar, CssBaseline, IconButton, Menu } from '@mui/material';
3 | import MenuIcon from '@mui/icons-material/Menu';
4 | import { Link as Linko } from '@mui/material';
5 | import { Link, useNavigate } from 'react-router-dom';
6 | import CircularProgress from '@mui/material/CircularProgress';
7 | import SearchInput from './Sections/Search';
8 | import BasketShop from './Sections/BasketShop';
9 | import logo from '../../assets/images/logo.jpeg';
10 | import './style.css';
11 |
12 | const style = {
13 | position: 'absolute',
14 | top: '50%',
15 | left: '50%',
16 | transform: 'translate(-50%, -50%)',
17 | bgcolor: 'rgb(0 0 0 / 0.9)',
18 | textAlign: "center",
19 | boxShadow: 24,
20 | width: '600px',
21 | py: 2,
22 | border: '2px solid white'
23 | };
24 |
25 | const pages = ['Home', 'About', "Filter", 'Rate'];
26 | const links = ['Adventure', 'Classics', 'Crime', 'Fantasy', 'Historical fiction', 'Horror', 'Humour and satire'];
27 |
28 | function Header() {
29 | const [result, setResult] = useState([]);
30 | const [loading, setLoading] = useState(true);
31 | const [open, setOpen] = useState(false);
32 | const [anchorElNav, setAnchorElNav] = useState(null);
33 |
34 | const isLogin = localStorage.getItem('getID');
35 | const navigate = useNavigate();
36 |
37 |
38 |
39 | const handleOpenNavMenu = (event) => {
40 | setAnchorElNav(event.currentTarget);
41 | };
42 |
43 | const handleCloseNavMenu = () => {
44 | setAnchorElNav(null);
45 | };
46 |
47 | const CloseModal = () => {
48 | setTimeout(handleClose, 2000);
49 | console.log('hello')
50 | }
51 |
52 |
53 |
54 |
55 | const Logout = () => {
56 | if (localStorage) {
57 | localStorage.clear()
58 | navigate('/');
59 | }
60 | };
61 | const handleClose = () => setOpen(false);
62 | const handleOpen = () => setOpen(true);
63 |
64 | console.log(loading);
65 |
66 | return (
67 |
68 |
69 |
75 |
76 | {result ?
77 | <>
78 | {result.map((res, index) => (
79 |
80 |
93 | {index + 1} - {res.volumeInfo.title} .
94 |
95 | ))
96 | }
97 | >
98 | :
99 | <>
100 |
101 | Loading For Books Data ...
102 | >
103 | }
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
131 | Library Books
132 |
133 |
134 |
135 | {pages.map((page) => (
136 |
141 | {page}
142 |
143 | ))}
144 |
145 |
146 |
147 |
148 |
149 |
150 |
158 |
159 |
160 |
214 |
215 |
216 |
217 |
218 |
219 |
224 | {links.map((link) => (
225 |
235 | {link}
236 |
237 | ))}
238 |
239 | {isLogin ?
240 |
241 |
242 | Logout
243 |
244 |
245 |
246 |
247 |
248 | :
249 |
250 | navigate('/login')}>
251 | Login
252 |
253 | navigate('/Register')}>
254 | Register
255 |
256 |
257 |
258 | }
259 |
260 |
261 |
262 |
263 | )
264 | }
265 |
266 | export default Header;
--------------------------------------------------------------------------------
/src/Components/Header/Sections/BasketShop.js:
--------------------------------------------------------------------------------
1 | import React, {useState, useContext} from 'react'
2 | import { Typography, Box, Menu, MenuItem, IconButton, Badge } from '@mui/material';
3 | import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
4 | import RemoveShoppingCartIcon from '@mui/icons-material/RemoveShoppingCart';
5 | import PaidIcon from '@mui/icons-material/Paid';
6 | import { Link } from 'react-router-dom';
7 | import { ShoppingContext } from '../../../Context/ContextShopping';
8 | //
9 |
10 | function BasketShop() {
11 | const isLogin = localStorage.getItem('getID');
12 | const [BasketNav, setBasketNav] = useState(null);
13 | const {store, listbooks, userbudget} = useContext(ShoppingContext);
14 |
15 | const handleOpenNavBasket = (event) => {
16 | setBasketNav(event.currentTarget);
17 | };
18 |
19 | const handleCloseNavBasket = () => {
20 | setBasketNav(null);
21 | };
22 |
23 |
24 |
25 | return (
26 |
27 |
28 | {isLogin ?
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
79 |
80 |
81 | :
82 |
83 |
84 |
85 | }
86 |
87 |
88 |
89 | )
90 | }
91 |
92 | export default BasketShop
93 |
94 |
--------------------------------------------------------------------------------
/src/Components/Header/Sections/Menu.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/Components/Header/Sections/Search.js:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react'
2 | import SearchIcon from '@mui/icons-material/Search';
3 | import { getBooks } from '../../utils/BooksApi';
4 | import { styled, InputBase, Button, alpha } from '@mui/material';
5 |
6 | const SearchIconWrapper = styled('div')(({ theme }) => ({
7 | padding: theme.spacing(0, 2),
8 | height: '100%',
9 | position: 'absolute',
10 | pointerEvents: 'none',
11 | display: 'flex',
12 | alignItems: 'center',
13 | justifyContent: 'center',
14 | }));
15 |
16 |
17 | const StyledInputBase = styled(InputBase)(({ theme }) => ({
18 | color: 'inherit',
19 | '& .MuiInputBase-input': {
20 | padding: theme.spacing(1, 1, 1, 0),
21 | // vertical padding + font size from searchIcon
22 | paddingLeft: `calc(1em + ${theme.spacing(4)})`,
23 | transition: theme.transitions.create('width'),
24 | width: '100%',
25 | [theme.breakpoints.up('sm')]: {
26 | width: '12ch',
27 | '&:focus': {
28 | width: '20ch',
29 | },
30 | },
31 | },
32 | }));
33 |
34 | const Search = styled('div')(({ theme }) => ({
35 | position: 'relative',
36 | borderRadius: theme.shape.borderRadius,
37 | backgroundColor: alpha(theme.palette.common.white, 0.15),
38 | '&:hover': {
39 | backgroundColor: alpha(theme.palette.common.white, 0.25),
40 | },
41 | marginLeft: 0,
42 | width: '100%',
43 | [theme.breakpoints.up('sm')]: {
44 | marginLeft: theme.spacing(1),
45 | width: 'auto',
46 | },
47 | }));
48 |
49 | function SearchInput({handleOpen, setResult, setLoading, result}) {
50 | const [search, setSearch] = useState('');
51 |
52 | const isLogin = localStorage.getItem('getID');
53 |
54 |
55 | const HandleSearchBook = (e) => {
56 | setSearch(e.target.value)
57 | }
58 |
59 | const handleCLick = async () => {
60 | if (search.length > 3) {
61 | await setResult(setResult(getBooks(search, 'intitle:%22').then(data => setResult(data))));
62 | setLoading(false);
63 | }
64 | handleOpen();
65 | console.log(result);
66 | }
67 |
68 | return (
69 |
70 |
71 |
72 |
73 |
74 |
75 |
80 |
81 | Search
82 |
83 |
84 | )
85 | }
86 |
87 | export default SearchInput
--------------------------------------------------------------------------------
/src/Components/Header/Sections/SearchModal.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/Components/Header/Sections/SearchModal.js
--------------------------------------------------------------------------------
/src/Components/Header/style.css:
--------------------------------------------------------------------------------
1 |
2 | #btnnavlink{
3 | transition: 0.4s ease-in-out;
4 | }
5 |
6 | #btnnavlink:hover{
7 | color: #2e2e2e;
8 | transition: 0.4 ease-in-out;
9 | }
10 |
11 | #categorieLink{
12 | transition: 0.4s ease-in-out;
13 | cursor: pointer;
14 | }
15 |
16 | #categorieLink:hover{
17 | color:rgb(0, 89, 255);
18 | text-decoration: underline;
19 | text-decoration-color: rgb(180, 206, 255);
20 | text-decoration-thickness: 2px;
21 | text-decoration-skip-ink: none; /* prevent ink skipping */
22 | text-underline-position: under; /* position the underline under the text */
23 | text-underline-offset: 2px; /* set the spacing between the lines to 2px */
24 | }
25 |
26 | #book_link{
27 | color: white;
28 | cursor: pointer;
29 | transition: 0.4s ease-in-out;
30 | }
31 |
32 | #book_link:hover{
33 | color: #ff6145;
34 | }
35 |
36 | #shoppingcard{
37 | cursor: pointer;
38 | }
39 |
--------------------------------------------------------------------------------
/src/Components/utils/BooksApi.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export const getBooks = async (tagelem, intype) => {
4 | const Books = await axios.get(`https://www.googleapis.com/books/v1/volumes?q=${intype}${tagelem}&key=AIzaSyDKG8AN_GKcPk-V3AaA0DXYvuJ2kpdXUG8`)
5 | return Books.data.items;
6 | }
7 |
8 | /*
9 | import axios from "axios";
10 |
11 | export const getBooks = async (with, search) => {
12 | const response = await axios.get("https://api-url.com/books");
13 | return response.data;
14 | };
15 |
16 | */
--------------------------------------------------------------------------------
/src/Context/ContextReview.js:
--------------------------------------------------------------------------------
1 | import React, { createContext, useReducer, useRef } from 'react';
2 | import Box from '@mui/material/Box';
3 | import { TextField, Button, Typography, Modal, FormControl } from '@mui/material';
4 |
5 | import './style.css';
6 |
7 | export const ReviewContext = createContext();
8 |
9 | const style = {
10 | position: 'absolute',
11 | top: '50%',
12 | left: '50%',
13 | transform: 'translate(-50%, -50%)',
14 | bgcolor: 'rgb(0 0 0 / 0.9)',
15 | textAlign: "center",
16 | boxShadow: 24,
17 | width: '600px',
18 | py: 10,
19 | border: '2px solid white'
20 | };
21 |
22 |
23 | const ShowModal = ({open, setOpen, UpdateKey,review, setReview}) => {
24 | const UpdatedElement = useRef();
25 | const handleClose = () => setOpen(false);
26 |
27 | const handleUpdate = () => {
28 | /* Add Code Here To Update is From Databse,
29 | if not when The Page Reload The Updated Element Will Desepear*/
30 | //const index = review.findIndex(elem => elem.id == UpdateKey);
31 |
32 | const updatedReviews = [...review];
33 |
34 | console.log(UpdateKey)
35 | const message = UpdatedElement.current.value;
36 |
37 |
38 | if(message){
39 | //console.log(index)
40 | console.log(UpdateKey);
41 | const updatedReview = [
42 | ...review.slice(0,UpdateKey),
43 | {...review[UpdateKey], review : message},
44 | ...review.slice(UpdateKey + 1)
45 | ];
46 | console.log(updatedReviews);
47 | setReview(updatedReview);
48 | }
49 | }
50 |
51 | return (
52 |
58 |
59 | e.preventDefault()}>
60 | Update Your Message :
61 |
76 | Update
77 |
78 |
79 |
80 | )
81 | }
82 |
83 |
84 |
85 | function ReviewProvider(props) {
86 | return (
87 |
88 | {props.children}
89 |
90 | )
91 | }
92 |
93 |
94 |
95 |
96 | export default ReviewProvider
97 |
--------------------------------------------------------------------------------
/src/Context/ContextShopping.js:
--------------------------------------------------------------------------------
1 | import React, { useState, createContext, useContext } from 'react'
2 |
3 | import { CardMedia, FormControl, Container, Alert, Modal, Button, Typography, Box } from '@mui/material';
4 | import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
5 | import tobuybook from "../assets/images/tobuybook.jpg";
6 | import { useNavigate } from 'react-router-dom';
7 | export const ShoppingContext = createContext();
8 |
9 | const style = {
10 | position: 'absolute',
11 | top: '50%',
12 | left: '50%',
13 | transform: 'translate(-50%, -50%)',
14 | bgcolor: 'rgb(0 0 0 / 0.9)',
15 | textAlign: "center",
16 | boxShadow: 24,
17 | width: '450px',
18 | py: 10,
19 | };
20 |
21 |
22 | const BookData = () => {
23 | const {book, message, setMessage, addRateValue} = useContext(ShoppingContext);
24 | const [open, setOpen] = useState(false);
25 | const handleOpen = () => {
26 | setOpen(true)
27 | };
28 | const handleClose = () => {
29 | setMessage('');
30 | setOpen(false);
31 | };
32 |
33 | return (
34 |
35 |
47 |
48 |
49 |
53 |
54 |
55 | Click The Link Bellow For Rating Book
56 | title : {book.volumeInfo.title}
57 | Author : {book.volumeInfo.authors}
58 | Buy This Book
59 |
60 |
61 |
67 |
68 |
69 | < ShoppingCartIcon style={{ width: "250px", height: "120px", color: 'yellow' }} />
70 |
71 | Title :
72 | {book.volumeInfo.title}
73 | e.preventDefault()}>
74 | Add Book
75 |
76 | {message == 'Book Added To The Basket' ?
77 |
78 | This Book was Added Successfully
79 |
80 | :
81 | {message}
82 | }
83 |
84 |
85 |
86 | )
87 | }
88 |
89 | function ShoppingProvider(props) {
90 | const [book, setBook] = useState([]);
91 | const [store, setStore] = useState(0);
92 | const [listbooks, setListbooks] = useState([]);
93 | const [userbudget, setUserbudget] = useState(Math.floor(Math.random() * (100 - 30 + 1)) + 30);
94 | const [message, setMessage] = useState('');
95 | const [price, setPrice] = useState(Math.floor(Math.random() * (25 - 12 + 1)) + 12);
96 | const navigate = useNavigate();
97 | console.log(listbooks);
98 |
99 | const addRateValue = async () => {
100 | const findBook = listbooks.filter(booky => booky.volumeInfo.title == book.volumeInfo.title);
101 |
102 | if (findBook.length > 0) {
103 | return setMessage("You Buy This Book Before !")
104 | } else if (userbudget < price) {
105 | return setMessage(`Your Budget is ${userbudget} $, Not Enough To Buy This Book That Cost ${price} $ !`);
106 | } else {
107 | setMessage('');
108 | }
109 | setStore(store + 1);
110 | setListbooks([...listbooks, book]);
111 | const newUserBudget = userbudget - price;
112 | setUserbudget(newUserBudget);
113 | setMessage('Book Added To The Basket');
114 |
115 |
116 | }
117 |
118 | const UpdateBasket = (e) =>{
119 | const DeleteBook = listbooks.filter(book => book.id != e.target.value);
120 | console.log(DeleteBook);
121 | console.log(e.target.value);
122 | setStore(store - 1);
123 |
124 | navigate('/sales_list');
125 |
126 | if(listbooks.length == 1){
127 | setUserbudget(Math.floor(Math.random() * (100 - 30 + 1)) + 30);
128 | setListbooks(DeleteBook);
129 | }else{
130 | setListbooks(DeleteBook);
131 | }
132 | }
133 |
134 | return (
135 |
136 | {props.children}
137 |
138 | )
139 | }
140 |
141 | export default ShoppingProvider
--------------------------------------------------------------------------------
/src/Context/SearchContext.js:
--------------------------------------------------------------------------------
1 | import React, {useState, createContext, useEffect } from 'react'
2 | export const SearchContext = createContext();
3 |
4 |
5 |
6 | function SearchProvider(props) {
7 | const [search, setSearch] = useState('');
8 | const [result, setResult] = useState([]);
9 |
10 |
11 | return (
12 |
13 | {props.children}
14 |
15 | )
16 | }
17 |
18 | export default SearchProvider
--------------------------------------------------------------------------------
/src/Context/style.css:
--------------------------------------------------------------------------------
1 | #name, #review {
2 | color:white;
3 | font-weight : bold;
4 | size: "20px";
5 | }
--------------------------------------------------------------------------------
/src/Data/Books.js:
--------------------------------------------------------------------------------
1 | const Books = [
2 | {
3 | id: 1,
4 | name : 'To Kill a Mockingbird',
5 | Author : 'Harper Lee',
6 | publisher: 'Hachette Book Group',
7 | date_publication: '1960',
8 | subject : 'The novel examines racism in the American South',
9 | description:'Lee\'s To Kill a Mockingbird was published in 1960 and became an immediate classic of literature. The novel examines racism in the American South through the innocent wide eyes of a clever young girl named Jean Louise (“Scout”) Finch. Its iconic characters, most notably the sympathetic and just lawyer and father Atticus Finch, served as role models and changed perspectives in the United States at a time when tensions regarding race were high',
10 | number_pages : '250',
11 | price : "10 $",
12 | about_actor : 'believed to be one of the most influential authors to have ever existed, famously published only a single novel (up until its controversial sequel was published in 2015 just before her death).'
13 | },
14 |
15 | {
16 | id: 2,
17 | name : 'The Great Gatsby',
18 | Author : 'F. Scott Fitzgerald',
19 | publisher: 'Public Domain',
20 | date_publication: '1920',
21 | subject : 'adventure of Jay Gatsby',
22 | description:'The novel is told from the perspective of a young man named Nick Carraway who has recently moved to New York City and is befriended by his eccentric nouveau riche neighbor with mysterious origins, Jay Gatsby.',
23 | number_pages : '350',
24 | price : "20 $",
25 | about_actor : 'is distinguished as one of the greatest texts for introducing students to the art of reading literature critically (which means you may have read it in school).'
26 | },
27 |
28 | {
29 | id: 3,
30 | name : 'One Hundred Years of Solitude',
31 | Author : 'Gabriel García Márquez',
32 | publisher: ' Lutfi Ozkok',
33 | date_publication: '1967',
34 | subject : 'the story of seven generations of the Buendía family',
35 | description:'The novel tells the story of seven generations of the Buendía family and follows the establishment of their town Macondo until its destruction along with the last of the family’s descendents. In fantastical form, the novel explores the genre of magic realism by emphasizing the extraordinary nature of commonplace things while mystical things are shown to be common.',
36 | number_pages : '156',
37 | price : "50 $",
38 | about_actor: 'The late Colombian author Gabriel García Márquez published his most famous work, One Hundred Years of Solitude, in 1967.'
39 | },
40 |
41 | {
42 | id: 4,
43 | name : 'A Passage to India',
44 | Author : 'E.M. Forster',
45 | publisher: 'Columbia Pictures',
46 | date_publication: '1924',
47 | subject : ' tensions between the Indian community and the colonial British community',
48 | description:'The book was published in 1924 and follows a Muslim Indian doctor named Aziz and his relationships with an English professor, Cyril Fielding, and a visiting English schoolteacher named Adela Quested. When Adela believes that Aziz has assaulted her while on a trip to the Marabar caves near the fictional city of Chandrapore, where the story is set, tensions between the Indian community and the colonial British community rise. The possibility of friendship and connection between English and Indian people, despite their cultural differences and imperial tensions, is explored in the conflict. The novel’s colorful descriptions of nature, the landscape of India, and the figurative power that they are given within the text solidifies it as a great work of fiction.',
49 | number_pages : '520',
50 | price : "25 $",
51 | about_actor:'E.M. Forster wrote his novel A Passage to India after multiple trips to the country throughout his early life.'
52 | },
53 |
54 | {
55 | id: 5,
56 | name : 'Invisible Man',
57 | Author : 'Ralph Ellison',
58 | publisher: 'Encyclopædia Britannica, Inc.',
59 | date_publication: '1953',
60 | subject : 'men who never believes he is “invisible” to others socially',
61 | description:'The narrator of the novel, a man who is never named but believes he is “invisible” to others socially, tells the story of his move from the South to college and then to New York City. In each location he faces extreme adversity and discrimination, falling into and out of work, relationships, and questionable social movements in a wayward and ethereal mindset. The novel is renowned for its surreal and experimental style of writing that explores the symbolism surrounding African American identity and culture. Invisible Man won the U.S. National Book Award for Fiction in 1953.',
62 | number_pages : '785',
63 | price : "30 $",
64 | about_actor : 'Often confused with H.G. Wells\'s science-fiction novella of nearly the same name (just subtract a “The”), Ralph Ellison\'s Invisible Man is a groundbreaking novel in the expression of identity for the African American male',
65 | },
66 |
67 | {
68 | id: 6,
69 | name : 'Don Quixote',
70 | Author : 'Miguel de Cervantes',
71 | publisher: 'Project Gutenberg',
72 | date_publication: '1720',
73 | subject : 'story of a man who takes the name “Don Quixote de la Mancha”',
74 | description:'The novel, which is very regularly regarded as one of the best literary works of all time, tells the story of a man who takes the name “Don Quixote de la Mancha” and sets off in a fit of obsession over romantic novels about chivalry to revive the custom and become a hero himself. The character of Don Quixote has become an idol and somewhat of an archetypal character, influencing many major works of art, music, and literature since the novel’s publication. The text has been so influential that a word, quixotic, based on the Don Quixote character, was created to describe someone who is, “foolishly impractical especially in the pursuit of ideals; especially: marked by rash lofty romantic ideas or extravagantly chivalrous action.”',
75 | number_pages : '',
76 | price : "40 $",
77 | about_actor : 'Miguel de Cervantes\'s Don Quixote, perhaps the most influential and well-known work of Spanish literature, was first published in full in 1615.'
78 | },
79 |
80 | {
81 | id: 7,
82 | name : 'Mrs. Dalloway',
83 | Author : 'Virginia Woolf',
84 | publisher: 'Library of Congress, Washington, D.C',
85 | date_publication: '1924',
86 | subject : 'one day in the life of a British socialite named Clarissa Dalloway',
87 | description:'Using a combination of a third-person narration and the thoughts of various characters, the novel uses a stream-of-consciousness style all the way through. The result of this style is a deeply personal and revealing look into the characters’ minds, with the novel relying heavily on character rather than plot to tell its story.',
88 | number_pages : '1520',
89 | price : "5 $",
90 | about_actor :'Possibly the most idiosyncratic novel of this list, Virginia Woolf’s Mrs. Dalloway describes exactly one day in the life of a British socialite named Clarissa Dalloway'
91 | },
92 |
93 | {
94 | id: 8,
95 | name : 'Beloved',
96 | Author : 'Toni Morrison',
97 | publisher: 'Library of Congress',
98 | date_publication: '1973',
99 | subject : 'The novel investigates the trauma of slavery even after freedom',
100 | description:'The novel investigates the trauma of slavery even after freedom has been gained, depicting Sethe’s guilt and emotional pain after having killed her own child, whom she named Beloved, to keep her from living life as a slave. A spectral figure appears in the lives of the characters and goes by the same name as the child, embodying the family’s anguish and hardship and making their feelings and past unavoidable. The novel was lauded for addressing the psychological effects of slavery and the importance of family and community in healing. Beloved was awarded the Pulitzer Prize for fiction in 1988.',
101 | number_pages : '241',
102 | price : "23 $",
103 | about_actor:'Toni Morrison’s 1987 spiritual and haunting novel Beloved tells the story of an escaped slave named Sethe who has fled to Cincinnati, Ohio, in the year 1873.'
104 | },
105 |
106 | {
107 | id: 9,
108 | name : 'Things Fall Apart',
109 | Author : 'Chinua Achebe',
110 | publisher: 'Library of Congress',
111 | date_publication: '201',
112 | subject : 'The novel follows an Igbo man named Okonkwo, describing his family, the village in Nigeria',
113 | description:' Chinua Achebe’s Things Fall Apart, published in 1958, is one such work of Nigerian literature that had to overcome the bias of some literary circles and one that has been able to gain recognition worldwide despite it. The novel follows an Igbo man named Okonkwo, describing his family, the village in Nigeria where he lives, and the effects of British colonialism on his native country. The novel is an example of African postcolonial literature, a genre that has grown in size and recognition since the mid-1900s as African people have been able to share their often unheard stories of imperialism from the perspective of the colonized. The novel is frequently assigned for reading in courses on world literature and African studies.',
114 | number_pages : '243',
115 | price : "35 $",
116 | about_actor: "The Western canon of “great literature” often focuses on writers who come from North America or Europe and often ignores accomplished writers and amazing works of literature from other parts of the world."
117 | },
118 | ]
119 |
120 | export default Books;
--------------------------------------------------------------------------------
/src/Data/Contacts.js:
--------------------------------------------------------------------------------
1 | const Contacts =[
2 | {
3 | id:1,
4 | user_id : 1,
5 | content : 'I d\'ont Find { In Search of Lost Time by Marcel Proust } Book Please I want It.',
6 | published_date : '03/10/2023',
7 | },
8 |
9 | {
10 | id:2,
11 | user_id : 1,
12 | content : 'i want to by { One Hundred Years of Solitude } Book Please I added to Us.',
13 | published_date : '03/01/2023',
14 | },
15 |
16 | {
17 | id:3,
18 | user_id : 3,
19 | content : 'wen i search for { War and Peace } Book can\'t find it Please I want It.',
20 | published_date : '07/02/2023',
21 | },
22 |
23 | {
24 | id:4,
25 | user_id : 5,
26 | content : 'I d\'ont Find { In Search of Lost Time by Marcel Proust } Book Please I want It.',
27 | published_date : '03/30/2023',
28 | },
29 |
30 | {
31 | id:5,
32 | user_id : 5,
33 | content : 'I d\'ont Find { The Lion, the Witch, and the Wardrobe } Book Please I want It.',
34 | published_date : '03/23/2023',
35 | },
36 |
37 | {
38 | id:6,
39 | user_id : 2,
40 | content : 'I d\'ont Find { Lord of the Rings } Book Please I want It.',
41 | published_date : '03/23/2023',
42 | },
43 |
44 | ]
45 |
46 | export default Contacts;
--------------------------------------------------------------------------------
/src/Data/Rates.js:
--------------------------------------------------------------------------------
1 | const Reviews = [
2 | {
3 | id: 1,
4 | user_id : 2,
5 | Rate : '8',
6 | book_id : 2,
7 | },
8 |
9 | {
10 | id: 2,
11 | user_id : 3,
12 | review : '10',
13 | book_id : 3,
14 | },
15 |
16 | {
17 | id: 3,
18 | user_id : 5,
19 | review : '3',
20 | book_id : 5,
21 | },
22 |
23 | {
24 | id:4,
25 | user_id : 5,
26 | review : '7',
27 | book_id : 5,
28 | },
29 |
30 | {
31 | id:5,
32 | user_id : 4,
33 | review : '8',
34 | book_id : 7,
35 | },
36 |
37 | {
38 | id: 6,
39 | user_id : 3,
40 | review : '8',
41 | book_id : 2,
42 | },
43 |
44 | {
45 | id:7,
46 | user_id : 4,
47 | review : '6',
48 | book_id : 7,
49 | },
50 | ]
--------------------------------------------------------------------------------
/src/Data/Reviews.js:
--------------------------------------------------------------------------------
1 | const Reviews = [
2 | {
3 | id: 1,
4 | user_id : 2,
5 | review : 'great book, but is short in number of pages (: hhhhhhhhhhhh',
6 | book_id : 2,
7 | },
8 |
9 | {
10 | id: 2,
11 | user_id : 2,
12 | review : 'Good Book, give me a lot of experience',
13 | book_id : 3,
14 | },
15 |
16 | {
17 | id: 3,
18 | user_id : 5,
19 | review : 'this is a borring book',
20 | book_id : 5,
21 | },
22 |
23 | {
24 | id: 4,
25 | user_id : 5,
26 | review : 'We I read This Books i found that is one of the best in my list',
27 | book_id : 7,
28 | },
29 | ]
30 |
31 | export default Reviews;
--------------------------------------------------------------------------------
/src/Data/SalesList.js:
--------------------------------------------------------------------------------
1 | const SalesList =[
2 | {
3 | id : '1',
4 | user_id : '5',
5 | book_id : '2',
6 | number_books: '1',
7 | date_sale : '02/10/2022'
8 | },
9 |
10 | {
11 | id : '1',
12 | user_id : '6',
13 | book_id : '7',
14 | number_books: '4',
15 | date_sale : '02/12/2020'
16 | },
17 |
18 | {
19 | id : '1',
20 | user_id : '5',
21 | book_id : '2',
22 | number_books: '6',
23 | date_sale : '01/10/2021'
24 | },
25 |
26 | {
27 | id : '1',
28 | user_id : '5',
29 | book_id : '7',
30 | number_books: '1',
31 | date_sale : '02/04/2023'
32 | }
33 |
34 | ]
--------------------------------------------------------------------------------
/src/Data/Users.js:
--------------------------------------------------------------------------------
1 | const Users = [
2 | {
3 | id: 1,
4 | Firstname: "AHMED",
5 | Secondname: "BEN HAMOUDA",
6 | Username: "ahmedBH",
7 | email: "ahmed.benhamouda98@gmail.com",
8 | password: "isitcom147dev",
9 | address: "Hammem Ghezez, Nabeul, Tunisia",
10 | },
11 | {
12 | id: 2,
13 | Firstname: "Salim",
14 | Secondname: "Ben Hassan",
15 | Username: "Salim.Writer",
16 | email: "Salim.98benhssan@gmail.com",
17 | password: "pass1e58melaibb",
18 | address: "Hammem Ghezez, Nabeul, Tunisia",
19 | },
20 | {
21 | id: 3,
22 | Firstname: "Bechir",
23 | Secondname: "Belhaj salah",
24 | Username: "Becho.Photographer",
25 | email: "BichoCA1921@infos@gmail.com",
26 | password: "pass158meliabb",
27 | address: "Hammem Ghezez, Nabeul, Tunisia",
28 | },
29 | {
30 | id: 4,
31 | Firstname: "Iheb",
32 | Secondname: "Benlhaj Salah",
33 | Username: "OussDev",
34 | email: "csgo1.6lol97@gmail.com",
35 | password: "pass158melibsb",
36 | address: "Hammem Ghezez, Nabeul, Tunisia",
37 | },
38 | {
39 | id: 5,
40 | Firstname: "Marwen",
41 | Secondname: "Ben Slim",
42 | Username: "Marwen_bs",
43 | email: "WebDev.Marwenoksuits.fr@gmail.com",
44 | password: "realwebdev9474",
45 | address: "hay al gahzela, ariana, Tunisia",
46 | }
47 | ]
48 |
49 | export default Users;
--------------------------------------------------------------------------------
/src/assets/images/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/background1.jpg
--------------------------------------------------------------------------------
/src/assets/images/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/background2.jpg
--------------------------------------------------------------------------------
/src/assets/images/background3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/background3.jpg
--------------------------------------------------------------------------------
/src/assets/images/background4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/background4.jpg
--------------------------------------------------------------------------------
/src/assets/images/background5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/background5.jpg
--------------------------------------------------------------------------------
/src/assets/images/booksLib.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/booksLib.jpeg
--------------------------------------------------------------------------------
/src/assets/images/bookswall.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/bookswall.jpg
--------------------------------------------------------------------------------
/src/assets/images/download.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/download.jpeg
--------------------------------------------------------------------------------
/src/assets/images/logo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/logo.jpeg
--------------------------------------------------------------------------------
/src/assets/images/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/profile.png
--------------------------------------------------------------------------------
/src/assets/images/review.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/review.jpg
--------------------------------------------------------------------------------
/src/assets/images/reviews.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/reviews.jpg
--------------------------------------------------------------------------------
/src/assets/images/reviews.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/reviews.png
--------------------------------------------------------------------------------
/src/assets/images/tobuybook.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmedbh25/Books_Library/a0380fbd9471bc404cf10c1b2b9c80cfd85dc461/src/assets/images/tobuybook.jpg
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 | import ShoppingProvider from './Context/ContextShopping';
5 | import ReviewProvider from './Context/ContextReview';
6 | import SearchProvider from './Context/SearchContext';
7 | import { BrowserRouter } from 'react-router-dom';
8 |
9 | const root = ReactDOM.createRoot(document.getElementById('root'));
10 | root.render(
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 |
24 |
--------------------------------------------------------------------------------