diff --git a/AllTranslationAssets.ts b/AllTranslationAssets.ts index bd826a6b3..78242e79c 100644 --- a/AllTranslationAssets.ts +++ b/AllTranslationAssets.ts @@ -124,7 +124,8 @@ export default class AllTranslationAssets { loginNeeded: new Translation( {"en":"

Log in

A personal layout is only available for OpenStreetMap users","es":"

Entrar

El diseño personalizado sólo está disponible para los usuarios de OpenstreetMap","ca":"

Entrar

El disseny personalizat només està disponible pels usuaris d' OpenstreetMap","gl":"

Iniciar a sesión

O deseño personalizado só está dispoñíbel para os usuarios do OpenstreetMap","de":"

Anmelden

Ein persönliches Layout ist nur für OpenStreetMap-Benutzer verfügbar"} ), reload: new Translation( {"en":"Reload the data","es":"Recargar datos","ca":"Recarregar dades","gl":"Recargar os datos","de":"Daten neu laden"} ), }, - reviews: { title: new Translation( {"en":"Reviews","nl":"Beoordelingen"} ), - attribution: new Translation( {"en":"Reviews are powered by Mangrove Reviews and are available under CC-BY 4.0"} ), + reviews: { title: new Translation( {"en":"{count} reviews","nl":"{count} beoordelingen"} ), + no_reviews_yet: new Translation( {"en":"There are no reviews yet. Be the first to write one and help open data and the business!","nl":"Er zijn nog geen beoordelingen. Wees de eerste om een beoordeling te schrijven en help open data en het bedrijf"} ), + attribution: new Translation( {"en":"Reviews are powered by Mangrove Reviews and are available under CC-BY 4.0","nl":"De beoordelingen worden voorzien door Mangrove Reviews en zijn beschikbaar onder deCC-BY 4.0-licentie "} ), }, }} \ No newline at end of file diff --git a/Logic/Web/MangroveReviews.ts b/Logic/Web/MangroveReviews.ts index 1d8f45b32..80b6a4449 100644 --- a/Logic/Web/MangroveReviews.ts +++ b/Logic/Web/MangroveReviews.ts @@ -30,7 +30,33 @@ export default class MangroveReviews { mangrove.getReviews({sub: uri}).then( (data) => { - const reviews = []; + const reviews = [{ + date: new Date(), + comment: "Short", + rating: 1, + author: "Troll" + },{ + date: new Date(), + comment: "Not good", + rating: 10, + author: "Troll" + },{ + date: new Date(), + comment: "Not soo good", + rating: 20, + author: "Troll" + },{ + date: new Date(), + comment: "Meh", + rating: 30, + author: "Troll" + }, + { + date: new Date(), + comment: "Lorum ipsum lorem qsmldkfj qsdfmqmsd qmlsdmlkjazmeliq dmqlsdkf amldkfjqmlskdbmaize qsmdl fka mqlsnkd azie qmxbilqmslef amlzdf qsmdlfk afdml kqbnqsdlkf m", + rating: 50, + author: "Troll" + }]; for (const review of data.reviews) { const r = review.payload; reviews.push({ diff --git a/UI/ReviewElement.ts b/UI/ReviewElement.ts index 858c23911..c908cbe33 100644 --- a/UI/ReviewElement.ts +++ b/UI/ReviewElement.ts @@ -23,30 +23,43 @@ export default class ReviewElement extends UIElement { InnerRender(): string { + function genStars(rating: number) { + const scoreTen = Math.round(rating / 10); + return new Combine([ + "".repeat(Math.floor(scoreTen / 2)), + scoreTen % 2 == 1 ? "" : "" + ]) + } + const elements = []; + const revs = this._reviews.data; + 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([ + genStars(avg).SetClass("stars"), + Translations.t.reviews.title + .Subs({count: "" + revs.length}) + ]) - elements.push(Translations.t.reviews.title.SetClass("review-title")); + .SetClass("review-title")); - elements.push(...this._reviews.data.map(review => { - const stars = Math.round(review.rating / 10) - const fullStars = Math.floor(stars / 2); + elements.push(...revs.map(review => { const d = review.date; - return new Combine( [ new Combine([ + genStars(review.rating) + .SetClass("review-rating"), + new FixedUiElement(review.comment).SetClass("review-comment") + ]).SetClass("review-stars-comment"), - new Combine([ - "".repeat(fullStars), - stars % 2 == 1 ? "" : "" - ]).SetClass("review-rating"), + new Combine([ + + new FixedUiElement(review.author).SetClass("review-author"), new FixedUiElement(`${d.getFullYear()}-${Utils.TwoDigits(d.getMonth() + 1)}-${Utils.TwoDigits(d.getDate())} ${Utils.TwoDigits(d.getHours())}:${Utils.TwoDigits(d.getMinutes())}`) - .SetClass("review-date"), - ]).SetClass("review-stars-date"), - - new FixedUiElement(review.comment).SetClass("review-comment"), - "
", - new FixedUiElement(review.author).SetClass("review-author"), + .SetClass("review-date") + ]).SetClass("review-author-date") ] ).SetClass("review-element") diff --git a/assets/translations.json b/assets/translations.json index ae6b47d90..779aa056e 100644 --- a/assets/translations.json +++ b/assets/translations.json @@ -910,8 +910,8 @@ }, "reviews": { "title": { - "en": "Reviews", - "nl": "Beoordelingen" + "en": "{count} reviews", + "nl": "{count} beoordelingen" }, "no_reviews_yet": { "en": "There are no reviews yet. Be the first to write one and help open data and the business!", diff --git a/css/ReviewElement.css b/css/ReviewElement.css index 9389fc57c..4d2a1dda8 100644 --- a/css/ReviewElement.css +++ b/css/ReviewElement.css @@ -1,3 +1,18 @@ +.review-title { + font-size: x-large; + display: flex; + justify-content: space-between; + align-items: center; + padding-left: 1em; + padding-right: 1em; +} + +.review-title img { + max-width: 1.5em; + height: 1.5em; +} + + .review-rating img { max-width: 1em; height: 1em; @@ -6,24 +21,34 @@ .review-rating { display: flex; flex-direction: row; + width: 5em; + margin-right: 0.5em; + flex-shrink: 0; } .review-date { color: var(--subtle-detail-color-light-contrast); } -.review-stars-date { +.review-stars-comment { display: flex; - justify-content: space-between; margin-bottom: 0.5em; } + + .review-author { font-weight: bold; + margin-right: 0.5em; +} + +.review-author-date { display: flex; + margin-bottom: 0.5em; justify-content: flex-end; } + .review-element { padding: 1em; margin: 0.5em; @@ -51,6 +76,3 @@ margin-left: 0.5em; } -.review-title { - font-size: x-large; -} \ No newline at end of file