expand character select
This commit is contained in:
parent
721f90aabb
commit
a7e521512b
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||||
import AuthService from '../../utils/AuthService'
|
import AuthService from '../../utils/AuthService'
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
import Navbar from '../Navbar/Navbar';
|
import Navbar from '../Navbar/Navbar';
|
||||||
|
import GameContainer from '../GameContainer/GameContainer';
|
||||||
|
|
||||||
const options = {};
|
const options = {};
|
||||||
const auth = new AuthService(__AUTH0_CLIENT_ID__, __AUTH0_DOMAIN__, options);
|
const auth = new AuthService(__AUTH0_CLIENT_ID__, __AUTH0_DOMAIN__, options);
|
||||||
|
@ -11,6 +12,7 @@ class App extends Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isAuthenticated: this.isAuthenticated(),
|
isAuthenticated: this.isAuthenticated(),
|
||||||
|
gameState: 'chooseCharacters'
|
||||||
/*profile: auth.getProfile()*/
|
/*profile: auth.getProfile()*/
|
||||||
}
|
}
|
||||||
auth.on('profile_updated', (newProfile) => {
|
auth.on('profile_updated', (newProfile) => {
|
||||||
|
@ -19,6 +21,8 @@ class App extends Component {
|
||||||
})
|
})
|
||||||
this.logout = this.logout.bind(this);
|
this.logout = this.logout.bind(this);
|
||||||
this.getNickName = this.getNickName.bind(this);
|
this.getNickName = this.getNickName.bind(this);
|
||||||
|
this.startGame = this.startGame.bind(this);
|
||||||
|
this.endGame = this.endGame.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
isAuthenticated() {
|
isAuthenticated() {
|
||||||
|
@ -29,19 +33,38 @@ class App extends Component {
|
||||||
return auth.getProfile() && auth.getProfile().hasOwnProperty('nickname')?auth.getProfile().nickname:'';
|
return auth.getProfile() && auth.getProfile().hasOwnProperty('nickname')?auth.getProfile().nickname:'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startGame() {
|
||||||
|
this.setState({gameState: 'game'});
|
||||||
|
}
|
||||||
|
|
||||||
|
endGame() {
|
||||||
|
this.setState({gameState: 'chooseCharacters'});
|
||||||
|
}
|
||||||
|
|
||||||
logout() {
|
logout() {
|
||||||
auth.logout();
|
auth.logout();
|
||||||
this.setState({isAuthenticated: this.isAuthenticated()});
|
this.setState({isAuthenticated: this.isAuthenticated()});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let loginButton = !this.state.isAuthenticated ?
|
let loginButton = !this.state.isAuthenticated ?
|
||||||
<button className="btn btn-info login-button" onClick={auth.login.bind(this)}>Log in to save your progress!</button> : '';
|
<button className="btn btn-info login-button" onClick={auth.login.bind(this)}>Log in to save your progress!</button> : '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar isAuthenticated={this.state.isAuthenticated} nickName={this.getNickName()} handleLogin={auth.login.bind(this)} handleLogout={this.logout} />
|
<Navbar isAuthenticated={this.state.isAuthenticated}
|
||||||
|
handleLogin={auth.login.bind(this)}
|
||||||
|
handleLogout={this.logout}
|
||||||
|
gameState={this.state.gameState}
|
||||||
|
handleEndGame={this.endGame}
|
||||||
|
/>
|
||||||
<div className="container game">
|
<div className="container game">
|
||||||
|
<GameContainer
|
||||||
|
isAuthenticated={this.state.isAuthenticated}
|
||||||
|
nickName={this.getNickName()}
|
||||||
|
gameState={this.state.gameState}
|
||||||
|
handleStartGame={this.startGame}
|
||||||
|
/>
|
||||||
<div className="row text-center">{loginButton}</div>
|
<div className="row text-center">{loginButton}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,5 +20,5 @@ body {
|
||||||
padding: 6px 15px;
|
padding: 6px 15px;
|
||||||
}
|
}
|
||||||
.game {
|
.game {
|
||||||
padding-top: 80px;
|
padding-top: 70px;
|
||||||
}
|
}
|
29
src/components/ChooseCharacters/CharacterRow.jsx
Normal file
29
src/components/ChooseCharacters/CharacterRow.jsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
class CharacterRow extends Component {
|
||||||
|
render() {
|
||||||
|
let strCharacters = '';
|
||||||
|
this.props.characters.map(function(items) {
|
||||||
|
Object.keys(items).map(function(item) {
|
||||||
|
if(item!='selected') strCharacters+=item+', ';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
strCharacters = strCharacters.slice(0, -2);
|
||||||
|
|
||||||
|
let chooseRow = (
|
||||||
|
<div className="choose-row">
|
||||||
|
<span className={this.props.selected ?
|
||||||
|
'glyphicon glyphicon-small glyphicon-check' :
|
||||||
|
'glyphicon glyphicon-small glyphicon-unchecked'}></span> {strCharacters}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{chooseRow}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CharacterRow;
|
108
src/components/ChooseCharacters/ChooseCharacters.jsx
Normal file
108
src/components/ChooseCharacters/ChooseCharacters.jsx
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import './ChooseCharacters.scss';
|
||||||
|
import CharacterRow from './CharacterRow';
|
||||||
|
|
||||||
|
let kanaArray = [
|
||||||
|
"あ","い","う","え","お",
|
||||||
|
"か","き","く","け","こ",
|
||||||
|
"さ","し","す","せ","そ",
|
||||||
|
"た","ち","つ","て","と",
|
||||||
|
"な","に","ぬ","ね","の",
|
||||||
|
"は","ひ","ふ","へ","ほ",
|
||||||
|
"ま","み","む","め","も",
|
||||||
|
"や","ゆ","よ",
|
||||||
|
"ら","り","る","れ","ろ",
|
||||||
|
"わ","を","ん"
|
||||||
|
];
|
||||||
|
let romajiArray = [
|
||||||
|
"a","i","u","e","o",
|
||||||
|
"ka","ki","ku","ke","ko",
|
||||||
|
"sa","shi","su","se","so",
|
||||||
|
"ta","chi","tsu","te","to",
|
||||||
|
"na","ni","nu","ne","no",
|
||||||
|
"ha","hi","fu","he","ho",
|
||||||
|
"ma","mi","mu","me","mo",
|
||||||
|
"ya","yu","yo",
|
||||||
|
"ra","ri","ru","re","ro",
|
||||||
|
"wa","wo","n"
|
||||||
|
];
|
||||||
|
|
||||||
|
/*let hiraganaItems = {
|
||||||
|
group1: { a: 'あ', i: 'い', u: 'う', e: 'え', o: 'お' },
|
||||||
|
group2: { ka: 'か', ki: 'き', ku: 'く', ke: 'け', ko: 'こ' }
|
||||||
|
}*/
|
||||||
|
|
||||||
|
class ChooseCharacters extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
hiraganaItems: [
|
||||||
|
{
|
||||||
|
group1: [
|
||||||
|
{ selected: true, a: 'あ', i: 'い', u: 'う', e: 'え', o: 'お' }
|
||||||
|
],
|
||||||
|
group2: [
|
||||||
|
{ selected: false, ka: 'か', ki: 'き', ku: 'く', ke: 'け', ko: 'こ' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
this.startGame = this.startGame.bind(this);
|
||||||
|
this.toggleGroup = this.toggleGroup.bind(this);
|
||||||
|
this.showHiraganaRows = this.showHiraganaRows.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
showHiraganaRows() {
|
||||||
|
return (this.state.hiraganaItems.map(function(groups) {
|
||||||
|
return Object.keys(groups).map(function(group) {
|
||||||
|
return groups[group].map(function(item) {
|
||||||
|
return <CharacterRow characters={groups[group]} selected={item.selected} />
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleGroup(e) {
|
||||||
|
console.log('event: '+e);
|
||||||
|
}
|
||||||
|
|
||||||
|
startGame() {
|
||||||
|
this.props.handleStartGame('foo');
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="choose-characters">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-xs-12">
|
||||||
|
<div className="panel panel-default">
|
||||||
|
<div className="panel-body welcome">
|
||||||
|
<h4>Welcome to Kana Quiz{this.props.nickName !== '' && typeof this.props.nickName !== 'undefined'?', '+this.props.nickName:''}!</h4>
|
||||||
|
<p>Please choose the groups of characters that you'd like to be studying.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-6">
|
||||||
|
<div className="panel panel-default">
|
||||||
|
<div className="panel-heading">Hiragana (ひらがな)</div>
|
||||||
|
<div className="panel-body selection-areas">
|
||||||
|
{this.showHiraganaRows()}
|
||||||
|
</div>
|
||||||
|
<div className="panel-footer text-center"><a href="javascript:;">All</a> · <a href="javascript:;">None</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6">
|
||||||
|
<div className="panel panel-default">
|
||||||
|
<div className="panel-heading">Katakana (カタカナ)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-xs-12 text-center"><button className="btn btn-danger startgame-button" onClick={this.startGame}>Start the Quiz!</button></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChooseCharacters;
|
38
src/components/ChooseCharacters/ChooseCharacters.scss
Normal file
38
src/components/ChooseCharacters/ChooseCharacters.scss
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
.welcome {
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.choose-characters
|
||||||
|
{
|
||||||
|
.panel-heading {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.choose-row {
|
||||||
|
font-size: 1.1em;
|
||||||
|
border-bottom: 1px #eee solid;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.choose-row:hover {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.choose-row:last-child {
|
||||||
|
border-bottom: 0px;
|
||||||
|
}
|
||||||
|
.glyphicon {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
.glyphicon-check {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.glyphicon-unchecked {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
.selection-areas {
|
||||||
|
padding: 7px;
|
||||||
|
}
|
||||||
|
}
|
25
src/components/GameContainer/GameContainer.jsx
Normal file
25
src/components/GameContainer/GameContainer.jsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import ChooseCharacters from '../ChooseCharacters/ChooseCharacters';
|
||||||
|
|
||||||
|
class GameContainer extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.startGame = this.startGame.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
startGame(options) {
|
||||||
|
this.props.handleStartGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let currentScreen = this.props.gameState==='chooseCharacters' ? <ChooseCharacters handleStartGame={this.startGame} nickName={this.props.nickName} /> :
|
||||||
|
(this.props.gameState==='game' ? '<Game />' : '');
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{currentScreen}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GameContainer;
|
|
@ -3,15 +3,24 @@ import './Navbar.scss';
|
||||||
|
|
||||||
class Navbar extends Component {
|
class Navbar extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
let leftLink;
|
||||||
|
switch(this.props.gameState) {
|
||||||
|
case 'chooseCharacters':
|
||||||
|
default:
|
||||||
|
leftLink = <li id="nav-kanaquiz"><a href="javascript:;">Kana Quiz <span>2</span></a></li>
|
||||||
|
break;
|
||||||
|
case 'game':
|
||||||
|
leftLink = <li id="nav-choosecharacters"><a href="#" onClick={this.props.handleEndGame}><span className="glyphicon glyphicon-small glyphicon-arrow-left"></span> Back to menu</a></li>
|
||||||
|
}
|
||||||
let profileButton = this.props.isAuthenticated ?
|
let profileButton = this.props.isAuthenticated ?
|
||||||
<a href="#" onClick={this.props.handleLogout}><span className="glyphicon glyphicon-small glyphicon-user"></span> {this.props.nickName}</a> :
|
<a href="#" onClick={this.props.handleLogout}><span className="glyphicon glyphicon-small glyphicon-log-out"></span> Log out</a> :
|
||||||
<a href="#" onClick={this.props.handleLogin}><span className="glyphicon glyphicon-small glyphicon-user"></span> Log in</a>;
|
<a href="#" onClick={this.props.handleLogin}><span className="glyphicon glyphicon-small glyphicon-log-in"></span> Log in</a>;
|
||||||
return (
|
return (
|
||||||
<nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
<nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div id="navbar">
|
<div id="navbar">
|
||||||
<ul className="nav navbar-nav">
|
<ul className="nav navbar-nav">
|
||||||
<li id="nav-kanaquiz"><a href="javascript:;">Kana Quiz 2</a></li>
|
{leftLink}
|
||||||
</ul>
|
</ul>
|
||||||
<ul className="nav navbar-nav navbar-right">
|
<ul className="nav navbar-nav navbar-right">
|
||||||
<li id="nav-settings"><a href="#"><span className="glyphicon glyphicon-small glyphicon-cog"></span> Settings</a></li>
|
<li id="nav-settings"><a href="#"><span className="glyphicon glyphicon-small glyphicon-cog"></span> Settings</a></li>
|
||||||
|
|
|
@ -1,15 +1,30 @@
|
||||||
#nav-profile {
|
|
||||||
text-transform:capitalize;
|
|
||||||
}
|
|
||||||
#navbar ul li {
|
#navbar ul li {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 1.0em;
|
||||||
|
}
|
||||||
.glyphicon {
|
.glyphicon {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
color: #62bbff;
|
color: #d9534f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navbar-inverse {
|
.navbar-inverse {
|
||||||
background-color: #333;
|
background-color: #444;
|
||||||
|
}
|
||||||
|
.nav a {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
.nav a:hover {
|
||||||
|
color: #bbb !important;
|
||||||
|
}
|
||||||
|
#nav-kanaquiz a, #nav-kanaquiz {
|
||||||
|
color: #fff !important;
|
||||||
|
span {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#nav-kanaquiz a:hover {
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
// From http://getbootstrap.com/examples/non-responsive/non-responsive.css
|
// From http://getbootstrap.com/examples/non-responsive/non-responsive.css
|
||||||
.container .navbar-header,
|
.container .navbar-header,
|
||||||
|
|
Loading…
Reference in a new issue