Browse Source

HW react-store done

Alyona Brytvina 2 years ago
parent
commit
34acb01c4f
5 changed files with 1445 additions and 55 deletions
  1. 1 0
      .gitignore
  2. 6 0
      .idea/vcs.xml
  3. 1284 31
      package-lock.json
  4. 5 0
      package.json
  5. 149 24
      src/App.js

+ 1 - 0
.gitignore

@@ -5,6 +5,7 @@
 /.pnp
 .pnp.js
 
+
 # testing
 /coverage
 

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

File diff suppressed because it is too large
+ 1284 - 31
package-lock.json


+ 5 - 0
package.json

@@ -6,9 +6,14 @@
     "@testing-library/jest-dom": "^5.16.1",
     "@testing-library/react": "^12.1.2",
     "@testing-library/user-event": "^13.5.0",
+    "node-sass": "^7.0.0",
     "react": "^17.0.2",
     "react-dom": "^17.0.2",
+    "react-redux": "^7.2.6",
+    "react-router-dom": "^5.3.0",
     "react-scripts": "5.0.0",
+    "redux": "^4.1.2",
+    "redux-thunk": "^2.4.1",
     "web-vitals": "^2.1.2"
   },
   "scripts": {

+ 149 - 24
src/App.js

@@ -3,7 +3,10 @@ import './App.scss';
 import thunk from 'redux-thunk';
 import {createStore, combineReducers, applyMiddleware} from 'redux';
 import {Provider, connect} from 'react-redux';
-import {useState} from 'react';
+import {useEffect, useState} from 'react';
+import {Router, Route, Link, Redirect, match} from 'react-router-dom';
+import {createBrowserHistory} from 'history';
+
 
 const actionPending = name => ({type: 'PROMISE', status: 'PENDING', name});
 const actionResolved = (name, payload) => ({type: 'PROMISE', status: 'RESOLVED', name, payload});
@@ -217,20 +220,23 @@ const store = createStore(combineReducers(
 store.subscribe(() => console.log(store.getState()));
 
 store.dispatch(actionRootCats());
-store.dispatch(actionCatById('5dc458985df9d670df48cc47'));
-
 
 const Logo = () =>
-    <img src={logo} className="Logo" alt="logo"/>;
+    <Link to="/">
+        <img src={logo} className="Logo" alt="logo"/>
+    </Link>;
 
 const Header = () =>
     <header className="header">
         <Logo/>
+        <Login/>
         <CKoshik/>
     </header>;
 
 const CategoryListItem = ({_id, name}) =>
-    <li><a href={`#/category/${_id}`}>{name}</a></li>;
+    <li>
+        <Link to={`/category/${_id}`}>{name}</Link>
+    </li>;
 
 const CategoryList = ({cats}) => {
     return (
@@ -240,9 +246,28 @@ const CategoryList = ({cats}) => {
     );
 };
 
-
 const CCategoryList = connect(state => ({cats: state.promise.rootCats?.payload || []}))(CategoryList);
 
+const PageGood = ({good: {name, price, images}, match: {params: {_id}}, getData}) => {
+    const isFirstImgExists = images && images[0] && images[0].url;
+
+    useEffect(() => {
+        getData(_id);
+    }, []);
+
+    return (
+        <div>
+            <h2>{name}</h2>
+            {isFirstImgExists && <img src={`${backendURL}/${images[0].url}`} alt={name}/>}
+            <strong>{price} грн</strong>
+        </div>
+    );
+};
+
+const CPageGood = connect(state => ({
+    good: state.promise.goodById?.payload ?? [],
+}), {getData: actionGoodById})(PageGood);
+
 const Aside = () =>
     <aside className="aside">
         <CCategoryList/>
@@ -251,12 +276,23 @@ const Aside = () =>
 const GoodCard = ({good: {_id, name, price, images}, onAdd}) =>
     <li className="GoodCard">
         <h2>{name}</h2>
-        {images && images[0] && images[0].url && <img src={backendURL + '/' + images[0].url}/>}
+        {images && images[0] && images[0].url && <img src={`${backendURL}/${images[0].url}`}/>}
         <strong>{price} грн</strong>
         <button onClick={() => onAdd({_id, name, price, images})}>+</button>
+        <Link to={`/good/${_id}`}>
+            Подробнее
+        </Link>
     </li>;
 
-const CGoodCard = connect(null, {onAdd: actionCartAdd})(GoodCard);
+
+const Login = () =>
+    <Link to="/login">
+        <h2 className="login">Личный кабинет</h2>
+    </Link>;
+
+const CGoodCard = connect(null, {
+    onAdd: actionCartAdd
+})(GoodCard);
 
 const Koshik = ({cart}) => {
     let goodsInCart = cart;
@@ -265,7 +301,11 @@ const Koshik = ({cart}) => {
         allGoodsInCart += goodsInCart[key].count;
     }
     return (
-        <h2 className="koshikCounter">В корзине:{allGoodsInCart}</h2>
+        <h2 className="koshikCounter">
+            <Link to="/cart">В корзине:{allGoodsInCart}
+            </Link>
+        </h2>
+
     );
 };
 
@@ -277,7 +317,7 @@ const Category = ({cat: {name, goods = []} = {}}) => {
         <div className="Category">
             <h1>{name}</h1>
             <ul className="ul">
-                {goods.map(good => <CGoodCard key={good._id} good={good}/>)}
+                {(goods || []).map(good => <CGoodCard key={good._id} good={good}/>)}
             </ul>
         </div>
     );
@@ -348,15 +388,15 @@ const LoginForm = ({onCartLogin}) => {
     const [login, setLogin] = useState('');
     const [password, setPassword] = useState('');
     const isDisabled = login === '' || password === '';
-    console.log(login, password, isDisabled)
+    console.log(login, password, isDisabled);
 
     const onChange = (event) => {
-        event.target.name === 'login' ?  setLogin(event.target.value) : setPassword(event.target.value);
+        event.target.name === 'login' ? setLogin(event.target.value) : setPassword(event.target.value);
     };
 
     return (
         <div className="inputWrapper">
-            <h1>Регистрация</h1>
+            <h2>Вход в личный кабинет</h2>
             <input
                 className="inputLogin"
                 name="login"
@@ -381,6 +421,8 @@ const LoginForm = ({onCartLogin}) => {
                         onCartLogin(login, password);
                     }}>Login
             </button>
+            <h4>Вы еще не зарегистрированы?</h4>
+            <Link to="/registration">Зарегистрироваться</Link>
         </div>
     );
 };
@@ -388,16 +430,95 @@ const LoginForm = ({onCartLogin}) => {
 const CLoginForm = connect(
     null,
     {
-        onCartLogin: actionFullRegister
+        onCartLogin: actionFullLogin
     })(LoginForm);
 
+const RegisterForm = ({onCartRegister}) => {
+    const [login, setLogin] = useState('');
+    const [password, setPassword] = useState('');
+    const isDisabled = login === '' || password === '';
+    console.log(login, password, isDisabled);
+
+    const onChange = (event) => {
+        event.target.name === 'login' ? setLogin(event.target.value) : setPassword(event.target.value);
+    };
+
+    return (
+        <div className="inputWrapper">
+            <h2>Регистрация</h2>
+            <input
+                className="inputLogin"
+                name="userName"
+                style={{borderColor: isDisabled ? 'red' : ''}}
+                placeholder="введите имя"
+                type="text"
+                onChange={onChange}
+            />
+            <input
+                className="inputLogin"
+                name="login"
+                style={{borderColor: isDisabled ? 'red' : ''}}
+                placeholder="*введите логин"
+                type="text"
+                onChange={onChange}
+            />
+            <input
+                className="inputPsw"
+                name="password"
+                style={{borderColor: isDisabled ? 'red' : ''}}
+                placeholder="*введите пароль"
+                type="password"
+                onChange={onChange}
+            />
+            <button
+                className="buttonLogin"
+                disabled={isDisabled}
+                onClick={
+                    () => {
+                        onCartRegister(login, password);
+                    }}>Login
+            </button>
+            <Link to="/login">Войти в личный кабинет</Link>
+        </div>
+    );
+};
+
+const CRegisterForm = connect(
+    null,
+    {
+        onCartRegister: actionFullRegister
+    })(RegisterForm);
+
+const PageMain = () =>
+    <h1>Главная страничка</h1>;
+
+const PageCategory = ({match: {params: {_id}}, getData}) => {
+
+    useEffect(() => {
+        getData(_id);
+    }, [_id]);
+
+    return (
+        <div>
+            <CCategory/>
+        </div>
+    );
+};
+
+const CPageCategory = connect(null, {getData: actionCatById})(PageCategory);
+
 const Main = () =>
     <main className="main">
         <Aside/>
         <Content>
-            <CCategory/>
-            <CLoginForm/>
-            <CCart/>
+
+            <Route path="/" component={PageMain} exact/>
+            <Route path="/category/:_id" component={CPageCategory} exact/>
+            <Route path="/cart" component={CCart} exact/>
+            <Route path="/login" component={CLoginForm} exact/>
+            <Route path="/registration" component={CRegisterForm} exact/>
+            <Route path="/good/:_id" component={CPageGood} exact/>
+            {/*<CCategory/>*/}
         </Content>
     </main>;
 
@@ -411,16 +532,20 @@ const Footer = () =>
         <Logo/>
     </footer>;
 
+const history = createBrowserHistory();
+
 //import {Provider, connect} from 'react-redux';
 function App() {
     return (
-        <Provider store={store}>
-            <div className="App">
-                <Header/>
-                <Main/>
-                <Footer/>
-            </div>
-        </Provider>
+        <Router history={history}>
+            <Provider store={store}>
+                <div className="App">
+                    <Header/>
+                    <Main/>
+                    <Footer/>
+                </div>
+            </Provider>
+        </Router>
     );
 }