├── _config.yml ├── mern-blog-app ├── api │ ├── .gitignore │ ├── models │ │ ├── Category.js │ │ ├── User.js │ │ └── Post.js │ ├── package.json │ ├── routes │ │ ├── categories.js │ │ ├── auth.js │ │ ├── users.js │ │ └── posts.js │ └── index.js └── client │ ├── src │ ├── pages │ │ ├── home │ │ │ ├── home.css │ │ │ └── Home.jsx │ │ ├── single │ │ │ ├── single.css │ │ │ └── Single.jsx │ │ ├── write │ │ │ ├── write.css │ │ │ └── Write.jsx │ │ ├── register │ │ │ ├── register.css │ │ │ └── Register.jsx │ │ ├── login │ │ │ ├── login.css │ │ │ └── Login.jsx │ │ └── settings │ │ │ ├── settings.css │ │ │ └── Settings.jsx │ ├── components │ │ ├── posts │ │ │ ├── posts.css │ │ │ └── Posts.jsx │ │ ├── header │ │ │ ├── header.css │ │ │ └── Header.jsx │ │ ├── post │ │ │ ├── Post.jsx │ │ │ └── post.css │ │ ├── topbar │ │ │ ├── topbar.css │ │ │ └── TopBar.jsx │ │ ├── sidebar │ │ │ ├── sidebar.css │ │ │ └── Sidebar.jsx │ │ └── singlePost │ │ │ ├── singlePost.css │ │ │ └── SinglePost.jsx │ ├── index.js │ ├── context │ │ ├── Actions.js │ │ ├── Context.js │ │ └── Reducer.js │ └── App.js │ ├── .gitignore │ ├── package.json │ ├── public │ └── index.html │ └── README.md ├── React Quiz ├── src │ ├── assets │ │ └── bg.jpg │ ├── sounds │ │ ├── play.mp3 │ │ ├── wait.mp3 │ │ ├── wrong.mp3 │ │ └── correct.mp3 │ ├── index.js │ ├── components │ │ ├── Timer.jsx │ │ ├── Start.jsx │ │ └── Trivia.jsx │ ├── App.css │ └── App.jsx ├── .gitignore ├── package.json ├── public │ └── index.html └── README.md ├── MERN Project ├── api │ ├── .gitignore │ ├── models │ │ ├── Cart.js │ │ ├── User.js │ │ ├── Product.js │ │ └── Order.js │ ├── package.json │ ├── routes │ │ ├── stripe.js │ │ ├── verifyToken.js │ │ ├── auth.js │ │ ├── cart.js │ │ ├── product.js │ │ ├── user.js │ │ └── order.js │ └── index.js ├── admin │ ├── src │ │ ├── pages │ │ │ ├── home │ │ │ │ ├── home.css │ │ │ │ └── Home.jsx │ │ │ ├── userList │ │ │ │ ├── userList.css │ │ │ │ └── UserList.jsx │ │ │ ├── productList │ │ │ │ ├── productList.css │ │ │ │ └── ProductList.jsx │ │ │ ├── newProduct │ │ │ │ ├── newProduct.css │ │ │ │ └── NewProduct.jsx │ │ │ ├── newUser │ │ │ │ ├── newUser.css │ │ │ │ └── NewUser.jsx │ │ │ ├── login │ │ │ │ └── Login.jsx │ │ │ ├── product │ │ │ │ ├── product.css │ │ │ │ └── Product.jsx │ │ │ └── user │ │ │ │ ├── user.css │ │ │ │ └── User.jsx │ │ ├── App.css │ │ ├── components │ │ │ ├── chart │ │ │ │ ├── chart.css │ │ │ │ └── Chart.jsx │ │ │ ├── sidebar │ │ │ │ ├── sidebar.css │ │ │ │ └── Sidebar.jsx │ │ │ ├── featuredInfo │ │ │ │ ├── featuredInfo.css │ │ │ │ └── FeaturedInfo.jsx │ │ │ ├── topbar │ │ │ │ ├── Topbar.jsx │ │ │ │ └── topbar.css │ │ │ ├── widgetLg │ │ │ │ ├── widgetLg.css │ │ │ │ └── WidgetLg.jsx │ │ │ └── widgetSm │ │ │ │ ├── widgetSm.css │ │ │ │ └── WidgetSm.jsx │ │ ├── requestMethods.js │ │ ├── index.js │ │ ├── firebase.js │ │ ├── redux │ │ │ ├── userRedux.js │ │ │ ├── store.js │ │ │ ├── apiCalls.js │ │ │ └── productRedux.js │ │ ├── App.js │ │ └── dummyData.js │ ├── .gitignore │ ├── public │ │ └── index.html │ ├── package.json │ └── README.md └── client │ ├── src │ ├── responsive.js │ ├── redux │ │ ├── apiCalls.js │ │ ├── cartRedux.js │ │ ├── userRedux.js │ │ └── store.js │ ├── requestMethods.js │ ├── components │ │ ├── Announcement.jsx │ │ ├── Categories.jsx │ │ ├── CategoryItem.jsx │ │ ├── Newsletter.jsx │ │ ├── Products.jsx │ │ ├── Product.jsx │ │ ├── Navbar.jsx │ │ ├── Slider.jsx │ │ └── Footer.jsx │ ├── index.js │ ├── pages │ │ ├── Home.jsx │ │ ├── Success.jsx │ │ ├── Register.jsx │ │ ├── Login.jsx │ │ ├── ProductList.jsx │ │ └── Product.jsx │ ├── App.jsx │ └── data.js │ ├── .gitignore │ ├── public │ └── index.html │ ├── package.json │ └── README.md └── README.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /mern-blog-app/api/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/home/home.css: -------------------------------------------------------------------------------- 1 | .home{ 2 | display: flex; 3 | } -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/single/single.css: -------------------------------------------------------------------------------- 1 | .single{ 2 | display: flex; 3 | } -------------------------------------------------------------------------------- /React Quiz/src/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/ReactJs-Advanced-Projects/HEAD/React Quiz/src/assets/bg.jpg -------------------------------------------------------------------------------- /React Quiz/src/sounds/play.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/ReactJs-Advanced-Projects/HEAD/React Quiz/src/sounds/play.mp3 -------------------------------------------------------------------------------- /React Quiz/src/sounds/wait.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/ReactJs-Advanced-Projects/HEAD/React Quiz/src/sounds/wait.mp3 -------------------------------------------------------------------------------- /MERN Project/api/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .env.local 3 | .env.development.local 4 | .env.test.local 5 | .env.production.local 6 | node_modules -------------------------------------------------------------------------------- /React Quiz/src/sounds/wrong.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/ReactJs-Advanced-Projects/HEAD/React Quiz/src/sounds/wrong.mp3 -------------------------------------------------------------------------------- /React Quiz/src/sounds/correct.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/ReactJs-Advanced-Projects/HEAD/React Quiz/src/sounds/correct.mp3 -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/home/home.css: -------------------------------------------------------------------------------- 1 | .home{ 2 | flex: 4; 3 | } 4 | 5 | .homeWidgets{ 6 | display: flex; 7 | margin: 20px; 8 | } -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/posts/posts.css: -------------------------------------------------------------------------------- 1 | .posts{ 2 | flex: 9; 3 | display: flex; 4 | flex-wrap: wrap; 5 | margin: 20px; 6 | } -------------------------------------------------------------------------------- /MERN Project/admin/src/App.css: -------------------------------------------------------------------------------- 1 | .container{ 2 | display: flex; 3 | margin-top: 10px; 4 | } 5 | 6 | 7 | .link{ 8 | text-decoration: none; 9 | color: inherit; 10 | } -------------------------------------------------------------------------------- /MERN Project/client/src/responsive.js: -------------------------------------------------------------------------------- 1 | import { css } from "styled-components"; 2 | 3 | export const mobile = (props) => { 4 | return css` 5 | @media only screen and (max-width: 380px) { 6 | ${props} 7 | } 8 | `; 9 | }; 10 | -------------------------------------------------------------------------------- /React Quiz/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | ReactDOM.render( 6 | 7 | 8 | , 9 | document.getElementById('root') 10 | ); 11 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/chart/chart.css: -------------------------------------------------------------------------------- 1 | .chart { 2 | margin: 20px; 3 | padding: 20px; 4 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 5 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 6 | } 7 | 8 | .chartTitle { 9 | margin-bottom: 20px; 10 | } 11 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/posts/Posts.jsx: -------------------------------------------------------------------------------- 1 | import Post from "../post/Post"; 2 | import "./posts.css"; 3 | 4 | export default function Posts({ posts }) { 5 | return ( 6 |
7 | {posts.map((p) => ( 8 | 9 | ))} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /mern-blog-app/api/models/Category.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const CategorySchema = new mongoose.Schema( 4 | { 5 | name: { 6 | type: String, 7 | required: true, 8 | }, 9 | }, 10 | { timestamps: true } 11 | ); 12 | 13 | module.exports = mongoose.model("Category", CategorySchema); 14 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/single/Single.jsx: -------------------------------------------------------------------------------- 1 | import "./single.css"; 2 | import Sidebar from "../../components/sidebar/Sidebar"; 3 | import SinglePost from "../../components/singlePost/SinglePost"; 4 | 5 | export default function Single() { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | import { ContextProvider } from "./context/Context"; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | 10 | 11 | , 12 | document.getElementById("root") 13 | ); 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReactJs-Advanced-Projects 2 | 3 | ## Tech We Used 4 | 5 | - ReactJs 6 | - Firebase Hosting 7 | - Firebase Auth 8 | - Firebase Storage 9 | - React-Dom 10 | - React Redux 11 | 12 | 13 | ## Steps to run in your machine 14 | 15 | #### Run the following commands 16 | ``` 17 | npm i 18 | npm run start 19 | ``` 20 | 21 | 22 | 23 | 24 | #### Hope you liked this project, dont forget to ⭐ the repo. 25 | -------------------------------------------------------------------------------- /React Quiz/.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 | -------------------------------------------------------------------------------- /MERN Project/admin/.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 | -------------------------------------------------------------------------------- /mern-blog-app/client/.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 | -------------------------------------------------------------------------------- /MERN Project/client/src/redux/apiCalls.js: -------------------------------------------------------------------------------- 1 | import { loginFailure, loginStart, loginSuccess } from "./userRedux"; 2 | import { publicRequest } from "../requestMethods"; 3 | 4 | export const login = async (dispatch, user) => { 5 | dispatch(loginStart()); 6 | try { 7 | const res = await publicRequest.post("/auth/login", user); 8 | dispatch(loginSuccess(res.data)); 9 | } catch (err) { 10 | dispatch(loginFailure()); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /MERN Project/admin/src/requestMethods.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | const BASE_URL = "http://localhost:5000/api/"; 4 | const TOKEN = JSON.parse(JSON.parse(localStorage.getItem("persist:root")).user).currentUser.accessToken; 5 | 6 | export const publicRequest = axios.create({ 7 | baseURL: BASE_URL, 8 | }); 9 | 10 | export const userRequest = axios.create({ 11 | baseURL: BASE_URL, 12 | headers: { token: `Bearer ${TOKEN}` }, 13 | }); 14 | -------------------------------------------------------------------------------- /MERN Project/client/.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 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /MERN Project/client/src/requestMethods.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | const BASE_URL = "http://localhost:5000/api/"; 4 | const TOKEN = 5 | JSON.parse(JSON.parse(localStorage.getItem("persist:root")).user).currentUser 6 | .accessToken || ""; 7 | 8 | export const publicRequest = axios.create({ 9 | baseURL: BASE_URL, 10 | }); 11 | 12 | export const userRequest = axios.create({ 13 | baseURL: BASE_URL, 14 | header: { token: `Bearer ${TOKEN}` }, 15 | }); 16 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/Announcement.jsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | const Container = styled.div` 4 | height: 30px; 5 | background-color: teal; 6 | color: white; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | font-size: 14px; 11 | font-weight: 500; 12 | `; 13 | 14 | const Announcement = () => { 15 | return Super Deal! Free Shipping on Orders Over $50; 16 | }; 17 | 18 | export default Announcement; 19 | -------------------------------------------------------------------------------- /MERN Project/api/models/Cart.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const CartSchema = new mongoose.Schema( 4 | { 5 | userId: { type: String, required: true }, 6 | products: [ 7 | { 8 | productId: { 9 | type: String, 10 | }, 11 | quantity: { 12 | type: Number, 13 | default: 1, 14 | }, 15 | }, 16 | ], 17 | }, 18 | { timestamps: true } 19 | ); 20 | 21 | module.exports = mongoose.model("Cart", CartSchema); 22 | -------------------------------------------------------------------------------- /MERN Project/admin/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | import { Provider } from "react-redux"; 5 | import { store, persistor } from "./redux/store"; 6 | import { PersistGate } from "redux-persist/integration/react"; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | 13 | , 14 | document.getElementById("root") 15 | ); 16 | -------------------------------------------------------------------------------- /MERN Project/client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | import { Provider } from "react-redux"; 5 | import { store, persistor } from "./redux/store"; 6 | import { PersistGate } from 'redux-persist/integration/react' 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | 13 | , 14 | document.getElementById("root") 15 | ); 16 | -------------------------------------------------------------------------------- /mern-blog-app/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "bcrypt": "^5.0.1", 4 | "dotenv": "^9.0.2", 5 | "express": "^4.17.1", 6 | "mongoose": "^5.12.9", 7 | "multer": "^1.4.2", 8 | "nodemon": "^2.0.7", 9 | "path": "^0.12.7" 10 | }, 11 | "name": "api", 12 | "version": "1.0.0", 13 | "main": "index.js", 14 | "devDependencies": {}, 15 | "scripts": { 16 | "start": "nodemon index.js" 17 | }, 18 | "author": "", 19 | "license": "ISC", 20 | "description": "" 21 | } 22 | -------------------------------------------------------------------------------- /MERN Project/api/models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const UserSchema = new mongoose.Schema( 4 | { 5 | username: { type: String, required: true, unique: true }, 6 | email: { type: String, required: true, unique: true }, 7 | password: { type: String, required: true }, 8 | isAdmin: { 9 | type: Boolean, 10 | default: false, 11 | }, 12 | img: { type: String }, 13 | }, 14 | { timestamps: true } 15 | ); 16 | 17 | module.exports = mongoose.model("User", UserSchema); 18 | -------------------------------------------------------------------------------- /MERN Project/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecommerceapi", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cors": "^2.8.5", 14 | "crypto-js": "^4.1.1", 15 | "dotenv": "^10.0.0", 16 | "express": "^4.17.1", 17 | "jsonwebtoken": "^8.5.1", 18 | "mongoose": "^6.0.5", 19 | "nodemon": "^2.0.12", 20 | "stripe": "^8.174.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /React Quiz/src/components/Timer.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export default function Timer({ setTimeOut, questionNumber }) { 4 | const [timer, setTimer] = useState(30); 5 | 6 | useEffect(() => { 7 | if (timer === 0) return setTimeOut(true); 8 | const interval = setInterval(() => { 9 | setTimer((prev) => prev - 1); 10 | }, 1000); 11 | return () => clearInterval(interval); 12 | }, [timer, setTimeOut]); 13 | 14 | useEffect(() => { 15 | setTimer(30); 16 | }, [questionNumber]); 17 | return timer; 18 | } 19 | -------------------------------------------------------------------------------- /MERN Project/client/src/redux/cartRedux.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const cartSlice = createSlice({ 4 | name: "cart", 5 | initialState: { 6 | products: [], 7 | quantity: 0, 8 | total: 0, 9 | }, 10 | reducers: { 11 | addProduct: (state, action) => { 12 | state.quantity += 1; 13 | state.products.push(action.payload); 14 | state.total += action.payload.price * action.payload.quantity; 15 | }, 16 | }, 17 | }); 18 | 19 | export const { addProduct } = cartSlice.actions; 20 | export default cartSlice.reducer; 21 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/header/header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | margin-top: 60px; 3 | } 4 | 5 | .headerTitles { 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | font-family: "Lora", serif; 10 | color: #444; 11 | } 12 | 13 | .headerTitleSm { 14 | position: absolute; 15 | top: 18%; 16 | font-size: 20px; 17 | } 18 | 19 | .headerTitleLg { 20 | position: absolute; 21 | top: 20%; 22 | font-size: 100px; 23 | } 24 | 25 | .headerImg{ 26 | width: 100%; 27 | height: 450px; 28 | margin-top: 80px; 29 | object-fit: cover; 30 | } -------------------------------------------------------------------------------- /MERN Project/api/routes/stripe.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const stripe = require("stripe")(process.env.STRIPE_KEY); 3 | 4 | router.post("/payment", (req, res) => { 5 | stripe.charges.create( 6 | { 7 | source: req.body.tokenId, 8 | amount: req.body.amount, 9 | currency: "usd", 10 | }, 11 | (stripeErr, stripeRes) => { 12 | if (stripeErr) { 13 | res.status(500).json(stripeErr); 14 | } else { 15 | res.status(200).json(stripeRes); 16 | } 17 | } 18 | ); 19 | }); 20 | 21 | module.exports = router; 22 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/header/Header.jsx: -------------------------------------------------------------------------------- 1 | import "./header.css"; 2 | 3 | export default function Header() { 4 | return ( 5 |
6 |
7 | React & Node 8 | Blog 9 |
10 | 15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /MERN Project/api/models/Product.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const ProductSchema = new mongoose.Schema( 4 | { 5 | title: { type: String, required: true, unique: true }, 6 | desc: { type: String, required: true }, 7 | img: { type: String, required: true }, 8 | categories: { type: Array }, 9 | size: { type: Array }, 10 | color: { type: Array }, 11 | price: { type: Number, required: true }, 12 | inStock: { type: Boolean, default: true }, 13 | }, 14 | { timestamps: true } 15 | ); 16 | 17 | module.exports = mongoose.model("Product", ProductSchema); 18 | -------------------------------------------------------------------------------- /React Quiz/src/components/Start.jsx: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | 3 | export default function Start({ setUsername }) { 4 | const inputRef = useRef(); 5 | 6 | const handleClick = () => { 7 | inputRef.current.value && setUsername(inputRef.current.value); 8 | }; 9 | 10 | return ( 11 |
12 | 17 | 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/userList/userList.css: -------------------------------------------------------------------------------- 1 | .userList { 2 | flex: 4; 3 | } 4 | 5 | .userListUser { 6 | display: flex; 7 | align-items: center; 8 | } 9 | 10 | .userListImg { 11 | width: 32px; 12 | height: 32px; 13 | border-radius: 50%; 14 | object-fit: cover; 15 | margin-right: 10px; 16 | } 17 | 18 | .userListEdit{ 19 | border: none; 20 | border-radius: 10px; 21 | padding: 5px 10px; 22 | background-color: #3bb077; 23 | color: white; 24 | cursor: pointer; 25 | margin-right: 20px; 26 | } 27 | 28 | .userListDelete{ 29 | color: red; 30 | cursor: pointer; 31 | } -------------------------------------------------------------------------------- /mern-blog-app/api/models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const UserSchema = new mongoose.Schema( 4 | { 5 | username: { 6 | type: String, 7 | required: true, 8 | unique: true, 9 | }, 10 | email: { 11 | type: String, 12 | required: true, 13 | unique: true, 14 | }, 15 | password: { 16 | type: String, 17 | required: true, 18 | }, 19 | profilePic: { 20 | type: String, 21 | default: "", 22 | }, 23 | }, 24 | { timestamps: true } 25 | ); 26 | 27 | module.exports = mongoose.model("User", UserSchema); 28 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/productList/productList.css: -------------------------------------------------------------------------------- 1 | .productList{ 2 | flex: 4; 3 | } 4 | 5 | .productListItem{ 6 | display: flex; 7 | align-items: center; 8 | } 9 | 10 | .productListImg { 11 | width: 32px; 12 | height: 32px; 13 | border-radius: 50%; 14 | object-fit: cover; 15 | margin-right: 10px; 16 | } 17 | 18 | .productListEdit{ 19 | border: none; 20 | border-radius: 10px; 21 | padding: 5px 10px; 22 | background-color: #3bb077; 23 | color: white; 24 | cursor: pointer; 25 | margin-right: 20px; 26 | } 27 | 28 | .productListDelete{ 29 | color: red; 30 | cursor: pointer; 31 | } -------------------------------------------------------------------------------- /MERN Project/api/models/Order.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const OrderSchema = new mongoose.Schema( 4 | { 5 | userId: { type: String, required: true }, 6 | products: [ 7 | { 8 | productId: { 9 | type: String, 10 | }, 11 | quantity: { 12 | type: Number, 13 | default: 1, 14 | }, 15 | }, 16 | ], 17 | amount: { type: Number, required: true }, 18 | address: { type: Object, required: true }, 19 | status: { type: String, default: "pending" }, 20 | }, 21 | { timestamps: true } 22 | ); 23 | 24 | module.exports = mongoose.model("Order", OrderSchema); 25 | -------------------------------------------------------------------------------- /mern-blog-app/api/routes/categories.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const Category = require("../models/Category"); 3 | 4 | router.post("/", async (req, res) => { 5 | const newCat = new Category(req.body); 6 | try { 7 | const savedCat = await newCat.save(); 8 | res.status(200).json(savedCat); 9 | } catch (err) { 10 | res.status(500).json(err); 11 | } 12 | }); 13 | 14 | router.get("/", async (req, res) => { 15 | try { 16 | const cats = await Category.find(); 17 | res.status(200).json(cats); 18 | } catch (err) { 19 | res.status(500).json(err); 20 | } 21 | }); 22 | 23 | module.exports = router; 24 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/Categories.jsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { categories } from "../data"; 3 | import { mobile } from "../responsive"; 4 | import CategoryItem from "./CategoryItem"; 5 | 6 | const Container = styled.div` 7 | display: flex; 8 | padding: 20px; 9 | justify-content: space-between; 10 | ${mobile({ padding: "0px", flexDirection:"column" })} 11 | 12 | `; 13 | 14 | const Categories = () => { 15 | return ( 16 | 17 | {categories.map((item) => ( 18 | 19 | ))} 20 | 21 | ); 22 | }; 23 | 24 | export default Categories; 25 | -------------------------------------------------------------------------------- /mern-blog-app/api/models/Post.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const PostSchema = new mongoose.Schema( 4 | { 5 | title: { 6 | type: String, 7 | required: true, 8 | unique: true, 9 | }, 10 | desc: { 11 | type: String, 12 | required: true, 13 | }, 14 | photo: { 15 | type: String, 16 | required: false, 17 | }, 18 | username: { 19 | type: String, 20 | required: true, 21 | }, 22 | categories: { 23 | type: Array, 24 | required: false, 25 | }, 26 | }, 27 | { timestamps: true } 28 | ); 29 | 30 | module.exports = mongoose.model("Post", PostSchema); 31 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/context/Actions.js: -------------------------------------------------------------------------------- 1 | export const LoginStart = (userCredentials) => ({ 2 | type: "LOGIN_START", 3 | }); 4 | 5 | export const LoginSuccess = (user) => ({ 6 | type: "LOGIN_SUCCESS", 7 | payload: user, 8 | }); 9 | 10 | export const LoginFailure = () => ({ 11 | type: "LOGIN_FAILURE", 12 | }); 13 | 14 | export const Logout = () => ({ 15 | type: "LOGOUT", 16 | }); 17 | 18 | export const UpdateStart = (userCredentials) => ({ 19 | type: "UPDATE_START", 20 | }); 21 | 22 | export const UpdateSuccess = (user) => ({ 23 | type: "UPDATE_SUCCESS", 24 | payload: user, 25 | }); 26 | 27 | export const UpdateFailure = () => ({ 28 | type: "UPDATE_FAILURE", 29 | }); 30 | -------------------------------------------------------------------------------- /MERN Project/client/src/pages/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Announcement from "../components/Announcement"; 3 | import Categories from "../components/Categories"; 4 | import Footer from "../components/Footer"; 5 | import Navbar from "../components/Navbar"; 6 | import Newsletter from "../components/Newsletter"; 7 | import Products from "../components/Products"; 8 | import Slider from "../components/Slider"; 9 | 10 | const Home = () => { 11 | return ( 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
21 | ); 22 | }; 23 | 24 | export default Home; 25 | -------------------------------------------------------------------------------- /MERN Project/admin/src/firebase.js: -------------------------------------------------------------------------------- 1 | // Import the functions you need from the SDKs you need 2 | import { initializeApp } from "firebase/app"; 3 | // TODO: Add SDKs for Firebase products that you want to use 4 | // https://firebase.google.com/docs/web/setup#available-libraries 5 | 6 | // Your web app's Firebase configuration 7 | const firebaseConfig = { 8 | apiKey: "AIzaSyCB-h_T2ZL-a7xt5zMvZmSh8GBXtawzL0c", 9 | authDomain: "shop-889c6.firebaseapp.com", 10 | projectId: "shop-889c6", 11 | storageBucket: "shop-889c6.appspot.com", 12 | messagingSenderId: "105110075028", 13 | appId: "1:105110075028:web:7cee5adf1ed39f597e6681", 14 | }; 15 | 16 | // Initialize Firebase 17 | const app = initializeApp(firebaseConfig); 18 | 19 | export default app; 20 | -------------------------------------------------------------------------------- /MERN Project/client/src/redux/userRedux.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const userSlice = createSlice({ 4 | name: "user", 5 | initialState: { 6 | currentUser: null, 7 | isFetching: false, 8 | error: false, 9 | }, 10 | reducers: { 11 | loginStart: (state) => { 12 | state.isFetching = true; 13 | }, 14 | loginSuccess: (state, action) => { 15 | state.isFetching = false; 16 | state.currentUser = action.payload; 17 | }, 18 | loginFailure: (state) => { 19 | state.isFetching = false; 20 | state.error = true; 21 | }, 22 | }, 23 | }); 24 | 25 | export const { loginStart, loginSuccess, loginFailure } = userSlice.actions; 26 | export default userSlice.reducer; 27 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/newProduct/newProduct.css: -------------------------------------------------------------------------------- 1 | .newProduct { 2 | flex: 4; 3 | margin-left: 100px; 4 | } 5 | 6 | .addProductForm { 7 | margin-top: 10px; 8 | } 9 | 10 | .addProductItem { 11 | width: 250px; 12 | display: flex; 13 | flex-direction: column; 14 | margin-bottom: 10px; 15 | } 16 | 17 | .addProductItem > label { 18 | color: gray; 19 | font-weight: 600; 20 | margin-bottom: 10px; 21 | } 22 | 23 | .addProductItem > input { 24 | padding: 10px; 25 | } 26 | 27 | .addProductItem > select { 28 | padding: 10px; 29 | } 30 | 31 | .addProductButton { 32 | margin-top: 10px; 33 | padding: 7px 10px; 34 | border: none; 35 | border-radius: 10px; 36 | background-color: darkblue; 37 | color: white; 38 | font-weight: 600; 39 | cursor: pointer; 40 | } 41 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/chart/Chart.jsx: -------------------------------------------------------------------------------- 1 | import "./chart.css"; 2 | import { 3 | LineChart, 4 | Line, 5 | XAxis, 6 | CartesianGrid, 7 | Tooltip, 8 | ResponsiveContainer, 9 | } from "recharts"; 10 | 11 | export default function Chart({ title, data, dataKey, grid }) { 12 | 13 | return ( 14 |
15 |

{title}

16 | 17 | 18 | 19 | 20 | 21 | {grid && } 22 | 23 | 24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /MERN Project/admin/src/redux/userRedux.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const userSlice = createSlice({ 4 | name: "user", 5 | initialState: { 6 | currentUser: null, 7 | isFetching: false, 8 | error: false, 9 | }, 10 | reducers: { 11 | loginStart: (state) => { 12 | state.isFetching = true; 13 | }, 14 | loginSuccess: (state, action) => { 15 | state.isFetching = false; 16 | state.currentUser = action.payload; 17 | }, 18 | loginFailure: (state) => { 19 | state.isFetching = false; 20 | state.error = true; 21 | }, 22 | logout: (state) => { 23 | state.currentUser = null; 24 | }, 25 | }, 26 | }); 27 | 28 | export const { loginStart, loginSuccess, loginFailure } = userSlice.actions; 29 | export default userSlice.reducer; 30 | -------------------------------------------------------------------------------- /MERN Project/client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 17 | React App 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /MERN Project/admin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | 18 | React Admin App 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/sidebar/sidebar.css: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | flex: 1; 3 | height: calc(100vh - 50px); 4 | background-color: rgb(251, 251, 255); 5 | position: sticky; 6 | top: 50px; 7 | } 8 | 9 | .sidebarWrapper { 10 | padding: 20px; 11 | color: #555; 12 | } 13 | 14 | .sidebarMenu { 15 | margin-bottom: 10px; 16 | } 17 | 18 | .sidebarTitle { 19 | font-size: 13px; 20 | color: rgb(187, 186, 186); 21 | } 22 | 23 | .sidebarList { 24 | list-style: none; 25 | padding: 5px; 26 | } 27 | 28 | .sidebarListItem { 29 | padding: 5px; 30 | cursor: pointer; 31 | display: flex; 32 | align-items: center; 33 | border-radius: 10px; 34 | } 35 | 36 | .sidebarListItem.active, 37 | .sidebarListItem:hover { 38 | background-color: rgb(240, 240, 255); 39 | } 40 | 41 | .sidebarIcon{ 42 | margin-right: 5px; 43 | font-size: 20px !important; 44 | } 45 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/context/Context.js: -------------------------------------------------------------------------------- 1 | import { createContext, useEffect, useReducer } from "react"; 2 | import Reducer from "./Reducer"; 3 | 4 | const INITIAL_STATE = { 5 | user: JSON.parse(localStorage.getItem("user")) || null, 6 | isFetching: false, 7 | error: false, 8 | }; 9 | 10 | export const Context = createContext(INITIAL_STATE); 11 | 12 | export const ContextProvider = ({ children }) => { 13 | const [state, dispatch] = useReducer(Reducer, INITIAL_STATE); 14 | 15 | useEffect(() => { 16 | localStorage.setItem("user", JSON.stringify(state.user)); 17 | }, [state.user]); 18 | 19 | return ( 20 | 28 | {children} 29 | 30 | ); 31 | }; 32 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/home/Home.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import Header from "../../components/header/Header"; 3 | import Posts from "../../components/posts/Posts"; 4 | import Sidebar from "../../components/sidebar/Sidebar"; 5 | import "./home.css"; 6 | import axios from "axios"; 7 | import { useLocation } from "react-router"; 8 | 9 | export default function Home() { 10 | const [posts, setPosts] = useState([]); 11 | const { search } = useLocation(); 12 | 13 | useEffect(() => { 14 | const fetchPosts = async () => { 15 | const res = await axios.get("/posts" + search); 16 | setPosts(res.data); 17 | }; 18 | fetchPosts(); 19 | }, [search]); 20 | return ( 21 | <> 22 |
23 |
24 | 25 | 26 |
27 | 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/post/Post.jsx: -------------------------------------------------------------------------------- 1 | import "./post.css"; 2 | import { Link } from "react-router-dom"; 3 | 4 | export default function Post({ post }) { 5 | const PF = "http://localhost:5000/images/"; 6 | return ( 7 |
8 | {post.photo && } 9 |
10 |
11 | {post.categories.map((c) => ( 12 | {c.name} 13 | ))} 14 |
15 | 16 | {post.title} 17 | 18 |
19 | 20 | {new Date(post.createdAt).toDateString()} 21 | 22 |
23 |

{post.desc}

24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /React Quiz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "milionaire", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "react": "^17.0.2", 10 | "react-dom": "^17.0.2", 11 | "react-scripts": "4.0.3", 12 | "use-sound": "^3.0.0", 13 | "web-vitals": "^1.0.1" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MERN Project/client/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore, combineReducers } from "@reduxjs/toolkit"; 2 | import cartReducer from "./cartRedux"; 3 | import userReducer from "./userRedux"; 4 | import { 5 | persistStore, 6 | persistReducer, 7 | FLUSH, 8 | REHYDRATE, 9 | PAUSE, 10 | PERSIST, 11 | PURGE, 12 | REGISTER, 13 | } from "redux-persist"; 14 | import storage from "redux-persist/lib/storage"; 15 | 16 | const persistConfig = { 17 | key: "root", 18 | version: 1, 19 | storage, 20 | }; 21 | 22 | const rootReducer = combineReducers({ user: userReducer, cart: cartReducer }); 23 | 24 | const persistedReducer = persistReducer(persistConfig, rootReducer); 25 | 26 | export const store = configureStore({ 27 | reducer: persistedReducer, 28 | middleware: (getDefaultMiddleware) => 29 | getDefaultMiddleware({ 30 | serializableCheck: { 31 | ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], 32 | }, 33 | }), 34 | }); 35 | 36 | export let persistor = persistStore(store); 37 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/featuredInfo/featuredInfo.css: -------------------------------------------------------------------------------- 1 | .featured { 2 | width: 100%; 3 | display: flex; 4 | justify-content: space-between; 5 | } 6 | 7 | .featuredItem { 8 | flex: 1; 9 | margin: 0px 20px; 10 | padding: 30px; 11 | border-radius: 10px; 12 | cursor: pointer; 13 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 14 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 15 | } 16 | 17 | .featuredTitle{ 18 | font-size: 20px; 19 | } 20 | 21 | .featuredMoneyContainer{ 22 | margin: 10px 0px; 23 | display: flex; 24 | align-items: center; 25 | } 26 | 27 | .featuredMoney{ 28 | font-size: 30px; 29 | font-weight: 600; 30 | } 31 | 32 | .featuredMoneyRate{ 33 | display: flex; 34 | align-items: center; 35 | margin-left: 20px; 36 | } 37 | 38 | .featuredIcon{ 39 | font-size: 14px; 40 | margin-left: 5px; 41 | color: green; 42 | } 43 | 44 | .featuredIcon.negative{ 45 | color: red; 46 | } 47 | 48 | .featuredSub{ 49 | font-size: 15px; 50 | color: gray; 51 | } -------------------------------------------------------------------------------- /MERN Project/admin/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore, combineReducers } from "@reduxjs/toolkit"; 2 | import userReducer from "./userRedux"; 3 | import productReducer from "./productRedux"; 4 | import { 5 | persistStore, 6 | persistReducer, 7 | FLUSH, 8 | REHYDRATE, 9 | PAUSE, 10 | PERSIST, 11 | PURGE, 12 | REGISTER, 13 | } from "redux-persist"; 14 | import storage from "redux-persist/lib/storage"; 15 | 16 | const persistConfig = { 17 | key: "root", 18 | version: 1, 19 | storage, 20 | }; 21 | 22 | const rootReducer = combineReducers({ 23 | user: userReducer, 24 | product: productReducer, 25 | }); 26 | 27 | const persistedReducer = persistReducer(persistConfig, rootReducer); 28 | 29 | export const store = configureStore({ 30 | reducer: persistedReducer, 31 | middleware: (getDefaultMiddleware) => 32 | getDefaultMiddleware({ 33 | serializableCheck: { 34 | ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], 35 | }, 36 | }), 37 | }); 38 | 39 | export let persistor = persistStore(store); 40 | -------------------------------------------------------------------------------- /MERN Project/api/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const mongoose = require("mongoose"); 4 | const dotenv = require("dotenv"); 5 | dotenv.config(); 6 | const userRoute = require("./routes/user"); 7 | const authRoute = require("./routes/auth"); 8 | const productRoute = require("./routes/product"); 9 | const cartRoute = require("./routes/cart"); 10 | const orderRoute = require("./routes/order"); 11 | const stripeRoute = require("./routes/stripe"); 12 | const cors = require("cors"); 13 | 14 | 15 | mongoose 16 | .connect(process.env.MONGO_URL) 17 | .then(() => console.log("DB Connection Successfull!")) 18 | .catch((err) => { 19 | console.log(err); 20 | }); 21 | 22 | app.use(cors()); 23 | app.use(express.json()); 24 | app.use("/api/auth", authRoute); 25 | app.use("/api/users", userRoute); 26 | app.use("/api/products", productRoute); 27 | app.use("/api/carts", cartRoute); 28 | app.use("/api/orders", orderRoute); 29 | app.use("/api/checkout", stripeRoute); 30 | 31 | app.listen(process.env.PORT || 5000, () => { 32 | console.log("Backend server is running!"); 33 | }); 34 | -------------------------------------------------------------------------------- /mern-blog-app/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-blog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "axios": "^0.21.1", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-router-dom": "^5.2.0", 13 | "react-scripts": "4.0.3", 14 | "web-vitals": "^1.0.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | }, 40 | "proxy": "http://localhost:5000/api/" 41 | } 42 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/topbar/Topbar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./topbar.css"; 3 | import { NotificationsNone, Language, Settings } from "@material-ui/icons"; 4 | 5 | export default function Topbar() { 6 | return ( 7 |
8 |
9 |
10 | lamaadmin 11 |
12 |
13 |
14 | 15 | 2 16 |
17 |
18 | 19 | 2 20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/newUser/newUser.css: -------------------------------------------------------------------------------- 1 | .newUser { 2 | flex: 4; 3 | } 4 | 5 | .newUserForm { 6 | display: flex; 7 | flex-wrap: wrap; 8 | } 9 | 10 | .newUserItem { 11 | width: 400px; 12 | display: flex; 13 | flex-direction: column; 14 | margin-top: 10px; 15 | margin-right: 20px; 16 | } 17 | 18 | .newUserItem > label { 19 | margin-bottom: 10px; 20 | font-size: 14px; 21 | font-weight: 600; 22 | color: rgb(151, 150, 150); 23 | } 24 | 25 | .newUserItem > input { 26 | height: 20px; 27 | padding: 10px; 28 | border: 1px solid gray; 29 | border-radius: 5px; 30 | } 31 | 32 | .newUserGender > input { 33 | margin-top: 15px; 34 | } 35 | 36 | .newUserGender>label{ 37 | margin: 10px; 38 | font-size: 18px; 39 | color: #555; 40 | } 41 | 42 | .newUserSelect{ 43 | height: 40px; 44 | border-radius: 5px; 45 | } 46 | 47 | .newUserButton{ 48 | width: 200px; 49 | border: none; 50 | background-color: darkblue; 51 | color: white; 52 | padding: 7px 10px; 53 | font-weight: 600; 54 | border-radius: 10px; 55 | margin-top: 30px; 56 | cursor: pointer; 57 | } -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/topbar/topbar.css: -------------------------------------------------------------------------------- 1 | .top { 2 | width: 100%; 3 | height: 50px; 4 | background-color: white; 5 | position: sticky; 6 | top: 0; 7 | display: flex; 8 | align-items: center; 9 | font-family: "Josefin Sans", sans-serif; 10 | z-index: 999; 11 | } 12 | 13 | .topLeft, 14 | .topRight { 15 | flex: 3; 16 | display: flex; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | .topCenter { 22 | flex: 6; 23 | } 24 | 25 | .topIcon { 26 | font-size: 20px; 27 | margin-right: 10px; 28 | color: #444; 29 | cursor: pointer; 30 | } 31 | 32 | .topImg { 33 | width: 40px; 34 | height: 40px; 35 | border-radius: 50%; 36 | object-fit: cover; 37 | cursor: pointer; 38 | } 39 | 40 | .topList { 41 | display: flex; 42 | justify-content: center; 43 | margin: 0; 44 | padding: 0; 45 | list-style: none; 46 | } 47 | 48 | .topListItem { 49 | margin-right: 20px; 50 | font-size: 18px; 51 | font-weight: 300; 52 | cursor: pointer; 53 | } 54 | 55 | .topSearchIcon { 56 | font-size: 18px; 57 | color: #666; 58 | cursor: pointer; 59 | margin-left: 15px; 60 | } 61 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/topbar/topbar.css: -------------------------------------------------------------------------------- 1 | .topbar { 2 | width: 100%; 3 | height: 50px; 4 | background-color: white; 5 | position: sticky; 6 | top: 0; 7 | z-index: 999; 8 | } 9 | 10 | .topbarWrapper { 11 | height: 100%; 12 | padding: 0px 20px; 13 | display: flex; 14 | align-items: center; 15 | justify-content: space-between; 16 | } 17 | 18 | .logo { 19 | font-weight: bold; 20 | font-size: 30px; 21 | color: darkblue; 22 | cursor: pointer; 23 | } 24 | 25 | .topRight{ 26 | display: flex; 27 | align-items: center; 28 | } 29 | 30 | .topbarIconContainer { 31 | position: relative; 32 | cursor: pointer; 33 | margin-right: 10px; 34 | color: #555; 35 | } 36 | 37 | .topIconBadge{ 38 | width: 15px; 39 | height: 15px; 40 | position: absolute; 41 | top: -5px; 42 | right: 0px; 43 | background-color: red; 44 | color: white; 45 | border-radius: 50%; 46 | display: flex; 47 | align-items: center; 48 | justify-content: center; 49 | font-size: 10px; 50 | } 51 | 52 | .topAvatar{ 53 | width: 40px; 54 | height: 40px; 55 | border-radius: 50%; 56 | cursor: pointer; 57 | } -------------------------------------------------------------------------------- /mern-blog-app/client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 15 | 20 | 26 | Blog React App 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/widgetLg/widgetLg.css: -------------------------------------------------------------------------------- 1 | .widgetLg { 2 | flex: 2; 3 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 4 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 5 | padding: 20px; 6 | } 7 | 8 | .widgetLgTitle { 9 | font-size: 22px; 10 | font-weight: 600; 11 | } 12 | 13 | .widgetLgTable{ 14 | width: 100%; 15 | border-spacing: 20px; 16 | } 17 | 18 | .widgetLgTh{ 19 | text-align: left; 20 | } 21 | 22 | .widgetLgUser{ 23 | display: flex; 24 | align-items: center; 25 | font-weight: 600; 26 | } 27 | 28 | .widgetLgImg { 29 | width: 40px; 30 | height: 40px; 31 | border-radius: 50%; 32 | object-fit: cover; 33 | margin-right: 10px; 34 | } 35 | 36 | .widgetLgDate,.widgetLgAmount{ 37 | font-weight: 300; 38 | } 39 | 40 | .widgetLgButton { 41 | padding: 5px 7px; 42 | border: none; 43 | border-radius: 10px; 44 | } 45 | 46 | .widgetLgButton.approved{ 47 | background-color: #e5faf2; 48 | color: #3bb077; 49 | } 50 | .widgetLgButton.declined{ 51 | background-color: #fff0f1; 52 | color: #d95087; 53 | 54 | } 55 | .widgetLgButton.pending{ 56 | background-color: #ebf1fe; 57 | color: #2a7ade; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/write/write.css: -------------------------------------------------------------------------------- 1 | .write { 2 | padding-top: 50px; 3 | } 4 | 5 | .writeImg { 6 | margin-left: 150px; 7 | width: 70vw; 8 | height: 250px; 9 | border-radius: 10px; 10 | object-fit: cover; 11 | } 12 | 13 | .writeForm { 14 | position: relative; 15 | } 16 | 17 | .writeFormGroup { 18 | margin-left: 150px; 19 | display: flex; 20 | align-items: center; 21 | } 22 | 23 | .writeIcon { 24 | width: 25px; 25 | height: 25px; 26 | border-radius: 50%; 27 | border: 1px solid; 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | font-size: 20px; 32 | color: rgb(121, 118, 118); 33 | cursor: pointer; 34 | } 35 | 36 | .writeInput { 37 | font-size: 30px; 38 | border: none; 39 | padding: 20px; 40 | width: 70vw; 41 | } 42 | 43 | .writeInput:focus { 44 | outline: none; 45 | } 46 | 47 | .writeText { 48 | font-size: 20px; 49 | height: 100vh; 50 | } 51 | 52 | .writeSubmit { 53 | position: absolute; 54 | top: 20px; 55 | right: 50px; 56 | color: white; 57 | background-color: teal; 58 | padding: 10px; 59 | border: none; 60 | border-radius: 10px; 61 | cursor: pointer; 62 | font-size: 16px; 63 | } 64 | -------------------------------------------------------------------------------- /MERN Project/api/routes/verifyToken.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | const verifyToken = (req, res, next) => { 4 | const authHeader = req.headers.token; 5 | if (authHeader) { 6 | const token = authHeader.split(" ")[1]; 7 | jwt.verify(token, process.env.JWT_SEC, (err, user) => { 8 | if (err) res.status(403).json("Token is not valid!"); 9 | req.user = user; 10 | next(); 11 | }); 12 | } else { 13 | return res.status(401).json("You are not authenticated!"); 14 | } 15 | }; 16 | 17 | const verifyTokenAndAuthorization = (req, res, next) => { 18 | verifyToken(req, res, () => { 19 | if (req.user.id === req.params.id || req.user.isAdmin) { 20 | next(); 21 | } else { 22 | res.status(403).json("You are not alowed to do that!"); 23 | } 24 | }); 25 | }; 26 | 27 | const verifyTokenAndAdmin = (req, res, next) => { 28 | verifyToken(req, res, () => { 29 | if (req.user.isAdmin) { 30 | next(); 31 | } else { 32 | res.status(403).json("You are not alowed to do that!"); 33 | } 34 | }); 35 | }; 36 | 37 | module.exports = { 38 | verifyToken, 39 | verifyTokenAndAuthorization, 40 | verifyTokenAndAdmin, 41 | }; 42 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/post/post.css: -------------------------------------------------------------------------------- 1 | .post { 2 | width: 385px; 3 | margin: 0px 25px 40px 25px; 4 | } 5 | 6 | .postImg { 7 | width: 100%; 8 | height: 280px; 9 | object-fit: cover; 10 | border-radius: 7px; 11 | } 12 | 13 | .postInfo { 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | } 18 | 19 | .postCat { 20 | font-family: "Varela Round", sans-serif; 21 | font-size: 11px; 22 | color: #be9656; 23 | line-height: 20px; 24 | margin-top: 15px; 25 | margin-right: 10px; 26 | cursor: pointer; 27 | } 28 | 29 | .postTitle { 30 | font-family: "Josefin Sans", sans-serif; 31 | font-size: 24px; 32 | font-weight: 700; 33 | margin-top: 15px; 34 | cursor: pointer; 35 | } 36 | 37 | .postDate { 38 | font-family: "Lora", serif; 39 | font-style: italic; 40 | font-size: 13px; 41 | color: #999; 42 | margin-top: 15px; 43 | } 44 | 45 | .postDesc { 46 | font-family: "Varela Round", sans-serif; 47 | font-size: 14px; 48 | color: #444; 49 | line-height: 24px; 50 | margin-top: 15px; 51 | overflow: hidden; 52 | text-overflow: ellipsis; 53 | display: -webkit-box; 54 | -webkit-line-clamp: 4; 55 | -webkit-box-orient: vertical; 56 | } 57 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/context/Reducer.js: -------------------------------------------------------------------------------- 1 | const Reducer = (state, action) => { 2 | switch (action.type) { 3 | case "LOGIN_START": 4 | return { 5 | user: null, 6 | isFetching: true, 7 | error: false, 8 | }; 9 | case "LOGIN_SUCCESS": 10 | return { 11 | user: action.payload, 12 | isFetching: false, 13 | error: false, 14 | }; 15 | case "LOGIN_FAILURE": 16 | return { 17 | user: null, 18 | isFetching: false, 19 | error: true, 20 | }; 21 | case "UPDATE_START": 22 | return { 23 | ...state, 24 | isFetching:true 25 | }; 26 | case "UPDATE_SUCCESS": 27 | return { 28 | user: action.payload, 29 | isFetching: false, 30 | error: false, 31 | }; 32 | case "UPDATE_FAILURE": 33 | return { 34 | user: state.user, 35 | isFetching: false, 36 | error: true, 37 | }; 38 | case "LOGOUT": 39 | return { 40 | user: null, 41 | isFetching: false, 42 | error: false, 43 | }; 44 | default: 45 | return state; 46 | } 47 | }; 48 | 49 | export default Reducer; 50 | -------------------------------------------------------------------------------- /mern-blog-app/api/routes/auth.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const User = require("../models/User"); 3 | const bcrypt = require("bcrypt"); 4 | 5 | //REGISTER 6 | router.post("/register", async (req, res) => { 7 | try { 8 | const salt = await bcrypt.genSalt(10); 9 | const hashedPass = await bcrypt.hash(req.body.password, salt); 10 | const newUser = new User({ 11 | username: req.body.username, 12 | email: req.body.email, 13 | password: hashedPass, 14 | }); 15 | 16 | const user = await newUser.save(); 17 | res.status(200).json(user); 18 | } catch (err) { 19 | res.status(500).json(err); 20 | } 21 | }); 22 | 23 | //LOGIN 24 | router.post("/login", async (req, res) => { 25 | try { 26 | const user = await User.findOne({ username: req.body.username }); 27 | !user && res.status(400).json("Wrong credentials!"); 28 | 29 | const validated = await bcrypt.compare(req.body.password, user.password); 30 | !validated && res.status(400).json("Wrong credentials!"); 31 | 32 | const { password, ...others } = user._doc; 33 | res.status(200).json(others); 34 | } catch (err) { 35 | res.status(500).json(err); 36 | } 37 | }); 38 | 39 | module.exports = router; 40 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/App.js: -------------------------------------------------------------------------------- 1 | import Home from "./pages/home/Home"; 2 | import TopBar from "./components/topbar/TopBar"; 3 | import Single from "./pages/single/Single"; 4 | import Write from "./pages/write/Write"; 5 | import Settings from "./pages/settings/Settings"; 6 | import Login from "./pages/login/Login"; 7 | import Register from "./pages/register/Register"; 8 | import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; 9 | import { useContext } from "react"; 10 | import { Context } from "./context/Context"; 11 | 12 | function App() { 13 | const { user } = useContext(Context); 14 | return ( 15 | 16 | 17 | 18 | 19 | 20 | 21 | {user ? : } 22 | {user ? : } 23 | {user ? : } 24 | {user ? : } 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | } 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/register/register.css: -------------------------------------------------------------------------------- 1 | .register { 2 | height: calc(100vh - 50px); 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | justify-content: center; 7 | background: linear-gradient( 8 | rgba(255, 255, 255, 0.5), 9 | rgba(255, 255, 255, 0.5) 10 | ), 11 | url("https://images.pexels.com/photos/317355/pexels-photo-317355.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 12 | background-size: cover; 13 | } 14 | 15 | .registerTitle { 16 | font-size: 50px; 17 | } 18 | 19 | .registerForm { 20 | margin-top: 20px; 21 | display: flex; 22 | flex-direction: column; 23 | } 24 | 25 | .registerForm > label { 26 | margin: 10px 0; 27 | } 28 | 29 | .registerInput { 30 | padding: 10px; 31 | background-color: white; 32 | border: none; 33 | } 34 | 35 | .registerButton { 36 | margin-top: 20px; 37 | cursor: pointer; 38 | background-color: teal; 39 | border: none; 40 | color: white; 41 | border-radius: 10px; 42 | padding: 10px; 43 | } 44 | 45 | .registerLoginButton { 46 | position: absolute; 47 | top: 60px; 48 | right: 20px; 49 | background-color: lightcoral; 50 | cursor: pointer; 51 | border: none; 52 | padding: 10px; 53 | color: white; 54 | border-radius: 10px; 55 | } 56 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/widgetSm/widgetSm.css: -------------------------------------------------------------------------------- 1 | .widgetSm{ 2 | flex: 1; 3 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 4 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 5 | padding: 20px; 6 | margin-right: 20px; 7 | } 8 | 9 | .widgetSmTitle{ 10 | font-size: 22px; 11 | font-weight: 600; 12 | } 13 | 14 | .widgetSmImg{ 15 | width: 40px; 16 | height: 40px; 17 | border-radius: 50%; 18 | object-fit: cover; 19 | } 20 | 21 | .widgetSmList{ 22 | margin: 0; 23 | padding: 0; 24 | list-style: none; 25 | } 26 | 27 | .widgetSmListItem{ 28 | display: flex; 29 | align-items: center; 30 | justify-content: space-between; 31 | margin: 20px 0px; 32 | } 33 | 34 | .widgetSmUser{ 35 | display: flex; 36 | flex-direction: column; 37 | } 38 | 39 | .widgetSmUsername{ 40 | font-weight: 600; 41 | } 42 | 43 | .widgetSmUserTitle{ 44 | font-weight: 300; 45 | } 46 | 47 | .widgetSmButton{ 48 | display: flex; 49 | align-items: center; 50 | border: none; 51 | border-radius: 10px; 52 | padding: 7px 10px; 53 | background-color: #eeeef7; 54 | color: #555; 55 | cursor: pointer; 56 | } 57 | 58 | .widgetSmIcon{ 59 | font-size: 16px !important; 60 | margin-right: 5px; 61 | } -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/login/Login.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { login } from "../../redux/apiCalls"; 4 | 5 | const Login = () => { 6 | const [username, setUsername] = useState(""); 7 | const [password, setPassword] = useState(""); 8 | const dispatch = useDispatch(); 9 | 10 | const handleClick = (e) => { 11 | e.preventDefault(); 12 | login(dispatch, { username, password }); 13 | }; 14 | 15 | return ( 16 |
25 | setUsername(e.target.value)} 30 | /> 31 | setPassword(e.target.value)} 36 | /> 37 | 40 |
41 | ); 42 | }; 43 | 44 | export default Login; 45 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/sidebar/sidebar.css: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | flex: 3; 3 | margin: 20px; 4 | padding-bottom: 30px; 5 | background-color: #fdfbfb; 6 | border-radius: 10px; 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | } 11 | 12 | .sidebarItem { 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | } 17 | 18 | .sidebarTitle { 19 | margin: 10px; 20 | padding: 5px; 21 | width: 80%; 22 | border-top: 1px solid #a7a4a4; 23 | border-bottom: 1px solid #a7a4a4; 24 | font-family: "Varela Round", sans-serif; 25 | font-size: 12px; 26 | color: #222; 27 | font-weight: 600; 28 | line-height: 20px; 29 | text-align: center; 30 | } 31 | 32 | .sidebarItem > img { 33 | margin-top: 15px; 34 | } 35 | 36 | .sidebarItem > p { 37 | padding: 30px; 38 | } 39 | 40 | .sidebarList { 41 | list-style: none; 42 | margin-bottom: 30px; 43 | } 44 | 45 | .sidebarListItem { 46 | display: inline-block; 47 | width: 50%; 48 | margin-top: 15px; 49 | cursor: pointer; 50 | } 51 | 52 | .sidebarSocial { 53 | margin-top: 15px; 54 | width: 250px; 55 | display: flex; 56 | align-items: center; 57 | justify-content: center; 58 | } 59 | 60 | .sidebarIcon{ 61 | font-size: 16px; 62 | margin-left: 10px; 63 | cursor: pointer; 64 | } -------------------------------------------------------------------------------- /MERN Project/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "new", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.12.3", 7 | "@material-ui/icons": "^4.11.2", 8 | "@reduxjs/toolkit": "^1.6.1", 9 | "@testing-library/jest-dom": "^5.11.4", 10 | "@testing-library/react": "^11.1.0", 11 | "@testing-library/user-event": "^12.1.10", 12 | "axios": "^0.21.4", 13 | "react": "^17.0.2", 14 | "react-dom": "^17.0.2", 15 | "react-redux": "^7.2.5", 16 | "react-router-dom": "^5.3.0", 17 | "react-scripts": "4.0.3", 18 | "react-stripe-checkout": "^2.6.3", 19 | "redux-persist": "^6.0.0", 20 | "styled-components": "^5.3.1", 21 | "web-vitals": "^1.0.1" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MERN Project/client/src/App.jsx: -------------------------------------------------------------------------------- 1 | import Product from "./pages/Product"; 2 | import Home from "./pages/Home"; 3 | import ProductList from "./pages/ProductList"; 4 | import Register from "./pages/Register"; 5 | import Login from "./pages/Login"; 6 | import Cart from "./pages/Cart"; 7 | import { 8 | BrowserRouter as Router, 9 | Switch, 10 | Route, 11 | Redirect, 12 | } from "react-router-dom"; 13 | import Success from "./pages/Success"; 14 | import { useSelector } from "react-redux"; 15 | 16 | const App = () => { 17 | const user = useSelector((state) => state.user.currentUser); 18 | return ( 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {user ? : } 37 | 38 | {user ? : } 39 | 40 | 41 | 42 | ); 43 | }; 44 | 45 | export default App; 46 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/login/login.css: -------------------------------------------------------------------------------- 1 | .login { 2 | height: calc(100vh - 50px); 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | justify-content: center; 7 | background: linear-gradient( 8 | rgba(255, 255, 255, 0.5), 9 | rgba(255, 255, 255, 0.5) 10 | ), 11 | url("https://images.pexels.com/photos/768473/pexels-photo-768473.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500"); 12 | background-size: cover; 13 | } 14 | 15 | .loginTitle { 16 | font-size: 50px; 17 | } 18 | 19 | .loginForm { 20 | margin-top: 20px; 21 | display: flex; 22 | flex-direction: column; 23 | } 24 | 25 | .loginForm > label { 26 | margin: 10px 0; 27 | } 28 | 29 | .loginInput { 30 | padding: 10px; 31 | background-color: white; 32 | border: none; 33 | } 34 | 35 | .loginButton { 36 | margin-top: 20px; 37 | cursor: pointer; 38 | background-color: lightcoral; 39 | border: none; 40 | color: white; 41 | border-radius: 10px; 42 | padding: 10px; 43 | } 44 | 45 | .loginButton:disabled{ 46 | cursor: not-allowed; 47 | background-color: rgb(252, 173, 173); 48 | } 49 | 50 | .loginRegisterButton { 51 | position: absolute; 52 | top: 60px; 53 | right: 20px; 54 | background-color: teal; 55 | cursor: pointer; 56 | border: none; 57 | padding: 10px; 58 | color: white; 59 | border-radius: 10px; 60 | } 61 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/CategoryItem.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | import styled from "styled-components"; 3 | import { mobile } from "../responsive"; 4 | 5 | const Container = styled.div` 6 | flex: 1; 7 | margin: 3px; 8 | height: 70vh; 9 | position: relative; 10 | `; 11 | 12 | const Image = styled.img` 13 | width: 100%; 14 | height: 100%; 15 | object-fit: cover; 16 | ${mobile({ height: "20vh" })} 17 | 18 | `; 19 | 20 | const Info = styled.div` 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | width: 100%; 25 | height: 100%; 26 | display: flex; 27 | flex-direction: column; 28 | align-items: center; 29 | justify-content: center; 30 | `; 31 | 32 | const Title = styled.h1` 33 | color:white; 34 | margin-bottom: 20px; 35 | `; 36 | 37 | const Button = styled.button` 38 | border:none; 39 | padding: 10px; 40 | background-color: white; 41 | color:gray; 42 | cursor: pointer; 43 | font-weight: 600; 44 | `; 45 | 46 | const CategoryItem = ({ item }) => { 47 | return ( 48 | 49 | 50 | 51 | 52 | {item.title} 53 | 54 | 55 | 56 | 57 | ); 58 | }; 59 | 60 | export default CategoryItem; 61 | -------------------------------------------------------------------------------- /MERN Project/admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lamaadmin", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.11.4", 7 | "@material-ui/data-grid": "^4.0.0-alpha.29", 8 | "@material-ui/icons": "^4.11.2", 9 | "@reduxjs/toolkit": "^1.6.1", 10 | "@testing-library/jest-dom": "^5.11.4", 11 | "@testing-library/react": "^11.1.0", 12 | "@testing-library/user-event": "^12.1.10", 13 | "axios": "^0.21.4", 14 | "firebase": "^9.1.0", 15 | "react": "^17.0.2", 16 | "react-dom": "^17.0.2", 17 | "react-redux": "^7.2.5", 18 | "react-router-dom": "^5.2.0", 19 | "react-scripts": "4.0.3", 20 | "recharts": "^2.0.9", 21 | "redux-persist": "^6.0.0", 22 | "timeago.js": "^4.0.2", 23 | "web-vitals": "^1.0.1" 24 | }, 25 | "scripts": { 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "eslintConfig": { 32 | "extends": [ 33 | "react-app", 34 | "react-app/jest" 35 | ] 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.2%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/widgetSm/WidgetSm.jsx: -------------------------------------------------------------------------------- 1 | import "./widgetSm.css"; 2 | import { Visibility } from "@material-ui/icons"; 3 | import { useEffect, useState } from "react"; 4 | import { userRequest } from "../../requestMethods"; 5 | 6 | export default function WidgetSm() { 7 | const [users, setUsers] = useState([]); 8 | 9 | useEffect(() => { 10 | const getUsers = async () => { 11 | try { 12 | const res = await userRequest.get("users/?new=true"); 13 | setUsers(res.data); 14 | } catch {} 15 | }; 16 | getUsers(); 17 | }, []); 18 | 19 | return ( 20 |
21 | New Join Members 22 | 43 |
44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /mern-blog-app/api/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const dotenv = require("dotenv"); 4 | const mongoose = require("mongoose"); 5 | const authRoute = require("./routes/auth"); 6 | const userRoute = require("./routes/users"); 7 | const postRoute = require("./routes/posts"); 8 | const categoryRoute = require("./routes/categories"); 9 | const multer = require("multer"); 10 | const path = require("path"); 11 | 12 | dotenv.config(); 13 | app.use(express.json()); 14 | app.use("/images", express.static(path.join(__dirname, "/images"))); 15 | 16 | mongoose 17 | .connect(process.env.MONGO_URL, { 18 | useNewUrlParser: true, 19 | useUnifiedTopology: true, 20 | useCreateIndex: true, 21 | useFindAndModify:true 22 | }) 23 | .then(console.log("Connected to MongoDB")) 24 | .catch((err) => console.log(err)); 25 | 26 | const storage = multer.diskStorage({ 27 | destination: (req, file, cb) => { 28 | cb(null, "images"); 29 | }, 30 | filename: (req, file, cb) => { 31 | cb(null, req.body.name); 32 | }, 33 | }); 34 | 35 | const upload = multer({ storage: storage }); 36 | app.post("/api/upload", upload.single("file"), (req, res) => { 37 | res.status(200).json("File has been uploaded"); 38 | }); 39 | 40 | app.use("/api/auth", authRoute); 41 | app.use("/api/users", userRoute); 42 | app.use("/api/posts", postRoute); 43 | app.use("/api/categories", categoryRoute); 44 | 45 | app.listen("5000", () => { 46 | console.log("Backend is running."); 47 | }); 48 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/Newsletter.jsx: -------------------------------------------------------------------------------- 1 | import { Send } from "@material-ui/icons"; 2 | import styled from "styled-components"; 3 | import { mobile } from "../responsive"; 4 | 5 | const Container = styled.div` 6 | height: 60vh; 7 | background-color: #fcf5f5; 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | flex-direction: column; 12 | `; 13 | const Title = styled.h1` 14 | font-size: 70px; 15 | margin-bottom: 20px; 16 | `; 17 | 18 | const Desc = styled.div` 19 | font-size: 24px; 20 | font-weight: 300; 21 | margin-bottom: 20px; 22 | ${mobile({ textAlign: "center" })} 23 | 24 | `; 25 | 26 | const InputContainer = styled.div` 27 | width: 50%; 28 | height: 40px; 29 | background-color: white; 30 | display: flex; 31 | justify-content: space-between; 32 | border: 1px solid lightgray; 33 | ${mobile({ width: "80%" })} 34 | `; 35 | 36 | const Input = styled.input` 37 | border: none; 38 | flex: 8; 39 | padding-left: 20px; 40 | `; 41 | 42 | const Button = styled.button` 43 | flex: 1; 44 | border: none; 45 | background-color: teal; 46 | color: white; 47 | `; 48 | 49 | const Newsletter = () => { 50 | return ( 51 | 52 | Newsletter 53 | Get timely updates from your favorite products. 54 | 55 | 56 | 59 | 60 | 61 | ); 62 | }; 63 | 64 | export default Newsletter; 65 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/settings/settings.css: -------------------------------------------------------------------------------- 1 | .settings { 2 | display: flex; 3 | } 4 | 5 | .settingsWrapper { 6 | flex: 9; 7 | padding: 20px; 8 | } 9 | 10 | .settingsTitle { 11 | display: flex; 12 | align-items: center; 13 | justify-content: space-between; 14 | } 15 | 16 | .settingsUpdateTitle { 17 | font-size: 30px; 18 | margin-bottom: 20px; 19 | color: lightcoral; 20 | } 21 | 22 | .settingsDeleteTitle { 23 | color: red; 24 | font-size: 12px; 25 | cursor: pointer; 26 | } 27 | 28 | .settingsForm { 29 | display: flex; 30 | flex-direction: column; 31 | } 32 | 33 | .settingsPP { 34 | display: flex; 35 | align-items: center; 36 | margin: 10px 0; 37 | } 38 | 39 | .settingsPP > img { 40 | width: 70px; 41 | height: 70px; 42 | border-radius: 20px; 43 | object-fit: cover; 44 | } 45 | 46 | .settingsPPIcon { 47 | width: 25px; 48 | height: 25px; 49 | border-radius: 50%; 50 | background-color: lightcoral; 51 | color: white; 52 | display: flex; 53 | align-items: center; 54 | justify-content: center; 55 | margin-left: 10px; 56 | cursor: pointer; 57 | } 58 | 59 | .settingsForm > label { 60 | font-size: 20px; 61 | margin-top: 20px; 62 | } 63 | 64 | .settingsForm > input { 65 | color: gray; 66 | margin: 10px 0; 67 | height: 30px; 68 | border: none; 69 | border-bottom: 1px solid lightgray; 70 | } 71 | 72 | .settingsSubmit{ 73 | width: 150px; 74 | align-self: center; 75 | border: none; 76 | border-radius: 10px; 77 | color: white; 78 | background-color: teal; 79 | padding: 10px; 80 | margin-top: 20px; 81 | cursor: pointer; 82 | } -------------------------------------------------------------------------------- /MERN Project/api/routes/auth.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const User = require("../models/User"); 3 | const CryptoJS = require("crypto-js"); 4 | const jwt = require("jsonwebtoken"); 5 | 6 | //REGISTER 7 | router.post("/register", async (req, res) => { 8 | const newUser = new User({ 9 | username: req.body.username, 10 | email: req.body.email, 11 | password: CryptoJS.AES.encrypt( 12 | req.body.password, 13 | process.env.PASS_SEC 14 | ).toString(), 15 | }); 16 | 17 | try { 18 | const savedUser = await newUser.save(); 19 | res.status(201).json(savedUser); 20 | } catch (err) { 21 | res.status(500).json(err); 22 | } 23 | }); 24 | 25 | //LOGIN 26 | 27 | router.post("/login", async (req, res) => { 28 | try { 29 | const user = await User.findOne({ username: req.body.username }); 30 | !user && res.status(401).json("Wrong credentials!"); 31 | 32 | const hashedPassword = CryptoJS.AES.decrypt( 33 | user.password, 34 | process.env.PASS_SEC 35 | ); 36 | const OriginalPassword = hashedPassword.toString(CryptoJS.enc.Utf8); 37 | 38 | OriginalPassword !== req.body.password && 39 | res.status(401).json("Wrong credentials!"); 40 | 41 | const accessToken = jwt.sign( 42 | { 43 | id: user._id, 44 | isAdmin: user.isAdmin, 45 | }, 46 | process.env.JWT_SEC, 47 | {expiresIn:"3d"} 48 | ); 49 | 50 | const { password, ...others } = user._doc; 51 | 52 | res.status(200).json({...others, accessToken}); 53 | } catch (err) { 54 | res.status(500).json(err); 55 | } 56 | }); 57 | 58 | module.exports = router; 59 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/home/Home.jsx: -------------------------------------------------------------------------------- 1 | import Chart from "../../components/chart/Chart"; 2 | import FeaturedInfo from "../../components/featuredInfo/FeaturedInfo"; 3 | import "./home.css"; 4 | import { userData } from "../../dummyData"; 5 | import WidgetSm from "../../components/widgetSm/WidgetSm"; 6 | import WidgetLg from "../../components/widgetLg/WidgetLg"; 7 | import { useEffect, useMemo, useState } from "react"; 8 | import { userRequest } from "../../requestMethods"; 9 | 10 | export default function Home() { 11 | const [userStats, setUserStats] = useState([]); 12 | 13 | const MONTHS = useMemo( 14 | () => [ 15 | "Jan", 16 | "Feb", 17 | "Mar", 18 | "Apr", 19 | "May", 20 | "Jun", 21 | "Jul", 22 | "Agu", 23 | "Sep", 24 | "Oct", 25 | "Nov", 26 | "Dec", 27 | ], 28 | [] 29 | ); 30 | 31 | useEffect(() => { 32 | const getStats = async () => { 33 | try { 34 | const res = await userRequest.get("/users/stats"); 35 | res.data.map((item) => 36 | setUserStats((prev) => [ 37 | ...prev, 38 | { name: MONTHS[item._id - 1], "Active User": item.total }, 39 | ]) 40 | ); 41 | } catch {} 42 | }; 43 | getStats(); 44 | }, [MONTHS]); 45 | 46 | return ( 47 |
48 | 49 | 55 |
56 | 57 | 58 |
59 |
60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/widgetLg/WidgetLg.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { userRequest } from "../../requestMethods"; 3 | import "./widgetLg.css"; 4 | import {format} from "timeago.js" 5 | 6 | export default function WidgetLg() { 7 | const [orders, setOrders] = useState([]); 8 | 9 | useEffect(() => { 10 | const getOrders = async () => { 11 | try { 12 | const res = await userRequest.get("orders"); 13 | setOrders(res.data); 14 | } catch {} 15 | }; 16 | getOrders(); 17 | }, []); 18 | const Button = ({ type }) => { 19 | return ; 20 | }; 21 | return ( 22 |
23 |

Latest transactions

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {orders.map((order) => ( 32 | 33 | 36 | 37 | 38 | 41 | 42 | ))} 43 |
CustomerDateAmountStatus
34 | {order.userId} 35 | {format(order.createdAt)}${order.amount} 39 |
44 |
45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /MERN Project/client/src/pages/Success.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { useSelector } from "react-redux"; 3 | import { useLocation } from "react-router"; 4 | import { userRequest } from "../requestMethods"; 5 | 6 | const Success = () => { 7 | const location = useLocation(); 8 | //in Cart.jsx I sent data and cart. Please check that page for the changes.(in video it's only data) 9 | const data = location.state.stripeData; 10 | const cart = location.state.cart; 11 | const currentUser = useSelector((state) => state.user.currentUser); 12 | const [orderId, setOrderId] = useState(null); 13 | 14 | useEffect(() => { 15 | const createOrder = async () => { 16 | try { 17 | const res = await userRequest.post("/orders", { 18 | userId: currentUser._id, 19 | products: cart.products.map((item) => ({ 20 | productId: item._id, 21 | quantity: item._quantity, 22 | })), 23 | amount: cart.total, 24 | address: data.billing_details.address, 25 | }); 26 | setOrderId(res.data._id); 27 | } catch {} 28 | }; 29 | data && createOrder(); 30 | }, [cart, data, currentUser]); 31 | 32 | return ( 33 |
42 | {orderId 43 | ? `Order has been created successfully. Your order number is ${orderId}` 44 | : `Successfull. Your order is being prepared...`} 45 | 46 |
47 | ); 48 | }; 49 | 50 | export default Success; 51 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/login/Login.jsx: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { useContext, useRef } from "react"; 3 | import { Link } from "react-router-dom"; 4 | import { Context } from "../../context/Context"; 5 | import "./login.css"; 6 | 7 | export default function Login() { 8 | const userRef = useRef(); 9 | const passwordRef = useRef(); 10 | const { dispatch, isFetching } = useContext(Context); 11 | 12 | const handleSubmit = async (e) => { 13 | e.preventDefault(); 14 | dispatch({ type: "LOGIN_START" }); 15 | try { 16 | const res = await axios.post("/auth/login", { 17 | username: userRef.current.value, 18 | password: passwordRef.current.value, 19 | }); 20 | dispatch({ type: "LOGIN_SUCCESS", payload: res.data }); 21 | } catch (err) { 22 | dispatch({ type: "LOGIN_FAILURE" }); 23 | } 24 | }; 25 | 26 | return ( 27 |
28 | Login 29 |
30 | 31 | 37 | 38 | 44 | 47 |
48 | 53 |
54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /MERN Project/api/routes/cart.js: -------------------------------------------------------------------------------- 1 | const Cart = require("../models/Cart"); 2 | const { 3 | verifyToken, 4 | verifyTokenAndAuthorization, 5 | verifyTokenAndAdmin, 6 | } = require("./verifyToken"); 7 | 8 | const router = require("express").Router(); 9 | 10 | //CREATE 11 | 12 | router.post("/", verifyToken, async (req, res) => { 13 | const newCart = new Cart(req.body); 14 | 15 | try { 16 | const savedCart = await newCart.save(); 17 | res.status(200).json(savedCart); 18 | } catch (err) { 19 | res.status(500).json(err); 20 | } 21 | }); 22 | 23 | //UPDATE 24 | router.put("/:id", verifyTokenAndAuthorization, async (req, res) => { 25 | try { 26 | const updatedCart = await Cart.findByIdAndUpdate( 27 | req.params.id, 28 | { 29 | $set: req.body, 30 | }, 31 | { new: true } 32 | ); 33 | res.status(200).json(updatedCart); 34 | } catch (err) { 35 | res.status(500).json(err); 36 | } 37 | }); 38 | 39 | //DELETE 40 | router.delete("/:id", verifyTokenAndAuthorization, async (req, res) => { 41 | try { 42 | await Cart.findByIdAndDelete(req.params.id); 43 | res.status(200).json("Cart has been deleted..."); 44 | } catch (err) { 45 | res.status(500).json(err); 46 | } 47 | }); 48 | 49 | //GET USER CART 50 | router.get("/find/:userId", verifyTokenAndAuthorization, async (req, res) => { 51 | try { 52 | const cart = await Cart.findOne({ userId: req.params.userId }); 53 | res.status(200).json(cart); 54 | } catch (err) { 55 | res.status(500).json(err); 56 | } 57 | }); 58 | 59 | // //GET ALL 60 | 61 | router.get("/", verifyTokenAndAdmin, async (req, res) => { 62 | try { 63 | const carts = await Cart.find(); 64 | res.status(200).json(carts); 65 | } catch (err) { 66 | res.status(500).json(err); 67 | } 68 | }); 69 | 70 | module.exports = router; 71 | -------------------------------------------------------------------------------- /mern-blog-app/api/routes/users.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const User = require("../models/User"); 3 | const Post = require("../models/Post"); 4 | const bcrypt = require("bcrypt"); 5 | 6 | //UPDATE 7 | router.put("/:id", async (req, res) => { 8 | if (req.body.userId === req.params.id) { 9 | if (req.body.password) { 10 | const salt = await bcrypt.genSalt(10); 11 | req.body.password = await bcrypt.hash(req.body.password, salt); 12 | } 13 | try { 14 | const updatedUser = await User.findByIdAndUpdate( 15 | req.params.id, 16 | { 17 | $set: req.body, 18 | }, 19 | { new: true } 20 | ); 21 | res.status(200).json(updatedUser); 22 | } catch (err) { 23 | res.status(500).json(err); 24 | } 25 | } else { 26 | res.status(401).json("You can update only your account!"); 27 | } 28 | }); 29 | 30 | //DELETE 31 | router.delete("/:id", async (req, res) => { 32 | if (req.body.userId === req.params.id) { 33 | try { 34 | const user = await User.findById(req.params.id); 35 | try { 36 | await Post.deleteMany({ username: user.username }); 37 | await User.findByIdAndDelete(req.params.id); 38 | res.status(200).json("User has been deleted..."); 39 | } catch (err) { 40 | res.status(500).json(err); 41 | } 42 | } catch (err) { 43 | res.status(404).json("User not found!"); 44 | } 45 | } else { 46 | res.status(401).json("You can delete only your account!"); 47 | } 48 | }); 49 | 50 | //GET USER 51 | router.get("/:id", async (req, res) => { 52 | try { 53 | const user = await User.findById(req.params.id); 54 | const { password, ...others } = user._doc; 55 | res.status(200).json(others); 56 | } catch (err) { 57 | res.status(500).json(err); 58 | } 59 | }); 60 | 61 | module.exports = router; 62 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/sidebar/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { useEffect, useState } from "react"; 3 | import { Link } from "react-router-dom"; 4 | import "./sidebar.css"; 5 | 6 | export default function Sidebar() { 7 | const [cats, setCats] = useState([]); 8 | 9 | useEffect(() => { 10 | const getCats = async () => { 11 | const res = await axios.get("/categories"); 12 | setCats(res.data); 13 | }; 14 | getCats(); 15 | }, []); 16 | return ( 17 |
18 |
19 | ABOUT ME 20 | 24 |

25 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptate qui 26 | necessitatibus nostrum illum reprehenderit. 27 |

28 |
29 |
30 | CATEGORIES 31 |
    32 | {cats.map((c) => ( 33 | 34 |
  • {c.name}
  • 35 | 36 | ))} 37 |
38 |
39 |
40 | FOLLOW US 41 |
42 | 43 | 44 | 45 | 46 |
47 |
48 |
49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /MERN Project/admin/src/App.js: -------------------------------------------------------------------------------- 1 | import Sidebar from "./components/sidebar/Sidebar"; 2 | import Topbar from "./components/topbar/Topbar"; 3 | import "./App.css"; 4 | import Home from "./pages/home/Home"; 5 | import { 6 | BrowserRouter as Router, 7 | Switch, 8 | Route, 9 | Redirect, 10 | } from "react-router-dom"; 11 | import UserList from "./pages/userList/UserList"; 12 | import User from "./pages/user/User"; 13 | import NewUser from "./pages/newUser/NewUser"; 14 | import ProductList from "./pages/productList/ProductList"; 15 | import Product from "./pages/product/Product"; 16 | import NewProduct from "./pages/newProduct/NewProduct"; 17 | import Login from "./pages/login/Login"; 18 | import { useSelector } from "react-redux"; 19 | 20 | function App() { 21 | const admin = useSelector((state) => state.user.currentUser.isAdmin); 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | {admin && ( 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 | )} 57 |
58 |
59 | ); 60 | } 61 | 62 | export default App; 63 | -------------------------------------------------------------------------------- /MERN Project/admin/src/redux/apiCalls.js: -------------------------------------------------------------------------------- 1 | import { loginFailure, loginStart, loginSuccess } from "./userRedux"; 2 | import { publicRequest, userRequest } from "../requestMethods"; 3 | import { 4 | getProductFailure, 5 | getProductStart, 6 | getProductSuccess, 7 | deleteProductFailure, 8 | deleteProductStart, 9 | deleteProductSuccess, 10 | updateProductFailure, 11 | updateProductStart, 12 | updateProductSuccess, 13 | addProductFailure, 14 | addProductStart, 15 | addProductSuccess, 16 | } from "./productRedux"; 17 | 18 | export const login = async (dispatch, user) => { 19 | dispatch(loginStart()); 20 | try { 21 | const res = await publicRequest.post("/auth/login", user); 22 | dispatch(loginSuccess(res.data)); 23 | } catch (err) { 24 | dispatch(loginFailure()); 25 | } 26 | }; 27 | 28 | export const getProducts = async (dispatch) => { 29 | dispatch(getProductStart()); 30 | try { 31 | const res = await publicRequest.get("/products"); 32 | dispatch(getProductSuccess(res.data)); 33 | } catch (err) { 34 | dispatch(getProductFailure()); 35 | } 36 | }; 37 | 38 | export const deleteProduct = async (id, dispatch) => { 39 | dispatch(deleteProductStart()); 40 | try { 41 | // const res = await userRequest.delete(`/products/${id}`); 42 | dispatch(deleteProductSuccess(id)); 43 | } catch (err) { 44 | dispatch(deleteProductFailure()); 45 | } 46 | }; 47 | 48 | export const updateProduct = async (id, product, dispatch) => { 49 | dispatch(updateProductStart()); 50 | try { 51 | // update 52 | dispatch(updateProductSuccess({ id, product })); 53 | } catch (err) { 54 | dispatch(updateProductFailure()); 55 | } 56 | }; 57 | export const addProduct = async (product, dispatch) => { 58 | dispatch(addProductStart()); 59 | try { 60 | const res = await userRequest.post(`/products`, product); 61 | dispatch(addProductSuccess(res.data)); 62 | } catch (err) { 63 | dispatch(addProductFailure()); 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/userList/UserList.jsx: -------------------------------------------------------------------------------- 1 | import "./userList.css"; 2 | import { DataGrid } from "@material-ui/data-grid"; 3 | import { DeleteOutline } from "@material-ui/icons"; 4 | import { userRows } from "../../dummyData"; 5 | import { Link } from "react-router-dom"; 6 | import { useState } from "react"; 7 | 8 | export default function UserList() { 9 | const [data, setData] = useState(userRows); 10 | 11 | const handleDelete = (id) => { 12 | setData(data.filter((item) => item.id !== id)); 13 | }; 14 | 15 | const columns = [ 16 | { field: "id", headerName: "ID", width: 90 }, 17 | { 18 | field: "user", 19 | headerName: "User", 20 | width: 200, 21 | renderCell: (params) => { 22 | return ( 23 |
24 | 25 | {params.row.username} 26 |
27 | ); 28 | }, 29 | }, 30 | { field: "email", headerName: "Email", width: 200 }, 31 | { 32 | field: "status", 33 | headerName: "Status", 34 | width: 120, 35 | }, 36 | { 37 | field: "transaction", 38 | headerName: "Transaction Volume", 39 | width: 160, 40 | }, 41 | { 42 | field: "action", 43 | headerName: "Action", 44 | width: 150, 45 | renderCell: (params) => { 46 | return ( 47 | <> 48 | 49 | 50 | 51 | handleDelete(params.row.id)} 54 | /> 55 | 56 | ); 57 | }, 58 | }, 59 | ]; 60 | 61 | return ( 62 |
63 | 70 |
71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/singlePost/singlePost.css: -------------------------------------------------------------------------------- 1 | .singlePost { 2 | flex: 9; 3 | } 4 | 5 | .singlePostWrapper { 6 | padding: 20px; 7 | padding-right: 0; 8 | display: flex; 9 | flex-direction: column; 10 | } 11 | 12 | .singlePostImg { 13 | width: 100%; 14 | height: 300px; 15 | border-radius: 5px; 16 | object-fit: cover; 17 | } 18 | 19 | .singlePostTitle { 20 | text-align: center; 21 | margin: 10px; 22 | font-family: "Lora", serif; 23 | font-size: 28px; 24 | } 25 | 26 | .singlePostTitleInput { 27 | margin: 10px; 28 | font-family: "Lora", serif; 29 | font-size: 28px; 30 | text-align: center; 31 | border: none; 32 | color: gray; 33 | border-bottom: 1px solid lightgray; 34 | } 35 | 36 | .singlePostTitleInput:focus { 37 | outline: none; 38 | } 39 | 40 | .singlePostEdit { 41 | float: right; 42 | font-size: 16px; 43 | } 44 | 45 | .singlePostIcon { 46 | margin-left: 10px; 47 | cursor: pointer; 48 | } 49 | 50 | .singlePostIcon:first-child { 51 | color: teal; 52 | } 53 | 54 | .singlePostIcon:last-child { 55 | color: tomato; 56 | } 57 | 58 | .singlePostInfo { 59 | margin-bottom: 20px; 60 | display: flex; 61 | justify-content: space-between; 62 | font-size: 16px; 63 | font-family: "Varela Round", sans-serif; 64 | color: #b39656; 65 | } 66 | 67 | .singlePostDesc { 68 | color: #666; 69 | font-size: 18px; 70 | line-height: 25px; 71 | } 72 | 73 | .singlePostDesc::first-letter { 74 | margin-left: 20px; 75 | font-size: 30px; 76 | font-weight: 600; 77 | } 78 | 79 | .singlePostDescInput { 80 | border: none; 81 | color: #666; 82 | font-size: 18px; 83 | line-height: 25px; 84 | } 85 | 86 | .singlePostDescInput:focus { 87 | outline: none; 88 | } 89 | .singlePostButton { 90 | width: 100px; 91 | border: none; 92 | background-color: teal; 93 | padding: 5px; 94 | color: white; 95 | border-radius: 5px; 96 | cursor: pointer; 97 | align-self: flex-end; 98 | margin-top: 20px; 99 | } 100 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/Products.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import styled from "styled-components"; 3 | import { popularProducts } from "../data"; 4 | import Product from "./Product"; 5 | import axios from "axios"; 6 | 7 | const Container = styled.div` 8 | padding: 20px; 9 | display: flex; 10 | flex-wrap: wrap; 11 | justify-content: space-between; 12 | `; 13 | 14 | const Products = ({ cat, filters, sort }) => { 15 | const [products, setProducts] = useState([]); 16 | const [filteredProducts, setFilteredProducts] = useState([]); 17 | 18 | useEffect(() => { 19 | const getProducts = async () => { 20 | try { 21 | const res = await axios.get( 22 | cat 23 | ? `http://localhost:5000/api/products?category=${cat}` 24 | : "http://localhost:5000/api/products" 25 | ); 26 | setProducts(res.data); 27 | } catch (err) {} 28 | }; 29 | getProducts(); 30 | }, [cat]); 31 | 32 | useEffect(() => { 33 | cat && 34 | setFilteredProducts( 35 | products.filter((item) => 36 | Object.entries(filters).every(([key, value]) => 37 | item[key].includes(value) 38 | ) 39 | ) 40 | ); 41 | }, [products, cat, filters]); 42 | 43 | useEffect(() => { 44 | if (sort === "newest") { 45 | setFilteredProducts((prev) => 46 | [...prev].sort((a, b) => a.createdAt - b.createdAt) 47 | ); 48 | } else if (sort === "asc") { 49 | setFilteredProducts((prev) => 50 | [...prev].sort((a, b) => a.price - b.price) 51 | ); 52 | } else { 53 | setFilteredProducts((prev) => 54 | [...prev].sort((a, b) => b.price - a.price) 55 | ); 56 | } 57 | }, [sort]); 58 | 59 | return ( 60 | 61 | {cat 62 | ? filteredProducts.map((item) => ) 63 | : products 64 | .slice(0, 8) 65 | .map((item) => )} 66 | 67 | ); 68 | }; 69 | 70 | export default Products; 71 | -------------------------------------------------------------------------------- /MERN Project/client/src/components/Product.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | FavoriteBorderOutlined, 3 | SearchOutlined, 4 | ShoppingCartOutlined, 5 | } from "@material-ui/icons"; 6 | import { Link } from "react-router-dom"; 7 | import styled from "styled-components"; 8 | 9 | const Info = styled.div` 10 | opacity: 0; 11 | width: 100%; 12 | height: 100%; 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | background-color: rgba(0, 0, 0, 0.2); 17 | z-index: 3; 18 | display: flex; 19 | align-items: center; 20 | justify-content: center; 21 | transition: all 0.5s ease; 22 | cursor: pointer; 23 | `; 24 | 25 | const Container = styled.div` 26 | flex: 1; 27 | margin: 5px; 28 | min-width: 280px; 29 | height: 350px; 30 | display: flex; 31 | align-items: center; 32 | justify-content: center; 33 | background-color: #f5fbfd; 34 | position: relative; 35 | 36 | &:hover ${Info}{ 37 | opacity: 1; 38 | } 39 | `; 40 | 41 | const Circle = styled.div` 42 | width: 200px; 43 | height: 200px; 44 | border-radius: 50%; 45 | background-color: white; 46 | position: absolute; 47 | `; 48 | 49 | const Image = styled.img` 50 | height: 75%; 51 | z-index: 2; 52 | `; 53 | 54 | const Icon = styled.div` 55 | width: 40px; 56 | height: 40px; 57 | border-radius: 50%; 58 | background-color: white; 59 | display: flex; 60 | align-items: center; 61 | justify-content: center; 62 | margin: 10px; 63 | transition: all 0.5s ease; 64 | &:hover { 65 | background-color: #e9f5f5; 66 | transform: scale(1.1); 67 | } 68 | `; 69 | 70 | const Product = ({ item }) => { 71 | return ( 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | ); 90 | }; 91 | 92 | export default Product; 93 | -------------------------------------------------------------------------------- /MERN Project/client/src/pages/Register.jsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { mobile } from "../responsive"; 3 | 4 | const Container = styled.div` 5 | width: 100vw; 6 | height: 100vh; 7 | background: linear-gradient( 8 | rgba(255, 255, 255, 0.5), 9 | rgba(255, 255, 255, 0.5) 10 | ), 11 | url("https://images.pexels.com/photos/6984661/pexels-photo-6984661.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940") 12 | center; 13 | background-size: cover; 14 | display: flex; 15 | align-items: center; 16 | justify-content: center; 17 | `; 18 | 19 | const Wrapper = styled.div` 20 | width: 40%; 21 | padding: 20px; 22 | background-color: white; 23 | ${mobile({ width: "75%" })} 24 | `; 25 | 26 | const Title = styled.h1` 27 | font-size: 24px; 28 | font-weight: 300; 29 | `; 30 | 31 | const Form = styled.form` 32 | display: flex; 33 | flex-wrap: wrap; 34 | `; 35 | 36 | const Input = styled.input` 37 | flex: 1; 38 | min-width: 40%; 39 | margin: 20px 10px 0px 0px; 40 | padding: 10px; 41 | `; 42 | 43 | const Agreement = styled.span` 44 | font-size: 12px; 45 | margin: 20px 0px; 46 | `; 47 | 48 | const Button = styled.button` 49 | width: 40%; 50 | border: none; 51 | padding: 15px 20px; 52 | background-color: teal; 53 | color: white; 54 | cursor: pointer; 55 | `; 56 | 57 | const Register = () => { 58 | return ( 59 | 60 | 61 | CREATE AN ACCOUNT 62 |
63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | By creating an account, I consent to the processing of my personal 71 | data in accordance with the PRIVACY POLICY 72 | 73 | 74 |
75 |
76 |
77 | ); 78 | }; 79 | 80 | export default Register; 81 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/register/Register.jsx: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { useState } from "react"; 3 | import { Link } from "react-router-dom"; 4 | import "./register.css"; 5 | 6 | export default function Register() { 7 | const [username, setUsername] = useState(""); 8 | const [email, setEmail] = useState(""); 9 | const [password, setPassword] = useState(""); 10 | const [error, setError] = useState(false); 11 | 12 | const handleSubmit = async (e) => { 13 | e.preventDefault(); 14 | setError(false); 15 | try { 16 | const res = await axios.post("/auth/register", { 17 | username, 18 | email, 19 | password, 20 | }); 21 | res.data && window.location.replace("/login"); 22 | } catch (err) { 23 | setError(true); 24 | } 25 | }; 26 | return ( 27 |
28 | Register 29 |
30 | 31 | setUsername(e.target.value)} 36 | /> 37 | 38 | setEmail(e.target.value)} 43 | /> 44 | 45 | setPassword(e.target.value)} 50 | /> 51 | 54 |
55 | 60 | {error && Something went wrong!} 61 |
62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/newUser/NewUser.jsx: -------------------------------------------------------------------------------- 1 | import "./newUser.css"; 2 | 3 | export default function NewUser() { 4 | return ( 5 |
6 |

New User

7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 45 | 49 |
50 | 51 |
52 |
53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /MERN Project/api/routes/product.js: -------------------------------------------------------------------------------- 1 | const Product = require("../models/Product"); 2 | const { 3 | verifyToken, 4 | verifyTokenAndAuthorization, 5 | verifyTokenAndAdmin, 6 | } = require("./verifyToken"); 7 | 8 | const router = require("express").Router(); 9 | 10 | //CREATE 11 | 12 | router.post("/", verifyTokenAndAdmin, async (req, res) => { 13 | const newProduct = new Product(req.body); 14 | 15 | try { 16 | const savedProduct = await newProduct.save(); 17 | res.status(200).json(savedProduct); 18 | } catch (err) { 19 | res.status(500).json(err); 20 | } 21 | }); 22 | 23 | //UPDATE 24 | router.put("/:id", verifyTokenAndAdmin, async (req, res) => { 25 | try { 26 | const updatedProduct = await Product.findByIdAndUpdate( 27 | req.params.id, 28 | { 29 | $set: req.body, 30 | }, 31 | { new: true } 32 | ); 33 | res.status(200).json(updatedProduct); 34 | } catch (err) { 35 | res.status(500).json(err); 36 | } 37 | }); 38 | 39 | //DELETE 40 | router.delete("/:id", verifyTokenAndAdmin, async (req, res) => { 41 | try { 42 | await Product.findByIdAndDelete(req.params.id); 43 | res.status(200).json("Product has been deleted..."); 44 | } catch (err) { 45 | res.status(500).json(err); 46 | } 47 | }); 48 | 49 | //GET PRODUCT 50 | router.get("/find/:id", async (req, res) => { 51 | try { 52 | const product = await Product.findById(req.params.id); 53 | res.status(200).json(product); 54 | } catch (err) { 55 | res.status(500).json(err); 56 | } 57 | }); 58 | 59 | //GET ALL PRODUCTS 60 | router.get("/", async (req, res) => { 61 | const qNew = req.query.new; 62 | const qCategory = req.query.category; 63 | try { 64 | let products; 65 | 66 | if (qNew) { 67 | products = await Product.find().sort({ createdAt: -1 }).limit(1); 68 | } else if (qCategory) { 69 | products = await Product.find({ 70 | categories: { 71 | $in: [qCategory], 72 | }, 73 | }); 74 | } else { 75 | products = await Product.find(); 76 | } 77 | 78 | res.status(200).json(products); 79 | } catch (err) { 80 | res.status(500).json(err); 81 | } 82 | }); 83 | 84 | module.exports = router; 85 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/productList/ProductList.jsx: -------------------------------------------------------------------------------- 1 | import "./productList.css"; 2 | import { DataGrid } from "@material-ui/data-grid"; 3 | import { DeleteOutline } from "@material-ui/icons"; 4 | import { Link } from "react-router-dom"; 5 | import { useEffect } from "react"; 6 | import { useDispatch, useSelector } from "react-redux"; 7 | import { deleteProduct, getProducts } from "../../redux/apiCalls"; 8 | 9 | export default function ProductList() { 10 | const dispatch = useDispatch(); 11 | const products = useSelector((state) => state.product.products); 12 | 13 | useEffect(() => { 14 | getProducts(dispatch); 15 | }, [dispatch]); 16 | 17 | const handleDelete = (id) => { 18 | deleteProduct(id, dispatch); 19 | }; 20 | 21 | const columns = [ 22 | { field: "_id", headerName: "ID", width: 220 }, 23 | { 24 | field: "product", 25 | headerName: "Product", 26 | width: 200, 27 | renderCell: (params) => { 28 | return ( 29 |
30 | 31 | {params.row.title} 32 |
33 | ); 34 | }, 35 | }, 36 | { field: "inStock", headerName: "Stock", width: 200 }, 37 | { 38 | field: "price", 39 | headerName: "Price", 40 | width: 160, 41 | }, 42 | { 43 | field: "action", 44 | headerName: "Action", 45 | width: 150, 46 | renderCell: (params) => { 47 | return ( 48 | <> 49 | 50 | 51 | 52 | handleDelete(params.row._id)} 55 | /> 56 | 57 | ); 58 | }, 59 | }, 60 | ]; 61 | 62 | return ( 63 |
64 | row._id} 69 | pageSize={8} 70 | checkboxSelection 71 | /> 72 |
73 | ); 74 | } 75 | -------------------------------------------------------------------------------- /MERN Project/admin/src/components/featuredInfo/FeaturedInfo.jsx: -------------------------------------------------------------------------------- 1 | import "./featuredInfo.css"; 2 | import { ArrowDownward, ArrowUpward } from "@material-ui/icons"; 3 | import { useEffect, useState } from "react"; 4 | import { userRequest } from "../../requestMethods"; 5 | 6 | export default function FeaturedInfo() { 7 | const [income, setIncome] = useState([]); 8 | const [perc, setPerc] = useState(0); 9 | 10 | useEffect(() => { 11 | const getIncome = async () => { 12 | try { 13 | const res = await userRequest.get("orders/income"); 14 | setIncome(res.data); 15 | setPerc((res.data[1].total * 100) / res.data[0].total - 100); 16 | } catch {} 17 | }; 18 | getIncome(); 19 | }, []); 20 | 21 | return ( 22 |
23 |
24 | Revanue 25 |
26 | ${income[1]?.total} 27 | 28 | %{Math.floor(perc)}{" "} 29 | {perc < 0 ? ( 30 | 31 | ) : ( 32 | 33 | )} 34 | 35 |
36 | Compared to last month 37 |
38 |
39 | Sales 40 |
41 | $4,415 42 | 43 | -1.4 44 | 45 |
46 | Compared to last month 47 |
48 |
49 | Cost 50 |
51 | $2,225 52 | 53 | +2.4 54 | 55 |
56 | Compared to last month 57 |
58 |
59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/pages/write/Write.jsx: -------------------------------------------------------------------------------- 1 | import { useContext, useState } from "react"; 2 | import "./write.css"; 3 | import axios from "axios"; 4 | import { Context } from "../../context/Context"; 5 | 6 | export default function Write() { 7 | const [title, setTitle] = useState(""); 8 | const [desc, setDesc] = useState(""); 9 | const [file, setFile] = useState(null); 10 | const { user } = useContext(Context); 11 | 12 | const handleSubmit = async (e) => { 13 | e.preventDefault(); 14 | const newPost = { 15 | username: user.username, 16 | title, 17 | desc, 18 | }; 19 | if (file) { 20 | const data =new FormData(); 21 | const filename = Date.now() + file.name; 22 | data.append("name", filename); 23 | data.append("file", file); 24 | newPost.photo = filename; 25 | try { 26 | await axios.post("/upload", data); 27 | } catch (err) {} 28 | } 29 | try { 30 | const res = await axios.post("/posts", newPost); 31 | window.location.replace("/post/" + res.data._id); 32 | } catch (err) {} 33 | }; 34 | return ( 35 |
36 | {file && ( 37 | 38 | )} 39 |
40 |
41 | 44 | setFile(e.target.files[0])} 49 | /> 50 | setTitle(e.target.value)} 56 | /> 57 |
58 |
59 | 65 |
66 | 69 |
70 |
71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /mern-blog-app/client/src/components/topbar/TopBar.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { Context } from "../../context/Context"; 4 | import "./topbar.css"; 5 | 6 | export default function TopBar() { 7 | const { user, dispatch } = useContext(Context); 8 | const PF = "http://localhost:5000/images/" 9 | 10 | const handleLogout = () => { 11 | dispatch({ type: "LOGOUT" }); 12 | }; 13 | return ( 14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 |
22 |
    23 |
  • 24 | 25 | HOME 26 | 27 |
  • 28 |
  • 29 | 30 | ABOUT 31 | 32 |
  • 33 |
  • 34 | 35 | CONTACT 36 | 37 |
  • 38 |
  • 39 | 40 | WRITE 41 | 42 |
  • 43 |
  • 44 | {user && "LOGOUT"} 45 |
  • 46 |
47 |
48 |
49 | {user ? ( 50 | 51 | 52 | 53 | ) : ( 54 |
    55 |
  • 56 | 57 | LOGIN 58 | 59 |
  • 60 |
  • 61 | 62 | REGISTER 63 | 64 |
  • 65 |
66 | )} 67 | 68 |
69 |
70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /MERN Project/admin/src/redux/productRedux.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | export const productSlice = createSlice({ 4 | name: "product", 5 | initialState: { 6 | products: [], 7 | isFetching: false, 8 | error: false, 9 | }, 10 | reducers: { 11 | //GET ALL 12 | getProductStart: (state) => { 13 | state.isFetching = true; 14 | state.error = false; 15 | }, 16 | getProductSuccess: (state, action) => { 17 | state.isFetching = false; 18 | state.products = action.payload; 19 | }, 20 | getProductFailure: (state) => { 21 | state.isFetching = false; 22 | state.error = true; 23 | }, 24 | //DELETE 25 | deleteProductStart: (state) => { 26 | state.isFetching = true; 27 | state.error = false; 28 | }, 29 | deleteProductSuccess: (state, action) => { 30 | state.isFetching = false; 31 | state.products.splice( 32 | state.products.findIndex((item) => item._id === action.payload), 33 | 1 34 | ); 35 | }, 36 | deleteProductFailure: (state) => { 37 | state.isFetching = false; 38 | state.error = true; 39 | }, 40 | //UPDATE 41 | updateProductStart: (state) => { 42 | state.isFetching = true; 43 | state.error = false; 44 | }, 45 | updateProductSuccess: (state, action) => { 46 | state.isFetching = false; 47 | state.products[ 48 | state.products.findIndex((item) => item._id === action.payload.id) 49 | ] = action.payload.product; 50 | }, 51 | updateProductFailure: (state) => { 52 | state.isFetching = false; 53 | state.error = true; 54 | }, 55 | //UPDATE 56 | addProductStart: (state) => { 57 | state.isFetching = true; 58 | state.error = false; 59 | }, 60 | addProductSuccess: (state, action) => { 61 | state.isFetching = false; 62 | state.products.push(action.payload); 63 | }, 64 | addProductFailure: (state) => { 65 | state.isFetching = false; 66 | state.error = true; 67 | }, 68 | }, 69 | }); 70 | 71 | export const { 72 | getProductStart, 73 | getProductSuccess, 74 | getProductFailure, 75 | deleteProductStart, 76 | deleteProductSuccess, 77 | deleteProductFailure, 78 | updateProductStart, 79 | updateProductSuccess, 80 | updateProductFailure, 81 | addProductStart, 82 | addProductSuccess, 83 | addProductFailure, 84 | } = productSlice.actions; 85 | 86 | export default productSlice.reducer; 87 | -------------------------------------------------------------------------------- /MERN Project/api/routes/user.js: -------------------------------------------------------------------------------- 1 | const User = require("../models/User"); 2 | const { 3 | verifyToken, 4 | verifyTokenAndAuthorization, 5 | verifyTokenAndAdmin, 6 | } = require("./verifyToken"); 7 | 8 | const router = require("express").Router(); 9 | 10 | //UPDATE 11 | router.put("/:id", verifyTokenAndAuthorization, async (req, res) => { 12 | if (req.body.password) { 13 | req.body.password = CryptoJS.AES.encrypt( 14 | req.body.password, 15 | process.env.PASS_SEC 16 | ).toString(); 17 | } 18 | 19 | try { 20 | const updatedUser = await User.findByIdAndUpdate( 21 | req.params.id, 22 | { 23 | $set: req.body, 24 | }, 25 | { new: true } 26 | ); 27 | res.status(200).json(updatedUser); 28 | } catch (err) { 29 | res.status(500).json(err); 30 | } 31 | }); 32 | 33 | //DELETE 34 | router.delete("/:id", verifyTokenAndAuthorization, async (req, res) => { 35 | try { 36 | await User.findByIdAndDelete(req.params.id); 37 | res.status(200).json("User has been deleted..."); 38 | } catch (err) { 39 | res.status(500).json(err); 40 | } 41 | }); 42 | 43 | //GET USER 44 | router.get("/find/:id", verifyTokenAndAdmin, async (req, res) => { 45 | try { 46 | const user = await User.findById(req.params.id); 47 | const { password, ...others } = user._doc; 48 | res.status(200).json(others); 49 | } catch (err) { 50 | res.status(500).json(err); 51 | } 52 | }); 53 | 54 | //GET ALL USER 55 | router.get("/", verifyTokenAndAdmin, async (req, res) => { 56 | const query = req.query.new; 57 | try { 58 | const users = query 59 | ? await User.find().sort({ _id: -1 }).limit(5) 60 | : await User.find(); 61 | res.status(200).json(users); 62 | } catch (err) { 63 | res.status(500).json(err); 64 | } 65 | }); 66 | 67 | //GET USER STATS 68 | 69 | router.get("/stats", verifyTokenAndAdmin, async (req, res) => { 70 | const date = new Date(); 71 | const lastYear = new Date(date.setFullYear(date.getFullYear() - 1)); 72 | 73 | try { 74 | const data = await User.aggregate([ 75 | { $match: { createdAt: { $gte: lastYear } } }, 76 | { 77 | $project: { 78 | month: { $month: "$createdAt" }, 79 | }, 80 | }, 81 | { 82 | $group: { 83 | _id: "$month", 84 | total: { $sum: 1 }, 85 | }, 86 | }, 87 | ]); 88 | res.status(200).json(data) 89 | } catch (err) { 90 | res.status(500).json(err); 91 | } 92 | }); 93 | 94 | module.exports = router; 95 | -------------------------------------------------------------------------------- /React Quiz/src/components/Trivia.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import useSound from "use-sound"; 3 | import play from "../sounds/play.mp3"; 4 | import correct from "../sounds/correct.mp3"; 5 | import wrong from "../sounds/wrong.mp3"; 6 | 7 | export default function Trivia({ 8 | data, 9 | questionNumber, 10 | setQuestionNumber, 11 | setTimeOut, 12 | }) { 13 | const [question, setQuestion] = useState(null); 14 | const [selectedAnswer, setSelectedAnswer] = useState(null); 15 | const [className, setClassName] = useState("answer"); 16 | const [letsPlay] = useSound(play); 17 | const [correctAnswer] = useSound(correct); 18 | const [wrongAnswer] = useSound(wrong); 19 | 20 | useEffect(() => { 21 | letsPlay(); 22 | }, [letsPlay]); 23 | 24 | useEffect(() => { 25 | setQuestion(data[questionNumber - 1]); 26 | }, [data, questionNumber]); 27 | 28 | const delay = (duration, callback) => { 29 | setTimeout(() => { 30 | callback(); 31 | }, duration); 32 | }; 33 | 34 | const handleClick = (a) => { 35 | setSelectedAnswer(a); 36 | setClassName("answer active"); 37 | delay(3000, () => { 38 | setClassName(a.correct ? "answer correct" : "answer wrong"); 39 | }); 40 | // setTimeout(() => { 41 | // setClassName(a.correct ? "answer correct" : "answer wrong"); 42 | // }, 3000); 43 | 44 | // setTimeout(() => { 45 | delay(5000, () => { 46 | if (a.correct) { 47 | correctAnswer(); 48 | delay(1000, () => { 49 | setQuestionNumber((prev) => prev + 1); 50 | setSelectedAnswer(null); 51 | }); 52 | // setTimeout(() => { 53 | // setQuestionNumber((prev) => prev + 1); 54 | // setSelectedAnswer(null); 55 | // }, 1000); 56 | } else { 57 | wrongAnswer(); 58 | delay(1000, () => { 59 | setTimeOut(true); 60 | }); 61 | // setTimeout(() => { 62 | // setTimeOut(true); 63 | // }, 1000); 64 | } 65 | // }, 5000); 66 | }) 67 | }; 68 | return ( 69 |
70 |
{question?.question}
71 |
72 | {question?.answers.map((a) => ( 73 |
!selectedAnswer && handleClick(a)} 76 | > 77 | {a.text} 78 |
79 | ))} 80 |
81 |
82 | ); 83 | } 84 | -------------------------------------------------------------------------------- /mern-blog-app/api/routes/posts.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const User = require("../models/User"); 3 | const Post = require("../models/Post"); 4 | 5 | //CREATE POST 6 | router.post("/", async (req, res) => { 7 | const newPost = new Post(req.body); 8 | try { 9 | const savedPost = await newPost.save(); 10 | res.status(200).json(savedPost); 11 | } catch (err) { 12 | res.status(500).json(err); 13 | } 14 | }); 15 | 16 | //UPDATE POST 17 | router.put("/:id", async (req, res) => { 18 | try { 19 | const post = await Post.findById(req.params.id); 20 | if (post.username === req.body.username) { 21 | try { 22 | const updatedPost = await Post.findByIdAndUpdate( 23 | req.params.id, 24 | { 25 | $set: req.body, 26 | }, 27 | { new: true } 28 | ); 29 | res.status(200).json(updatedPost); 30 | } catch (err) { 31 | res.status(500).json(err); 32 | } 33 | } else { 34 | res.status(401).json("You can update only your post!"); 35 | } 36 | } catch (err) { 37 | res.status(500).json(err); 38 | } 39 | }); 40 | 41 | //DELETE POST 42 | router.delete("/:id", async (req, res) => { 43 | try { 44 | const post = await Post.findById(req.params.id); 45 | if (post.username === req.body.username) { 46 | try { 47 | await post.delete(); 48 | res.status(200).json("Post has been deleted..."); 49 | } catch (err) { 50 | res.status(500).json(err); 51 | } 52 | } else { 53 | res.status(401).json("You can delete only your post!"); 54 | } 55 | } catch (err) { 56 | res.status(500).json(err); 57 | } 58 | }); 59 | 60 | //GET POST 61 | router.get("/:id", async (req, res) => { 62 | try { 63 | const post = await Post.findById(req.params.id); 64 | res.status(200).json(post); 65 | } catch (err) { 66 | res.status(500).json(err); 67 | } 68 | }); 69 | 70 | //GET ALL POSTS 71 | router.get("/", async (req, res) => { 72 | const username = req.query.user; 73 | const catName = req.query.cat; 74 | try { 75 | let posts; 76 | if (username) { 77 | posts = await Post.find({ username }); 78 | } else if (catName) { 79 | posts = await Post.find({ 80 | categories: { 81 | $in: [catName], 82 | }, 83 | }); 84 | } else { 85 | posts = await Post.find(); 86 | } 87 | res.status(200).json(posts); 88 | } catch (err) { 89 | res.status(500).json(err); 90 | } 91 | }); 92 | 93 | module.exports = router; 94 | -------------------------------------------------------------------------------- /MERN Project/admin/src/pages/product/product.css: -------------------------------------------------------------------------------- 1 | .product { 2 | flex: 4; 3 | padding: 20px; 4 | } 5 | 6 | .productTitleContainer { 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-between; 10 | } 11 | 12 | .productAddButton { 13 | width: 80px; 14 | border: none; 15 | padding: 5px; 16 | background-color: teal; 17 | color: white; 18 | border-radius: 5px; 19 | font-size: 16px; 20 | cursor: pointer; 21 | } 22 | 23 | .productTop { 24 | display: flex; 25 | } 26 | 27 | .productTopLeft, 28 | .productTopRight { 29 | flex: 1; 30 | } 31 | 32 | .productTopRight { 33 | padding: 20px; 34 | margin: 20px; 35 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 36 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 37 | } 38 | 39 | .productInfoImg { 40 | width: 40px; 41 | height: 40px; 42 | border-radius: 50%; 43 | object-fit: cover; 44 | margin-right: 20px; 45 | } 46 | 47 | .productInfoTop { 48 | display: flex; 49 | align-items: center; 50 | } 51 | 52 | .productName { 53 | font-weight: 600; 54 | } 55 | 56 | .productInfoBottom { 57 | margin-top: 10px; 58 | } 59 | 60 | .productInfoItem { 61 | width: 150px; 62 | display: flex; 63 | justify-content: space-between; 64 | } 65 | 66 | .productInfoValue { 67 | font-weight: 300; 68 | } 69 | 70 | .productBottom { 71 | padding: 20px; 72 | margin: 20px; 73 | -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 74 | box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75); 75 | } 76 | 77 | .productForm { 78 | display: flex; 79 | justify-content: space-between; 80 | } 81 | 82 | .productFormLeft { 83 | display: flex; 84 | flex-direction: column; 85 | } 86 | 87 | .productFormLeft > label { 88 | margin-bottom: 10px; 89 | color: gray; 90 | } 91 | 92 | .productFormLeft > input { 93 | margin-bottom: 10px; 94 | border: none; 95 | padding: 5px; 96 | border-bottom: 1px solid gray; 97 | } 98 | 99 | .productFormLeft >select{ 100 | margin-bottom: 10px; 101 | } 102 | 103 | .productUploadImg{ 104 | width: 100px; 105 | height: 100px; 106 | border-radius: 10px; 107 | object-fit: cover; 108 | margin-right: 20px; 109 | } 110 | 111 | .productFormRight{ 112 | display: flex; 113 | flex-direction: column; 114 | justify-content: space-around; 115 | } 116 | 117 | .productUpload{ 118 | display: flex; 119 | align-items: center; 120 | } 121 | 122 | .productButton{ 123 | border: none; 124 | padding: 5px; 125 | border-radius: 5px; 126 | background-color: darkblue; 127 | color:white; 128 | font-weight: 600; 129 | cursor: pointer; 130 | } -------------------------------------------------------------------------------- /MERN Project/client/src/data.js: -------------------------------------------------------------------------------- 1 | export const sliderItems = [ 2 | { 3 | id: 1, 4 | img: "https://i.ibb.co/XsdmR2c/1.png", 5 | title: "SUMMER SALE", 6 | desc: "DON'T COMPROMISE ON STYLE! GET FLAT 30% OFF FOR NEW ARRIVALS.", 7 | bg: "f5fafd", 8 | }, 9 | { 10 | id: 2, 11 | img: "https://i.ibb.co/DG69bQ4/2.png", 12 | title: "AUTUMN COLLECTION", 13 | desc: "DON'T COMPROMISE ON STYLE! GET FLAT 30% OFF FOR NEW ARRIVALS.", 14 | bg: "fcf1ed", 15 | }, 16 | { 17 | id: 3, 18 | img: "https://i.ibb.co/cXFnLLV/3.png", 19 | title: "LOUNGEWEAR LOVE", 20 | desc: "DON'T COMPROMISE ON STYLE! GET FLAT 30% OFF FOR NEW ARRIVALS.", 21 | bg: "fbf0f4", 22 | }, 23 | ]; 24 | 25 | export const categories = [ 26 | { 27 | id: 1, 28 | img: "https://images.pexels.com/photos/5886041/pexels-photo-5886041.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940", 29 | title: "SHIRT STYLE!", 30 | cat:"women" 31 | }, 32 | { 33 | id: 2, 34 | img: "https://images.pexels.com/photos/2983464/pexels-photo-2983464.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940", 35 | title: "LOUNGEWEAR LOVE", 36 | cat:"coat" 37 | }, 38 | { 39 | id: 3, 40 | img: "https://images.pexels.com/photos/5480696/pexels-photo-5480696.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500", 41 | title: "LIGHT JACKETS", 42 | cat:"jeans" 43 | }, 44 | ]; 45 | 46 | export const popularProducts = [ 47 | { 48 | id:1, 49 | img:"https://d3o2e4jr3mxnm3.cloudfront.net/Mens-Jake-Guitar-Vintage-Crusher-Tee_68382_1_lg.png", 50 | }, 51 | { 52 | id:2, 53 | img:"https://cdn.shopify.com/s/files/1/0101/4832/products/Angela_Natural_Tee.png?v=1606780388", 54 | }, 55 | { 56 | id:3, 57 | img:"https://www.prada.com/content/dam/pradanux_products/U/UCS/UCS319/1YOTF010O/UCS319_1YOT_F010O_S_182_SLF.png", 58 | }, 59 | { 60 | id:4, 61 | img:"https://www.burdastyle.com/pub/media/catalog/product/cache/7bd3727382ce0a860b68816435d76e26/107/BUS-PAT-BURTE-1320516/1170x1470_BS_2016_05_132_front.png", 62 | }, 63 | { 64 | id:5, 65 | img:"https://images.ctfassets.net/5gvckmvm9289/3BlDoZxSSjqAvv1jBJP7TH/65f9a95484117730ace42abf64e89572/Noissue-x-Creatsy-Tote-Bag-Mockup-Bundle-_4_-2.png", 66 | }, 67 | { 68 | id:6, 69 | img:"https://d3o2e4jr3mxnm3.cloudfront.net/Rocket-Vintage-Chill-Cap_66374_1_lg.png", 70 | }, 71 | { 72 | id:7, 73 | img:"https://www.vintageindustries.nl/download_front/qympzk1762/2217_Arrow_Jacket_Forest.png", 74 | }, 75 | { 76 | id:8, 77 | img:"https://www.pngarts.com/files/3/Women-Jacket-PNG-High-Quality-Image.png", 78 | }, 79 | ] -------------------------------------------------------------------------------- /MERN Project/client/src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import { Badge } from "@material-ui/core"; 2 | import { Search, ShoppingCartOutlined } from "@material-ui/icons"; 3 | import React from "react"; 4 | import styled from "styled-components"; 5 | import { mobile } from "../responsive"; 6 | import { useSelector } from "react-redux"; 7 | import { Link } from "react-router-dom"; 8 | 9 | const Container = styled.div` 10 | height: 60px; 11 | ${mobile({ height: "50px" })} 12 | `; 13 | 14 | const Wrapper = styled.div` 15 | padding: 10px 20px; 16 | display: flex; 17 | align-items: center; 18 | justify-content: space-between; 19 | ${mobile({ padding: "10px 0px" })} 20 | `; 21 | 22 | const Left = styled.div` 23 | flex: 1; 24 | display: flex; 25 | align-items: center; 26 | `; 27 | 28 | const Language = styled.span` 29 | font-size: 14px; 30 | cursor: pointer; 31 | ${mobile({ display: "none" })} 32 | `; 33 | 34 | const SearchContainer = styled.div` 35 | border: 0.5px solid lightgray; 36 | display: flex; 37 | align-items: center; 38 | margin-left: 25px; 39 | padding: 5px; 40 | `; 41 | 42 | const Input = styled.input` 43 | border: none; 44 | ${mobile({ width: "50px" })} 45 | `; 46 | 47 | const Center = styled.div` 48 | flex: 1; 49 | text-align: center; 50 | `; 51 | 52 | const Logo = styled.h1` 53 | font-weight: bold; 54 | ${mobile({ fontSize: "24px" })} 55 | `; 56 | const Right = styled.div` 57 | flex: 1; 58 | display: flex; 59 | align-items: center; 60 | justify-content: flex-end; 61 | ${mobile({ flex: 2, justifyContent: "center" })} 62 | `; 63 | 64 | const MenuItem = styled.div` 65 | font-size: 14px; 66 | cursor: pointer; 67 | margin-left: 25px; 68 | ${mobile({ fontSize: "12px", marginLeft: "10px" })} 69 | `; 70 | 71 | const Navbar = () => { 72 | const quantity = useSelector(state=>state.cart.quantity) 73 | return ( 74 | 75 | 76 | 77 | EN 78 | 79 | 80 | 81 | 82 | 83 |
84 | LAMA. 85 |
86 | 87 | REGISTER 88 | SIGN IN 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
98 |
99 | ); 100 | }; 101 | 102 | export default Navbar; 103 | -------------------------------------------------------------------------------- /MERN Project/api/routes/order.js: -------------------------------------------------------------------------------- 1 | const Order = require("../models/Order"); 2 | const { 3 | verifyToken, 4 | verifyTokenAndAuthorization, 5 | verifyTokenAndAdmin, 6 | } = require("./verifyToken"); 7 | 8 | const router = require("express").Router(); 9 | 10 | //CREATE 11 | 12 | router.post("/", verifyToken, async (req, res) => { 13 | const newOrder = new Order(req.body); 14 | 15 | try { 16 | const savedOrder = await newOrder.save(); 17 | res.status(200).json(savedOrder); 18 | } catch (err) { 19 | res.status(500).json(err); 20 | } 21 | }); 22 | 23 | //UPDATE 24 | router.put("/:id", verifyTokenAndAdmin, async (req, res) => { 25 | try { 26 | const updatedOrder = await Order.findByIdAndUpdate( 27 | req.params.id, 28 | { 29 | $set: req.body, 30 | }, 31 | { new: true } 32 | ); 33 | res.status(200).json(updatedOrder); 34 | } catch (err) { 35 | res.status(500).json(err); 36 | } 37 | }); 38 | 39 | //DELETE 40 | router.delete("/:id", verifyTokenAndAdmin, async (req, res) => { 41 | try { 42 | await Order.findByIdAndDelete(req.params.id); 43 | res.status(200).json("Order has been deleted..."); 44 | } catch (err) { 45 | res.status(500).json(err); 46 | } 47 | }); 48 | 49 | //GET USER ORDERS 50 | router.get("/find/:userId", verifyTokenAndAuthorization, async (req, res) => { 51 | try { 52 | const orders = await Order.find({ userId: req.params.userId }); 53 | res.status(200).json(orders); 54 | } catch (err) { 55 | res.status(500).json(err); 56 | } 57 | }); 58 | 59 | // //GET ALL 60 | 61 | router.get("/", verifyTokenAndAdmin, async (req, res) => { 62 | try { 63 | const orders = await Order.find(); 64 | res.status(200).json(orders); 65 | } catch (err) { 66 | res.status(500).json(err); 67 | } 68 | }); 69 | 70 | // GET MONTHLY INCOME 71 | 72 | router.get("/income", verifyTokenAndAdmin, async (req, res) => { 73 | const productId = req.query.pid; 74 | const date = new Date(); 75 | const lastMonth = new Date(date.setMonth(date.getMonth() - 1)); 76 | const previousMonth = new Date(new Date().setMonth(lastMonth.getMonth() - 1)); 77 | 78 | try { 79 | const income = await Order.aggregate([ 80 | { 81 | $match: { 82 | createdAt: { $gte: previousMonth }, 83 | ...(productId && { 84 | products: { $elemMatch: { productId } }, 85 | }), 86 | }, 87 | }, 88 | { 89 | $project: { 90 | month: { $month: "$createdAt" }, 91 | sales: "$amount", 92 | }, 93 | }, 94 | { 95 | $group: { 96 | _id: "$month", 97 | total: { $sum: "$sales" }, 98 | }, 99 | }, 100 | ]); 101 | res.status(200).json(income); 102 | } catch (err) { 103 | res.status(500).json(err); 104 | } 105 | }); 106 | 107 | module.exports = router; 108 | -------------------------------------------------------------------------------- /MERN Project/client/src/pages/Login.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import styled from "styled-components"; 3 | import { login } from "../redux/apiCalls"; 4 | import { mobile } from "../responsive"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | 7 | const Container = styled.div` 8 | width: 100vw; 9 | height: 100vh; 10 | background: linear-gradient( 11 | rgba(255, 255, 255, 0.5), 12 | rgba(255, 255, 255, 0.5) 13 | ), 14 | url("https://images.pexels.com/photos/6984650/pexels-photo-6984650.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940") 15 | center; 16 | background-size: cover; 17 | display: flex; 18 | align-items: center; 19 | justify-content: center; 20 | `; 21 | 22 | const Wrapper = styled.div` 23 | width: 25%; 24 | padding: 20px; 25 | background-color: white; 26 | ${mobile({ width: "75%" })} 27 | `; 28 | 29 | const Title = styled.h1` 30 | font-size: 24px; 31 | font-weight: 300; 32 | `; 33 | 34 | const Form = styled.form` 35 | display: flex; 36 | flex-direction: column; 37 | `; 38 | 39 | const Input = styled.input` 40 | flex: 1; 41 | min-width: 40%; 42 | margin: 10px 0; 43 | padding: 10px; 44 | `; 45 | 46 | const Button = styled.button` 47 | width: 40%; 48 | border: none; 49 | padding: 15px 20px; 50 | background-color: teal; 51 | color: white; 52 | cursor: pointer; 53 | margin-bottom: 10px; 54 | &:disabled { 55 | color: green; 56 | cursor: not-allowed; 57 | } 58 | `; 59 | 60 | const Link = styled.a` 61 | margin: 5px 0px; 62 | font-size: 12px; 63 | text-decoration: underline; 64 | cursor: pointer; 65 | `; 66 | 67 | const Error = styled.span` 68 | color: red; 69 | `; 70 | 71 | const Login = () => { 72 | const [username, setUsername] = useState(""); 73 | const [password, setPassword] = useState(""); 74 | const dispatch = useDispatch(); 75 | const { isFetching, error } = useSelector((state) => state.user); 76 | 77 | const handleClick = (e) => { 78 | e.preventDefault(); 79 | login(dispatch, { username, password }); 80 | }; 81 | return ( 82 | 83 | 84 | SIGN IN 85 |
86 | setUsername(e.target.value)} 89 | /> 90 | setPassword(e.target.value)} 94 | /> 95 | 98 | {error && Something went wrong...} 99 | DO NOT YOU REMEMBER THE PASSWORD? 100 | CREATE A NEW ACCOUNT 101 |
102 |
103 |
104 | ); 105 | }; 106 | 107 | export default Login; 108 | -------------------------------------------------------------------------------- /MERN Project/client/src/pages/ProductList.jsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import Navbar from "../components/Navbar"; 3 | import Announcement from "../components/Announcement"; 4 | import Products from "../components/Products"; 5 | import Newsletter from "../components/Newsletter"; 6 | import Footer from "../components/Footer"; 7 | import { mobile } from "../responsive"; 8 | import { useLocation } from "react-router"; 9 | import { useState } from "react"; 10 | 11 | const Container = styled.div``; 12 | 13 | const Title = styled.h1` 14 | margin: 20px; 15 | `; 16 | 17 | const FilterContainer = styled.div` 18 | display: flex; 19 | justify-content: space-between; 20 | `; 21 | 22 | const Filter = styled.div` 23 | margin: 20px; 24 | ${mobile({ width: "0px 20px", display: "flex", flexDirection: "column" })} 25 | `; 26 | 27 | const FilterText = styled.span` 28 | font-size: 20px; 29 | font-weight: 600; 30 | margin-right: 20px; 31 | ${mobile({ marginRight: "0px" })} 32 | `; 33 | 34 | const Select = styled.select` 35 | padding: 10px; 36 | margin-right: 20px; 37 | ${mobile({ margin: "10px 0px" })} 38 | `; 39 | const Option = styled.option``; 40 | 41 | const ProductList = () => { 42 | const location = useLocation(); 43 | const cat = location.pathname.split("/")[2]; 44 | const [filters, setFilters] = useState({}); 45 | const [sort, setSort] = useState("newest"); 46 | 47 | const handleFilters = (e) => { 48 | const value = e.target.value; 49 | setFilters({ 50 | ...filters, 51 | [e.target.name]: value, 52 | }); 53 | }; 54 | 55 | return ( 56 | 57 | 58 | 59 | {cat} 60 | 61 | 62 | Filter Products: 63 | 72 | 80 | 81 | 82 | Sort Products: 83 | 88 | 89 | 90 | 91 | 92 |