Feat/lottery endpoint #18

Merged
KevinMidboe merged 8 commits from feat/lottery-endpoint into master 2020-08-14 14:56:48 +00:00
6 changed files with 178 additions and 2 deletions

118
api/lottery.js Normal file
View File

@@ -0,0 +1,118 @@
const express = require('express');
const path = require('path');
const router = express.Router();
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/vinlottis', {
useNewUrlParser: true
})
const mustBeAuthenticated = require(path.join(
__dirname + '/../middleware/mustBeAuthenticated'
));
const config = require(path.join(__dirname + '/../config/defaults/lottery'));
const Highscore = require(path.join(__dirname + '/../schemas/Highscore'));
const Wine = require(path.join(__dirname + '/../schemas/Wine'));
// Utils
const epochToDateString = date => new Date(parseInt(date)).toDateString();
const getHighscoreByDates = highscore => {
let groupedLotteries = {}
highscore.forEach(user => {
user.wins.map(win => {
const epochDate = new Date(win.date).setHours(0,0,0,0);
const obj = {
name: user.name,
color: win.color,
wine: win.wine,
date: epochDate
}
groupedLotteries[epochDate] ?
groupedLotteries[epochDate].push(obj) : groupedLotteries[epochDate] = [obj];
})
})
return groupedLotteries
}
const groupedHighscoreToSortedList = groupedLotteries => {
return Object.keys(groupedLotteries).map(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 =>
Wine.findById(element.wine)
.then(wine => {
element.wine = wine
return element
})
))
}
// Routes
router.route('/all').get((req, res) => {
return Highscore.find()
.then(highscore => getHighscoreByDates(highscore))
.then(groupedLotteries => groupedHighscoreToSortedList(groupedLotteries))
.then(lotteries => res.send({
message: "Lotteries by date!",
lotteries
}))
})
router.route('/by-date/:date').get((req, res) => {
const { date } = req.params;
const dateString = epochToDateString(date);
return Highscore.find()
.then(highscore => getHighscoreByDates(highscore))
.then(async (lotteries) => {
const lottery = lotteries[date];
if (lottery != null) {
return res.send({
message: `Lottery for date: ${dateString}`,
lottery: await resolveWineReferences(lottery)
})
} else {
return res.status(404).send({
message: `No lottery found for date: ${dateString}`
})
}
})
})
router.route("/by-name").get((req, res) => {
const { name } = req.query;
return Highscore.find({ name })
.then(async (highscore) => {
highscore = highscore[0]
if (highscore) {
const highscoreWithResolvedWines = await resolveWineReferences(highscore.wins)
return res.send({
message: `Lottery winnings by name: ${name}`,
highscore: highscoreWithResolvedWines
})
} else {
return res.status(404).send({
message: `Name: ${ name } not found in leaderboards.`
})
}
})
})
module.exports = router;

View File

@@ -15,6 +15,7 @@ const virtualApi = require(path.join(__dirname + "/api/virtualLottery"));
const virtualRegistrationApi = require(path.join(
__dirname + "/api/virtualRegistration"
));
const lottery = require(path.join(__dirname + "/api/lottery"));
//This is required for the chat to work
const chat = require(path.join(__dirname + "/api/chat"))(io);
@@ -94,6 +95,7 @@ app.use("/api/", updateApi);
app.use("/api/", retrieveApi);
app.use("/api/", wineinfoApi);
app.use("/api/", chatHistory);
app.use("/api/lottery", lottery);
app.use("/api/virtual/", virtualApi(io));
app.use("/api/virtual-registration/", virtualRegistrationApi);
app.use("/subscription", subscriptionApi);

View File

@@ -245,6 +245,18 @@ const postWineChosen = (id, wineName) => {
});
};
const historyAll = () => {
const url = new URL(`/api/lottery/all`, BASE_URL);
return fetch(url.href).then(resp => {
if (resp.ok) {
return resp.json();
} else {
return handleErrors(resp);
}
});
}
export {
statistics,
colorStatistics,
@@ -270,5 +282,6 @@ export {
getChatHistory,
finishedDraw,
getAmIWinner,
postWineChosen
postWineChosen,
historyAll
};

View File

@@ -0,0 +1,34 @@
<template>
<div>
<h1>Historie fra tidligere lotteri</h1>
<div v-if="lotteries.length" v-for="lottery in lotteries">
<Winners :winners="lottery.winners" :title="`Vinnere fra ${lottery.dateString}`" />
</div>
</div>
</template>
<script>
import { historyAll } from '@/api'
import Winners from '@/ui/Winners'
export default {
name: 'History page of prev lotteries',
components: { Winners },
data() {
return {
lotteries: [],
}
},
created() {
historyAll()
.then(history => this.lotteries = history.lotteries.reverse())
}
}
</script>
<style lang="scss" scoped>
h1 {
text-align: center;
}
</style>

View File

@@ -10,6 +10,7 @@ import AdminPage from "@/components/AdminPage";
import WinnerPage from "@/components/WinnerPage";
import LotteryPage from "@/components/LotteryPage";
import HistoryPage from "@/components/HistoryPage";
const routes = [
{
@@ -47,6 +48,10 @@ const routes = [
{
path: "/winner/:id",
component: WinnerPage
},
{
path: "/history",
component: HistoryPage
}
];

View File

@@ -1,6 +1,6 @@
<template>
<div>
<h2 v-if="winners.length > 0">Vinnere</h2>
<h2 v-if="winners.length > 0"> {{ title ? title : 'Vinnere' }}</h2>
<div class="winners" v-if="winners.length > 0">
<div class="winner" v-for="(winner, index) in winners" :key="index">
<div :class="winner.color + '-ballot'" class="ballot-element">{{ winner.name }}</div>
@@ -14,6 +14,10 @@ export default {
props: {
winners: {
type: Array
},
title: {
type: String,
required: false
}
}
};