Advertisement
Guest User

Untitled

a guest
Nov 27th, 2019
486
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from "react";
  2. import PropTypes from "prop-types";
  3. import {
  4.   Container,
  5.   CardImg,
  6.   CardBody,
  7.   CardTitle,
  8.   CardFooter,
  9.   Button,
  10.   Input,
  11.   FormGroup,
  12.   Label,
  13.   Card,
  14.   Modal,
  15.   ModalHeader,
  16.   ModalBody,
  17.   ModalFooter,
  18.   Row,
  19.   Col,
  20. } from "reactstrap";
  21. import CommentList from "../../Components/Comment/CommentList";
  22. import Loading from "../../Components/Loading";
  23. import Error from "../../Components/Alert/Error";
  24. import CommentApi from "../../Apis/CommentApi";
  25. import InfoMessage from "../../Components/Alert/InfoMessage";
  26. import MovieDetails from "./partials/MovieDetails";
  27. import {ratings} from "../../Utils/utilsConst";
  28. import {CardHeader} from "semantic-ui-react";
  29.  
  30. class DetailMovie extends React.Component {
  31.   state = {
  32.     comments: [],
  33.     comment: "",
  34.     rate: 1,
  35.     disabled: true,
  36.     hasErrors: false,
  37.     loading: false,
  38.     message: "There is an issue to fetch data from server. Please try again later.",
  39.     info: false,
  40.     infoMessage: "The comment is added successfully",
  41.     modal: false,
  42.   };
  43.  
  44.   async componentDidMount() {
  45.     await this.onFetchComments();
  46.   }
  47.  
  48.   onFetchComments = async () => {
  49.     this.setState({loading: true});
  50.     try {
  51.       const commentApi = new CommentApi();
  52.       const data = await commentApi.getAllComments(this.props.match.params.imdbID);
  53.       if (!data.success) {
  54.         this.onShowErrorMessage();
  55.       } else {
  56.         this.setState({
  57.           comments: data.data,
  58.           loading: false,
  59.         });
  60.       }
  61.     } catch (err) {
  62.       console.log("onFetchComments err: ", err);
  63.       this.onShowErrorMessage();
  64.     }
  65.   };
  66.  
  67.   toggle = () => {
  68.     const {modal} = this.state;
  69.     this.setState({modal: !modal});
  70.   };
  71.  
  72.   onChange = e => {
  73.     this.setState({
  74.       [e.target.name]: e.target.value,
  75.       disabled: e.target.value === "",
  76.     });
  77.   };
  78.  
  79.   onSubmit = async () => {
  80.     const {comment, rate} = this.state;
  81.     if (comment === "") {
  82.       return;
  83.     }
  84.  
  85.     this.setState({loading: true, modal: false});
  86.     try {
  87.       const commentApi = new CommentApi();
  88.       const body = {
  89.         comment,
  90.         rate,
  91.         elementId: this.props.match.params.imdbID,
  92.       };
  93.       const data = await commentApi.addComment(body);
  94.       if (!data.success) {
  95.         this.onShowErrorMessage();
  96.       } else {
  97.         await this.onFetchComments();
  98.         this.setState({
  99.           comment: "",
  100.           disabled: true,
  101.           loading: false,
  102.           info: true,
  103.           infoMessage: "The comment is added successfully",
  104.         });
  105.         setTimeout(this.onClearMessage, 2000);
  106.       }
  107.     } catch (err) {
  108.       console.log("onSubmit err: ", err);
  109.       this.onShowErrorMessage();
  110.     }
  111.   };
  112.  
  113.   onShowErrorMessage = () => {
  114.     this.setState({hasErrors: true, loading: false});
  115.     setTimeout(this.onClearMessage, 5000);
  116.   };
  117.  
  118.   onClearMessage = () => {
  119.     this.setState({hasErrors: false, info: false});
  120.   };
  121.  
  122.   getReviewModal = () => {
  123.     const {modal, comment, rate} = this.state;
  124.     return (
  125.       <Modal isOpen={modal} toggle={this.toggle}>
  126.         <ModalHeader toggle={this.toggle}>Add Review</ModalHeader>
  127.         <ModalBody>
  128.           <FormGroup>
  129.             <Label for="comment">Comment</Label>
  130.             <Input
  131.               id="comment"
  132.               type="text"
  133.               name="comment"
  134.               placeholder="Type comment"
  135.               onChange={this.onChange}
  136.               value={comment}
  137.             />
  138.           </FormGroup>
  139.           <FormGroup>
  140.             <Label for="rate">Rate(Out of 5)</Label>
  141.             <Input
  142.               type="select"
  143.               name="rate"
  144.               value={rate}
  145.               onChange={this.onChange}
  146.               style={{width: 200}}
  147.             >
  148.               {ratings.map(rating => (
  149.                 // eslint-disable-next-line react/jsx-key
  150.                 <option>{rating}</option>
  151.               ))}
  152.             </Input>
  153.           </FormGroup>
  154.         </ModalBody>
  155.         <ModalFooter>
  156.           <Button color="primary" disabled={!rate || !comment} onClick={this.onSubmit}>
  157.             Submit
  158.           </Button>
  159.           <Button color="secondary" onClick={this.toggle}>
  160.             Cancel
  161.           </Button>
  162.         </ModalFooter>
  163.       </Modal>
  164.     );
  165.   };
  166.  
  167.   getAverageRating = () => {
  168.     const {comments} = this.state;
  169.  
  170.     let rating = 0;
  171.  
  172.     comments.length > 0 &&
  173.       comments.map(comment => {
  174.         rating += parseInt(comment.rate);
  175.       });
  176.     const averageRating = rating / comments.length;
  177.     return averageRating;
  178.   };
  179.  
  180.   render() {
  181.     const {data} = this.props.history.location.state;
  182.     const {comments, loading, hasErrors, message, info, infoMessage} = this.state;
  183.     if (!data) {
  184.       return null;
  185.     }
  186.     const reviewModal = this.getReviewModal();
  187.     const averageRating = this.getAverageRating();
  188.     return (
  189.       <Container className="detail-container">
  190.         {hasErrors && <Error message={message} />}
  191.         {loading && <Loading />}
  192.         <Card className="flex-row flex-wrap">
  193.           <CardHeader className="border-0 col-4 mt-4">
  194.             <CardImg className="movie-image" src={data.Poster} top />
  195.             <div className="rating mt-4">{averageRating ? averageRating.toFixed(1) : 0}</div>
  196.             <div className="text-primary" style={{fontSize: 30}}>
  197.               {comments.length} votes
  198.             </div>
  199.           </CardHeader>
  200.           <CardBody className="px-2 col-8">
  201.             <MovieDetails movieID={data.imdbID} />
  202.           </CardBody>
  203.           <CardFooter className="w-100">
  204.             <Button color="success" onClick={this.toggle}>
  205.               Review It
  206.             </Button>
  207.           </CardFooter>
  208.         </Card>
  209.         {reviewModal}
  210.         {info && <InfoMessage message={infoMessage} />}
  211.  
  212.         <CommentList
  213.           comments={comments}
  214.           onFetch={this.onFetchComments}
  215.           onShowErrorMessage={this.onShowErrorMessage}
  216.         />
  217.       </Container>
  218.     );
  219.   }
  220. }
  221.  
  222. DetailMovie.propTypes = {
  223.   history: PropTypes.any,
  224.   match: PropTypes.shape({
  225.     params: PropTypes.shape({
  226.       imdbID: PropTypes.string.isRequired,
  227.     }),
  228.   }),
  229. };
  230.  
  231. export default DetailMovie;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement