Merge pull request #46 from KevinMidboe/feat/history-page-by-date

Feat/history page by date
This commit is contained in:
2020-10-11 18:22:10 +02:00
committed by GitHub
4 changed files with 91 additions and 73 deletions

View File

@@ -6,53 +6,61 @@ const Wine = require(path.join(__dirname + '/../schemas/Wine'));
// Utils // Utils
const epochToDateString = date => new Date(parseInt(date)).toDateString(); const epochToDateString = date => new Date(parseInt(date)).toDateString();
const getHighscoreByDates = highscore => { const sortNewestFirst = (lotteries) => {
let groupedLotteries = {} return lotteries.sort((a, b) => parseInt(a.date) < parseInt(b.date) ? 1 : -1)
}
highscore.forEach(user => { const groupHighscoreByDate = async (highscore=undefined) => {
user.wins.map(win => { if (highscore == undefined)
highscore = await Highscore.find();
const highscoreByDate = [];
highscore.forEach(person => {
person.wins.map(win => {
const epochDate = new Date(win.date).setHours(0,0,0,0); const epochDate = new Date(win.date).setHours(0,0,0,0);
const obj = { const winnerObject = {
name: user.name, name: person.name,
color: win.color, color: win.color,
wine: win.wine, wine: win.wine,
date: epochDate date: epochDate
} }
groupedLotteries[epochDate] ? const existingDateIndex = highscoreByDate.findIndex(el => el.date == epochDate)
groupedLotteries[epochDate].push(obj) : groupedLotteries[epochDate] = [obj]; if (existingDateIndex > -1)
highscoreByDate[existingDateIndex].winners.push(winnerObject);
else
highscoreByDate.push({
date: epochDate,
winners: [winnerObject]
})
}) })
}) })
return groupedLotteries return sortNewestFirst(highscoreByDate);
} }
const groupedHighscoreToSortedList = groupedLotteries => { const resolveWineReferences = (highscoreObject, key) => {
return Object.keys(groupedLotteries).map(key => { const listWithWines = highscoreObject[key]
const winners = groupedLotteries[key];
return {
date: parseInt(key),
dateString: epochToDateString(key),
winners
}
}).sort((a,b) => parseInt(a.date) > parseInt(b.date) ? 1 : -1)
}
const resolveWineReferences = listWithWines => {
return Promise.all(listWithWines.map(element => return Promise.all(listWithWines.map(element =>
Wine.findById(element.wine) Wine.findById(element.wine)
.then(wine => { .then(wine => {
element.wine = wine element.wine = wine
return element return element
}) }))
)) )
.then(resolvedListWithWines => {
highscoreObject[key] = resolvedListWithWines;
return highscoreObject
})
} }
// end utils
// Routes // Routes
const all = (req, res) => { const all = (req, res) => {
return Highscore.find() return Highscore.find()
.then(highscore => getHighscoreByDates(highscore)) .then(highscore => groupHighscoreByDate(highscore))
.then(groupedLotteries => groupedHighscoreToSortedList(groupedLotteries))
.then(lotteries => res.send({ .then(lotteries => res.send({
message: "Lotteries by date!", message: "Lotteries by date!",
lotteries lotteries
@@ -60,61 +68,60 @@ const all = (req, res) => {
} }
const latest = (req, res) => { const latest = (req, res) => {
return Highscore.find() return groupHighscoreByDate()
.then(highscore => getHighscoreByDates(highscore)) .then(lotteries => lotteries.shift())
.then(groupedLotteries => groupedHighscoreToSortedList(groupedLotteries)) .then(latestLottery => resolveWineReferences(latestLottery, "winners"))
.then(lotteries => res.send({ .then(lottery => res.send({
message: "Latest lottery!", message: "Latest lottery!",
lottery: lotteries.slice(-1).pop() winners: lottery.winners
})) })
)
} }
const byEpochDate = (req, res) => { const byEpochDate = (req, res) => {
const { date } = req.params; let { date } = req.params;
date = new Date(new Date(parseInt(date)).setHours(0,0,0,0)).getTime()
const dateString = epochToDateString(date); const dateString = epochToDateString(date);
return Highscore.find() return groupHighscoreByDate()
.then(highscore => getHighscoreByDates(highscore)) .then(lotteries => {
.then(async (lotteries) => { const lottery = lotteries.filter(lottery => lottery.date == date)
const lottery = lotteries[date]; if (lottery.length > 0) {
let highscoreWithResolvedWines = await resolveWineReferences(lottery) return lottery[0]
highscoreWithResolvedWines = highscoreWithResolvedWines.reverse()
if (lottery != null) {
return res.send({
message: `Lottery for date: ${dateString}`,
lottery: highscoreWithResolvedWines
})
} else { } else {
return res.status(404).send({ return res.status(404).send({
message: `No lottery found for date: ${dateString}` message: `No lottery found for date: ${ dateString }`
}) })
} }
}) })
.then(lottery => resolveWineReferences(lottery, "winners"))
.then(lottery => res.send({
message: `Lottery for date: ${ dateString}`,
date,
winners: lottery.winners
}))
} }
const byName = (req, res) => { const byName = (req, res) => {
const { name } = req.params; const { name } = req.params;
const regexName = new RegExp(name, "i"); // lowercase regex of the name const regexName = new RegExp(name, "i"); // lowercase regex of the name
return Highscore.find({ "name": { $regex : regexName } }) return Highscore.find({ name })
.then(async (highscore) => { .then(highscore => {
highscore = highscore[0] if (highscore.length > 0) {
if (highscore) { return highscore[0]
let highscoreWithResolvedWines = await resolveWineReferences(highscore.wins)
highscoreWithResolvedWines = highscoreWithResolvedWines.reverse()
return res.send({
message: `Lottery winnings by name: ${name}`,
name: name,
highscore: highscoreWithResolvedWines
})
} else { } else {
return res.status(404).send({ return res.status(404).send({
message: `Name: ${ name } not found in leaderboards.` message: `Name: ${ name } not found in leaderboards.`
}) })
} }
}) })
.then(highscore => resolveWineReferences(highscore, "wins"))
.then(highscore => res.send({
message: `Lottery winnings for name: ${ name }.`,
name: highscore.name,
wins: highscore.wins
}))
} }
module.exports = { module.exports = {

View File

@@ -333,9 +333,8 @@ const historyAll = () => {
}); });
} }
const getWinnerByName = (name) => { const historyByDate = (date) => {
const encodedName = encodeURIComponent(name) const url = new URL(`/api/lottery/by-date/${ date }`, BASE_URL);
const url = new URL(`/api/lottery/by-name/${name}`, BASE_URL);
return fetch(url.href).then(resp => { return fetch(url.href).then(resp => {
if (resp.ok) { if (resp.ok) {
@@ -343,7 +342,7 @@ const getWinnerByName = (name) => {
} else { } else {
return handleErrors(resp); return handleErrors(resp);
} }
}) });
} }
export { export {
@@ -378,5 +377,5 @@ export {
getAmIWinner, getAmIWinner,
postWineChosen, postWineChosen,
historyAll, historyAll,
getWinnerByName historyByDate
}; };

View File

@@ -2,14 +2,15 @@
<div> <div>
<h1>Historie fra tidligere lotteri</h1> <h1>Historie fra tidligere lotteri</h1>
<div v-if="lotteries.length" v-for="lottery in lotteries"> <div v-if="lotteries.length || lotteries != null" v-for="lottery in lotteries">
<Winners :winners="lottery.winners" :title="`Vinnere fra ${lottery.dateString}`" /> <Winners :winners="lottery.winners" :title="`Vinnere fra ${ humanReadableDate(lottery.date) }`" />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { historyAll } from '@/api' import { historyByDate, historyAll } from '@/api'
import { humanReadableDate } from "@/utils";
import Winners from '@/ui/Winners' import Winners from '@/ui/Winners'
export default { export default {
@@ -20,9 +21,18 @@ export default {
lotteries: [], lotteries: [],
} }
}, },
methods: {
humanReadableDate: humanReadableDate
},
created() { created() {
historyAll() const dateFromUrl = this.$route.params.date;
.then(history => this.lotteries = history.lotteries.reverse())
if (dateFromUrl !== undefined)
historyByDate(dateFromUrl)
.then(history => this.lotteries = { "lottery": history })
else
historyAll()
.then(history => this.lotteries = history.lotteries)
} }
} }
</script> </script>

View File

@@ -2,8 +2,10 @@
<div> <div>
<h2 v-if="winners.length > 0"> {{ title ? title : 'Vinnere' }}</h2> <h2 v-if="winners.length > 0"> {{ title ? title : 'Vinnere' }}</h2>
<div class="winners" v-if="winners.length > 0"> <div class="winners" v-if="winners.length > 0">
<div class="winner" v-for="(winner, index) in winners" :key="index"> <div v-for="(winner, index) in winners" :key="index">
<div :class="winner.color + '-raffle'" class="ballot-element">{{ winner.name }}</div> <router-link :to="`/highscore/${ encodeURIComponent(winner.name) }`">
<div :class="winner.color + '-ballot'" class="ballot-element">{{ winner.name }}</div>
</router-link>
</div> </div>
</div> </div>
</div> </div>