├── Front ├── .gitignore ├── src │ ├── assets │ │ ├── css │ │ │ ├── addbook.css │ │ │ ├── bookcard.css │ │ │ ├── index.css │ │ │ ├── Login.css │ │ │ ├── footer.css │ │ │ ├── bookbtn.css │ │ │ ├── navbar.css │ │ │ └── profile.css │ │ └── images │ │ │ ├── cover.jpg │ │ │ ├── logowa.png │ │ │ ├── logowacopy.png │ │ │ └── brickwork-covers-top.jpg │ ├── components │ │ ├── Sign │ │ │ ├── casino-background_2x-removebg-preview.png │ │ │ ├── Sign.js │ │ │ ├── Sign_in_up_component │ │ │ │ ├── Sign_in.js │ │ │ │ └── Sign_up.js │ │ │ └── Sign.module.css │ │ ├── admin │ │ │ ├── Dashboard.jsx │ │ │ ├── TrafficSource.jsx │ │ │ ├── SummaryCards.jsx │ │ │ └── Usermanagement.jsx │ │ ├── Category.jsx │ │ ├── BooksPage.jsx │ │ ├── favorites.jsx │ │ ├── BookCard.jsx │ │ ├── SearchResult.jsx │ │ ├── AboutUS.jsx │ │ ├── Navbar.jsx │ │ ├── Footer.jsx │ │ ├── Login.jsx │ │ ├── AddBook.jsx │ │ ├── OneBook.jsx │ │ └── Profile.jsx │ ├── pages │ │ ├── Book.jsx │ │ ├── AllBooks.jsx │ │ ├── HomePage.jsx │ │ └── NotFound.jsx │ ├── index.jsx │ ├── ProtectedRoute.js │ ├── AdminRoute.jsx │ ├── layouts │ │ └── MainLayout.jsx │ ├── AuthContext.js │ └── App.jsx ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── favicon.png │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── package.json └── README.md ├── back ├── .gitignore ├── middelware │ └── jwt.js ├── models │ ├── User.js │ └── Book.js ├── package.json ├── app.js ├── routes │ ├── adminRoutes.js │ ├── bookRoutes.js │ └── auth.js └── package-lock.json └── README.md /Front/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /.env -------------------------------------------------------------------------------- /back/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /.env -------------------------------------------------------------------------------- /Front/src/assets/css/addbook.css: -------------------------------------------------------------------------------- 1 | .addbook{ 2 | margin-bottom: 100px; 3 | } -------------------------------------------------------------------------------- /Front/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /Front/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/public/favicon.ico -------------------------------------------------------------------------------- /Front/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/public/favicon.png -------------------------------------------------------------------------------- /Front/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/public/logo192.png -------------------------------------------------------------------------------- /Front/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/public/logo512.png -------------------------------------------------------------------------------- /Front/src/assets/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/src/assets/images/cover.jpg -------------------------------------------------------------------------------- /Front/src/assets/images/logowa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/src/assets/images/logowa.png -------------------------------------------------------------------------------- /Front/src/assets/css/bookcard.css: -------------------------------------------------------------------------------- 1 | .clicked { 2 | transform: scale(0.95); 3 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 4 | } 5 | -------------------------------------------------------------------------------- /Front/src/assets/images/logowacopy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/src/assets/images/logowacopy.png -------------------------------------------------------------------------------- /Front/src/assets/images/brickwork-covers-top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/src/assets/images/brickwork-covers-top.jpg -------------------------------------------------------------------------------- /Front/src/components/Sign/casino-background_2x-removebg-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlaeBara/Electronic-Library-Full-Stack/HEAD/Front/src/components/Sign/casino-background_2x-removebg-preview.png -------------------------------------------------------------------------------- /Front/src/pages/Book.jsx: -------------------------------------------------------------------------------- 1 | import OneBook from '../components/OneBook' 2 | import React from 'react'; 3 | 4 | 5 | const AllBooks = () => { 6 | return ( 7 | <> 8 | 9 | 10 | ) 11 | } 12 | 13 | export default AllBooks; -------------------------------------------------------------------------------- /Front/src/pages/AllBooks.jsx: -------------------------------------------------------------------------------- 1 | import BooksPage from '../components/BooksPage' 2 | import React from 'react'; 3 | 4 | 5 | const AllBooks = () => { 6 | return ( 7 | <> 8 | 9 | 10 | ) 11 | } 12 | 13 | export default AllBooks; -------------------------------------------------------------------------------- /Front/src/pages/HomePage.jsx: -------------------------------------------------------------------------------- 1 | import Allcategories from '../components/Categories' 2 | import React from 'react'; 3 | 4 | 5 | const HomePage = () => { 6 | return ( 7 | <> 8 | 9 | 10 | ) 11 | } 12 | 13 | export default HomePage; -------------------------------------------------------------------------------- /Front/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /Front/src/ProtectedRoute.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Navigate } from 'react-router-dom'; 3 | import { useAuth } from './AuthContext'; 4 | 5 | const ProtectedRoute = ({ children }) => { 6 | const { isLoggedIn } = useAuth(); 7 | 8 | if (!isLoggedIn) { 9 | return ; 10 | } 11 | 12 | return children; 13 | }; 14 | 15 | export default ProtectedRoute; -------------------------------------------------------------------------------- /Front/src/AdminRoute.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Navigate } from 'react-router-dom'; 3 | import { useAuth } from './AuthContext'; 4 | 5 | const AdminRoute = ({ children }) => { 6 | const { isAdmin, isLoading } = useAuth(); 7 | 8 | if (isLoading) { 9 | return
Loading...
; // Or any loading indicator 10 | } 11 | 12 | if (!isAdmin) { 13 | return ; 14 | } 15 | 16 | return children; 17 | }; 18 | 19 | export default AdminRoute; -------------------------------------------------------------------------------- /back/middelware/jwt.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | 3 | const jwtMiddleware = (req, res, next) => { 4 | const token = req.cookies.token; 5 | if (!token) return res.status(401).json({ msg: 'No token, authorization denied' }); 6 | 7 | try { 8 | const decoded = jwt.verify(token, process.env.JWT_SECRET); 9 | req.user = decoded; 10 | next(); 11 | } catch (err) { 12 | res.status(403).json({ msg: 'Token is not valid' }); 13 | } 14 | }; 15 | 16 | 17 | module.exports={jwtMiddleware} -------------------------------------------------------------------------------- /Front/src/components/admin/Dashboard.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SummaryCards from './SummaryCards'; 3 | import Usermanagement from './Usermanagement'; 4 | import { Container, Row, Col } from 'react-bootstrap'; 5 | 6 | const Dashboard = () => { 7 | return ( 8 | 9 |

Admin Dashboard

10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | ); 18 | }; 19 | 20 | export default Dashboard; -------------------------------------------------------------------------------- /back/models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | // The users mongo db schema 4 | const UserSchema = new mongoose.Schema({ 5 | username: { type: String, required: true }, 6 | phone: { type: String }, 7 | address: { type: String}, 8 | country: { type: String }, 9 | email: { type: String, required: true, unique: true }, 10 | password: { type: String, required: true }, 11 | profileImage: { type: String }, 12 | role: { type: String, enum: ['user', 'admin'], default: 'user' } 13 | }); 14 | 15 | const User = mongoose.model('User', UserSchema); 16 | 17 | module.exports = User; 18 | -------------------------------------------------------------------------------- /Front/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 | -------------------------------------------------------------------------------- /back/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "back", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "start": "nodemon app.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "bcryptjs": "^2.4.3", 15 | "body-parser": "^1.20.2", 16 | "cloudinary": "^2.3.0", 17 | "cookie-parser": "^1.4.6", 18 | "cors": "^2.8.5", 19 | "dotenv": "^16.4.5", 20 | "express": "^4.19.2", 21 | "jsonwebtoken": "^9.0.2", 22 | "mongoose": "^8.5.1", 23 | "nodemon": "^3.1.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Front/src/assets/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | body { 15 | font-family: 'Roboto', sans-serif; 16 | } 17 | @media (max-width: 768px) { 18 | h1 { 19 | font-size: 2rem !important; 20 | } 21 | h2 { 22 | font-size: 1.5rem !important; 23 | } 24 | } -------------------------------------------------------------------------------- /Front/src/layouts/MainLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Outlet } from 'react-router-dom'; 3 | import Navbar from '../components/Navbar'; 4 | import Footer from '../components/Footer'; 5 | import { useAuth } from '../AuthContext'; 6 | 7 | const MainLayout = () => { 8 | const { isLoggedIn, setIsLoggedIn, checkAuthStatus } = useAuth(); 9 | 10 | return ( 11 | <> 12 | 17 | 18 |