Merge branch 'master' into ticket/TURNIERE-138
This commit is contained in:
commit
4f079d75ec
|
|
@ -340,6 +340,7 @@ const default_applicationstate = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var __store;
|
var __store;
|
||||||
|
var applicationHydrated = false;
|
||||||
|
|
||||||
export function initializeStore(initialState = default_applicationstate) {
|
export function initializeStore(initialState = default_applicationstate) {
|
||||||
__store = createStore(
|
__store = createStore(
|
||||||
|
|
@ -348,7 +349,9 @@ export function initializeStore(initialState = default_applicationstate) {
|
||||||
composeWithDevTools(applyMiddleware(thunkMiddleware))
|
composeWithDevTools(applyMiddleware(thunkMiddleware))
|
||||||
);
|
);
|
||||||
__store.subscribe(() => {
|
__store.subscribe(() => {
|
||||||
|
if(applicationHydrated) {
|
||||||
localStorage.setItem('reduxState', JSON.stringify(__store.getState()));
|
localStorage.setItem('reduxState', JSON.stringify(__store.getState()));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return __store;
|
return __store;
|
||||||
}
|
}
|
||||||
|
|
@ -449,11 +452,12 @@ function rehydrateApplicationState() {
|
||||||
if(persistedState) {
|
if(persistedState) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.REHYDRATE,
|
type : actiontypes_userinfo.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.userinfo, {})
|
parameters : Object.assign({}, persistedState.userinfo)
|
||||||
});
|
});
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_tournamentinfo.REHYDRATE,
|
type : actiontypes_tournamentinfo.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.tournamentinfo, {})
|
parameters : Object.assign({}, persistedState.tournamentinfo)
|
||||||
});
|
});
|
||||||
|
applicationHydrated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,53 +2,242 @@ import React from 'react';
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
Button,
|
Button,
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
CardTitle,
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
InputGroupAddon
|
InputGroupAddon
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
|
import '../../static/css/editablestringlist.css';
|
||||||
|
|
||||||
export default class EditableStringList extends React.Component {
|
export default class EditableStringList extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
entries: props.entries
|
groupSize: props.groupSize,
|
||||||
|
teams: props.teams,
|
||||||
|
groups: props.groups
|
||||||
};
|
};
|
||||||
this.add = this.add.bind(this);
|
this.add = this.add.bind(this);
|
||||||
this.remove = this.remove.bind(this);
|
this.remove = this.remove.bind(this);
|
||||||
|
this.onGroupSwitch = this.onGroupSwitch.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(text) {
|
add(text) {
|
||||||
if (text === '' || this.state.entries.includes(text)) {
|
if (text === '' || this.state.teams.includes(text)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.state.entries.push(text);
|
this.state.teams.push(text);
|
||||||
this.setState({entries: this.state.entries});
|
|
||||||
this.props.onChange(this.state.entries);
|
var lastGroup = this.state.groups[this.state.groups.length - 1];
|
||||||
|
if(lastGroup === undefined || lastGroup.length >= this.state.groupSize) {
|
||||||
|
this.state.groups[this.state.groups.length] = [];
|
||||||
|
}
|
||||||
|
lastGroup = this.state.groups[this.state.groups.length - 1];
|
||||||
|
lastGroup[lastGroup.length] = text;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
teams: this.state.teams,
|
||||||
|
groups: this.state.groups
|
||||||
|
});
|
||||||
|
|
||||||
|
this.props.onTeamsChange(this.state.teams);
|
||||||
|
this.props.onGroupsChange(this.state.groups);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(text) {
|
remove(text) {
|
||||||
let tmp = this.state.entries.filter(item => item !== text);
|
if(this.removeTeamFromGroup(text) === false) {
|
||||||
this.setState({entries: tmp});
|
return false;
|
||||||
this.props.onChange(tmp);
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
teams: this.state.teams,
|
||||||
|
groups: this.state.groups
|
||||||
|
});
|
||||||
|
|
||||||
|
this.props.onTeamsChange(this.state.teams);
|
||||||
|
this.props.onGroupsChange(this.state.groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeTeamFromGroup(text) {
|
||||||
|
this.state.teams = this.state.teams.filter(item => item !== text);
|
||||||
|
|
||||||
|
let teamIndex = this.findTeam(text);
|
||||||
|
if(teamIndex === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move every first team to the next group
|
||||||
|
this.state.groups[teamIndex.group].splice(teamIndex.team, 1);
|
||||||
|
for(var group = teamIndex.group; group < this.state.groups.length - 1; group++) {
|
||||||
|
let currentGroup = this.state.groups[group];
|
||||||
|
currentGroup[currentGroup.length] = this.state.groups[group + 1].splice(0, 1)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the last group in case it is empty
|
||||||
|
if(this.state.groups[this.state.groups.length - 1].length === 0) {
|
||||||
|
this.state.groups.splice(this.state.groups.length - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
findTeam(text) {
|
||||||
|
for(var group = 0; group < this.state.groups.length; group++) {
|
||||||
|
for(var team = 0; team < this.state.groups[group].length; team++) {
|
||||||
|
if(this.state.groups[group][team] === text) {
|
||||||
|
return {
|
||||||
|
group: group,
|
||||||
|
team: team
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeGroups(newSize) {
|
||||||
|
let oldGroups = this.state.groups;
|
||||||
|
var rearrangedGroups = [];
|
||||||
|
|
||||||
|
for(var oldGroupIndex = 0; oldGroupIndex < oldGroups.length; oldGroupIndex++) {
|
||||||
|
for(var oldTeamIndex = 0; oldTeamIndex < oldGroups[oldGroupIndex].length; oldTeamIndex++) {
|
||||||
|
let index = oldGroupIndex * this.state.groupSize + oldTeamIndex;
|
||||||
|
|
||||||
|
let newGroupIndex = Math.floor(index / newSize);
|
||||||
|
let newTeamIndex = index % newSize;
|
||||||
|
|
||||||
|
if(newTeamIndex === 0) {
|
||||||
|
rearrangedGroups[newGroupIndex] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
rearrangedGroups[newGroupIndex][newTeamIndex] = oldGroups[oldGroupIndex][oldTeamIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
groupSize: newSize,
|
||||||
|
groups: rearrangedGroups
|
||||||
|
});
|
||||||
|
this.props.onGroupsChange(this.state.groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupSwitch(src, dest) {
|
||||||
|
const groupCopy = this.state.groups.slice();
|
||||||
|
|
||||||
|
const srcTeam = groupCopy[src.group][src.team];
|
||||||
|
const destTeam = groupCopy[dest.group][dest.team];
|
||||||
|
|
||||||
|
groupCopy[src.group].splice(src.team, 1, destTeam);
|
||||||
|
groupCopy[dest.group].splice(dest.team, 1, srcTeam);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
groups: groupCopy
|
||||||
|
});
|
||||||
|
this.props.onGroupsChange(this.state.groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if ((typeof this.state.entries !== 'undefined') && this.state.entries.length > 0) {
|
if(this.props.groupSize !== this.state.groupSize) {
|
||||||
|
this.resizeGroups(this.props.groupSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.props.groupPhaseEnabled) {
|
||||||
|
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-light p-3 text-secondary font-italic">
|
<div className="bg-light p-3 text-secondary font-italic">
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
||||||
{this.state.entries.map((text) => <Item text={text} key={text} removeItem={this.remove}/>)}
|
<GroupView groups={this.state.groups} removeTeam={this.remove} onGroupSwitched={this.onGroupSwitch}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className="bg-light p-3 text-secondary text-center font-italic">
|
<div className="bg-light p-3 text-secondary text-center font-italic">
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
||||||
{this.props.placeholder}
|
{this.props.groupPlaceHolder}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
||||||
|
return (
|
||||||
|
<div className="bg-light p-3 text-secondary font-italic">
|
||||||
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
||||||
|
{this.state.teams.map((text) => <Item text={text} key={text} removeItem={this.remove}/>)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className="bg-light p-3 text-secondary text-center font-italic">
|
||||||
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
||||||
|
{this.props.teamPlaceholder}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupView extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{this.props.groups.map((group, groupindex) => (
|
||||||
|
<Card className="group-card" key={groupindex}>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>Group {groupindex + 1}</CardTitle>
|
||||||
|
{group.map((team, teamindex) => (
|
||||||
|
<div key={team} draggable droppable="droppable"
|
||||||
|
className="grouped-team-item"
|
||||||
|
onDragStart={(e) => this.onDragStart(e, groupindex,teamindex)}
|
||||||
|
onDragOver={(e) => this.onDragOver(e)}
|
||||||
|
onDrop={(e) => this.onDrop(e, groupindex, teamindex)}>
|
||||||
|
|
||||||
|
<Item text={team} removeItem={this.props.removeTeam}/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragStart(e, group, team) {
|
||||||
|
e.dataTransfer.setData(
|
||||||
|
'text/plain',
|
||||||
|
JSON.stringify({
|
||||||
|
group: group,
|
||||||
|
team: team
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragOver(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrop(e, group, team) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let src = JSON.parse(e.dataTransfer.getData('text'));
|
||||||
|
let dest = {
|
||||||
|
group: group,
|
||||||
|
team: team
|
||||||
|
};
|
||||||
|
|
||||||
|
this.props.onGroupSwitched(src, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +293,7 @@ class Item extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Alert className="d-inline-block m-2" color="info" isOpen={this.state.visible} toggle={this.onDismiss}>
|
<Alert className="team-item m-2" color="info" isOpen={this.state.visible} toggle={this.onDismiss}>
|
||||||
{this.props.text}
|
{this.props.text}
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
"react-dom": "^16.6.1",
|
"react-dom": "^16.6.1",
|
||||||
"react-favicon": "^0.0.14",
|
"react-favicon": "^0.0.14",
|
||||||
"react-notify-toast": "^0.5.0",
|
"react-notify-toast": "^0.5.0",
|
||||||
|
"react-pose": "^4.0.8",
|
||||||
"react-redux": "^5.1.1",
|
"react-redux": "^5.1.1",
|
||||||
"reactstrap": "^6.5.0",
|
"reactstrap": "^6.5.0",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { notify } from 'react-notify-toast';
|
import { notify } from 'react-notify-toast';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import posed from 'react-pose';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
|
@ -9,7 +10,6 @@ import {
|
||||||
CardBody,
|
CardBody,
|
||||||
Container,
|
Container,
|
||||||
CustomInput,
|
CustomInput,
|
||||||
Fade,
|
|
||||||
Form,
|
Form,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
Input,
|
Input,
|
||||||
|
|
@ -25,7 +25,7 @@ import { createTournament } from '../js/api';
|
||||||
|
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
class PrivateCreatePage extends React.Component {
|
class CreatePage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSignedIn } = this.props;
|
const { isSignedIn } = this.props;
|
||||||
|
|
@ -66,11 +66,9 @@ function mapStateToCreatePageProperties(state) {
|
||||||
return { isSignedIn };
|
return { isSignedIn };
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreatePage = connect(
|
export default connect(
|
||||||
mapStateToCreatePageProperties
|
mapStateToCreatePageProperties
|
||||||
)(PrivateCreatePage);
|
)(CreatePage);
|
||||||
|
|
||||||
export default CreatePage;
|
|
||||||
|
|
||||||
function CreateTournamentCard() {
|
function CreateTournamentCard() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -85,23 +83,41 @@ function CreateTournamentCard() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GroupphaseFader = posed.div({
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
height: 150
|
||||||
|
},
|
||||||
|
hidden: {
|
||||||
|
opacity: 0,
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
class CreateTournamentForm extends React.Component {
|
class CreateTournamentForm extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
fadeIn: false,
|
groupPhaseEnabled: false,
|
||||||
|
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
public: false,
|
public: false,
|
||||||
teams: []
|
|
||||||
|
groupSize: 4,
|
||||||
|
groupAdvance: 1,
|
||||||
|
teams: [],
|
||||||
|
groups: []
|
||||||
};
|
};
|
||||||
this.toggle = this.toggle.bind(this);
|
this.handleGroupPhaseEnabledInput = this.handleGroupPhaseEnabledInput.bind(this);
|
||||||
this.teamListUpdate = this.teamListUpdate.bind(this);
|
this.teamListUpdate = this.teamListUpdate.bind(this);
|
||||||
|
this.groupListUpdate = this.groupListUpdate.bind(this);
|
||||||
this.create = this.create.bind(this);
|
this.create = this.create.bind(this);
|
||||||
this.handleNameInput = this.handleNameInput.bind(this);
|
this.handleNameInput = this.handleNameInput.bind(this);
|
||||||
this.handleDescriptionInput = this.handleDescriptionInput.bind(this);
|
this.handleDescriptionInput = this.handleDescriptionInput.bind(this);
|
||||||
this.handlePublicInput = this.handlePublicInput.bind(this);
|
this.handlePublicInput = this.handlePublicInput.bind(this);
|
||||||
|
this.handleGroupSizeInput = this.handleGroupSizeInput.bind(this);
|
||||||
|
this.handleGroupAdvanceInput = this.handleGroupAdvanceInput.bind(this);
|
||||||
|
|
||||||
this.create = this.create.bind(this);
|
this.create = this.create.bind(this);
|
||||||
}
|
}
|
||||||
|
|
@ -122,24 +138,35 @@ class CreateTournamentForm extends React.Component {
|
||||||
<CustomInput type="checkbox" id="public"
|
<CustomInput type="checkbox" id="public"
|
||||||
label="Turnier öffentlich anzeigen (schreibgeschützt)" checked={this.state.public} onChange={this.handlePublicInput}/>
|
label="Turnier öffentlich anzeigen (schreibgeschützt)" checked={this.state.public} onChange={this.handlePublicInput}/>
|
||||||
<CustomInput type="checkbox" id="mix-teams" label="Teams mischen"/>
|
<CustomInput type="checkbox" id="mix-teams" label="Teams mischen"/>
|
||||||
<CustomInput type="checkbox" id="group-phase" label="Gruppenphase" onClick={this.toggle}/>
|
<CustomInput type="checkbox" id="group-phase" label="Gruppenphase"
|
||||||
|
checked={this.state.groupPhaseEnabled} onChange={this.handleGroupPhaseEnabledInput}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<Fade in={this.state.fadeIn} tag="div" className="mt-3" baseClass="d-none"
|
<GroupphaseFader pose={this.state.groupPhaseEnabled? 'visible' : 'hidden'} className="groupphasefader">
|
||||||
baseClassActive="d-block">
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="teams-per-group">Anzahl Teams pro Gruppe</Label>
|
<Label for="teams-per-group">Anzahl Teams pro Gruppe</Label>
|
||||||
<Input type="number" name="teams-per-group" size="255"/>
|
<Input type="number" name="teams-per-group" min="3"
|
||||||
|
value={this.state.groupSize} onChange={this.handleGroupSizeInput}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="teams-group-to-playoff">Wie viele Teams sollen nach der Gruppenphase
|
<Label for="teams-group-to-playoff">Wie viele Teams sollen nach der Gruppenphase
|
||||||
weiterkommen?</Label>
|
weiterkommen?</Label>
|
||||||
<Input type="number" name="teams-group-to-playoff" size="255"/>
|
<Input type="number" name="teams-group-to-playoff" min="1" max={this.state.groupSize - 1}
|
||||||
|
value={this.state.groupAdvance} onChange={this.handleGroupAdvanceInput}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Fade>
|
</GroupphaseFader>
|
||||||
</Form>
|
</Form>
|
||||||
<h3 className="custom-font mt-4">Teams</h3>
|
<h3 className="custom-font mt-4">Teams</h3>
|
||||||
<EditableStringList addButtonText="hinzufügen" placeholder="Keine Teams hinzugefügt!" entries={[]}
|
<EditableStringList
|
||||||
onChange={this.teamListUpdate} inputPlaceholder="Teamname"/>
|
addButtonText="hinzufügen"
|
||||||
|
teamPlaceholder="Keine Teams hinzugefügt!"
|
||||||
|
groupPlaceHolder="Keine Gruppen verfügbar!"
|
||||||
|
teams={[]}
|
||||||
|
groups={[]}
|
||||||
|
groupPhaseEnabled={this.state.groupPhaseEnabled}
|
||||||
|
groupSize={this.state.groupSize}
|
||||||
|
onTeamsChange={this.teamListUpdate}
|
||||||
|
onGroupsChange={this.groupListUpdate}
|
||||||
|
inputPlaceholder="Teamname"/>
|
||||||
<Button color="success" size="lg" className="w-100 shadow-sm mt-4" onClick={this.create}>Turnier erstellen</Button>
|
<Button color="success" size="lg" className="w-100 shadow-sm mt-4" onClick={this.create}>Turnier erstellen</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -149,10 +176,28 @@ class CreateTournamentForm extends React.Component {
|
||||||
this.setState({teams: list});
|
this.setState({teams: list});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle() {
|
groupListUpdate(list) {
|
||||||
|
this.setState({groups: list});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGroupSizeInput(input) {
|
||||||
|
let newSize = input.target.value;
|
||||||
|
if(newSize <= this.state.groupAdvance) {
|
||||||
this.setState({
|
this.setState({
|
||||||
fadeIn: !this.state.fadeIn
|
groupSize: newSize,
|
||||||
|
groupAdvance: newSize - 1
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({ groupSize: newSize });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGroupAdvanceInput(input) {
|
||||||
|
this.setState({ groupAdvance: input.target.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGroupPhaseEnabledInput(input) {
|
||||||
|
this.setState({ groupPhaseEnabled: input.target.checked });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNameInput(input) {
|
handleNameInput(input) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
.group-card {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-item {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grouped-team-item {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
border-radius: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grouped-team-item:last-child {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grouped-team-item > .m-2 {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
116
yarn.lock
116
yarn.lock
|
|
@ -715,6 +715,18 @@
|
||||||
lodash "^4.17.11"
|
lodash "^4.17.11"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@emotion/is-prop-valid@^0.7.3":
|
||||||
|
version "0.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz#a6bf4fa5387cbba59d44e698a4680f481a8da6cc"
|
||||||
|
integrity sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "0.7.1"
|
||||||
|
|
||||||
|
"@emotion/memoize@0.7.1":
|
||||||
|
version "0.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
|
||||||
|
integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==
|
||||||
|
|
||||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
||||||
|
|
@ -728,6 +740,21 @@
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
||||||
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
||||||
|
|
||||||
|
"@popmotion/easing@^1.0.1":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.2.tgz#17d925c45b4bf44189e5a38038d149df42d8c0b4"
|
||||||
|
integrity sha512-IkdW0TNmRnWTeWI7aGQIVDbKXPWHVEYdGgd5ZR4SH/Ty/61p63jCjrPxX1XrR7IGkl08bjhJROStD7j+RKgoIw==
|
||||||
|
|
||||||
|
"@popmotion/popcorn@^0.3.6":
|
||||||
|
version "0.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.3.6.tgz#eb4e3a04dd45c9516cc55b3350760ff47d7d55da"
|
||||||
|
integrity sha512-B8Hdk4LOjCHTIiUd9KfD+9PgLR2iSe9T/X5G9IAl055KY2iAqodIEtTlO6EBpjP8tQWVfI3C4A/fEf0RqYqPPw==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
framesync "^4.0.1"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
style-value-types "^3.1.0"
|
||||||
|
|
||||||
"@samverschueren/stream-to-observable@^0.3.0":
|
"@samverschueren/stream-to-observable@^0.3.0":
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
||||||
|
|
@ -740,6 +767,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
||||||
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
|
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
|
||||||
|
|
||||||
|
"@types/invariant@^2.2.29":
|
||||||
|
version "2.2.29"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.29.tgz#aa845204cd0a289f65d47e0de63a6a815e30cc66"
|
||||||
|
integrity sha512-lRVw09gOvgviOfeUrKc/pmTiRZ7g7oDOU6OAutyuSHpm1/o2RaBQvRhgK8QEdu+FFuw/wnWb29A/iuxv9i8OpQ==
|
||||||
|
|
||||||
|
"@types/node@^10.0.5":
|
||||||
|
version "10.14.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
|
||||||
|
integrity sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.7.8":
|
"@webassemblyjs/ast@1.7.8":
|
||||||
version "1.7.8"
|
version "1.7.8"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.8.tgz#f31f480debeef957f01b623f27eabc695fa4fe8f"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.8.tgz#f31f480debeef957f01b623f27eabc695fa4fe8f"
|
||||||
|
|
@ -3703,6 +3740,13 @@ fragment-cache@^0.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
map-cache "^0.2.2"
|
map-cache "^0.2.2"
|
||||||
|
|
||||||
|
framesync@^4.0.0, framesync@^4.0.1:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.0.2.tgz#b03b62852f12b0d80086b60834b089718f03cda5"
|
||||||
|
integrity sha512-hQLD5NURHmzB4Symo6JJ5HDw2TWwhr6T3gw9aChNMsZvkxcD8U8Gcz/hllAOOMGE+HO3ScpRPahpXDQRgF19JQ==
|
||||||
|
dependencies:
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
|
||||||
fresh@0.5.2:
|
fresh@0.5.2:
|
||||||
version "0.5.2"
|
version "0.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||||
|
|
@ -4095,6 +4139,11 @@ hash.js@^1.0.0, hash.js@^1.0.3:
|
||||||
inherits "^2.0.3"
|
inherits "^2.0.3"
|
||||||
minimalistic-assert "^1.0.1"
|
minimalistic-assert "^1.0.1"
|
||||||
|
|
||||||
|
hey-listen@^1.0.4, hey-listen@^1.0.5:
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
|
||||||
|
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
|
||||||
|
|
||||||
hmac-drbg@^1.0.0:
|
hmac-drbg@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||||
|
|
@ -6088,11 +6137,47 @@ pkg-dir@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^3.0.0"
|
find-up "^3.0.0"
|
||||||
|
|
||||||
|
popmotion-pose@^3.4.0:
|
||||||
|
version "3.4.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/popmotion-pose/-/popmotion-pose-3.4.7.tgz#faa55f5a61f249e7615f536529ed65989f2d031c"
|
||||||
|
integrity sha512-mOn9fovrAiCRxANGnFyIGSYN9YArhJXbeK9Az5HBSoC3bUbhJ1heYguzboqg/jfrgEoPZ6UdUTgJsyivlYMsPg==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
popmotion "^8.6.2"
|
||||||
|
pose-core "^2.1.0"
|
||||||
|
style-value-types "^3.0.6"
|
||||||
|
ts-essentials "^1.0.3"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
|
popmotion@^8.6.2:
|
||||||
|
version "8.6.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-8.6.8.tgz#ccc1eaf1613f0611ba6b48d8171c25a518a1e917"
|
||||||
|
integrity sha512-BRzdgEHLqicl18RH2+gev/gVAQsU6OJD2eXii+J8Jabvw//fTNdkKIi+o8YM1cFU2QH+bnAAr0PEC3eiXMPJ1w==
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
"@popmotion/popcorn" "^0.3.6"
|
||||||
|
framesync "^4.0.0"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
style-value-types "^3.1.0"
|
||||||
|
stylefire "2.4.3"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
popper.js@^1.14.1:
|
popper.js@^1.14.1:
|
||||||
version "1.14.7"
|
version "1.14.7"
|
||||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.7.tgz#e31ec06cfac6a97a53280c3e55e4e0c860e7738e"
|
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.7.tgz#e31ec06cfac6a97a53280c3e55e4e0c860e7738e"
|
||||||
integrity sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==
|
integrity sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==
|
||||||
|
|
||||||
|
pose-core@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pose-core/-/pose-core-2.1.0.tgz#653c85a9a06f924611b909b4a2180ce102bbb258"
|
||||||
|
integrity sha512-36mVAnIgbM6jfyRug8EqqFbazHUAk9dxwVRpX61FlVw3amI/j7AFegtVU56N0Dht2aYDJIhgYPUYraT1CzjHDw==
|
||||||
|
dependencies:
|
||||||
|
"@types/invariant" "^2.2.29"
|
||||||
|
"@types/node" "^10.0.5"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
posix-character-classes@^0.1.0:
|
posix-character-classes@^0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||||
|
|
@ -6462,6 +6547,16 @@ react-popper@^0.10.4:
|
||||||
popper.js "^1.14.1"
|
popper.js "^1.14.1"
|
||||||
prop-types "^15.6.1"
|
prop-types "^15.6.1"
|
||||||
|
|
||||||
|
react-pose@^4.0.8:
|
||||||
|
version "4.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-pose/-/react-pose-4.0.8.tgz#91bdfafde60e4096e7878a35dcc77715bed68f24"
|
||||||
|
integrity sha512-WN/583nKJZkKmKg5ha+eErOGWF9GV6A5EngC7WHQX5b910X9rTlOlxzdKlUy/dDcsTRMZEtHV0Sy2gLPYsVQCQ==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/is-prop-valid" "^0.7.3"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
popmotion-pose "^3.4.0"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
react-redux@^5.1.1:
|
react-redux@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.1.tgz#88e368682c7fa80e34e055cd7ac56f5936b0f52f"
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.1.tgz#88e368682c7fa80e34e055cd7ac56f5936b0f52f"
|
||||||
|
|
@ -7456,6 +7551,11 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||||
|
|
||||||
|
style-value-types@^3.0.6, style-value-types@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.1.0.tgz#07e06090e7581adff4c7955d544c1029d0663795"
|
||||||
|
integrity sha512-7eaMZ8RKWIQUKHPQK7qv3zLYmvZNb2pCmO4WguXdVFymd2Qj9xqSUoo7LQ8Wd8eiLuoSd+uqzsvcodyvD8nn6Q==
|
||||||
|
|
||||||
styled-jsx@3.1.0:
|
styled-jsx@3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.1.0.tgz#c295e4170298b5bb858f848c4b73e423a73a68f3"
|
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.1.0.tgz#c295e4170298b5bb858f848c4b73e423a73a68f3"
|
||||||
|
|
@ -7470,6 +7570,15 @@ styled-jsx@3.1.0:
|
||||||
stylis "3.5.3"
|
stylis "3.5.3"
|
||||||
stylis-rule-sheet "0.0.10"
|
stylis-rule-sheet "0.0.10"
|
||||||
|
|
||||||
|
stylefire@2.4.3:
|
||||||
|
version "2.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/stylefire/-/stylefire-2.4.3.tgz#1b39847251000bda86ebf82fa2bb4be7dafe6bc4"
|
||||||
|
integrity sha512-8rckFzuDlVWSyrkmnyTg8avadQavk2t6YkFKUUocsXoj/8NScOjb+/avbB4nrmoPtzD0kN7IyuhKq8jimIBTBQ==
|
||||||
|
dependencies:
|
||||||
|
framesync "^4.0.0"
|
||||||
|
hey-listen "^1.0.4"
|
||||||
|
style-value-types "^3.0.6"
|
||||||
|
|
||||||
stylis-rule-sheet@0.0.10:
|
stylis-rule-sheet@0.0.10:
|
||||||
version "0.0.10"
|
version "0.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430"
|
resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430"
|
||||||
|
|
@ -7676,7 +7785,12 @@ trim-right@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||||
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
|
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
|
||||||
|
|
||||||
tslib@^1.9.0:
|
ts-essentials@^1.0.3:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a"
|
||||||
|
integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==
|
||||||
|
|
||||||
|
tslib@^1.9.0, tslib@^1.9.1:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||||
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
|
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue