259 lines
6.1 KiB
JavaScript
259 lines
6.1 KiB
JavaScript
import React from "react"
|
|
import { connect } from "react-redux"
|
|
import { SpinnerCircular } from "spinners-react";
|
|
import InputMask from 'react-input-mask';
|
|
|
|
import { sendFeedback, sendNewAppeal } from "../../../actions"
|
|
import { _checkStrValue } from "../../../utils";
|
|
|
|
class Rating extends React.Component
|
|
{
|
|
constructor(props)
|
|
{
|
|
super(props)
|
|
this.state = {
|
|
name: "",
|
|
phone: "",
|
|
comment: "",
|
|
opened: false,
|
|
hidden: false,
|
|
deleted: false,
|
|
rating: 0,
|
|
hovered: 0,
|
|
stars: [],
|
|
completed: false,
|
|
publish: false,
|
|
loading: false,
|
|
errors: [],
|
|
}
|
|
|
|
let outOf = props.outOf ? props.outOf : 5
|
|
|
|
for (var i = 0; i < outOf; i++) {
|
|
this.state.stars.push(i + 1)
|
|
}
|
|
}
|
|
|
|
static getDerivedStateFromProps(nextProps, prevState)
|
|
{
|
|
return {}
|
|
}
|
|
|
|
componentDidMount() {}
|
|
|
|
componentDidUpdate(prevProps, prevState) {}
|
|
|
|
changeRating(newRating)
|
|
{
|
|
this.setState({
|
|
rating: newRating
|
|
})
|
|
|
|
if (this.props.onChange) this.props.onChange(newRating)
|
|
}
|
|
|
|
_handle_hoverRating(rating)
|
|
{
|
|
this.setState({
|
|
hovered: rating,
|
|
})
|
|
}
|
|
|
|
_handleRate = (newRating) =>
|
|
{
|
|
this.setState({
|
|
rating: newRating,
|
|
hovered: newRating,
|
|
opened: true,
|
|
});
|
|
}
|
|
|
|
_handle_onFieldChange = (field, value) =>
|
|
{
|
|
const update = { ...this.state };
|
|
update[field] = value;
|
|
|
|
this.setState(update);
|
|
}
|
|
|
|
_handle_onSetPublished = () =>
|
|
{
|
|
const { name, phone, comment, rating } = this.state;
|
|
|
|
if(!this.state.publish)
|
|
{
|
|
this.setState({ publish: this.state.publish ? false : true });
|
|
|
|
sendFeedback({
|
|
name,
|
|
phone,
|
|
comment,
|
|
rating,
|
|
})
|
|
.then(() => {})
|
|
.catch(() => {});
|
|
|
|
setTimeout(() => {
|
|
this.setState({ hidden: true })
|
|
}, 1000);
|
|
|
|
setTimeout(() => {
|
|
this.setState({ deleted: true })
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
_removeError = (name) =>
|
|
{
|
|
const errors = [ ...this.state.errors ];
|
|
|
|
if(typeof name === "string")
|
|
{
|
|
if(errors.indexOf(name) > -1)
|
|
{
|
|
errors.splice(errors.indexOf(name), 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(let i in name)
|
|
{
|
|
if(errors.indexOf(name[i]) > -1)
|
|
{
|
|
errors.splice(errors.indexOf(name[i]), 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.setState({ errors });
|
|
}
|
|
|
|
_handle_onFormSubmit = (event) =>
|
|
{
|
|
event.preventDefault();
|
|
|
|
const { name, phone, comment, rating } = this.state;
|
|
|
|
const payload = {
|
|
name: name,
|
|
phone: phone,
|
|
email: "",
|
|
description: comment,
|
|
contract_numbers: [],
|
|
evaluation: rating,
|
|
};
|
|
|
|
this.setState({ completed: true, loading: true }, () =>
|
|
{
|
|
sendNewAppeal(payload)
|
|
.then((result) =>
|
|
{
|
|
this.setState({ completed: true, loading: false });
|
|
});
|
|
});
|
|
}
|
|
|
|
render()
|
|
{
|
|
const { opened, hidden, deleted, stars, rating, hovered, completed, publish, loading, name, phone, comment, errors } = this.state
|
|
const data = ["Очень плохо", "Плохо", "Нормально", "Хорошо", "Отлично"]
|
|
|
|
if(deleted)
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
return (
|
|
<div className={`rate_us ${ opened && "opened" } ${ hidden && "hidden" }`}>
|
|
<div className={`rate_body ${ completed && "completed" }`}>
|
|
{ completed ? ( <>
|
|
{ loading ? (
|
|
<SpinnerCircular size={ 45 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
|
|
) : (
|
|
<>
|
|
<p>Спасибо за Вашу оценку!</p>
|
|
<div className="form_field checkbox">
|
|
<input type="checkbox"
|
|
checked={ publish ? true : false }
|
|
hidden=""
|
|
id="rate_allow_publish"
|
|
name="rate_allow_publish"
|
|
onChange={ this._handle_onSetPublished }
|
|
/>
|
|
<label htmlFor="rate_allow_publish" className="unselectable">Даю разрешение на публикацию своего отзыва в сети Интернет</label>
|
|
</div>
|
|
</>
|
|
) }
|
|
</>
|
|
) : (
|
|
<>
|
|
<p>Оцените нас</p>
|
|
<div className="rate_start">
|
|
<p>{ hovered > 0 ? data[ hovered - 1 ] : rating > 0 ? data[ rating - 1 ] : <> </> }</p>
|
|
<div
|
|
className="stars"
|
|
>
|
|
{ stars.map((star, index) => {
|
|
return (
|
|
<label key={ index }
|
|
className={rating < star ? (hovered < star ? "" : "hover") : "active"}
|
|
onClick={() =>
|
|
{
|
|
this._handleRate(star)
|
|
}}
|
|
onMouseEnter={() => {
|
|
this._handle_hoverRating(star)
|
|
}}
|
|
onMouseLeave={() => {
|
|
this._handle_hoverRating(0)
|
|
}}
|
|
/>
|
|
)}
|
|
) }
|
|
</div>
|
|
</div>
|
|
<form onSubmit={ this._handle_onFormSubmit }>
|
|
<div className="form_field">
|
|
<input type="text" placeholder="Имя" name="name" onChange={ (event) => this._handle_onFieldChange(event.target.name, event.target.value) } defaultValue={ name }/>
|
|
</div>
|
|
<div className="form_field">
|
|
<InputMask
|
|
className={ errors.indexOf("phone") > -1 ? "error" : "" }
|
|
mask='+7 (999) 999 99 99'
|
|
id="phone"
|
|
name="phone"
|
|
value={ _checkStrValue(phone) }
|
|
placeholder="Телефон"
|
|
onChange={ (event) => { if(event.target.value !== "" && !isNaN(parseInt(event.target.value.replace(/[^\d]+/g, ''), 10)) && parseInt(event.target.value.replace(/[^\d]+/g, ''), 10) > 7) { this._removeError("phone"); } this._handle_onFieldChange(event.target.name, event.target.value); } }
|
|
/>
|
|
</div>
|
|
<div className="form_field">
|
|
<textarea
|
|
name="comment"
|
|
placeholder="Комментарий"
|
|
onChange={ (event) => this._handle_onFieldChange(event.target.name, event.target.value) }
|
|
defaultValue={ comment }
|
|
required={ rating > 4 ? false : true }
|
|
/>
|
|
</div>
|
|
<button type="submit" className="button button button-blue">
|
|
Отправить
|
|
</button>
|
|
</form>
|
|
</>
|
|
) }
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
function mapStateToProps(state, ownProps)
|
|
{
|
|
return {}
|
|
}
|
|
|
|
export default connect(mapStateToProps)(Rating)
|