import { UIEventSource } from "../../Logic/UIEventSource" import { Review } from "../../Logic/Web/Review" import Combine from "../Base/Combine" import Translations from "../i18n/Translations" import SingleReview from "./SingleReview" import BaseUIElement from "../BaseUIElement" import Img from "../Base/Img" import { VariableUiElement } from "../Base/VariableUIElement" import Link from "../Base/Link" /** * Shows the reviews and scoring base on mangrove.reviews * The middle element is some other component shown in the middle, e.g. the review input element */ export default class ReviewElement extends VariableUiElement { constructor(subject: string, reviews: UIEventSource, middleElement: BaseUIElement) { super( reviews.map((revs) => { const elements = [] revs.sort((a, b) => b.date.getTime() - a.date.getTime()) // Sort with most recent first const avg = revs.map((review) => review.rating).reduce((a, b) => a + b, 0) / revs.length elements.push( new Combine([ SingleReview.GenStars(avg), new Link( revs.length === 1 ? Translations.t.reviews.title_singular.Clone() : Translations.t.reviews.title.Subs({ count: "" + revs.length }), `https://mangrove.reviews/search?sub=${encodeURIComponent(subject)}`, true ), ]).SetClass("font-2xl flex justify-between items-center pl-2 pr-2") ) elements.push(middleElement) elements.push(...revs.map((review) => new SingleReview(review))) elements.push( new Combine([ Translations.t.reviews.attribution.Clone(), new Img("./assets/mangrove_logo.png"), ]).SetClass("review-attribution") ) return new Combine(elements).SetClass("block") }) ) } }