Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit

Permalink
Connect roulette to backend (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruioliveira02 authored Feb 12, 2022
1 parent 08ec994 commit 16ae2c3
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 63 deletions.
Empty file modified .husky/pre-commit
100644 → 100755
Empty file.
15 changes: 15 additions & 0 deletions components/Auth/AuthProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ export function AuthProvider({ children }) {
.finally(() => setFirstLoading(false));
}, [token]);

function refreshUser() {
api
.getCurrentUser()
.then((response) => {
setUser(response);
})
.catch((_errors) => {
// It means the jwt is expired
localStorage.clear();
delete API.defaults.headers.common["Authorization"];
setUser(null);
});
}

function login({ email, password }) {
setLoading(true);

Expand Down Expand Up @@ -109,6 +123,7 @@ export function AuthProvider({ children }) {
login,
logout,
editUser,
refreshUser,
}),
// eslint-disable-next-line
[user, isAuthenticated, isLoading, errors]
Expand Down
10 changes: 5 additions & 5 deletions components/moonstone/user/wheel/Wheel/index.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { getRouteMatcher } from "next/dist/shared/lib/router/utils";

function toHex(number) {
var res = number.toString(16);
res = res.length == 1 ? "0" + res : res;
Expand All @@ -12,7 +10,7 @@ export default function Wheel({ steps, angle }) {
for (var i = 0; i < steps; i++) {
colors.push((255.0 * i) / (steps - 1));
}
const percentage = 100 / steps + "%";

colors = colors.map((entry) => "#36DBEE" + toHex(entry));

const styleGlobal = {
Expand Down Expand Up @@ -42,10 +40,12 @@ export default function Wheel({ steps, angle }) {

return <div key={entry} style={st}></div>;
});

return (
<div className="relative h-full w-full">
<div className="h-full w-full rounded-full" style={styleGlobal}>
<div
className="h-full w-full rounded-full bg-quinary"
style={styleGlobal}
>
{borders}
</div>
<div className="absolute top-1/2 left-1/2 -ml-6 -mt-6 h-full w-full font-iregular text-5xl text-tertiary">
Expand Down
32 changes: 32 additions & 0 deletions components/moonstone/user/wheel/WheelMessage/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Dialog } from "@headlessui/react";
import { useRouter } from "next/router";

export default function WheelMessage({ title, description, onExit }) {
const router = useRouter();
return (
<>
<div className="fixed inset-0 z-30 h-full w-screen bg-white opacity-70"></div>
<Dialog
open={true}
className="fixed top-1/2 left-1/2 z-50 -translate-y-2/4 -translate-x-2/4 overflow-y-auto rounded-3xl border-8 border-secondary p-10 px-12"
onClose={(_) => {}}
>
<Dialog.Overlay />

<Dialog.Title className="font-iextrabold text-6xl text-primary">
{title}
</Dialog.Title>
<Dialog.Description className="mt-10 font-iregular text-lg">
{description}
</Dialog.Description>

<button
className="mt-10 h-12 w-28 rounded-full bg-quinary font-ibold text-lg"
onClick={(e) => onExit(e)}
>
OK
</button>
</Dialog>
</>
);
}
16 changes: 16 additions & 0 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,24 @@ export async function getAttendee(id) {
return response.data;
}

export async function getWheelPrizes() {
const response = await API.get("/api/v1/roulette/prizes");

return response.data;
}

export async function getAllBadges() {
const response = await API.get("/api/v1/badges");
}

export async function getWheelLatestWins() {
const response = await API.get("/api/v1/roulette/latestwins");

return response.data;
}

export async function spinWheel() {
const response = await API.post("/api/v1/roulette");

return response.data;
}
Expand Down
200 changes: 142 additions & 58 deletions pages/attendee/wheel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
import { withAuth } from "/components/Auth";
import { withAuth, useAuth } from "/components/Auth";

import Heading from "/components/moonstone/utils/Heading";

Expand All @@ -8,16 +8,123 @@ import Dashboard from "/components/moonstone/user/utils/Dashboard";
import ListItem3 from "/components/moonstone/user/wheel/ListItem3Cols";
import ListItem4 from "/components/moonstone/user/wheel/ListItem4Cols";
import Wheel from "/components/moonstone/user/wheel/Wheel";
import WheelMessage from "/components/moonstone/user/wheel/WheelMessage";
import ErrorMessage from "/components/utils/ErrorMessage";

import { getWheelPrizes, getWheelLatestWins, spinWheel } from "/lib/api";

/*
Gets how long ago the given date/time was in a user friendly way (10 seconds ago, 1 minute ago, etc)
*/
function displayTimeSince(dateString) {
const date = Date.parse(dateString);
const now = new Date();

const differenceMiliSeconds = now - date;

if (differenceMiliSeconds <= 60 * 1000)
return `${Math.round(differenceMiliSeconds / 1000)} seconds ago`;
if (differenceMiliSeconds <= 60 * 60 * 1000)
return `${Math.round(differenceMiliSeconds / (60 * 1000))} minutes ago`;
if (differenceMiliSeconds <= 24 * 60 * 60 * 1000)
return `${Math.round(differenceMiliSeconds / (60 * 60 * 1000))} hours ago`;

return `${Math.round(
differenceMiliSeconds / (24 * 60 * 60 * 1000)
)} days ago`;
}

function WheelPage() {
const defaultState = {
angle: 0,
speed: 0,
};
const angleSpeed = 20;
const fps = 60;
const [st, updateState] = useState(defaultState);

const { user, refreshUser } = useAuth();

const [prizes, updatePrizes] = useState([]);
const [latestWins, updateLatestWins] = useState([]);
const [error, updateError] = useState(false);
const [wheelMessage, updateWheelMessage] = useState(<></>);

const requestAllInfo = () => {
getWheelPrizes()
.then((response) => updatePrizes(response.data))
.catch((_) => updateError(true));

getWheelLatestWins()
.then((response) => updateLatestWins(response.data))
.catch((_) => updateError(true));
};

useEffect(requestAllInfo, []);

const spinTheWheel = () => {
updateState({ angle: 0, speed: angleSpeed });
spinWheel()
.then((response) => {
if (response.tokens) {
updateWheelMessage(
<WheelMessage
title="You won tokens!"
description={`Congratulations! You won ${response.tokens} tokens!`}
onExit={(_) => updateWheelMessage(null)}
/>
);
} else if (response.badge) {
updateWheelMessage(
<WheelMessage
title="You won a badge!"
description={`Congratulations! You won the ${response.badge.name} badge. Go check it out in the badgedex tab.`}
onExit={(_) => updateWheelMessage(null)}
/>
);
} else if (response.entries) {
updateWheelMessage(
<WheelMessage
title="You won entries to the final draw!"
description={`Congratulations! You won ${response.entries} entries for the final draw!`}
onExit={(_) => updateWheelMessage(null)}
/>
);
} else if (response.prize.name == "Nada") {
updateWheelMessage(
<WheelMessage
title="You din't win anything!"
description="Better luck next time."
onExit={(_) => updateWheelMessage(null)}
/>
);
} else {
//TODO:: CHANGE THIS MESSAGE
updateWheelMessage(
<WheelMessage
title={`You won a ${response.prize.name}!`}
description={`Congratulations! You won a ${response.prize.name}!`}
onExit={(_) => updateWheelMessage(null)}
/>
);
}
})
.catch((_) => {
wheelMessage = (
<WheelMessage
title="You don't have tokens!"
description="You do not have enough tokens to spin the wheel."
onExit={(_) => updateWheelMessage(null)}
/>
);
})
.finally((_) => {
requestAllInfo();
refreshUser();
});
};

const changeState = () => {
updateState({
angle: (st.angle + st.speed) % 360,
Expand All @@ -27,10 +134,27 @@ function WheelPage() {

//Rotate at 60fps
useEffect(() => {
console.log(st.angle);
if (st.speed > 0) setTimeout(changeState, 1000 / 60);
}, [st]);

const prizeComponents = prizes.map((entry, id) => (
<ListItem4
prob="2.00%"
key={id}
name={entry.name}
qnty={entry.stock}
maxQnty={entry.max_amount_per_attendee}
/>
));
const latestWinsComponents = latestWins.map((entry, id) => (
<ListItem3
key={id}
user={entry.attendee_name}
badge={entry.prize.name}
when={displayTimeSince(entry.date)}
isLast={id == latestWins.length - 1}
/>
));
return (
<Dashboard
href="wheel"
Expand All @@ -41,10 +165,14 @@ function WheelPage() {
<div className="col-span-1 float-left h-full w-full 2xl:w-1/2">
<Heading text="Achievements">
<div className="h-full w-40 pt-1">
<div className="col-span-1 float-left w-full">💰170 Tokens</div>
<div className="col-span-1 float-left w-full">
💰{user.token_balance} Tokens
</div>
</div>
<div className="h-full w-40 pt-1">
<div className="col-span-1 float-left w-full">🏅68 Badges</div>
<div className="col-span-1 float-left w-full">
🏅{user.badge_count} Badges
</div>
</div>
</Heading>
<div className="mb-10">
Expand All @@ -53,34 +181,24 @@ function WheelPage() {
</div>
<button
className="m-auto mt-10 block h-20 w-64 rounded-full bg-quinary"
onClick={(e) => updateState({ angle: 0, speed: angleSpeed })}
onClick={(e) => {
spinTheWheel();
}}
>
<p className="font-ibold font-bold">SPIN THE WHEEL</p>
<p className="font-iregular">15 tokens💰</p>
<p className="font-iregular">20 tokens💰</p>
</button>
</div>
</div>

<div className="col-span-1 float-right w-full 2xl:w-1/2 2xl:pl-6">
<div>
<Heading text="Latest Wins"></Heading>
<div className="h-72">
<ListItem3 user="usernameX" badge="Award" when="19 seconds ago" />
<ListItem3 user="usernameX" badge="Award" when="19 seconds ago" />
<ListItem3 user="usernameX" badge="Award" when="19 seconds ago" />
<ListItem3 user="usernameX" badge="Award" when="19 seconds ago" />
<ListItem3 user="usernameX" badge="Award" when="19 seconds ago" />
<ListItem3
user="usernameX"
badge="Award"
when="19 seconds ago"
isLast="true"
/>
</div>
<div className="h-auto">{latestWinsComponents}</div>
</div>

<div className="mt-10">
<Heading text="Checkpoints"></Heading>
<Heading text="Awards"></Heading>
<div className="mb-5 grid w-full grid-cols-4 pb-3">
<div className="text-left">
<p className="font-iregular">Name</p>
Expand All @@ -95,46 +213,12 @@ function WheelPage() {
<p className="text-iregular pr-4">Probability</p>
</div>
</div>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
/>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
/>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
/>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
/>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
/>
<ListItem4
name="Amazon voucher 10E"
maxQnty="1"
qnty="10"
prob="2.00%"
isLast="true"
/>
{prizeComponents}
</div>
</div>
</div>
{error && <ErrorMessage />}
{wheelMessage}
</Dashboard>
);
}
Expand Down

0 comments on commit 16ae2c3

Please sign in to comment.