diff --git a/.eslintrc b/.eslintrc index 7c2f7b3..d86e5c0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,8 +1,82 @@ { - "extends": ["react-app", "plugin:prettier/recommended"], + "env": { + "browser": true, + "es6": true, + "jest": true + }, + "extends": [ + "airbnb" + ], + "plugins": [ + "jsx-a11y", + "prettier" + ], + "parser": "babel-eslint", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2018, + "sourceType": "module" + }, "rules": { - "no-console": "warn", - "prettier/prettier": "error", - "array-callback-return": "off" + "react/jsx-props-no-spreading": 0, + "react/state-in-constructor": 0, + "quotes": 0, + "array-callback-return": 0, + "arrow-parens": 0, + "react/destructuring-assignment": 0, + "no-tabs": 0, + "#N/A": 0, + "prettier/prettier": 0, + "react/jsx-filename-extension": 0, + "import/no-extraneous-dependencies": 0, + "camelcase": 0, + "react/no-access-state-in-setstate": 0, + "no-param-reassign": 0, + "react/no-unused-state": 0, + "no-mixed-spaces-and-tabs": 0, + "max-len": 0, + "react/no-unused-prop-types": 0, + "import/order": 0, + "no-use-before-define": 0, + "import/prefer-default-export": 0, + "consistent-return": 0, + "copy.js": 0, + "react/sort-comp": 0, + "no-unused-expressions": 0, + "eqeqeq": 0, + "no-empty": 0, + "no-nested-ternary": 0, + "prefer-destructuring": 0, + "import/no-named-as-default": 0, + "import/no-duplicates": 0, + "no-restricted-syntax": 0, + "no-plusplus": 0, + "react/default-props-match-prop-types": 0, + "no-continue": 0, + "no-underscore-dangle": 0, + "react/jsx-no-bind": 0, + "react/prefer-stateless-function": 0, + "react/jsx-closing-tag-location": 0, + "guard-for-in": 0, + "import/named": 0, + "jsx-a11y/no-noninteractive-element-interactions": 0, + "jsx-a11y/alt-text": 0, + "no-unreachable": 0, + "no-multi-assign": 0, + "default-case": 0, + "prefer-const": 0, + "import/no-mutable-exports": 0, + "jsx-a11y/click-events-have-key-events": 0 + }, + "settings": { + "import resolver": { + "node": { + "paths": [ + "./client/src" + ] + } + } } -} +} \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 24e3483..707a704 100755 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,20 +1,14 @@ -import React, { Fragment } from "react"; -import LandingPage from "./pages/LandingPage/LandingPage"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; -import Alert from "./components/layout/alert"; -import "bootstrap/dist/css/bootstrap.css"; +import React from "react"; // Redux import { Provider } from "react-redux"; +import LandingPage from "./pages/LandingPage/LandingPage"; +import "bootstrap/dist/css/bootstrap.css"; import store from "./store"; -const App = () => { - return ( - - - - - - ); -}; +const App = () => ( + + + +); export default App; diff --git a/client/src/App.test.js b/client/src/App.test.js index 43367c0..7925db0 100755 --- a/client/src/App.test.js +++ b/client/src/App.test.js @@ -1,16 +1,16 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import App from './App'; import { Provider } from 'react-redux'; +import App from './App'; import store from './store'; it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render( - - - , - div - ); - ReactDOM.unmountComponentAtNode(div); + const div = document.createElement('div'); + ReactDOM.render( + + + , + div, + ); + ReactDOM.unmountComponentAtNode(div); }); diff --git a/client/src/Auth.js b/client/src/Auth.js index bb07ba1..008b1f6 100755 --- a/client/src/Auth.js +++ b/client/src/Auth.js @@ -1,12 +1,10 @@ -// src/Auth/Auth.js /* eslint no-restricted-globals: */ + import auth0 from "auth0-js"; -//import jwtDecode from "jwt-decode"; import jwtDecode from "jwt-decode"; +import { customAlert } from "./components/Confirm/Confirm"; -// jwtDecode =require(jwt-decode); - -let LOGIN_SUCCESS_PAGE = "/landingpage"; +const LOGIN_SUCCESS_PAGE = "/landingpage"; const LOGIN_FAILURE_PAGE = "/"; export default class Auth { @@ -16,55 +14,42 @@ export default class Auth { redirectUri: "http://localhost:8080/callback", audience: "https://demgamestest.auth0.com/api/v2/", responseType: "token id_token", - scope: "openid profile email address" + scope: "openid profile email address", }); - // auth0 = new auth0.WebAuth({ - // domain: 'pankaj-hashedin.auth0.com', - // clientID: '8APzGywrBbRrfx5BEx5iHFV6Zq3GWQai', - // redirectUri: 'http://localhost:8080/callback', - // audience:'https://pankaj-hashedin.auth0.com/api/v2/', - // responseType: 'token id_token', - // scope: 'openid profile email address' - // }); - - constructor() { - this.login = this.login.bind(this); - } - - login() { + login = () => { this.auth0.authorize({ - prompt: "login" + prompt: "login", }); } - setCohort(cohort) { - if(localStorage.getItem("cohort_address") !== "/landingpage") { + setCohort = (cohort) => { + if (localStorage.getItem("cohort_address") !== "/landingpage") { localStorage.setItem("cohort_address", cohort); } } - getCohort(){ + getCohort = () => { if (localStorage.getItem("cohort_address")) { return localStorage.getItem("cohort_address"); } + return null; } - setStyle(style){ - if(style !== null) { + setStyle = (style) => { + if (style !== null) { localStorage.setItem("style", style); } } - getStyle(){ + getStyle = () => { if (localStorage.getItem("style")) { return localStorage.getItem("style"); - } else { - return "orange"; } + return "orange"; } - logout() { + logout = () => { // Remove tokens and expiry time localStorage.removeItem("access_token"); localStorage.removeItem("id_token"); @@ -80,45 +65,45 @@ export default class Auth { connection: "demgamesDB", email: null, password: null, - username: null + username: null, + }, + (err) => { + if (err) return customAlert(`Something went wrong: ${err.message}`); + return customAlert("success signup without login!"); }, - function(err) { - if (err) return alert("Something went wrong: " + err.message); - return alert("success signup without login!"); - } ); } handleAuthentication() { this.auth0.parseHash((error, authResults) => { if (authResults && authResults.accessToken && authResults.idToken) { - let expiresAt = JSON.stringify( - authResults.expiresIn * 1000 + new Date().getTime() + const expiresAt = JSON.stringify( + authResults.expiresIn * 1000 + new Date().getTime(), ); localStorage.setItem("access_token", authResults.accessToken); localStorage.setItem("id_token", authResults.idToken); localStorage.setItem("expires_at", expiresAt); location.hash = ""; - location.pathname =localStorage.getItem("cohort_address") ? localStorage.getItem("cohort_address") : LOGIN_SUCCESS_PAGE; + location.pathname = localStorage.getItem("cohort_address") ? localStorage.getItem("cohort_address") : LOGIN_SUCCESS_PAGE; } else if (error) { location.pathname = LOGIN_FAILURE_PAGE; - console.log(error); + console.log(error); // eslint-disable-line } }); } - isAuthenticated() { - let expiresAt = JSON.parse(localStorage.getItem("expires_at")); + isAuthenticated = () => { + const expiresAt = JSON.parse(localStorage.getItem("expires_at")); return new Date().getTime() < expiresAt; } - getProfile() { + getProfile = () => { if (localStorage.getItem("id_token")) { return jwtDecode(localStorage.getItem("id_token")); } } - getAccessToken() { + getAccessToken = () => { if (localStorage.getItem("access_token")) { return localStorage.getItem("access_token"); } diff --git a/client/src/actions/alert.js b/client/src/actions/alert.js index 36dd6b9..2d05b42 100644 --- a/client/src/actions/alert.js +++ b/client/src/actions/alert.js @@ -1,12 +1,12 @@ -import uuid from 'uuid'; +import { v4 as uuid } from 'uuid'; import { SET_ALERT, REMOVE_ALERT } from './type'; export const setAlert = (msg, alertType) => dispatch => { - const id = uuid.v4(); - dispatch({ - type: SET_ALERT, - payload: { msg, alertType, id } - }); + const id = uuid.v4(); + dispatch({ + type: SET_ALERT, + payload: { msg, alertType, id }, + }); - setTimeout(() => dispatch({ type: REMOVE_ALERT, payload: id }),5000); -} \ No newline at end of file + setTimeout(() => dispatch({ type: REMOVE_ALERT, payload: id }), 5000); +}; diff --git a/client/src/actions/type.js b/client/src/actions/type.js index f750b25..876e04e 100644 --- a/client/src/actions/type.js +++ b/client/src/actions/type.js @@ -1,2 +1,2 @@ export const SET_ALERT = 'SET_ALERT'; -export const REMOVE_ALERT = 'REMOVE_ALERT'; \ No newline at end of file +export const REMOVE_ALERT = 'REMOVE_ALERT'; diff --git a/client/src/components/Add/AddChoices.js b/client/src/components/Add/AddChoices.js index eb655f4..09781e3 100755 --- a/client/src/components/Add/AddChoices.js +++ b/client/src/components/Add/AddChoices.js @@ -1,95 +1,131 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -//import '../App.css'; -import {connect} from 'react-redux'; +import React, { useState } from 'react'; +import { connect } from 'react-redux'; import Auth from '../../Auth'; import { config } from "../../settings"; +import { customAlert } from "../Confirm/Confirm"; -const auth0=new Auth(); - +const auth0 = new Auth(); const AddChoices = () => { + const initialState = { + choicestatement: '', + choicedescription: '', + weight: '', + isanswer: '', + questionid: '', + questions: [], + }; - const initialState = { - choicestatement:'', - choicedescription:'', - weight:'', - isanswer:'', - questionid:'', - questions:[] - }; - - const [formData, setFormData] = useState(initialState); + const [formData, setFormData] = useState(initialState); - const { - choicestatement, - choicedescription, - weight, - isanswer, - questionid, - } = formData; + const { + choicestatement, + choicedescription, + weight, + isanswer, + questionid, + } = formData; - const handleReset = () => { - setFormData({...formData, choicestatement: '', choicedescription: '', weight: '', isanswer: '', questionid: ''}); - }; + const handleReset = () => { + setFormData({ + ...formData, choicestatement: '', choicedescription: '', weight: '', isanswer: '', questionid: '', + }); + }; - const handleChange = (event) => { - setFormData({ ...formData, [event.target.name]: event.target.value }); - } + const handleChange = (event) => { + setFormData({ ...formData, [event.target.name]: event.target.value }); + }; - const handleSubmit = (event) => - { - event.preventDefault(); - fetch(config.baseUrl + '/addchoice', { - method: 'POST', - headers: { - authorization: "Bearer "+auth0.getAccessToken(), - 'Accept':'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(formData) + const handleSubmit = (event) => { + event.preventDefault(); + fetch(`${config.baseUrl}/addchoice`, { + method: 'POST', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }) + .then(res => res.json()) + .then(() => { + customAlert('The choice was successfully added'); + handleReset(); }) - .then(res=>res.json()) - .then((data)=>{ - - alert('The choice was successfully added'); - handleReset(); - }) - .catch((error)=>console.log(error)); - } - - let optionItems = formData.questions.map((question) => - - ); + .catch((error) => console.log(error)); // eslint-disable-line + }; - return ( -
-
-
-
-
handleSubmit(e)}> -
-
- - -
-
+ const optionItems = formData.questions.map((question) => ); - handleChange(e)}/>
- - handleChange(e)}/>
- handleChange(e)}/>
-
- | -
-
+ return ( +
+
+
+
+
handleSubmit(e)}> +
+
+ +
-
+ + handleChange(e)} + /> +
+ + />
- - +
{" "} - |{" "} + + {" "} + | + {" "}
-
+
); @@ -108,5 +111,5 @@ const AddGame = () => { export default connect( null, - {} + {}, )(AddGame); diff --git a/client/src/components/Add/AddQuestion.js b/client/src/components/Add/AddQuestion.js index 726e1fa..3f8033f 100755 --- a/client/src/components/Add/AddQuestion.js +++ b/client/src/components/Add/AddQuestion.js @@ -1,9 +1,9 @@ import React, { useState } from "react"; import "react-datepicker/dist/react-datepicker.css"; import { connect } from "react-redux"; -import PropTypes from "prop-types"; import Auth from "../../Auth"; -import { config } from "../../settings" +import { config } from "../../settings"; +import { customAlert } from "../Confirm/Confirm"; const auth0 = new Auth(); @@ -15,22 +15,21 @@ const AddQuestion = () => { question_statement: "", weight: "", explanation: "", - isitmedia: "" + isitmedia: "", }; const [formData, setFormData] = useState(initialState); const { - gameid, gametype, difficulty_level, question_statement, weight, explanation, - isitmedia + isitmedia, } = formData; - const reset = event => { + const reset = () => { setFormData(initialState); }; @@ -54,40 +53,40 @@ const AddQuestion = () => { } else { setFormData({ ...formData, [fieldName]: val }); } - }; const handleSubmit = event => { event.preventDefault(); - fetch(config.baseUrl + "/addquestion", { + fetch(`${config.baseUrl}/addquestion`, { method: "POST", headers: { - authorization: "Bearer " + auth0.getAccessToken(), + authorization: `Bearer ${auth0.getAccessToken()}`, Accept: "application/json", - "Content-Type": "application/json" + "Content-Type": "application/json", }, - body: JSON.stringify(formData) + body: JSON.stringify(formData), }) .then(res => res.json()) - .then(data => { - alert("Question was successfully added"); + .then(() => { + customAlert("Question was successfully added"); }) - .catch(error => console.log(error)); + .catch(error => console.log(error)); // eslint-disable-line }; return (
-
+
handleSubmit(e)} > -
-
+
); @@ -177,5 +182,5 @@ const AddQuestion = () => { export default connect( null, - {} + {}, )(AddQuestion); diff --git a/client/src/components/Add/Register.js b/client/src/components/Add/Register.js index fb065d2..13683a1 100755 --- a/client/src/components/Add/Register.js +++ b/client/src/components/Add/Register.js @@ -1,146 +1,139 @@ import React, { useState } from 'react'; import { connect } from 'react-redux'; -import PropTypes from 'prop-types'; -import { setAlert } from '../../actions/alert'; import DatePicker from 'react-datepicker'; +import { setAlert } from '../../actions/alert'; import { countryList } from './countryList'; -//import "react-datepicker/dist/react-datepicker.css"; import { config } from "../../settings"; import Auth from '../../Auth'; - -const auth0=new Auth(); - -const Register = ({ setAlert }) => { - - const initialState = { - firstName: "", - middleName: "", - lastName: "", - userName: "", - email: "", - dateOfBirth: new Date(), - gender: "Female", - country: "Afghanistan", - city: "", - program: "M&E" - }; - - const [formData, setFormData] = useState(initialState); - - const { - firstName, - middleName, - lastName, - userName, - email, - dateOfBirth, - gender, - country, - city, - program - } = formData; - - const handleDate = date => setFormData({ ...formData, dateOfBirth: date }); - - const handleChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); - - const handleSubmit = (event) => { - event.preventDefault(); - console.log('state----Form---data-----', formData); - - const submitData = () => { - - const url = config.baseUrl + '/registerplayer'; - - fetch(url, { - method: 'POST', - headers: { - authorization: "Bearer "+auth0.getAccessToken(), - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(formData) - }) - .then((res) => { - return (res.json()); - }) - .then((data) => { alert(data.message) }) - .catch((error) => console.log(error)); - - } - submitData(); +import { customAlert } from "../Confirm/Confirm"; + +const auth0 = new Auth(); + +const Register = () => { + const initialState = { + firstName: "", + middleName: "", + lastName: "", + userName: "", + email: "", + dateOfBirth: new Date(), + gender: "Female", + country: "Afghanistan", + city: "", + program: "M&E", + }; + + const [formData, setFormData] = useState(initialState); + + const { + firstName, + middleName, + lastName, + userName, + email, + dateOfBirth, + gender, + country, + city, + program, + } = formData; + + const handleDate = date => setFormData({ ...formData, dateOfBirth: date }); + + const handleChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); + + const handleSubmit = (event) => { + event.preventDefault(); + + const submitData = () => { + const url = `${config.baseUrl}/registerplayer`; + + fetch(url, { + method: 'POST', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }) + .then((res) => (res.json())) + .then((data) => { customAlert(data.message); }) + .catch((error) => console.log(error)); // eslint-disable-line }; - - const reset = (e) => { - e.preventDefault(); - setFormData(initialState); - } - - return ( -
+ submitData(); + }; + + const reset = (e) => { + e.preventDefault(); + setFormData(initialState); + }; + + return ( +
+
+
+
+
handleSubmit(e)}> + handleChange(e)} className="form-control mb-1" placeholder="First Name" /> + handleChange(e)} className="form-control mb-1" placeholder="Middle Name" /> + handleChange(e)} className="form-control mb-1" placeholder="Last Name" /> + handleChange(e)} className="form-control mb-1" placeholder="Username" /> + handleChange(e)} className="form-control mb-1" placeholder="Email" />
-
-
- handleSubmit(e)}> - handleChange(e)} className="form-control mb-1" placeholder="First Name" /> - handleChange(e)} className="form-control mb-1" placeholder="Middle Name" /> - handleChange(e)} className="form-control mb-1" placeholder="Last Name" /> - handleChange(e)} className="form-control mb-1" placeholder="Username" /> - handleChange(e)} className="form-control mb-1" placeholder="Email" /> - -
-
- - -
-
- -
-
-
Date of Birth:
- handleDate(e)} selected={dateOfBirth} isClearable={true} placeholderText={"MM/DD/YYYY"} />
-
-
- -
-
- - -
-
- - handleChange(e)} className="form-control mb-1" placeholder="City" /> - - -
-
- - -
-
- - | - -
+
+ +
+
+
+
+
Date of Birth:
+ handleDate(e)} selected={dateOfBirth} isClearable placeholderText="MM/DD/YYYY" /> + {' '} +
+
+
+
+
+ +
+
+ handleChange(e)} className="form-control mb-1" placeholder="City" /> +
+
+ +
-
- ); -} -Register.propTypes = { - setAlert: PropTypes.func.isRequired, - authDetail: PropTypes.object, + + {' '} + | + + +
+
+
+ ); }; export default connect(null, { setAlert })(Register); diff --git a/client/src/components/Add/countryList.js b/client/src/components/Add/countryList.js index 8de0d4c..88e0530 100644 --- a/client/src/components/Add/countryList.js +++ b/client/src/components/Add/countryList.js @@ -1,15 +1,15 @@ -export const countryList = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas" -,"Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia & Herzegovina","Botswana","Brazil","British Virgin Islands" -,"Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica" -,"Cote D Ivoire","Croatia","Cruise Ship","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea" -,"Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana" -,"Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India" -,"Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kuwait","Kyrgyz Republic","Laos","Latvia" -,"Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Mauritania" -,"Mauritius","Mexico","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Namibia","Nepal","Netherlands","Netherlands Antilles","New Caledonia" -,"New Zealand","Nicaragua","Niger","Nigeria","Norway","Oman","Pakistan","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal" -,"Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre & Miquelon","Samoa","San Marino","Satellite","Saudi Arabia","Senegal","Serbia","Seychelles" -,"Sierra Leone","Singapore","Slovakia","Slovenia","South Africa","South Korea","Spain","Sri Lanka","St Kitts & Nevis","St Lucia","St Vincent","St. Lucia","Sudan" -,"Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad & Tobago","Tunisia" -,"Turkey","Turkmenistan","Turks & Caicos","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","United States Minor Outlying Islands","Uruguay" -,"Uzbekistan","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"] +export const countryList = ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Anguilla", "Antigua & Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", + "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia & Herzegovina", "Botswana", "Brazil", "British Virgin Islands", + "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Chad", "Chile", "China", "Colombia", "Congo", "Cook Islands", "Costa Rica", + "Cote D Ivoire", "Croatia", "Cruise Ship", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", + "Estonia", "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "French West Indies", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", + "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea Bissau", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", + "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kuwait", "Kyrgyz Republic", "Laos", "Latvia", + "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Mauritania", + "Mauritius", "Mexico", "Moldova", "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", + "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway", "Oman", "Pakistan", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", + "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Rwanda", "Saint Pierre & Miquelon", "Samoa", "San Marino", "Satellite", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", + "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "South Africa", "South Korea", "Spain", "Sri Lanka", "St Kitts & Nevis", "St Lucia", "St Vincent", "St. Lucia", "Sudan", + "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor L'Este", "Togo", "Tonga", "Trinidad & Tobago", "Tunisia", + "Turkey", "Turkmenistan", "Turks & Caicos", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "United States Minor Outlying Islands", "Uruguay", + "Uzbekistan", "Venezuela", "Vietnam", "Virgin Islands (US)", "Yemen", "Zambia", "Zimbabwe"]; diff --git a/client/src/components/AnswerInfoPopup/index.js b/client/src/components/AnswerInfoPopup/index.js index f557d8f..73ac4d8 100755 --- a/client/src/components/AnswerInfoPopup/index.js +++ b/client/src/components/AnswerInfoPopup/index.js @@ -10,95 +10,121 @@ import './styles.scss'; import '../../commonStyles.scss'; import PropTypes from 'prop-types'; import { alignCenter } from './styles'; + function Transition(props) { - return ; + return ; } class AnswerInfoPopup extends Component { - constructor(props) { - super(props); - this.handleClick = this.handleClick.bind(this); - this.handleOkClick = this.handleOkClick.bind(this); - } + constructor(props) { + super(props); + this.handleClick = this.handleClick.bind(this); + this.handleOkClick = this.handleOkClick.bind(this); + } - handleClick() { - this.props.handleClose(); - this.props.showRightAnswer(); - } + handleClick() { + this.props.handleClose(); + this.props.showRightAnswer(); + } - handleOkClick() { - const { moduleScenario } = this.props; - this.props.handleClose(); - if (!moduleScenario) { - this.props.nextQuestion(); - } - } + handleOkClick() { + const { moduleScenario } = this.props; + this.props.handleClose(); + if (!moduleScenario) { + this.props.nextQuestion(); + } + } - render() { - const { open, handleClose, imageUrl, answerStatus, message, moduleScenario, currentScore, currentQuestionScore } = this.props; - return ( - - - answer-status - - - - {answerStatus ? 'Congratulations!' : ''} - - - - - {message} - - - - - You - {answerStatus ? ( - - earn - {/*moduleScenario ? currentQuestionScore :*/ currentQuestionScore} - - ) : ( - - lose - -10 - - )}{' '} - points.{' '} - {!answerStatus && ( - - )} - - - - {answerStatus ? ( - - ) : null} - - - ); - } + render() { + const { + open, handleClose, imageUrl, answerStatus, message, currentQuestionScore, + } = this.props; + return ( + + + answer-status + + + + + {answerStatus ? 'Congratulations!' : ''} + + + + + + {message} + + + + + You + {answerStatus ? ( + + earn + + {currentQuestionScore} + + + ) : ( + + lose + -10 + + )} + {' '} + points. + {' '} + {!answerStatus && ( + + )} + + + + {answerStatus ? ( + + ) : null} + + + ); + } } AnswerInfoPopup.propTypes = { - open: PropTypes.bool, - handleClose: PropTypes.func, - imageUrl: PropTypes.string, - answerStatus: PropTypes.bool, - message: PropTypes.string, - showRightAnswer: PropTypes.func, - nextQuestion: PropTypes.func + open: PropTypes.bool, + handleClose: PropTypes.func, + imageUrl: PropTypes.string, + answerStatus: PropTypes.bool, + message: PropTypes.string, + showRightAnswer: PropTypes.func, + nextQuestion: PropTypes.func, + moduleScenario: PropTypes.bool, + currentQuestionScore: PropTypes.number.isRequired, +}; + +AnswerInfoPopup.defaultProps = { + open: null, + handleClose: null, + imageUrl: null, + answerStatus: null, + message: null, + showRightAnswer: null, + nextQuestion: null, + moduleScenario: false, }; export default AnswerInfoPopup; diff --git a/client/src/components/AnswerInfoPopup/styles.js b/client/src/components/AnswerInfoPopup/styles.js index 5e90a38..daf361b 100755 --- a/client/src/components/AnswerInfoPopup/styles.js +++ b/client/src/components/AnswerInfoPopup/styles.js @@ -1,3 +1,3 @@ export const alignCenter = { - textAlign: 'center' + textAlign: 'center', }; diff --git a/client/src/components/Card/index.js b/client/src/components/Card/index.js index bd11c78..b1ac1df 100755 --- a/client/src/components/Card/index.js +++ b/client/src/components/Card/index.js @@ -3,17 +3,28 @@ import './styles.scss'; import PropTypes from 'prop-types'; export const Card = (props) => ( - + ); -Card.prototypes = { - answerClick: PropTypes.bool, - option: PropTypes.string, - selectedCard: PropTypes.bool +Card.propTypes = { + answerClick: PropTypes.bool, + option: PropTypes.string, + selectedCard: PropTypes.bool, + moduleColor: PropTypes.string, + color: PropTypes.string, + handleClick: PropTypes.func.isRequired, +}; + +Card.defaultProps = { + answerClick: null, + option: null, + selectedCard: null, + color: null, + moduleColor: null, }; diff --git a/client/src/components/Confirm/Confirm.js b/client/src/components/Confirm/Confirm.js new file mode 100644 index 0000000..2daf149 --- /dev/null +++ b/client/src/components/Confirm/Confirm.js @@ -0,0 +1,30 @@ +import { confirmAlert } from 'react-confirm-alert'; +import 'react-confirm-alert/src/react-confirm-alert.css'; + +export const confirmation = (title, message, callback) => { + confirmAlert({ + title, + message, + buttons: [ + { + label: 'Cancel', + }, + { + label: 'OK', + onClick: () => callback(), + }, + ], + }); +}; + +export const customAlert = (message) => { + confirmAlert({ + title: 'DemGames', + message, + buttons: [ + { + label: 'OK', + }, + ], + }); +}; diff --git a/client/src/components/CorrectAnswerInfo/index.js b/client/src/components/CorrectAnswerInfo/index.js index b8fe165..6fc20b8 100755 --- a/client/src/components/CorrectAnswerInfo/index.js +++ b/client/src/components/CorrectAnswerInfo/index.js @@ -1,86 +1,107 @@ -import React, { Fragment, Component } from 'react'; +import React, { Component } from 'react'; import './styles.scss'; -import { Card } from '../Card'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; +import { Card } from '../Card'; class CorrectAnswerInfo extends Component { - render() { - const { - level, - questionId, - moduleId, - totalQuestion, - correctAns, - selectedAnswer, - hideRightAnswer, - moduleColor - } = this.props; - const selectedAnsList = []; - selectedAnsList.push( - selectedAnswer.map((correct) => { - return this.props.gameData.gameData[moduleId - 1].levels[level - 1].questions[questionId - 1].options[ - correct - ]; - }) - ); + render() { + const { + level, + questionId, + moduleId, + totalQuestion, + correctAns, + selectedAnswer, + hideRightAnswer, + moduleColor, + } = this.props; + const selectedAnsList = []; + selectedAnsList.push( + selectedAnswer.map((correct) => this.props.gameData.gameData[moduleId - 1].levels[level - 1].questions[questionId - 1].options[ + correct + ]), + ); - let strSelectedAns = ''; - selectedAnsList[0].map((val) => { - return (strSelectedAns = strSelectedAns.concat(val + '\n')); - }); + let strSelectedAns = ''; + selectedAnsList[0].forEach((val) => { + strSelectedAns = strSelectedAns.concat(`${val}\n`); + }); - const correctAnsList = []; - correctAnsList.push( - correctAns.map((correct) => { - return this.props.gameData.gameData[moduleId - 1].levels[level - 1].questions[questionId - 1].options[ - correct - ]; - }) - ); + const correctAnsList = []; + correctAnsList.push( + correctAns.map((correct) => this.props.gameData.gameData[moduleId - 1].levels[level - 1].questions[questionId - 1].options[ + correct + ]), + ); - let strCorrectAns = ''; - correctAnsList[0].map((val) => { - return (strCorrectAns = strCorrectAns.concat(val + '\n')); - }); + let strCorrectAns = ''; + correctAnsList[0].forEach((val) => { + strCorrectAns = strCorrectAns.concat(`${val}\n`); + }); - return ( - -
- Level {level} : - - Question {questionId} out of {totalQuestion} - -
+ return ( + <> +
+ + Level + {level} + : + + + Question + {questionId} + out of + {totalQuestion} + +
-
-

Your answer

- -

Correct answer

- - -
-
- ); - } +
+

Your answer

+ +

Correct answer

+ + +
+ + ); + } } -const mapStateToProps = (state) => { - return { gameData: state.gameData }; -}; +const mapStateToProps = (state) => ({ gameData: state.gameData }); export default connect(mapStateToProps, null)(CorrectAnswerInfo); CorrectAnswerInfo.propTypes = { - level: PropTypes.number, - questionId: PropTypes.number, - moduleId: PropTypes.number, - totalQuestion: PropTypes.number, - correctAns: PropTypes.array, - selectedAnswer: PropTypes.array, - hideRightAnswer: PropTypes.func, - gameData: PropTypes.object + level: PropTypes.number.isRequired, + questionId: PropTypes.number.isRequired, + moduleId: PropTypes.number.isRequired, + totalQuestion: PropTypes.number.isRequired, + correctAns: PropTypes.func, + selectedAnswer: PropTypes.arrayOf( + PropTypes.string, + ).isRequired, + hideRightAnswer: PropTypes.func.isRequired, + moduleColor: PropTypes.string.isRequired, + gameData: PropTypes.shape({ + gameData: PropTypes.arrayOf( + PropTypes.shape({ + levels: PropTypes.arrayOf( + PropTypes.shape({ + questions: PropTypes.arrayOf( + PropTypes.shape({ + options: PropTypes.shape({}), + }), + ), + }), + ), + }), + ), + }).isRequired, }; +CorrectAnswerInfo.defaultProps = { + correctAns: null, +}; diff --git a/client/src/components/Details/index.js b/client/src/components/Details/index.js index aacdd56..c9f5cb5 100644 --- a/client/src/components/Details/index.js +++ b/client/src/components/Details/index.js @@ -1,24 +1,27 @@ import React from 'react'; +import PropTypes from 'prop-types'; import './styles.scss'; -export const Details=({data})=>{ - - return( -
- {data&&data.map((d)=> -
- -
- {d.key} -
-
:
-
- {d.value} -
- - -
- )} +export const Details = ({ data }) => ( +
+ {data && data.map((d) => ( +
+
+ {d.key}
- ); -} \ No newline at end of file +
:
+
+ {d.value} +
+
+ ))} +
+); + +Details.propTypes = { + data: PropTypes.arrayOf(PropTypes.shape({})), +}; + +Details.defaultProps = { + data: null, +}; diff --git a/client/src/components/DialogBox/DialogBox copy.js b/client/src/components/DialogBox/DialogBox copy.js index ec26c71..3ac86a1 100644 --- a/client/src/components/DialogBox/DialogBox copy.js +++ b/client/src/components/DialogBox/DialogBox copy.js @@ -8,7 +8,7 @@ import { isEmpty } from "lodash"; const modalStyles = { display: "flex", - alignItems: "center" + alignItems: "center", }; /** @@ -26,14 +26,15 @@ class DialogBox extends Component { constructor(props) { super(props); this.state = { - confirmButtonDisable: false + confirmButtonDisable: false, }; } + initialState = props => { const { data, edit, create } = props; - const values = create ? data : data.values, - id = data.id; + const values = create ? data : data.values; + const { id } = data; let confirmButtonDisable = false; if (create) { confirmButtonDisable = true; @@ -44,21 +45,24 @@ class DialogBox extends Component { type: "choice", title: "Choose new choice", value: "", - editable: true + editable: true, }); } - this.setState({ data: values, edit, id, confirmButtonDisable }); + this.setState({ + data: values, edit, id, confirmButtonDisable, + }); }; + componentDidMount = () => { this.initialState(this.props); }; - componentWillReceiveProps = props => { + + UNSAFE_componentWillReceiveProps = props => { this.initialState(props); }; - convertChoice = value => { - return String.fromCharCode(value + 65); - }; + convertChoice = value => String.fromCharCode(value + 65); + onConfirm = () => { const { edit, create, onConfirm } = this.props; const { data, id } = this.state; @@ -72,6 +76,7 @@ class DialogBox extends Component { onConfirm(); } }; + valueChange = (value, title, index = 0) => { const { data } = this.state; data.map(item => { @@ -81,34 +86,35 @@ class DialogBox extends Component { : (item.value = value); if (isEmpty(value)) { item.type === "options" - ? (item["error"] = true) - : (item["error"] = true); + ? (item.error = true) + : (item.error = true); } else { - item["error"] = false; + item.error = false; } } }); this.setState({ data, confirmButtonDisable: isEmpty(value) }); }; + render() { const { - bsSize, - cancelButtonType, - cancelButtonValue, - confirmButtonValue, - isConfirmation, - messageDescription, - messageNote, - messageTitle, - onCancel, - showMessage, - title, - messageBox, - create, - onDelete, - removeMessage - } = this.props, - { data, edit, confirmButtonDisable } = this.state; + bsSize, + cancelButtonType, + cancelButtonValue, + confirmButtonValue, + isConfirmation, + messageDescription, + messageNote, + messageTitle, + onCancel, + showMessage, + title, + messageBox, + create, + onDelete, + removeMessage, + } = this.props; + const { data, edit, confirmButtonDisable } = this.state; return (
{title}
-
X
+
+ X +
{messageBox ? ( @@ -134,100 +146,100 @@ class DialogBox extends Component {
) : (
- {!isEmpty(data) && - data.map((object, index) => { + {!isEmpty(data) + && data.map((object, index) => { switch (object.type) { case "options": return (
Choice/Option
- {object.value.map((option, option_index) => { - return ( -
- {this.convertChoice(option_index)} : - {create || edit ? ( - - this.valueChange( - e.target.value, - object.title, - option_index - ) - } - /> - ) : ( -
{option}
- )} -
- ); - })} + {object.value.map((option, option_index) => ( +
+ {this.convertChoice(option_index)} + {' '} + : + {create || edit ? ( + this.valueChange( + e.target.value, + object.title, + option_index, + )} + /> + ) : ( +
{option}
+ )} +
+ ))}
); case "choice": return ( -
+
- {object.title} : + {object.title} + {' '} + :
- object.editable && - this.valueChange("A", object.title) - } + onClick={() => object.editable + && this.valueChange("A", object.title)} > A
- object.editable && - this.valueChange("B", object.title) - } + onClick={() => object.editable + && this.valueChange("B", object.title)} > B
- object.editable && - this.valueChange("C", object.title) - } + onClick={() => object.editable + && this.valueChange("C", object.title)} > C
- object.editable && - this.valueChange("D", object.title) - } + onClick={() => object.editable + && this.valueChange("D", object.title)} > D
@@ -237,35 +249,36 @@ class DialogBox extends Component { ); case "text": return (edit || create) && object.editable ? ( -
- {object.title} : +
+ {object.title} + {' '} + : {object.multiline ? ( -
- - - - - -
-
- ) - } -} + handleSearch() { + fetch(`${config.baseUrl}/selectChoiceforDel`, { + method: 'post', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + "Content-Type": "Application/json", + Accept: "application/json", + }, + body: JSON.stringify(this.state.search), + }) + .then((res) => res.json()) + .then((data) => { + if (data.message === 'Not found') { + customAlert("Question with specified Id is not found"); + } else { + this.setState({ + choice: { + id: data[0].id, + choicestatement: data[0].choicestatement, + choicedescription: data[0].choicedescription, + weight: data[0].weight, + isanswer: data[0].answer, + questionid: data[0].questionid, + }, + }); + } + }) + .catch((error) => console.log(error)); // eslint-disable-line + } -const mapStateToProps = (state) => ({ - /* - player_given_name:state.authDetail.authDetail.player_given_name, - player_family_name:state.authDetail.authDetail.player_given_name, - player_picture:state.authDetail.authDetail.player_picture, - player_email:state.authDetail.authDetail.player_email, - player_username:state.authDetail.authDetail.player_username, - player_gender:state.authDetail.authDetail.player_gender, - player_dateOfBirth:state.authDetail.authDetail.player_dateOfBirth -// gameData: state.gameData -*/ -}); + handleReset() { + this.setState({ + search: { + id: '', + }, + }); + } -//Dispatch action to fetch game data and scores. -const mapDispatchToProps = (dispatch) => { - return { -// getGameData: (gameData) => dispatch(fetchGameData(gameData)), -// getScores: (scores) => dispatch(fetchScores(scores)), - setAuth:(authDetail) => dispatch(fetchAuthDetails(authDetail)), - clearAuth:(authDetail)=> dispatch(clearAuthDetails(authDetail)), - }; -}; + render() { + return ( +
+
+ + +
+
+
+ + + - - - - -
-
-
- ) - } + render() { + return ( +
+
+ + +
+
+
+ + + + - - - -
-
-
- ) - } -} + .catch((error) => console.log(error)); // eslint-disable-line + } -const mapStateToProps = (state) => ({ -/* player_given_name:state.authDetail.authDetail.player_given_name, - player_family_name:state.authDetail.authDetail.player_given_name, - player_picture:state.authDetail.authDetail.player_picture, - player_email:state.authDetail.authDetail.player_email, - player_username:state.authDetail.authDetail.player_username, - player_gender:state.authDetail.authDetail.player_gender, - player_dateOfBirth:state.authDetail.authDetail.player_dateOfBirth -// gameData: state.gameData -*/ -}); + handleSubmit(e) { + e.preventDefault(); + const url = `${config.baseUrl}/updatechoice`; + fetch(url, { + method: 'POST', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + "Content-Type": "Application/json", + Accept: "application/json", + }, + body: JSON.stringify(this.state.choice), + mode: 'cors', + }) + .then((res) => res.json()) + .then((data) => { + if (data.message === 'updated successfully') { + customAlert("Successfully Updated the choice detail"); + } + }) + .catch((error) => console.log(error)); // eslint-disable-line + } -//Dispatch action to fetch game data and scores. -const mapDispatchToProps = (dispatch) => { - return { -// getGameData: (gameData) => dispatch(fetchGameData(gameData)), -// getScores: (scores) => dispatch(fetchScores(scores)), - setAuth:(authDetail) => dispatch(fetchAuthDetails(authDetail)), - clearAuth:(authDetail)=> dispatch(clearAuthDetails(authDetail)), - }; -}; + render() { + return ( +
+
+ + +
+
+
+ + + - -
-
-
- ) - } -} + .catch((error) => console.log(error)); // eslint-disable-line + } -const mapStateToProps = (state) => ({ -/* player_given_name:state.authDetail.authDetail.player_given_name, - player_family_name:state.authDetail.authDetail.player_given_name, - player_picture:state.authDetail.authDetail.player_picture, - player_email:state.authDetail.authDetail.player_email, - player_username:state.authDetail.authDetail.player_username, - player_gender:state.authDetail.authDetail.player_gender, - player_dateOfBirth:state.authDetail.authDetail.player_dateOfBirth -// gameData: state.gameData -*/ -}); + handleSubmit(e) { + e.preventDefault(); + const url = `${config.baseUrl}/updategame`; + fetch(url, { + method: 'POST', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + "Content-Type": "Application/json", + Accept: "application/json", + }, + body: JSON.stringify(this.state.game), + mode: 'cors', + }) + .then((res) => res.json()) + .then((data) => { + if (data.message === 'updated successfully') { + customAlert("Successfully Updated the game detail"); + } + }) + .catch((error) => console.log(error)); // eslint-disable-line + } -//Dispatch action to fetch game data and scores. -const mapDispatchToProps = (dispatch) => { - return { -// getGameData: (gameData) => dispatch(fetchGameData(gameData)), -// getScores: (scores) => dispatch(fetchScores(scores)), - setAuth:(authDetail) => dispatch(fetchAuthDetails(authDetail)), - clearAuth:(authDetail)=> dispatch(clearAuthDetails(authDetail)), - }; -}; + render() { + return ( +
+
+ + +
+
+
+ + + - - - - -
-
-
- ) - } -} + .catch((error) => console.log(error)); // eslint-disable-line + } -const mapStateToProps = (state) => ({ -/* player_given_name:state.authDetail.authDetail.player_given_name, - player_family_name:state.authDetail.authDetail.player_given_name, - player_picture:state.authDetail.authDetail.player_picture, - player_email:state.authDetail.authDetail.player_email, - player_username:state.authDetail.authDetail.player_username, - player_gender:state.authDetail.authDetail.player_gender, - player_dateOfBirth:state.authDetail.authDetail.player_dateOfBirth -// gameData: state.gameData -*/ -}); + handleSubmit(e) { + e.preventDefault(); + const url = `${config.baseUrl}/updatequestion`; + fetch(url, { + method: 'POST', + headers: { + authorization: `Bearer ${auth0.getAccessToken()}`, + "Content-Type": "Application/json", + Accept: "application/json", + }, + body: JSON.stringify(this.state.question), + mode: 'cors', + }) + .then((res) => res.json()) + .then((data) => { + if (data.message === 'updated successfully') { + customAlert("Successfully Updated the game detail"); + } + }) + .catch((error) => console.log(error)); // eslint-disable-line + } -//Dispatch action to fetch game data and scores. -const mapDispatchToProps = (dispatch) => { - return { -// getGameData: (gameData) => dispatch(fetchGameData(gameData)), -// getScores: (scores) => dispatch(fetchScores(scores)), - setAuth:(authDetail) => dispatch(fetchAuthDetails(authDetail)), - clearAuth:(authDetail)=> dispatch(clearAuthDetails(authDetail)), - }; -}; + render() { + return ( +
+
+ + +
+
+
+ + + +