import gql from "graphql-tag" import * as React from "react" import styled from "styled-components" import withTranslate from "jamplay-common/i18n/withTranslate" import breakpoint from "styled-components-breakpoint" import ReviewSlider from "./ReviewSlider.component" import { getConfig } from "jamplay-common/remote-config" const DecoratorArtwork = ({ t }) => (
{t("book/reviews")}
{t("book-review/from-reader")}
) const Provider = styled.div` background-color: #fafafa; .wrapper { max-width: 1174px; margin: 0 auto; box-sizing: border-box; position: relative; ${breakpoint("mobile", "tablet")` padding: 10px 0 0 0;`} ${breakpoint("desktop")` padding: 34px 0 18px 0;`} @media screen and (max-width: 600px) { } /* Decorator artwork style */ .image-container { right: 13px; bottom: -30px; position: absolute; width: 320px; height: 350px; pointer-events: none; ${breakpoint( "tablet")` bottom: -12px; width: 275px; right: 10px; height: 290px; `} } .message-title { position: absolute; top: 24px; right: 116px; color: white; font-weight: bold; font-size: 16px; line-height: 23px; ${breakpoint( "tablet")` top: 20px; right: 97px; `} } .message-title-big { font-size: 30px; } .image-highlight { display: block; width: 100%; } @media screen and (max-width: 600px) { .image-container { bottom: -15px; right: 8px; width: 160px; height: 175px; } .message-title { top: 10px; right: 59px; font-size: 0.5rem; line-height: 10px; } .message-title-big { font-size: 0.8rem; } } } ` as any interface BookReviewPropTypes { Link?: any style?: any className?: string review: Array<{ node: BookReviewItemData }> bookId: string onWriteReviewClick?: () => void } export class BookHighlighReview extends React.Component< BookReviewPropTypes & withTranslatePropType, { width: number } > { public static fragments = { review: gql` fragment BookHighlighReview__BookReview on BookReview { rating review _id updatedAt createdAt user { _id name profilePicture } } ` } constructor(props) { super(props) this.state = { // no width on server side width: 0 } } /** * This function grouping review * and return array of review group * default is 3 * */ public static groupReviewsPerPage( items: Array<{ node: BookReviewItemData }>, NUMBER_OF_REVIEW_PER_PAGE: number = 3 ) { return items .reduce( (p: any[], c, index) => { if (p[p.length - 1].length >= NUMBER_OF_REVIEW_PER_PAGE) { p.push([]) } p[p.length - 1].push(c) return p }, [[]] ) .filter((page) => page.length > 0) } /** * Carousel show Item per page * in responsive way * - desktop, tablet : 3 * - mobile : 1 */ public onResize = () => { this.setState({ width: window.innerWidth }) } public observeWindowSize = (isCancel?: boolean) => { if (isCancel) { window.removeEventListener("resize", this.onResize) return } window.addEventListener("resize", this.onResize) } public componentDidMount() { // subscribe to window resize // to update state and re group // review item per page this.setState({ width: window.innerWidth }) this.observeWindowSize() } public componentWillUnmount() { // remove window resize listener // before component unmount this.observeWindowSize(true) } public render() { if (!this.state.width) { // will not render anything on server side return
} let { t } = this.props if (!t) { t = (s) => s } // group review item to paginated carousel item // and under 1174px will display only 1 item per page let itemPagePage = 3 if (this.state.width > 1174) { itemPagePage = 3 } else if (this.state.width > 1024) { itemPagePage = 2 } else { itemPagePage = 1 } const reviewGroupAsPage = BookHighlighReview.groupReviewsPerPage( // migrate field id to _id // to backwar compatible will // find every id field to change to // _id this.props.review.map(({ node }) => { const review = node as any const r = { ...review, _id: review.id || review._id, user: { ...review.user, _id: review.user.id || review.user._id } } return { node: { ...node, ...r } } }), itemPagePage ) return (
{reviewGroupAsPage.length > 0 ? : null}
) } } export default withTranslate(BookHighlighReview) as React.SFC< BookReviewPropTypes > & { fragments: { review: any } }