From cc3af121483ba125a061ed51c75a17010a08e6d9 Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sat, 11 Dec 2021 14:28:59 +0300
Subject: [PATCH 1/9] Improve layout and design of the login page
---
src/pages/Login.jsx | 124 ++++++++++++++++++++++++++++++++++----------
1 file changed, 96 insertions(+), 28 deletions(-)
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
index cf8b851..6480437 100644
--- a/src/pages/Login.jsx
+++ b/src/pages/Login.jsx
@@ -1,40 +1,108 @@
-import React from 'react';
-import { useNavigate } from 'react-router-dom';
+import * as React from 'react';
import axios from '../utils/axios'
-import {TOKEN_KEY} from '../utils/Constants'
+import { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { TOKEN_KEY } from '../utils/Constants'
+import Box from '@mui/material/Box';
+import Card from '@mui/material/Card';
+import TextField from '@mui/material/TextField';
+import AccountCircle from '@mui/icons-material/AccountCircle';
+import VpnKeyIcon from '@mui/icons-material/VpnKey';
+import IconButton from '@mui/material/IconButton';
+import Input from '@mui/material/Input';
+import InputLabel from '@mui/material/InputLabel';
+import InputAdornment from '@mui/material/InputAdornment';
+import FormControl from '@mui/material/FormControl';
+import Visibility from '@mui/icons-material/Visibility';
+import VisibilityOff from '@mui/icons-material/VisibilityOff';
+import Button from '@mui/material/Button';
+
function Login(props) {
const navigate = useNavigate()
- const [email, setEmail] = React.useState('')
- const [password, setPassword] = React.useState('')
+ const [email, setEmail] = useState('')
+ const [password, setPassword] = useState('')
+ const [values, setValues] = useState({
+ amount: '',
+ password: '',
+ weight: '',
+ weightRange: '',
+ showPassword: false,
+ });
+
+ const handleChange = (prop) => (event) => {
+ setValues({ ...values, [prop]: event.target.value });
+ };
+
+ const handleClickShowPassword = () => {
+ setValues({
+ ...values,
+ showPassword: !values.showPassword,
+ });
+ };
+
+ const handleMouseDownPassword = (event) => {
+ event.preventDefault();
+ };
- const login = (e)=>{
+ const login = (e) => {
e.preventDefault()
axios.post('/api/academy/auth/login',
- {
- email:email,
- password:password
- }
+ {
+ email: email,
+ password: values.password
+ }
)
- .then((response)=>{
- console.log(response)
- let token = response.data.token.access_token;
- let data = response.data;
- localStorage.setItem(TOKEN_KEY, JSON.stringify(data))
- navigate('/dashboard')
- })
- .catch((err)=>{
- console.log(err)
- })
+ .then((response) => {
+ console.log(response)
+ let token = response.data.token.access_token;
+ let data = response.data;
+ localStorage.setItem(TOKEN_KEY, JSON.stringify(data))
+ navigate('/dashboard')
+ })
+ .catch((err) => {
+ console.log(err)
+ })
}
return (
-
-
-
+
+
+
+
+
+ setEmail(e.target.value)} type="email" id="input-with-sx" label="Email" variant="standard" />
+
+
+
+
+
+ Password
+
+ setPassword(e.target.value)}
+ onChange={handleChange('password')}
+ endAdornment={
+
+
+ {values.showPassword ? : }
+
+
+ }
+ />
+
+
+
+
+
+
+
);
}
-export default Login;
\ No newline at end of file
+export default Login;
From df1f11786f3ae2b2ffc57f51d94cd2018cc501bb Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sat, 11 Dec 2021 14:29:44 +0300
Subject: [PATCH 2/9] Initial implementation of the products page
---
src/pages/Products.jsx | 85 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 79 insertions(+), 6 deletions(-)
diff --git a/src/pages/Products.jsx b/src/pages/Products.jsx
index e3fcba4..9d19aba 100644
--- a/src/pages/Products.jsx
+++ b/src/pages/Products.jsx
@@ -1,12 +1,85 @@
-import React, { useEffect } from 'react';
+import * as React from 'react';
+import { useState, useEffect } from 'react';
+import axios from 'axios';
+import Auth from '../utils/Auth';
+import { styled } from '@mui/material/styles';
+import Grid from '@mui/material/Grid';
+import Paper from '@mui/material/Paper';
+import Typography from '@mui/material/Typography';
+import ButtonBase from '@mui/material/ButtonBase';
+import { Box } from '@mui/system';
+
+const Img = styled('img')({
+ margin: 'auto',
+ display: 'block',
+ maxWidth: '80%',
+ maxHeight: '80%',
+});
function Products(props) {
-
+
+ const [products, setProducts] = useState([]);
+
+ useEffect(() => {
+ axios.get('https://fakestoreapi.com/products?limit=5')
+
+ .then(res => {
+ console.log(res);
+ setProducts(res.data);
+ })
+ .catch(err => {
+ console.log(err);
+ });
+ }, []);
+
+
return (
-
- Products
-
+
+
+
+ {products.map((product, i) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {product.title}
+
+
+ {product.category}
+
+
+
+
+
+ {product.price} €
+
+
+
+
+
+ Add to Cart
+
+
+
+
+
+ )
+ })}
+
+
+
);
}
-export default Products;
\ No newline at end of file
+Products = Auth(Products);
+
+export default Products;
From 9de8b1c3ab01fa2a30d1a9a3a88b1d238b3c54a0 Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sat, 11 Dec 2021 14:32:10 +0300
Subject: [PATCH 3/9] Refactor and restructuring for readability
---
src/App.js | 20 +++++++---------
src/components/Drawer.jsx | 49 +++++++++++++++------------------------
src/index.js | 15 ++++++------
src/pages/Categories.jsx | 11 +++++----
src/pages/Dashboard.jsx | 30 ++++++------------------
src/utils/Constants.js | 2 +-
6 files changed, 50 insertions(+), 77 deletions(-)
diff --git a/src/App.js b/src/App.js
index 7a13708..011e0cd 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,21 +4,19 @@ import Dashboard from './pages/Dashboard'
import Categories from './pages/Categories'
import Products from './pages/Products'
import Login from './pages/Login'
-import {Navigate, Route, Routes} from 'react-router-dom'
-import {useEffect,useState} from 'react'
+import { Navigate, Route, Routes } from 'react-router-dom'
+import { useEffect, useState } from 'react'
import Drawer from './components/Drawer'
function App(props) {
-
-
- return
- }/>
- }/>
- }/>
- }/>
-
-
+ return
+ } />
+ } />
+ } />
+ } />
+ } />
+
}
export default App;
diff --git a/src/components/Drawer.jsx b/src/components/Drawer.jsx
index 9e615f1..214a632 100644
--- a/src/components/Drawer.jsx
+++ b/src/components/Drawer.jsx
@@ -16,28 +16,25 @@ import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
-import InboxIcon from '@mui/icons-material/MoveToInbox';
-import MailIcon from '@mui/icons-material/Mail';
import { Routes, Link, Route, useLocation, useNavigate } from 'react-router-dom'
import Dashboard from '../pages/Dashboard'
import Categories from '../pages/Categories'
import Products from '../pages/Products'
+import Login from '../pages/Login'
import LogoutIcon from '@mui/icons-material/Logout';
-import GridViewIcon from '@mui/icons-material/GridView';
+import DashboardIcon from '@mui/icons-material/Dashboard';
import CategoryIcon from '@mui/icons-material/Category';
-import ProductionQuantityLimitsIcon from '@mui/icons-material/ProductionQuantityLimits';
-import Login from '../pages/Login'
+import ShoppingBagIcon from '@mui/icons-material/ShoppingBag';
+import HomeIcon from '@mui/icons-material/Home';
import Avatar from './Avatar'
import MenuItem from '@mui/material/MenuItem';
import Menu from '@mui/material/Menu';
import Tooltip from '@mui/material/Tooltip';
-import {navigate} from 'react-router-dom'
-import {TOKEN_KEY} from '../utils/Constants'
+import { navigate } from 'react-router-dom'
+import { TOKEN_KEY } from '../utils/Constants'
const drawerWidth = 240;
-
-
const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(
({ theme, open }) => ({
flexGrow: 1,
@@ -148,7 +145,7 @@ function PersistentDrawerLeft(props) {
-
+ E-Commerce
@@ -200,28 +197,20 @@ function PersistentDrawerLeft(props) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {['Dashboard', 'Categories', 'Products'].map((text, index) => (
+
+
+ {text === 'Dashboard' ? : text === 'Categories' ? : }
+
+
+
+ ))}
+
-
+
@@ -237,4 +226,4 @@ function PersistentDrawerLeft(props) {
);
}
-export default PersistentDrawerLeft
\ No newline at end of file
+export default PersistentDrawerLeft
diff --git a/src/index.js b/src/index.js
index bb29a24..a40960d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,30 +3,29 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
-import {BrowserRouter} from 'react-router-dom'
+import { BrowserRouter } from 'react-router-dom'
import Drawer from './components/Drawer'
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
const theme = createTheme({
-
palette: {
type: 'light',
primary: {
- main: '#000000',
+ main: '#6E85D3',
},
secondary: {
- main: '#f50057',
+ main: '#6E85D3',
},
},
})
ReactDOM.render(
-
-
+
+
-
-
+
+
,
document.getElementById('root')
);
diff --git a/src/pages/Categories.jsx b/src/pages/Categories.jsx
index 0e9ce54..d168c1e 100644
--- a/src/pages/Categories.jsx
+++ b/src/pages/Categories.jsx
@@ -1,17 +1,20 @@
import React, { useEffect } from 'react';
+import Auth from '../utils/Auth';
function Categories(props) {
console.log(props)
- useEffect(()=>{
+ useEffect(() => {
console.log('use effect')
let userData = JSON.parse(localStorage.getItem('myData'))
console.log(userData)
- },[])
+ }, [])
return (
- Categories
+
Categories
);
}
-export default Categories;
\ No newline at end of file
+Categories = Auth(Categories)
+
+export default Categories;
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index 3c13707..b331308 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -1,32 +1,16 @@
import React, { useEffect, useState } from 'react';
-import {Navigate} from 'react-router-dom'
-function Dashboard(props) {
- const [isLogged, setIsLogged] = React.useState(true)
- useEffect(()=>{
- console.log('1')
- let token;
- try {
- token = JSON.parse(localStorage.getItem('token'))
- console.log('2')
- if(!token)
- setIsLogged(false)
-
- } catch (error) {
- console.log(error)
- setIsLogged(false)
- }
-
- },[])
- console.log('3')
+import { Navigate } from 'react-router-dom'
+import Auth from '../utils/Auth';
- if(!isLogged)
- return
+function Dashboard(props) {
return (
- Dashboard
+
Dashboard
);
}
-export default Dashboard;
\ No newline at end of file
+Dashboard = Auth(Dashboard)
+
+export default Dashboard;
diff --git a/src/utils/Constants.js b/src/utils/Constants.js
index 1574da1..ebb7d22 100644
--- a/src/utils/Constants.js
+++ b/src/utils/Constants.js
@@ -1,2 +1,2 @@
export const TOKEN_KEY = 'token'
-export const BASE_URL = 'https://website-backend.computiq.tech'
\ No newline at end of file
+export const BASE_URL = 'https://website-backend.computiq.tech'
From 8eca412612ae27f62c37aad4f953079b9a249a5a Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sat, 11 Dec 2021 14:32:42 +0300
Subject: [PATCH 4/9] Implement authentication compnent
---
src/utils/Auth.jsx | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 src/utils/Auth.jsx
diff --git a/src/utils/Auth.jsx b/src/utils/Auth.jsx
new file mode 100644
index 0000000..8049558
--- /dev/null
+++ b/src/utils/Auth.jsx
@@ -0,0 +1,28 @@
+import React, { useState, useEffect } from 'react';
+import { TOKEN_KEY } from './Constants'
+import { useNavigate } from 'react-router-dom';
+
+const Auth = (Component) => {
+
+ const Authenticate = (props) => {
+ const navigate = useNavigate();
+ const [isLogged, setIsLogged] = useState(true);
+
+ useEffect(() => {
+ const token = localStorage.getItem(TOKEN_KEY);
+ if (!token) {
+ navigate('/login');
+ }
+ }, [navigate])
+
+ if (!isLogged) {
+ navigate('/login')
+ return null
+ }
+ return
+ }
+
+ return Authenticate
+}
+
+export default Auth;
From 49ada4976ac012e62c1ceedc89ff7685f3d65e0a Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sat, 11 Dec 2021 14:33:08 +0300
Subject: [PATCH 5/9] Change project name in `package.json`
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 2c613e9..1b9d070 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "axios-app",
+ "name": "task-09",
"version": "0.1.0",
"private": true,
"dependencies": {
From 46fc48a7642747fd00370a51fd3df9a523dff9c1 Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sun, 12 Dec 2021 01:33:46 +0300
Subject: [PATCH 6/9] Refactor and restructure Products component
---
src/App.js | 9 ++--
src/pages/Products.jsx | 98 +++++++++++++++++++++---------------------
2 files changed, 51 insertions(+), 56 deletions(-)
diff --git a/src/App.js b/src/App.js
index 011e0cd..8c4d4a2 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,11 +1,7 @@
-import logo from './logo.svg';
import './App.css';
-import Dashboard from './pages/Dashboard'
-import Categories from './pages/Categories'
-import Products from './pages/Products'
+
import Login from './pages/Login'
-import { Navigate, Route, Routes } from 'react-router-dom'
-import { useEffect, useState } from 'react'
+import { Route, Routes } from 'react-router-dom'
import Drawer from './components/Drawer'
@@ -15,6 +11,7 @@ function App(props) {
} />
} />
} />
+ } />
} />
}
diff --git a/src/pages/Products.jsx b/src/pages/Products.jsx
index 9d19aba..2084111 100644
--- a/src/pages/Products.jsx
+++ b/src/pages/Products.jsx
@@ -2,29 +2,31 @@ import * as React from 'react';
import { useState, useEffect } from 'react';
import axios from 'axios';
import Auth from '../utils/Auth';
-import { styled } from '@mui/material/styles';
+import Product from '../components/Product';
+import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
-import Paper from '@mui/material/Paper';
+import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
-import ButtonBase from '@mui/material/ButtonBase';
-import { Box } from '@mui/system';
+import HourglassBottomIcon from '@mui/icons-material/HourglassBottom';
-const Img = styled('img')({
- margin: 'auto',
- display: 'block',
- maxWidth: '80%',
- maxHeight: '80%',
-});
+const addToCart = (product) => {
+ if (localStorage.getItem('cart') === null) {
+ localStorage.setItem('cart', JSON.stringify([product]))
+ } else {
+ const cart = JSON.parse(localStorage.getItem('cart'))
+ cart.push(product)
+ localStorage.setItem('cart', JSON.stringify(cart))
+ }
+}
function Products(props) {
const [products, setProducts] = useState([]);
useEffect(() => {
- axios.get('https://fakestoreapi.com/products?limit=5')
+ axios.get('https://fakestoreapi.com/products?limit=10')
.then(res => {
- console.log(res);
setProducts(res.data);
})
.catch(err => {
@@ -32,51 +34,47 @@ function Products(props) {
});
}, []);
+ let originalProducts = [...products];
+
+ const onSearch = (e) => {
+ let search = e.target.value;
+
+ if (search.length > 0) {
+
+ let filteredProducts = products.filter(product => {
+ return product.title.toLowerCase().includes(search.toLowerCase());
+ });
+
+ setProducts(filteredProducts);
+
+ } else {
+ setProducts(originalProducts);
+ }
+ }
return (
-
-
+
+ :not(style)': { m: 1, maxWidth: '30rem', width: '20em' }, px: '2vw', pb: '2vh' }} noValidate autoComplete="off" >
+
+
+
- {products.map((product, i) => {
- return (
-
-
-
-
-
-
-
-
-
-
-
- {product.title}
-
-
- {product.category}
-
-
-
-
-
- {product.price} €
-
-
-
-
-
- Add to Cart
-
-
-
-
-
+ {(products.length > 0) ? products.map((product, index) => {
+ return (
+
)
- })}
+ }) :
+
+ Loading Products ...
+
+
+ }
+
+
-
+
);
}
From 93f105375f7c9db4a3cc96087db4c25eb808c361 Mon Sep 17 00:00:00 2001
From: Aland <32212842+alandio@users.noreply.github.com>
Date: Sun, 12 Dec 2021 01:58:40 +0300
Subject: [PATCH 7/9] Add Cart page component
---
src/components/Drawer.jsx | 45 +++++++++----
src/index.js | 3 +-
src/pages/Cart.jsx | 130 ++++++++++++++++++++++++++++++++++++++
src/pages/Dashboard.jsx | 3 +-
src/pages/Login.jsx | 7 --
5 files changed, 164 insertions(+), 24 deletions(-)
create mode 100644 src/pages/Cart.jsx
diff --git a/src/components/Drawer.jsx b/src/components/Drawer.jsx
index 214a632..f112b06 100644
--- a/src/components/Drawer.jsx
+++ b/src/components/Drawer.jsx
@@ -1,6 +1,11 @@
import * as React from 'react';
-import { useEffect } from 'react'
-import { styled, useTheme } from '@mui/material/styles';
+import { Link, useLocation, useNavigate } from 'react-router-dom'
+import { TOKEN_KEY } from '../utils/Constants'
+import Dashboard from '../pages/Dashboard'
+import Categories from '../pages/Categories'
+import Products from '../pages/Products'
+import Login from '../pages/Login'
+import Cart from '../pages/Cart';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
import CssBaseline from '@mui/material/CssBaseline';
@@ -16,22 +21,16 @@ import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
-import { Routes, Link, Route, useLocation, useNavigate } from 'react-router-dom'
-import Dashboard from '../pages/Dashboard'
-import Categories from '../pages/Categories'
-import Products from '../pages/Products'
-import Login from '../pages/Login'
import LogoutIcon from '@mui/icons-material/Logout';
import DashboardIcon from '@mui/icons-material/Dashboard';
import CategoryIcon from '@mui/icons-material/Category';
import ShoppingBagIcon from '@mui/icons-material/ShoppingBag';
-import HomeIcon from '@mui/icons-material/Home';
import Avatar from './Avatar'
import MenuItem from '@mui/material/MenuItem';
import Menu from '@mui/material/Menu';
import Tooltip from '@mui/material/Tooltip';
-import { navigate } from 'react-router-dom'
-import { TOKEN_KEY } from '../utils/Constants'
+import LocalMallIcon from '@mui/icons-material/LocalMall';
+import { styled, useTheme } from '@mui/material/styles';
const drawerWidth = 240;
@@ -101,20 +100,22 @@ function PersistentDrawerLeft(props) {
navigate('/login')
handleCloseUserMenu()
}
- useEffect(() => {
- }, [])
const renderContent = (routeName) => {
console.log(routeName)
switch (routeName) {
case '/login':
return
+ case '/cart':
+ return
case '/products':
return
case '/dashboard':
return
case '/categories':
return
+ default:
+ return
}
}
const handleOpenUserMenu = (event) => {
@@ -132,7 +133,8 @@ function PersistentDrawerLeft(props) {
flexGrow: 1,
display: 'flex',
flexDirection: 'row',
- justifyContent: 'space-between'
+ justifyContent: 'flex-start',
+ alignItems: 'center'
}}>
E-Commerce
+
+
+ { navigate('/cart') }}
+ edge="end"
+ sx={{ mr: 2 }}
+ >
+
+
+