Merge pull request #18 from KevinMidboe/feat/lottery-endpoint
Feat/lottery endpoint
This commit is contained in:
118
api/lottery.js
Normal file
118
api/lottery.js
Normal 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;
|
||||||
@@ -15,6 +15,7 @@ const virtualApi = require(path.join(__dirname + "/api/virtualLottery"));
|
|||||||
const virtualRegistrationApi = require(path.join(
|
const virtualRegistrationApi = require(path.join(
|
||||||
__dirname + "/api/virtualRegistration"
|
__dirname + "/api/virtualRegistration"
|
||||||
));
|
));
|
||||||
|
const lottery = require(path.join(__dirname + "/api/lottery"));
|
||||||
|
|
||||||
//This is required for the chat to work
|
//This is required for the chat to work
|
||||||
const chat = require(path.join(__dirname + "/api/chat"))(io);
|
const chat = require(path.join(__dirname + "/api/chat"))(io);
|
||||||
@@ -94,6 +95,7 @@ app.use("/api/", updateApi);
|
|||||||
app.use("/api/", retrieveApi);
|
app.use("/api/", retrieveApi);
|
||||||
app.use("/api/", wineinfoApi);
|
app.use("/api/", wineinfoApi);
|
||||||
app.use("/api/", chatHistory);
|
app.use("/api/", chatHistory);
|
||||||
|
app.use("/api/lottery", lottery);
|
||||||
app.use("/api/virtual/", virtualApi(io));
|
app.use("/api/virtual/", virtualApi(io));
|
||||||
app.use("/api/virtual-registration/", virtualRegistrationApi);
|
app.use("/api/virtual-registration/", virtualRegistrationApi);
|
||||||
app.use("/subscription", subscriptionApi);
|
app.use("/subscription", subscriptionApi);
|
||||||
|
|||||||
15
src/api.js
15
src/api.js
@@ -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 {
|
export {
|
||||||
statistics,
|
statistics,
|
||||||
colorStatistics,
|
colorStatistics,
|
||||||
@@ -270,5 +282,6 @@ export {
|
|||||||
getChatHistory,
|
getChatHistory,
|
||||||
finishedDraw,
|
finishedDraw,
|
||||||
getAmIWinner,
|
getAmIWinner,
|
||||||
postWineChosen
|
postWineChosen,
|
||||||
|
historyAll
|
||||||
};
|
};
|
||||||
|
|||||||
34
src/components/HistoryPage.vue
Normal file
34
src/components/HistoryPage.vue
Normal 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>
|
||||||
@@ -10,6 +10,7 @@ import AdminPage from "@/components/AdminPage";
|
|||||||
|
|
||||||
import WinnerPage from "@/components/WinnerPage";
|
import WinnerPage from "@/components/WinnerPage";
|
||||||
import LotteryPage from "@/components/LotteryPage";
|
import LotteryPage from "@/components/LotteryPage";
|
||||||
|
import HistoryPage from "@/components/HistoryPage";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@@ -47,6 +48,10 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "/winner/:id",
|
path: "/winner/:id",
|
||||||
component: WinnerPage
|
component: WinnerPage
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/history",
|
||||||
|
component: HistoryPage
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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="winners" v-if="winners.length > 0">
|
||||||
<div class="winner" v-for="(winner, index) in winners" :key="index">
|
<div class="winner" v-for="(winner, index) in winners" :key="index">
|
||||||
<div :class="winner.color + '-ballot'" class="ballot-element">{{ winner.name }}</div>
|
<div :class="winner.color + '-ballot'" class="ballot-element">{{ winner.name }}</div>
|
||||||
@@ -14,6 +14,10 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
winners: {
|
winners: {
|
||||||
type: Array
|
type: Array
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user