Create Vote
diff --git a/client/src/components/Pages/Home/index.test.tsx b/client/src/components/Pages/Home/index.test.tsx
deleted file mode 100644
index 5fcee4e..0000000
--- a/client/src/components/Pages/Home/index.test.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from "react";
-import { render } from "@testing-library/react";
-import Home from ".";
-
-test("renders main app page", () => {
- const { getByTestId } = render(
);
- const divElement = getByTestId('spinner');
- expect(divElement).toBeDefined();
-});
diff --git a/client/src/components/Pages/Home/index.tsx b/client/src/components/Pages/Home/index.tsx
index e0032ed..ee6606e 100644
--- a/client/src/components/Pages/Home/index.tsx
+++ b/client/src/components/Pages/Home/index.tsx
@@ -1,51 +1,38 @@
-import React, {Component} from "react";
+import React, {useEffect, useState} from "react";
import Spinner from "../../Spinner";
import PollList from "../../PollList";
+import { useReactOidc } from "@axa-fr/react-oidc-context";
-type HomeProps = {};
-type HomeState = {
- error: null | string,
- isLoaded: boolean,
- currentPolls: Array
-}
-class Home extends Component{
- constructor(props:HomeProps) {
- super(props);
- this.state = {
- error: null,
- isLoaded: false,
- currentPolls: []
- };
- }
- componentDidMount() {
- fetch("http://localhost:5000/api/getCurrentPolls")
+export const Home: React.FunctionComponent = () =>{
+ const [error, setError] = useState(null);
+ const [isLoaded, setLoaded] = useState(false);
+ const [currentPolls, setCurrentPolls] = useState([]);
+ const { oidcUser } = useReactOidc();
+
+ useEffect(() => {
+
+ fetch("http://localhost:5000/api/getCurrentPolls", { headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token
+ })})
.then(res => res.json())
.then((result) => {
- this.setState({
- isLoaded: true,
- currentPolls: result
- });
+ setLoaded(true);
+ setCurrentPolls(result);
},
(error) => {
- this.setState({
- isLoaded: true,
- error
- });
+ setLoaded(true);
+ setError(error);
});
- }
- render() {
- const {error, isLoaded, currentPolls} = this.state;
- if (error) {
- return(
+ }, [oidcUser.access_token ])
+
+ return (
+ error ?
Something went wrong! Please Try again
- );
- } else if(!isLoaded) {
- return()
- }else {
- return(
-
- )}
- }
+ : !isLoaded ?
+
+ :
+ )
+
}
export default Home;
diff --git a/client/src/components/Pages/Result/index.tsx b/client/src/components/Pages/Result/index.tsx
new file mode 100644
index 0000000..85ef60d
--- /dev/null
+++ b/client/src/components/Pages/Result/index.tsx
@@ -0,0 +1,150 @@
+import React, { useEffect, useState } from "react";
+import { useParams, useHistory } from 'react-router-dom';
+import Spinner from "../../Spinner";
+import "./result.css";
+import { useReactOidc } from "@axa-fr/react-oidc-context";
+
+type RouteParams = {
+ voteId: string
+}
+
+type Poll = {
+ name: string,
+ results: Object
+}
+
+export const Result: React.FunctionComponent = () =>{
+ const { voteId } = useParams();
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(false);
+
+ const [poll, setPoll] = useState(undefined);
+ const [ended, setEnded] = useState(false);
+ let history = useHistory();
+ const { oidcUser } = useReactOidc();
+ const evals = oidcUser.profile.groups.includes("eboard-evaluations");
+ useEffect(() => {
+ const interval = setInterval(() => {
+ if(!ended) {
+ fetch("http://localhost:5000/api/getCount", {
+ headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token,
+ "content-type": "application/json"
+ }),
+ method: "POST",
+ body: JSON.stringify({"voteId": voteId})
+ })
+ .then((res) => {
+ switch(res.status) {
+ case 200:
+ return res.json()
+ case 404:
+ return undefined
+ default:
+ throw new Error("Error Getting Poll Details");
+ }
+ })
+ .then((result) => {
+ setLoading(false);
+ setPoll(result)
+ },
+ (error) => {
+ setLoading(false);
+ setError(true);
+ });
+ }
+ }, 10000);
+ return () => clearInterval(interval);
+ }, [voteId, ended, oidcUser.access_token]);
+
+ useEffect(() => {
+ fetch("http://localhost:5000/api/getCount", {
+ headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token,
+ "content-type": "application/json"
+ }),
+ method: "POST",
+ body: JSON.stringify({"voteId": voteId})
+ })
+ .then((res) => {
+ switch(res.status) {
+ case 200:
+ return res.json()
+ case 404:
+ return undefined
+ default:
+ throw new Error("Error Getting Poll Details");
+ }
+ })
+ .then((result) => {
+ setLoading(false);
+ setPoll(result)
+ },
+ (error) => {
+ setLoading(false);
+ setError(true);
+ });
+ }, [voteId, oidcUser.access_token])
+
+ function endVoting() {
+ if(window.confirm("End Voting?")){
+ setLoading(true)
+ fetch("http://localhost:5000/api/endPoll", {
+ headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token,
+ "content-type": "application/json"
+ }),
+ method: "POST",
+ body: JSON.stringify({"voteId": voteId})
+ })
+ .then((res) => {
+ switch(res.status) {
+ case 200:
+ return res.json()
+ case 404:
+ return undefined
+ default:
+ throw new Error("Error Getting Poll Details");
+ }
+ })
+ .then((result) => {
+ setLoading(false);
+ setPoll(result)
+ setEnded(true)
+ },
+ (error) => {
+ setLoading(false);
+ setError(true);
+ });
+ }
+ }
+
+ return(
+ loading ? :
+ error ? Something went wrong : (
:
+ poll === undefined ?
+ Poll not found : (
:
+
+
+
{poll.name} {ended ? "Final" : null} Results
+
+ {ended? null :
These are refreshed every 10 seconds
}
+
+ {Object.entries(poll.results).map(function(option, idx){
+ return (
{option[0]} : {option[1]})
+ })}
+
+
+
+
+ {evals && !ended ? : }
+
+
+
+ )
+}
+
+export default Result;
diff --git a/client/src/components/Pages/Result/result.css b/client/src/components/Pages/Result/result.css
new file mode 100644
index 0000000..cf779e1
--- /dev/null
+++ b/client/src/components/Pages/Result/result.css
@@ -0,0 +1,32 @@
+.result-title-panel {
+ color: inherit;
+ font-size: 20px;
+ padding: 20px;
+}
+
+.result-list {
+ border: none;
+ border-radius: 2px;
+ box-shadow: 0 1px 4px rgba(0,0,0,.3);
+}
+
+.refresh-message {
+ padding: 12px;
+}
+
+.result-list-items{
+ background-color: white;
+ font-size: 14px;
+ padding:12px;
+ padding-right: 16px;
+}
+
+.result-list-items li {
+ list-style: none;
+ padding-top: 12px;
+}
+
+.exit-button {
+ margin-top: 24px;
+ text-align: center;
+}
diff --git a/client/src/components/Pages/Vote/index.tsx b/client/src/components/Pages/Vote/index.tsx
index d45a197..bfb3fb1 100644
--- a/client/src/components/Pages/Vote/index.tsx
+++ b/client/src/components/Pages/Vote/index.tsx
@@ -2,13 +2,15 @@ import React, { useEffect, useState } from "react";
import { useParams, useHistory } from 'react-router-dom';
import Spinner from "../../Spinner";
import "./vote.css";
+import { useReactOidc } from "@axa-fr/react-oidc-context";
+
type RouteParams = {
voteId: string
}
type Poll = {
- id: string,
- name: string,
- voteOptions: Array,
+ _id: string,
+ title: string,
+ choices: Array,
}
export const Vote: React.FunctionComponent = () =>{
@@ -18,12 +20,16 @@ export const Vote: React.FunctionComponent = () =>{
const [error, setError] = useState(false);
const [selected, setSelected] = useState(null);
+ const { oidcUser } = useReactOidc();
let history = useHistory();
useEffect(() => {
fetch("http://localhost:5000/api/getPollDetails", {
- headers: {"content-type": "application/json"},
+ headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token,
+ "content-type": "application/json"
+ }),
method: "POST",
body: JSON.stringify({"voteId": voteId})
})
@@ -44,32 +50,31 @@ export const Vote: React.FunctionComponent = () =>{
(error) => {
setLoading(false);
setError(true);
- console.log(error);
});
- }, [voteId])
+ }, [voteId, oidcUser.access_token])
function buttonClick(idx:number|null) {
if (idx !== null) {
fetch("http://localhost:5000/api/sendVote", {
- headers: {"content-type": "application/json"},
+ headers: new Headers({
+ 'Authorization': 'Bearer ' + oidcUser.access_token,
+ "content-type": "application/json"
+ }),
method: "POST",
- body: JSON.stringify({"voteId": voteId, "voteChoice": idx})
+ body: JSON.stringify({"voteId": voteId, "voteChoice": poll?.choices[idx]})
})
.then((res) => {
switch(res.status) {
case 204:
- //TODO- probably better to route to a "voted" screen than home
- //but this is prob okay for mvp
- history.push("/")
+ history.push("/result/" + voteId)
return;
default:
throw new Error("Error Voting");
}
})
.catch((error) => {
- setLoading(false);
- setError(true);
- console.log(error);
+ window.alert("An error occurred (You may have already voted)")
+ history.push("/result/" + voteId)
});
}
}
@@ -80,16 +85,16 @@ export const Vote: React.FunctionComponent = () =>{
Poll not found : (
:
-
{poll.name}
+
{poll.title}
- {poll.voteOptions.map(function(option, idx){
+ {poll.choices.map(function(option, idx){
return (
)
})}
-
You have selected: { selected !== null ? poll.voteOptions[selected] : null}
+
You have selected: { selected !== null ? poll.choices[selected] : null}