Browse Source

auth validation

Stepanova Asya 1 year ago
parent
commit
f38817446b

+ 1 - 1
public/index.html

@@ -4,7 +4,7 @@
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
   </head>
-  <body>
+  <body class="bg-dark">
     
     <div id="root"></div>
     

+ 6 - 3
src/App.js

@@ -9,7 +9,8 @@ import {Provider, connect}   from 'react-redux';
 import { store } from './store/store';
 import { actionAllPlaylists } from './store/promiseReducer';
 import { actionFullSetPlaylist } from './store/playerReducer';
-import {LoginForm, RegisterForm} from './components/authorization'
+import {CLoginForm} from './components/authorization'
+import {CRegisterForm} from './components/authRegistration'
 import {CreatePlaylist} from './components/createPlaylist'
 
 import { Header } from './components/header';
@@ -64,8 +65,10 @@ const Main = ({children}) =>
       <Content>
         <Switch>
           {store.getState().auth?.token && <Redirect from='/login' to={'/user'} exact />} 
-          <Route path={'/login'} component={LoginForm} />
-          <Route path={'/register'} component={RegisterForm}/>
+          {store.getState().auth?.token && <Redirect from='/register' to={'/user'} exact />} 
+          {!store.getState().auth?.token && <Redirect from='/user' to={'/login'} exact />}
+          <Route path={'/login'} component={CLoginForm} />
+          <Route path={'/register'} component={CRegisterForm}/>
 
           <Route path={'/allplaylists'} component={Aside}/>
           <Route path={'/playlist'} component={CPlaylistById} />

+ 77 - 0
src/components/authRegistration.js

@@ -0,0 +1,77 @@
+import React, {useState} from 'react';
+import {Link} from 'react-router-dom';
+import { actionAuthLogin } from '../store/authReducer';
+import { store } from '../store/store';
+import { connect } from 'react-redux';
+
+
+async function sendForm (url, data) {
+    let error = await fetch(`http://player-api/api/${url}`, {
+        method: 'POST',
+        body: data
+      }).then(res => res.json())
+      .then(data => {
+          if(data.token) {
+            store.dispatch(actionAuthLogin(data.token, data.user));
+            return data
+          } else {
+            console.log(data); 
+            return data.login[0];
+          }
+      })
+    return error;
+}
+
+export const RegisterForm = ({authState}) => {
+    const [login, setLogin] = useState('');
+    const [password, setPassword] = useState('');
+    const [name, setName] = useState('');
+    const [passwordConfirm, setPasswordConfirm] = useState('');
+    const [textModal, setTextModal] = useState('');
+  
+     const postForm = async (event)  =>{
+      event.preventDefault();
+      const data = new FormData();
+      data.append("login", login);
+      data.append("password", password);
+      data.append("name", name);
+
+      setTextModal(( typeof(await sendForm('register', data))==='string')? (await sendForm('register', data)) : '');
+      
+    }
+
+    return (
+      <form  onSubmit={postForm} id="register_form">
+        <div className="register container align-items-center justify-content-center vw-100 vh-100 d-flex">
+         <div className="col-4">
+               <h4 className="w-100 text-center">Sign Up</h4>
+              <hr/>
+              <label className="form-label">*Login</label><br/>
+               <input type="text" id="username" className="input form-control mb-3" placeholder="asya123"
+                  value={login} onChange={e => setLogin(e.target.value)}
+               />
+  
+               <label className="form-label">*Full Name</label><br/>
+               <input type="text" id="name" className="input form-control mb-3" placeholder="Anastasiia"
+                  value={name} onChange={e => setName(e.target.value)}
+               />
+  
+               <label className="form-label">*Password (8+ symbols)</label>
+               <input type="password" id="password" className="form-control mb-3" value={password} onChange={e => setPassword(e.target.value)} /> 
+  
+               <label  className="form-label">*Confirm password</label>
+               <input type="password" id="confirm_password" className="form-control mb-3" value={passwordConfirm} onChange={e => setPasswordConfirm(e.target.value)}/>
+               <p className='text-danger'>{textModal ? ('*' + textModal) : ''}</p>
+               <div className="d-flex justify-content-between align-items-center">
+                   <h6>Already a member? <Link to="/login" className="">Log in</Link></h6>
+                   <button type="submit" className="btn btn-outline-danger" disabled={password !== passwordConfirm || password.length < 8 || login.length < 3} onClick={() => console.log('/user')}>
+                   Sign Up
+                   </button>
+               </div>
+           </div>
+       </div>
+      </form>
+    )  
+  }
+
+  export const CRegisterForm = connect(state => ({ authState: state.auth?.token }))(RegisterForm);

+ 89 - 60
src/components/authorization.js

@@ -2,99 +2,128 @@ import React, {useState} from 'react';
 import {Link} from 'react-router-dom';
 import { actionAuthLogin } from '../store/authReducer';
 import { store } from '../store/store';
+import { connect } from 'react-redux';
 
 
-function sendForm (url, data) {
-    fetch(`http://player-api/api/${url}`, {
-        method: 'POST',
-        body: data
-      }).then(res => res.json())
-      .then(data => {
-          if(data.token) {
-            store.dispatch(actionAuthLogin(data.token, data.user));
-            //console.log(data)
-            return data
-          } else {
-            //console.log(data.login[0]); 
-          }
-      })
+
+async function sendForm (url, data) {
+  let error = await fetch(`http://player-api/api/${url}`, {
+      method: 'POST',
+      body: data
+    }).then(res => res.json())
+    .then(data => {
+        if(data.token) {
+          store.dispatch(actionAuthLogin(data.token, data.user));
+          return data
+        } else {
+          console.log(data.message)
+          return data.message;
+        }
+    })
+    console.log(error)
+    return error;
 }
 
-export const LoginForm = () => {
+export const LoginForm = ({authState}) => {
     const [login, setLogin] = useState('');
     const [password, setPassword] = useState('');
+    const [textModal, setTextModal] = useState('');
+
+
   
-    const postForm = (event)  =>{
+    
+    const postForm = async(event)  =>{
       event.preventDefault();
       const data = new FormData();
       data.append("login", login);
       data.append("password", password);
     
-      sendForm('login', data);
+      setTextModal(( typeof(await sendForm('login', data))==='string')? (await sendForm('login', data)) : '');
     }
-  
+
+  //   let history = useHistory();
+
+  //   useEffect(() => {
+  //     if (authState) {history.push('/user')}
+  // }, []);
+
     return <>
       <form onSubmit={postForm} className="authorization container align-items-center justify-content-center vw-100 vh-100 d-flex">
         <div className="col-4">
               <h4 className="w-100 text-center">Login</h4>
+              
               <hr/>
-              <label  className="form-label">Username</label><br/>
+              <label  className="form-label">*Username</label><br/>
               <input type="text" id="username" className='input form-control mb-3' value={login} onChange={e => setLogin(e.target.value)}/>
-              <label  className="form-label">Password</label>
+              <label  className="form-label">*Password</label>
               <input type="password" id="password" className='form-control mb-3' value={password} onChange={e => setPassword(e.target.value)}/>
+              <p className='text-danger'>{textModal ? ('*' + textModal) : ''}</p>
               <div className="d-flex justify-content-between">
                   <Link to="/register" className="">Register</Link>
-                  <button type='submit' className="btn btn-outline-danger" onClick={() => console.log(login, password)}>Log in</button>
+                  <button type='submit' className="btn btn-outline-danger" disabled={ password.length < 8 || login.length < 5} onClick={() => console.log(textModal)}>Log in</button>
               </div>
           </div>
       </form>
     </>
   }
+
+  export const CLoginForm = connect(state => ({ authState: state.auth?.token }))(LoginForm);
   
   
-  export const RegisterForm = () => {
-    const [login, setLogin] = useState('');
-    const [password, setPassword] = useState('');
-    const [name, setName] = useState('');
+  // export const RegisterForm = ({authState2}) => {
+  //   const [login, setLogin] = useState('');
+  //   const [password, setPassword] = useState('');
+  //   const [name, setName] = useState('');
+  //   const [passwordConfirm, setPasswordConfirm] = useState('')
   
-     const postForm = (event)  =>{
-      event.preventDefault();
-      const data = new FormData();
-      data.append("login", login);
-      data.append("password", password);
-      data.append("name", name);
+  //    const postForm = (event)  =>{
+  //     event.preventDefault();
+  //     const data = new FormData();
+  //     data.append("login", login);
+  //     data.append("password", password);
+  //     data.append("name", name);
 
-      sendForm('register', data);
+  //     sendForm('register', data);
       
-    }
+  //   }
+
+  // //   let history = useHistory();
+
+  // //   useEffect(() => {
+  // //     if (authState2) {history.push('/user')}
+  // // }, [authState2]);
   
-    return (
-      <form  onSubmit={postForm} id="register_form">
-        <div className="register container align-items-center justify-content-center vw-100 vh-100 d-flex">
-         <div className="col-4">
-               <h4 className="w-100 text-center">Sign Up</h4>
-              <hr/>
-              <label className="form-label">Login</label><br/>
-               <input type="text" id="username" className="input form-control mb-3" placeholder="asya123"
-                  value={login} onChange={e => setLogin(e.target.value)}
-               />
+  //   return (
+  //     <form  onSubmit={postForm} id="register_form">
+  //       <div className="register container align-items-center justify-content-center vw-100 vh-100 d-flex">
+  //        <div className="col-4">
+  //              <h4 className="w-100 text-center">Sign Up</h4>
+  //             <hr/>
+  //             <label className="form-label">Login</label><br/>
+  //              <input type="text" id="username" className="input form-control mb-3" placeholder="asya123"
+  //                 value={login} onChange={e => setLogin(e.target.value)}
+  //              />
   
-               <label className="form-label">Full Name</label><br/>
-               <input type="text" id="name" className="input form-control mb-3" placeholder="My Chemical Romance"
-                  value={name} onChange={e => setName(e.target.value)}
-               />
+  //              <label className="form-label">Full Name</label><br/>
+  //              <input type="text" id="name" className="input form-control mb-3" placeholder="Anastasiia"
+  //                 value={name} onChange={e => setName(e.target.value)}
+  //              />
   
-               <label className="form-label">Password</label>
-               <input type="password" id="password" className="form-control mb-3" value={password} onChange={e => setPassword(e.target.value)} /> 
+  //              <label className="form-label">Password</label>
+  //              <input type="password" id="password" className="form-control mb-3" value={password} onChange={e => setPassword(e.target.value)} /> 
   
-               <label  className="form-label">Confirm password</label>
-               <input type="password" id="confirm_password" className="form-control mb-3"/>
-               <div className="d-flex justify-content-between align-items-center">
-                   <h6>Already a member? <Link to="/login" className="">Log in</Link></h6>
-                   <button type="submit" className="btn btn-outline-danger">Sign Up</button>
-               </div>
-           </div>
-       </div>
-      </form>
-    )  
-  }
+  //              <label  className="form-label">Confirm password</label>
+  //              <input type="password" id="confirm_password" className="form-control mb-3" value={passwordConfirm} onChange={e => setPasswordConfirm(e.target.value)}/>
+  //              <div className="d-flex justify-content-between align-items-center">
+  //                  <h6>Already a member? <Link to="/login" className="">Log in</Link></h6>
+  //                  <button type="submit" className="btn btn-outline-danger" disabled={password !== passwordConfirm || password.length < 3 || login.length < 3} onClick={() => console.log(login, password)}>
+  //                  Sign Up
+  //                  </button>
+  //              </div>
+  //          </div>
+  //      </div>
+  //     </form>
+  //   )  
+  // }
+
+  // export const CRegisterForm = connect(state => ({ authState2: state.auth?.token }))(RegisterForm)

+ 6 - 4
src/components/header.js

@@ -25,14 +25,16 @@ export const Header = ({children}) =>
             <input className="form-control me-2 " type="search" placeholder="Search" aria-label="Search"/>
         
         </div>
-        <div className="d-flex">
-            <img alt='///' className='logoimg' src={image}/>
             <CLogout/>
-        </div>
+        
     </div>
   </nav>
   {children}
 </header>
 
-const CLogout = connect(state => ({children: `Logout (${state.auth.user?.login || 'anon'})`}), 
+const ImgLogout = () => {
+    return <img alt='///' className='logoimg' src={logoutimg}/>
+}
+
+const CLogout = connect(state => ({children: <ImgLogout/>}), 
                                               {onClick: actionAuthLogout})('button')

+ 38 - 12
src/components/playing.js

@@ -2,12 +2,31 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
 import React, {useState, useEffect} from 'react';
 import {faVolumeDown, faVolumeUp, faRandom, faStepBackward, faStopCircle, faStepForward, faPlayCircle, faRepeat} from '@fortawesome/free-solid-svg-icons'
 import { store } from '../store/store';
-import { actionFullSetTrack, actionFullPlay, actionFullPause, actionFullSetVolume, actionFullSetCurrentTime } from '../store/playerReducer';
+import {actionFullGetDuration, actionFullSetTrack, actionFullPlay, actionFullPause, actionFullSetVolume, actionFullSetCurrentTime } from '../store/playerReducer';
 import {Provider, connect}   from 'react-redux';
 
-export let NowPlayingPlayer = (track, duration) => {
+function msToTime(duration) {
+    let hours,minutes,seconds;
+    hours = Math.floor(duration / 3600);
+    minutes = Math.floor((duration - 3600 * hours) / 60);
+    seconds = Math.floor((duration - 3600 * hours - 60 * minutes) % 60);
+    
+    hours = (hours < 10) ? "0" + hours : hours;
+    minutes = (minutes < 10) ? "0" + minutes : minutes;
+    seconds = (seconds < 10) ? "0" + seconds : seconds;
+    
+    return minutes + ":" + seconds;
+    }
+
+export let NowPlayingPlayer = (props) => {
     const [volume, setVolume] = useState(10);
-    const [play, setPlay] = useState(false);
+    // let duration;
+
+    // useEffect(() => {
+    //     if (!store.getState().player?.duration) {
+    //         duration = msToTime(store.getState()?.player?.track?.src?.duration)
+    //     }
+    // }, []);
 
 return(
 <div className="player">
@@ -15,17 +34,17 @@ return(
         <div className="details">
             <div className="now-playing"></div>
             <div className="track-art"></div>
-            <div className="track-name">{store.getState()?.player?.track?.name|| 'Track Name'  }</div>
-            <div className="now-playing">{store.getState()?.player?.track?.id3?.artist || 'Artist'  }</div>
+            <div className="track-name">{props.track?.name|| 'Track Name'  }</div>
+            <div className="now-playing">{props.track?.id3?.artist || 'Artist'  }</div>
         </div>
 
         <div className="slider-container duration">
             <span className="current-time">00:00</span>
             <input type='range' min={1} max='100' value='0' className="seek-slider" 
-            // onChange={(e) => setVolume(e.target.value)}
+            // onChange={(e) => setDuration(e.target.value)}
 
             />
-            <span className="total-duration">{store.getState()?.player?.duration || '00:00'}</span>
+            <span className="total-duration">{msToTime(props.duration) !== 'NaN'? msToTime(props.duration) : '00:00'}</span>
             
         </div>
 
@@ -59,14 +78,14 @@ return(
               onClick={() => {
                 if(store.getState()?.player?.isPlaying === true) {
                     store.dispatch(actionFullPause());
-                    setPlay(true)
+                    //setPlay(true)
                  } else{
                     store.dispatch(actionFullPlay());
-                    setPlay(false)
+                    //setPlay(false)
                  } 
                 }}
             >
-                <FontAwesomeIcon icon={(play) ? faPlayCircle : faStopCircle} className='fa-5x' />
+                <FontAwesomeIcon icon={(!props.isPlaying) ? faPlayCircle : faStopCircle} className='fa-5x' />
             </div>
             <div className="next-track"
             //  onClick={nextTrack()}
@@ -84,5 +103,12 @@ return(
     </div>
 </div>)
 }
-
-export const СNowPlayingPlayer = connect(state => ({track: state.player?.track || [], duration: state.player?.duration}), )(NowPlayingPlayer);
+function mapStateToProps (state) {
+    return {
+        track: state.player?.track,
+        duration: state.player?.duration,
+        
+    }
+  }
+  //export const СNowPlayingPlayer = connect(mapStateToProps)(NowPlayingPlayer)
+  export const СNowPlayingPlayer = connect(state => ({track: state.player?.track || [], duration: state.player?.duration || [], isPlaying: state.player?.isPlaying || false}) )(NowPlayingPlayer);

+ 3 - 2
src/components/playlistById.js

@@ -81,8 +81,9 @@ const Track = ({track: {name, file, id3, id} = {} }, key) =>
 <tr>
     <th scope="row">{i++}</th>
     <td>          
-        <button onClick={async() => {
-            await (() => audio.src = `http://player-api/storage/tracks/${file}`)();
+        <button onClick={() => {
+            audio.src = `http://player-api/storage/tracks/${file}`;
+                
             store.dispatch(actionFullSetTrack({name, file, id3, id}));
             store.dispatch(actionFullPlay());
         }}>

+ 1 - 1
src/components/userPage.js

@@ -108,7 +108,7 @@ const [modalShow, setModalShow] = React.useState(false);
         onHide={() => setModalShow(false)}
       />
 
-    <h3>My playlists</h3>
+    <h3>My playlists:</h3>
     <СUsersPlaylists/>
 
     </>)

+ 1 - 1
src/store/authReducer.js

@@ -1,4 +1,4 @@
-
+import { useHistory } from 'react-router-dom';
 // const jwtDecode = token =>{
 //     try{
 //         let payload = JSON.parse(atob(token.split('.')[1]));

+ 1 - 24
src/store/playerReducer.js

@@ -55,32 +55,10 @@ export const actionFullPlay = () =>
     dispatch => {  
         audio.play();
         dispatch(actionPlay());
-        dispatch(actionFullGetDuration(msToTime(audio.duration)))
+        dispatch(actionFullGetDuration(audio.duration))
     }
 
 
-// let audio = new Audio();
-// const actionPlay = () => ({type:'PLAY'})
-// export const actionFullPlay = () =>
-//     dispatch => {  
-//         audio.play();
-//         dispatch(actionPlay());
-//         dispatch(actionFullGetDuration(msToTime(audio.duration)))
-//     }
-
-function msToTime(duration) {
-    let hours,minutes,seconds;
-    hours = Math.floor(duration / 3600);
-    minutes = Math.floor((duration - 3600 * hours) / 60);
-    seconds = Math.floor((duration - 3600 * hours - 60 * minutes) % 60);
-    
-    hours = (hours < 10) ? "0" + hours : hours;
-    minutes = (minutes < 10) ? "0" + minutes : minutes;
-    seconds = (seconds < 10) ? "0" + seconds : seconds;
-    
-    return minutes + ":" + seconds;
-    }
-
 
 const actionPause = () => ({type:'PAUSE'})
 export const actionFullPause = () =>
@@ -102,7 +80,6 @@ export const actionFullSetTrack = (track) =>
         //audio.src = `http://player-api/storage/tracks/${track.file}`;
         dispatch(actionSetTrack(track));
         dispatch(actionFullPlay());
-        dispatch(actionFullGetDuration(msToTime(audio.duration)));  
     }
 
 const actionGetDuration = (duration) => ({type:'GET_DURATION', duration})