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 } }