Compare commits

...

5 Commits

  1. 5
      .vscode/extensions.json
  2. 4
      src/Redux/proxy.js
  3. 1
      src/index.js
  4. 13
      src/views/Auth/Auth.js
  5. 8
      src/views/Auth/Auth.scss
  6. 93
      src/views/Auth/Login/Code/Code.js
  7. 10
      src/views/Auth/Login/Login.js
  8. 5
      src/views/Auth/Login/Mobile/Mobile.js
  9. 5
      src/views/Auth/Login/Timer/Timer.css
  10. 66
      src/views/Auth/Login/Timer/Timer.js
  11. 13
      src/views/ChatRoom/Body/Body.js
  12. 23
      src/views/ChatRoom/Body/ChatSuggest/ChatSuggest.js
  13. 6
      src/views/ChatRoom/Body/ChatSuggest/ChatSuggest.scss
  14. 12
      src/views/ChatRoom/Body/Message/DraggableMessage/DraggableMessage.js
  15. 37
      src/views/ChatRoom/Body/Message/RadioMessage/RadioMessage.js

@ -0,0 +1,5 @@
{
"recommendations": [
"rvest.vs-code-prettier-eslint"
]
}

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
const baseURL = 'http://localhost:4040/api/v1'; //"https://chatstory.ir/api/v1"; const baseURL = 'https://chatstory.ir/api/v1'; //"https://chatstory.ir/api/v1";
const token = ''; const token = '';
const loginURL = 'user/otp/login'; const loginURL = 'user/otp/login';
const logoutURL = 'user/logout'; const logoutURL = 'user/logout';
@ -31,7 +31,7 @@ class Proxy {
if (await this.refresh()) return this.result(url, (await fetch()).data.data); if (await this.refresh()) return this.result(url, (await fetch()).data.data);
break; break;
default: default:
toast(response.data.message); toast.error(response.data.message);
} }
return false; return false;
}; };

@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import App from './App'; import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import './index.scss'; import './index.scss';
import 'react-toastify/dist/ReactToastify.css';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>

@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import {ToastContainer} from 'react-toastify';
import Logo from './Logo/Logo'; import Logo from './Logo/Logo';
import Bio from './Bio/Bio'; import Bio from './Bio/Bio';
import Login from './Login/Login'; import Login from './Login/Login';
@ -24,6 +24,17 @@ export default class Auth extends Component {
{this.state.page === 'logo' ? <Logo setPage={this.setPage} /> : null} {this.state.page === 'logo' ? <Logo setPage={this.setPage} /> : null}
{this.state.page === 'bio' ? <Bio setPage={this.setPage} /> : null} {this.state.page === 'bio' ? <Bio setPage={this.setPage} /> : null}
{this.state.page === 'login' ? <Login /> : null} {this.state.page === 'login' ? <Login /> : null}
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</div> </div>
); );
} }

@ -5,5 +5,13 @@
direction: rtl; direction: rtl;
overflow-x: hidden; overflow-x: hidden;
position: relative; position: relative;
.Toastify__toast-container {
width: calc(100vw - 20px) !important;
padding: 0 !important;
left: 0 !important;
bottom: 30px !important;
margin: 0px auto !important;
max-height: 50px;
}
} }
} }

@ -1,14 +1,13 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import Timer from '../Timer/Timer';
export default class Code extends Component { export default class Code extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
auth_code1: '',
auth_code2: '',
auth_code3: '',
auth_code4: '',
flag: false, flag: false,
resendStatus: false,
}; };
} }
@ -20,19 +19,21 @@ export default class Code extends Component {
changeValue = (e) => { changeValue = (e) => {
if (e.target.value.match('^[0-9]{1}$')) { if (e.target.value.match('^[0-9]{1}$')) {
this.setState({ if (e.target.name === 'o1') {
[e.target.name]: e.target.value, if(typeof this.state.o1 === Number){
}); console.log(e.target.value);
if (e.target.name === 'auth_code1') { }else{
this.setState({ o1 : e.target.value }); this.setState({ o1 : e.target.value });
}
this.inputRef2.focus(); this.inputRef2.focus();
} else if (e.target.name === 'auth_code2') { } else if (e.target.name === 'o2') {
this.setState({ o2: e.target.value }); this.setState({ o2: e.target.value });
this.inputRef3.focus(); this.inputRef3.focus();
} else if (e.target.name === 'auth_code3') { } else if (e.target.name === 'o3') {
this.setState({ o3: e.target.value }); this.setState({ o3: e.target.value });
this.inputRef4.focus(); this.inputRef4.focus();
} else if (e.target.name === 'auth_code4') { } else if (e.target.name === 'o4') {
this.setState({ o4: e.target.value });
const o4 = e.target.value; const o4 = e.target.value;
const { o1, o2, o3 } = this.state; const { o1, o2, o3 } = this.state;
this.props.parent.setState({ otp: `${o1}${o2}${o3}${o4}` }); this.props.parent.setState({ otp: `${o1}${o2}${o3}${o4}` });
@ -48,15 +49,15 @@ export default class Code extends Component {
this.setState({ this.setState({
[e.target.name]: '', [e.target.name]: '',
}); });
if (e.target.name === 'auth_code1') { if (e.target.name === 'o1') {
return; return;
} else if (e.target.name === 'auth_code2') { } else if (e.target.name === 'o2') {
this.inputRef1.focus(); this.inputRef1.focus();
return; return;
} else if (e.target.name === 'auth_code3') { } else if (e.target.name === 'o3') {
this.inputRef2.focus(); this.inputRef2.focus();
return; return;
} else if (e.target.name === 'auth_code4') { } else if (e.target.name === 'o4') {
this.inputRef3.focus(); this.inputRef3.focus();
return; return;
} }
@ -67,6 +68,17 @@ export default class Code extends Component {
this.inputRef1.focus(); this.inputRef1.focus();
} }
onInput= (e) => {
e.target.value = e.target.value
.replace(/[\u0660-\u0669\u06f0-\u06f9]/g, function (c) {
return c.charCodeAt(0) & 0xf;
})
.replace(/[^\d]/, '')
.slice(-1);
}
render() { render() {
return ( return (
<> <>
@ -76,53 +88,72 @@ export default class Code extends Component {
</div> </div>
<div className="login-code__bottom d-flex"> <div className="login-code__bottom d-flex">
<input <input
name="auth_code1" name="o1"
type="number" type="text"
onChange={(e) => this.changeValue(e)} onChange={(e) => this.changeValue(e)}
maxLength="1" maxLength="2"
inputMode="numeric"
ref={(input) => { ref={(input) => {
this.inputRef1 = input; this.inputRef1 = input;
}} }}
autoComplete="false" autoComplete="false"
value={this.state.auth_code1} value={this.state.o1}
onKeyDown={(e) => this.keyboardEvent(e)} onKeyDown={(e) => this.keyboardEvent(e)}
onInput={this.onInput}
/> />
<input <input
name="auth_code2" name="o2"
type="number" type="text"
onChange={(e) => this.changeValue(e)} onChange={(e) => this.changeValue(e)}
maxLength="1" maxLength="2"
inputMode="numeric"
ref={(input) => { ref={(input) => {
this.inputRef2 = input; this.inputRef2 = input;
}} }}
autoComplete="false" autoComplete="false"
value={this.state.auth_code2} value={this.state.o2}
onKeyDown={(e) => this.keyboardEvent(e)} onKeyDown={(e) => this.keyboardEvent(e)}
onInput={this.onInput}
/> />
<input <input
name="auth_code3" name="o3"
type="number" type="text"
onChange={(e) => this.changeValue(e)} onChange={(e) => this.changeValue(e)}
maxLength="1" maxLength="2"
inputMode="numeric"
ref={(input) => { ref={(input) => {
this.inputRef3 = input; this.inputRef3 = input;
}} }}
autoComplete="false" autoComplete="false"
value={this.state.auth_code3} value={this.state.o3}
onKeyDown={(e) => this.keyboardEvent(e)} onKeyDown={(e) => this.keyboardEvent(e)}
onInput={this.onInput}
/> />
<input <input
name="auth_code4" name="o4"
type="number" type="text"
onChange={(e) => this.changeValue(e)} onChange={(e) => this.changeValue(e)}
maxLength="1" maxLength="2"
inputMode="numeric"
ref={(input) => { ref={(input) => {
this.inputRef4 = input; this.inputRef4 = input;
}} }}
autoComplete="false" autoComplete="false"
value={this.state.auth_code4} value={this.state.o4}
onKeyDown={(e) => this.keyboardEvent(e)} onKeyDown={(e) => this.keyboardEvent(e)}
onInput={this.onInput}
/> />
{!this.state.resendStatus ? (
<Timer seconds={5} parent={this} />
) : (
<span
style={{ top: 150, color: 'blue', textDecoration: 'underline' }}
className="logo__footer d-flex align-self-start"
onClick={ () => this.props.parent.resend()}
>
دریافت مجدد
</span>
)}
<div className="logo__footer d-flex align-self-center"> <div className="logo__footer d-flex align-self-center">
<h2 <h2
style={{ style={{

@ -15,10 +15,20 @@ class Login extends Component {
} }
async componentDidUpdate() { async componentDidUpdate() {
const { cellphone, otp, section } = this.state; const { cellphone, otp, section } = this.state;
// if(cellphone.length === 9 && !otp){
// this.setState({section: 1});
// this.props.otp({cellphone});
// }
if (cellphone && !otp) this.props.otp({ cellphone }); if (cellphone && !otp) this.props.otp({ cellphone });
if (section && cellphone && otp) this.props.login({ cellphone, otp }); if (section && cellphone && otp) this.props.login({ cellphone, otp });
} }
resend = () => {
const {cellphone} = this.state;
this.props.otp({cellphone});
}
render() { render() {
const { section } = this.state; const { section } = this.state;
return ( return (

@ -3,6 +3,7 @@ import phonenumber from '../../../../assets/icons/phonenumber.png';
export default class Mobile extends Component { export default class Mobile extends Component {
render() { render() {
return ( return (
<> <>
<div className="login-mobile__top d-flex"> <div className="login-mobile__top d-flex">
@ -11,6 +12,7 @@ export default class Mobile extends Component {
<img src={phonenumber} alt="" /> <img src={phonenumber} alt="" />
</div> </div>
<div className="login-mobile__input d-flex"> <div className="login-mobile__input d-flex">
<form onSubmit={() => this.props.parent.setState({ section: 1, cellphone: '09' + this.state.cellphone })} >
<input <input
type="text" type="text"
maxLength={9} maxLength={9}
@ -23,8 +25,11 @@ export default class Mobile extends Component {
}) })
.replace(/[^\d]/, '')) .replace(/[^\d]/, ''))
} }
// onAction={}
/> />
<div>09</div> <div>09</div>
</form>
</div> </div>
<button <button
onClick={() => onClick={() =>

@ -0,0 +1,5 @@
.timer{
flex-direction: row;
direction: rtl !important;
margin-right: 10px;
}

@ -0,0 +1,66 @@
import { Component } from 'react';
import './Timer.css';
export default class Timer extends Component {
constructor(props) {
super(props);
this.state = { time: {}, seconds: this.props.seconds, flag: true, };
this.timer = 0;
this.startTimer = this.startTimer.bind(this);
this.countDown = this.countDown.bind(this);
}
secondsToTime(secs) {
let hours = Math.floor(secs / (60 * 60));
let divisor_for_minutes = secs % (60 * 60);
let minutes = Math.floor(divisor_for_minutes / 60);
let divisor_for_seconds = divisor_for_minutes % 60;
let seconds = Math.ceil(divisor_for_seconds);
let obj = {
"h": hours,
"m": minutes,
"s": seconds
};
return obj;
}
componentDidMount() {
this.startTimer();
let timeLeftVar = this.secondsToTime(this.state.seconds);
this.setState({ time: timeLeftVar });
}
startTimer() {
if (this.timer === 0 && this.state.seconds > 0) {
this.timer = setInterval(this.countDown, 1000);
}
}
countDown = async () => {
// Remove one second, set state so a re-render happens.
let seconds = this.state.seconds - 1;
this.setState({
time: this.secondsToTime(seconds),
seconds: seconds,
});
if (seconds === 0) {
this.props.parent.setState({ resendStatus : true });
}
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return (
<div className="timer logo__footer d-flex" style={{ top : 150,color : 'blue' }}>
<div className="ml-2">دریافت مجدد کد در</div>
<div>{this.state.time.s}</div>:<div>{this.state.time.m+this.state.time.h*60}</div>
<div className="mr-2">دیگر</div>
</div>
);
}
}

@ -5,7 +5,7 @@ import ChatSuggest from './ChatSuggest/ChatSuggest';
import { RecordState } from 'audio-react-recorder'; import { RecordState } from 'audio-react-recorder';
import ReactPlayer from 'react-player'; import ReactPlayer from 'react-player';
import ReactAudioPlayer from 'react-audio-player'; import ReactAudioPlayer from 'react-audio-player';
import { ToastContainer } from 'react-toastify';
import photo from '../../../assets/images/reza.png'; import photo from '../../../assets/images/reza.png';
import photo1 from '../../../assets/images/user2.png'; import photo1 from '../../../assets/images/user2.png';
import './Body.scss'; import './Body.scss';
@ -419,6 +419,17 @@ class Body extends Component {
) : null} ) : null}
{this.state.footer === 'suggest' ? <ChatSuggest suggest={this.state.suggest} /> : null} {this.state.footer === 'suggest' ? <ChatSuggest suggest={this.state.suggest} /> : null}
</div> </div>
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</div> </div>
); );
} }

@ -7,8 +7,8 @@ export default class ChatSuggest extends Component {
return ( return (
<div className="chat-suggest portrait-slider d-flex flex-column"> <div className="chat-suggest portrait-slider d-flex flex-column">
<Carousel itemsToShow={1} isRTL={true} enableTilt={true} showArrows={false}> <Carousel itemsToShow={1} isRTL={true} enableTilt={true} showArrows={false}>
{suggest.map((item, i) => ( {suggest.map((row, i) => (
<Suggest item={item} key={i} /> <Row row={row} key={i} />
))} ))}
</Carousel> </Carousel>
</div> </div>
@ -16,9 +16,16 @@ export default class ChatSuggest extends Component {
} }
} }
class Suggest extends Component { const Row = (row) => {
render() { return (
const { item } = this.props; <div className="chat-suggest__row d-flex">
return <div className="chat-suggest__item d-flex">{item.text}</div>; {row.map((item, i) => (
} <Suggest item={item} key={i} />
} ))}
</div>
);
};
const Suggest = (item) => {
return <div className="chat-suggest__row--item d-flex">{item.text}</div>;
};

@ -6,7 +6,9 @@
// height : 40px; // height : 40px;
padding: 2px 0px 0px; padding: 2px 0px 0px;
align-items: flex-end; align-items: flex-end;
&__item { &__row{
width: 100%;
&--item {
padding: 8px 6px; padding: 8px 6px;
background-color: white; background-color: white;
border-radius: 5px; border-radius: 5px;
@ -17,6 +19,8 @@
min-height: 60px; min-height: 60px;
} }
} }
}
} }
.portrait-slider { .portrait-slider {

@ -3,15 +3,19 @@ import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import arrayMove from 'array-move'; import arrayMove from 'array-move';
import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt'; import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
const SortableItem = SortableElement(({ value }) => ( const SortableItem = SortableElement(({ row }) => (
<div className="message-2d__options--draggable d-flex">{value}</div> <div className="message-2d__options--row d-flex">
{row.map((item) => (
<div>{item.text}</div>
))}
</div>
)); ));
const SortableList = SortableContainer(({ items }) => { const SortableList = SortableContainer(({ items }) => {
return ( return (
<div className="message-2d__options d-flex flex-column"> <div className="message-2d__options d-flex flex-column">
{items.map((value, index) => ( {items.map((row, index) => (
<SortableItem key={`item-${value}`} index={index} value={value} /> <SortableItem key={`item-${index}`} index={index} value={row} />
))} ))}
</div> </div>
); );

@ -38,19 +38,8 @@ export default class RadioMessage extends Component {
) : null} ) : null}
</div> </div>
<div className="message-2d__options d-flex flex-wrap justify-content-center"> <div className="message-2d__options d-flex flex-wrap justify-content-center">
{message.options.map((item, i) => ( {message.options.map((row, i) => (
<div <Row row={row} key={i} />
key={i}
onClick={() => this.handleRadioChange(item.name)}
className="message-2d__options--radio"
style={{
backgroundColor:
item.name === this.state.value ? '#0000cc' : 'rgba(153, 153, 153, 0.87)',
color: item.name === this.state.value ? 'white' : 'black',
}}
>
{item.name}
</div>
))} ))}
</div> </div>
<button className="message-2d__submit"> <button className="message-2d__submit">
@ -61,3 +50,25 @@ export default class RadioMessage extends Component {
); );
} }
} }
const Row = (row) => {
return (
<div
key={i}
onClick={() => this.handleRadioChange(item.name)}
className="message-2d__options--row d-flex"
style={{
backgroundColor: item.name === this.state.value ? '#0000cc' : 'rgba(153, 153, 153, 0.87)',
color: item.name === this.state.value ? 'white' : 'black',
}}
>
{row.map((item) => (
<Item item={item} />
))}
</div>
);
};
const Item = (item) => {
return <div>{item.name}</div>;
};

Loading…
Cancel
Save