import * as React from "react" import styled, { css } from "styled-components" import breakpoint from "styled-components-breakpoint" import { RatingStarIndicator } from "../Book" import withTranslate from "jamplay-common/i18n/withTranslate" import gql from "graphql-tag" import { Header, HeaderSize } from "../Header" import { Textarea } from "../Textarea" import { RatingStarInput } from "./RatingStarInput" import { getConfig } from "jamplay-common/remote-config" import { Primary } from "../Button" // default constant const DEFAULT_MAX_REVIEW_CHARACTER_LENGTH = 200 // utility function calculateTotalCount(ratingInfo: RatingInfoData[]) { return ratingInfo.reduce((prev, current) => { return prev + current.count }, 0) } export function calculateRatingResult(ratingInfo: RatingInfoData[]) { // finding average of result const sum = ratingInfo.reduce((prev, current) => { return prev + current.count * current.rating }, 0) const totalCount = calculateTotalCount(ratingInfo) const result = sum / totalCount if (isNaN(result)) { return 0 } return Number(result.toFixed(2)) } export function calculatePercentPerBar(ratingInfo: RatingInfoData[]) { // calculate each bar percent const totalCount = calculateTotalCount(ratingInfo) return ratingInfo.map((item) => { let indicatorLevel = item.count / totalCount if (isNaN(indicatorLevel)) { indicatorLevel = 0 } return { ...item, indicatorLevel: Number(indicatorLevel.toFixed(2)) } }) } const ReviewSummaryMobileStyle = css`` const ReviewSummaryStyleContainer = styled.div.attrs({ className: "ReviewSummary" })` display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; .RatingStarIndicator--stars-container { margin: 0; } .ReviewSummary__rating-summary { display: flex; flex-direction: column; align-items: flex-start; .ReviewSummary__rating-statistic { display: flex; width: 100%; flex-direction: column; align-items: center; } } .ReviewSummary__rating-input--disabled { padding-top: 20px; white-space: pre-line; text-align: center; margin: 21px 0; font-weight: normal; color: #bbb; } .ReviewSummary__rating-input { padding-top: 20px; width: 100%; flex: 1 1 auto; text-align: center; .StarIndicator { justify-content: center; } } ${breakpoint("mobile", "tablet")`${ReviewSummaryMobileStyle}`}; h3, h4, .RatingStarContainer__label { white-space: nowrap; } .RatingStarContainer span { display: none; } .RatingStarIndicator--stars-container .jamplay-icon { font-size: 1.2rem; line-height: 1.2rem; } .ReviewSummary__star-input { margin: 13px 0; } .ReviewSummary__star-input .RatingStarIndicator--stars-container .jamplay-icon { font-size: 2rem; line-height: 2rem; } .ReviewSummary__rating-wrap { display: flex; padding: 0px 8px; line-height: 15px; } .ReviewSummary__rating-bar { height: 15px; width: 180px; position: relative; background-color: ${(props) => props.theme.borderGrey}; margin: 3px 5px; border-radius: 4px; box-sizing: border-box; overflow: hidden; margin-left: 3px; } .ReviewSummary__labels { min-width: 42px; } .ReviewSummary__rating-bar__indicator { position: absolute; left: 0%; top: 0%; height: 100%; background-color: ${(props) => props.theme.pumpkin}; } .ReviewSummary__confirm-review-button { margin-top: 10px; } ` // Review Component section export type ReviewValue = { content: string rating: number } export interface ReviewSummaryInputState { // Review Input value disabledReviewButton?: boolean isEdit?: boolean onReviewConfirm: (value: ReviewValue) => void onReviewChange: (value: ReviewValue) => void reviewValue: ReviewValue showReviewForm?: boolean disabledReviewFormReason?: string | null style?: any } export interface ReviewSummaryPropTypes { ref?: any bookRating: { eachCount: RatingInfoData[] count: number average: number } } type ReviewSummaryComponent = React.SFC< ReviewSummaryPropTypes & withTranslatePropType & ReviewSummaryInputState > & { fragments?: { bookRating: any } } export const ReviewSummary: ReviewSummaryComponent = (props) => { const result = calculateRatingResult(props.bookRating.eachCount) const total = calculateTotalCount(props.bookRating.eachCount) const bars = calculatePercentPerBar(props.bookRating.eachCount) let { t } = props if (!t) { t = (s) => s } const translate = t const onConfirmReviewClick = () => props.onReviewConfirm(props.reviewValue) const onStarChange = (starIndex) => props.onReviewChange({ ...props.reviewValue, rating: starIndex }) const onTextChange = (e) => props.onReviewChange({ ...props.reviewValue, content: e.target.value }) return (
{t("review/rating-header", { avg: (props.bookRating.average || 0).toFixed(2) })}
{translate("book/review-infomation-header", { count: props.bookRating.count })}
{bars.map((bar) => { return (
{translate("review/rating", { rating: bar.rating })}
{`(${bar.count})`}
) })}
{props.disabledReviewFormReason ? (
{translate(props.disabledReviewFormReason)}
) : (
{translate("review/rating-start-input-label")}