From d702e49bff5e907a426bcd5d8d88c0e3826c469c Mon Sep 17 00:00:00 2001 From: TTalex Date: Sat, 5 Oct 2024 20:17:38 +0200 Subject: [PATCH] feat(Challenge Page): added more content, and started split in components --- src/components/ChallengeExample.vue | 46 ++++++ src/components/ChallengeTimeline.vue | 58 +++++++ src/components/ChallengeTopContributors.vue | 38 +++++ src/views/CurrentChallenge.vue | 171 +++++++------------- 4 files changed, 202 insertions(+), 111 deletions(-) create mode 100644 src/components/ChallengeExample.vue create mode 100644 src/components/ChallengeTimeline.vue create mode 100644 src/components/ChallengeTopContributors.vue diff --git a/src/components/ChallengeExample.vue b/src/components/ChallengeExample.vue new file mode 100644 index 00000000000..c2af967a198 --- /dev/null +++ b/src/components/ChallengeExample.vue @@ -0,0 +1,46 @@ + + + + \ No newline at end of file diff --git a/src/components/ChallengeTimeline.vue b/src/components/ChallengeTimeline.vue new file mode 100644 index 00000000000..4260dc0e0a0 --- /dev/null +++ b/src/components/ChallengeTimeline.vue @@ -0,0 +1,58 @@ + + + + \ No newline at end of file diff --git a/src/components/ChallengeTopContributors.vue b/src/components/ChallengeTopContributors.vue new file mode 100644 index 00000000000..83d566821f1 --- /dev/null +++ b/src/components/ChallengeTopContributors.vue @@ -0,0 +1,38 @@ + + + + \ No newline at end of file diff --git a/src/views/CurrentChallenge.vue b/src/views/CurrentChallenge.vue index 970b2fe4093..a3ac93444cd 100644 --- a/src/views/CurrentChallenge.vue +++ b/src/views/CurrentChallenge.vue @@ -8,42 +8,34 @@ - - TODO: Explain the challenge, how to contribute etc.. - TODO: maybe add a place for proofs with missing prices (ideally proofs would be tagged for the challenge) - TODO: what about rewards ? badges for top 3 ? participation badges ? - TODO: Maybe a goal should be a number of product / prices, instead of the day + +
+

+ {{ challenge.icon }} Join other food price enthousiast (such as {{ challenge.topContributors[0]?.user_id || "you?" }}) in gathering information about {{ challenge.title }} {{ challenge.subtitle }}. +

+

+ {{ challenge.icon }} Your goal is to go nearby stores, find corresponding products and + + adding prices + +

+

+ {{ challenge.icon }} This challenge categories are + + {{ category }} + +

+
- - - -
- Start -
- -
- - - {{ challenge.end_date }} - -
- - {{ days_left_text }} - + +
+ + + + +

@@ -52,10 +44,10 @@ - + - + @@ -66,10 +58,10 @@

- + - +
@@ -77,55 +69,22 @@ - - - - - - - - {{ i+1 }}. {{ contributor.user_id }}, {{ contributor.price_count }} prices - - - - - + - - - - - - + +

+ Number of contributions per day +

+

Most recent contributions

- - + + @@ -142,7 +101,10 @@ export default { components: { StatCard: defineAsyncComponent(() => import('../components/StatCard.vue')), PriceCard: defineAsyncComponent(() => import('../components/PriceCard.vue')), - PriceChart: defineAsyncComponent(() => import('../components/PriceChart.vue')) + PriceChart: defineAsyncComponent(() => import('../components/PriceChart.vue')), + ChallengeTimeline: defineAsyncComponent(() => import('../components/ChallengeTimeline.vue')), + ChallengeExample: defineAsyncComponent(() => import('../components/ChallengeExample.vue')), + ChallengeTopContributors: defineAsyncComponent(() => import('../components/ChallengeTopContributors.vue')), }, data() { return { @@ -150,15 +112,16 @@ export default { title: "MILK", subtitle: "(and milk alternatives)", icon: "🥛", - start_date: "2024-09-01", - end_date: "2024-10-31", + startDate: "2024-09-01", + endDate: "2024-10-31", categories: ["en:milk-substitutes", "en:milks"], - top_contributors: [], - number_of_contributors: 0, - number_of_contributions: 0, - latest_contributions: [], - user_contributions: 0, - user_rank: 0 + topContributors: [], + numberOfContributors: 0, + numberOfContributions: 0, + latestContributions: [], + userContributions: 0, + userRank: 0, + exampleId: 32900 }, loading: false, } @@ -168,21 +131,6 @@ export default { username() { return this.appStore.user.username }, - nb_days() { - return Math.round((new Date(this.challenge.end_date) - new Date(this.challenge.start_date)) / (1000 * 60 * 60 * 24)) - }, - today_index() { - return Math.round((new Date() - new Date(this.challenge.start_date)) / (1000 * 60 * 60 * 24)) - }, - days_left_text() { - const days_left = this.nb_days - this.today_index - if (days_left <= 0) return "Challenge over" - if (days_left >= this.nb_days) return "Not started" - return `${days_left} days left` - }, - progress() { - return Math.min(100, this.today_index * 100 / this.nb_days) - } }, mounted() { this.getStats() @@ -191,36 +139,37 @@ export default { getStats() { this.loading = true // TODO: This should fetch only prices matching one of the product categories in this.challenge.categories - api.getPrices({ size: 100, created__gte: this.challenge.start_date, created__lte: this.challenge.end_date }) + // TODO: Also, this is both used to show a few recent contribution and to display the number of contributions per day + // The first requires only a size of 10, the second requires the entire data, so it probably should be another API point + api.getPrices({ size: 200, created__gte: this.challenge.startDate, created__lte: this.challenge.endDate }) .then((data) => { - this.challenge.latest_contributions = data.items - this.challenge.number_of_contributions = data.total + this.challenge.latestContributions = data.items + this.challenge.numberOfContributions = data.total this.loading = false }) // TODO: this should only fetch users that contributed to one of the product categories in this.challenge.categories, in the designated time range api.getUsers({ order_by: constants.USER_ORDER_LIST[0].key, size: 50}) .then((data) => { - this.challenge.top_contributors = data.items - this.challenge.number_of_contributors = data.total + this.challenge.topContributors = data.items + this.challenge.numberOfContributors = data.total for (let i = 0; i < data.items.length; i++) { const user = data.items[i] if (this.username && this.username == user.user_id) { - this.challenge.user_rank = i + this.challenge.userRank = i break } } }) if (this.username) { // TODO: This should fetch only prices matching one of the product categories in this.challenge.categories - api.getPrices({ owner: this.username, created__gte: this.challenge.start_date, created__lte: this.challenge.end_date }) + api.getPrices({ owner: this.username, created__gte: this.challenge.startDate, created__lte: this.challenge.endDate }) .then((data) => { - this.challenge.user_contributions = data.total + this.challenge.userContributions = data.total }) } } - } }