aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/dialogBox.tsx16
-rw-r--r--components/gameSettings.tsx363
-rw-r--r--styles/ui.css5
-rw-r--r--styles/utility.css7
4 files changed, 188 insertions, 203 deletions
diff --git a/components/dialogBox.tsx b/components/dialogBox.tsx
index 7abbded..0a61762 100644
--- a/components/dialogBox.tsx
+++ b/components/dialogBox.tsx
@@ -1,4 +1,4 @@
-import { CSSProperties, ReactNode } from 'react';
+import { ReactNode } from 'react';
import { Vierkant } from './ui';
@@ -7,20 +7,10 @@ import CancelIcon from '@material-ui/icons/Cancel';
export function DialogBox(props: {
children: ReactNode;
title: string;
- style?: CSSProperties;
onclick?: () => void;
+ hidden?: boolean;
}) {
- return <Vierkant
- style={{
- position: 'fixed',
- top: '50%',
- left: '50%',
- transform: 'translate(-50%, -50%)',
- boxShadow: '0 8px 32px -5px #0007',
- width: 392,
- ...props.style,
- }}
- >
+ return <Vierkant className={'dialogbox drop-2 pad-l posfix abscenter ' + (props.hidden ? 'dispnone' : '')}>
<h2 style={{ marginBottom: 24 }}>{props.title}</h2>
<span onClick={props.onclick}>
<CancelIcon
diff --git a/components/gameSettings.tsx b/components/gameSettings.tsx
index f562e5d..3c3a699 100644
--- a/components/gameSettings.tsx
+++ b/components/gameSettings.tsx
@@ -1,5 +1,5 @@
import axios from 'axios';
-import { Component, CSSProperties, ReactNode } from 'react';
+import { Component, CSSProperties, ReactNode, useEffect, useState } from 'react';
import { ruleset, userPreferences } from '../api/api';
import { DialogBox } from './dialogBox';
@@ -7,106 +7,93 @@ import { Button, CheckBox, Input, Vierkant } from './ui';
import BuildOutlinedIcon from '@material-ui/icons/BuildOutlined';
-type CurrentGameSettingsStateType = {
- editGameRulesDialogVisible: boolean;
- ruleset: ruleset;
-};
-
-export class CurrentGameSettings extends Component {
- state: CurrentGameSettingsStateType = {
- editGameRulesDialogVisible: false,
- ruleset: {
- timelimit: {
- enabled: false,
- shared: false,
- },
- ranked: false,
+export function CurrentGameSettings() {
+ var [editGameRulesDialogVisible, setEditGameRulesDialogVisible] = useState(false);
+ var [ruleset, setRuleset] = useState<ruleset>({
+ timelimit: {
+ enabled: false,
+ shared: false,
+ minutes: 0,
+ seconds: 0,
+ addmove: 0,
},
- };
-
- constructor(props: {}) {
- super(props);
+ ranked: false,
+ });
- if (typeof window === 'undefined') return; // return if run on server
-
- axios.request<userPreferences>({
+ useEffect(() => {
+ axios.request<{ preferences: userPreferences; }>({
method: 'get',
url: `/api/user/preferences`,
headers: { 'content-type': 'application/json' },
})
- // FIXME: this assumes the request ruleset has all properties of a ruleset
- .then(request => this.setState({ ruleset: request.data.ruleset || this.state.ruleset }))
+ .then(request => setRuleset(request.data.preferences.ruleset))
.catch(() => {});
- }
+ }, []);
- showEditGameRules = () => this.setState({ editGameRulesDialogVisible: true });
- hideEditGameRules = () => this.setState({ editGameRulesDialogVisible: false });
- setGameRules = (newRules: ruleset) => this.setState({ ruleset: newRules });
+ /* showEditGameRules = () => this.setState({ editGameRulesDialogVisible: true }); */
+ /* hideEditGameRules = () => this.setState({ editGameRulesDialogVisible: false }); */
+ /* setGameRules = (newRules: ruleset) => this.setState({ ruleset: newRules }); */
- render() {
- var timelimit_str = this.state.ruleset.timelimit.enabled
- ? `${this.state.ruleset.timelimit.minutes}m${this.state.ruleset.timelimit.seconds}s plus ${this.state.ruleset.timelimit.addmove}`
- : 'Geen tijdslimiet';
- var ranked_str = this.state.ruleset.ranked
- ? 'Gerangschikt'
- : 'Niet gerangschikt';
- return <div
+ var timelimit_str = ruleset.timelimit.enabled
+ ? `${ruleset.timelimit.minutes}m${ruleset.timelimit.seconds}s plus ${ruleset.timelimit.addmove}`
+ : 'Geen tijdslimiet';
+ var ranked_str = ruleset.ranked
+ ? 'Gerangschikt'
+ : 'Niet gerangschikt';
+ return <div
+ style={{
+ position: 'relative',
+ height: 80,
+ overflow: 'visible',
+ zIndex: 1,
+ }}
+ >
+ <p
+ className='subtile nosel posabs'
style={{
- position: 'relative',
- height: 80,
- overflow: 'visible',
- zIndex: 1,
+ top: '50%',
+ left: 0,
+ transform: 'translateY(-50%)',
}}
>
- <p
- style={{
- opacity: .75,
- fontStyle: 'italic',
- userSelect: 'none',
- position: 'absolute',
- top: '50%',
- left: 0,
- transform: 'translateY(-50%)',
- }}
- >
- {timelimit_str}
- <br />
- {ranked_str}
- </p>
- <Button
+ {timelimit_str}
+ <br />
+ {ranked_str}
+ </p>
+ <Button
+ style={{
+ width: 150,
+ position: 'absolute',
+ top: '50%',
+ right: 0,
+ transform: 'translateY(-50%)',
+ }}
+ onclick={() => setEditGameRulesDialogVisible(true)}
+ >
+ <BuildOutlinedIcon style={{ fontSize: 48 }} />
+ <span
style={{
- width: 150,
+ fontWeight: 600,
position: 'absolute',
+ right: 24,
top: '50%',
- right: 0,
+ width: 85,
+ verticalAlign: 'middle',
+ textAlign: 'center',
transform: 'translateY(-50%)',
+ userSelect: 'none',
}}
- onclick={this.showEditGameRules}
>
- <BuildOutlinedIcon style={{ fontSize: 48 }} />
- <span
- style={{
- fontWeight: 600,
- position: 'absolute',
- right: 24,
- top: '50%',
- width: 85,
- verticalAlign: 'middle',
- textAlign: 'center',
- transform: 'translateY(-50%)',
- userSelect: 'none',
- }}
- >
- Spelregels aanpassen
- </span>
- </Button>
- <EditGameSettings
- parentState={this.state}
- hideEditGameRules={this.hideEditGameRules}
- setGameRules={this.setGameRules}
- />
- </div>;
- }
+ Spelregels aanpassen
+ </span>
+ </Button>
+ <EditGameSettings
+ hideEditGameRules={() => setEditGameRulesDialogVisible(false)}
+ setGameRules={setRuleset}
+ ruleset={ruleset}
+ visible={editGameRulesDialogVisible}
+ />
+ </div>;
}
function GameSettingsSection(props: {
@@ -168,120 +155,116 @@ function GameRule(props: {
}
type editGameSettingsProps = {
- parentState: CurrentGameSettingsStateType;
+ visible: boolean;
+ ruleset: ruleset;
hideEditGameRules: () => void;
setGameRules: (newRules: ruleset) => void;
};
-export class EditGameSettings extends Component<editGameSettingsProps> {
- render() {
- return <DialogBox
- title='Spelregels aanpassen'
+export function EditGameSettings(props: editGameSettingsProps) {
+ return <DialogBox
+ title='Spelregels aanpassen'
+ hidden={!props.visible}
+ onclick={props.hideEditGameRules}
+ >
+ <div
style={{
- margin: 0,
- display: this.props.parentState.editGameRulesDialogVisible ? 'block' : 'none',
+ marginTop: 24,
+ maxHeight: 500,
+ overflowY: 'scroll',
+ borderRadius: 8,
}}
- onclick={this.props.hideEditGameRules}
>
- <div
- style={{
- marginTop: 24,
- maxHeight: 500,
- overflowY: 'scroll',
- borderRadius: 8,
- }}
+ <GameSettingsSection
+ title='Tijdslimiet'
+ state={props.ruleset.timelimit.enabled}
+ id='timelimit'
>
- <GameSettingsSection
- title='Tijdslimiet'
- state={this.props.parentState.ruleset.timelimit.enabled}
- id='timelimit'
+ <div
+ style={{
+ display: 'grid',
+ gridTemplateColumns: '1fr 1fr 1fr',
+ gridGap: 16,
+ margin: '16px 0',
+ }}
>
- <div
- style={{
- display: 'grid',
- gridTemplateColumns: '1fr 1fr 1fr',
- gridGap: 16,
- margin: '16px 0',
- }}
- >
- <Input
- id='timelimit_minutes'
- type='number'
- label='min'
- min={0}
- max={60}
- value={this.props.parentState.ruleset.timelimit.minutes}
- />
- <Input
- id='timelimit_seconds'
- type='number'
- label='sec'
- min={0}
- max={60}
- value={this.props.parentState.ruleset.timelimit.seconds}
- />
- <Input
- id='timelimit_addmove'
- type='number'
- label='plus'
- min={0}
- value={this.props.parentState.ruleset.timelimit.addmove}
- />
- </div>
- <CheckBox id='timelimit_shared' state={this.props.parentState.ruleset.timelimit.shared} />
- <span
- style={{
- verticalAlign: 'super',
- marginLeft: 4,
- }}
- >
- Timer gebruiken voor bijde spelers
- </span>
- </GameSettingsSection>
- {false && <GameSettingsSection title='Regelset' state={false}>
- <div
- style={{
- display: 'grid',
- gridTemplateColumns: '1fr 1fr',
- gridGap: 16,
- margin: '16px 0',
- }}
- >
- <GameRule title='+2' description='Extra kolommen' />
- <GameRule title='+4' description='Extra kolommen' />
- </div>
- <GameRule style={{ marginBottom: 16 }} title='Gravity' description='De zwaartekracht draait soms' />
- <GameRule title='Flashlight' description='Het veld wordt opgelicht door de vallende fiches' />
- </GameSettingsSection>}
- <GameSettingsSection
- title='Gerangschikt spel'
- state={this.props.parentState.ruleset.ranked}
- id='ranked'
- noMarginBottom
- />
- </div>
- <Button
- style={{
- textAlign: 'center',
- marginTop: 24,
- }}
- onclick={() => {
- var rules: ruleset = {
- timelimit: {
- enabled: document.getElementById('timelimit_enabled').classList.contains('on'),
- minutes: Number((document.getElementById('timelimit_minutes') as HTMLInputElement).value),
- seconds: Number((document.getElementById('timelimit_seconds') as HTMLInputElement).value),
- addmove: Number((document.getElementById('timelimit_addmove') as HTMLInputElement).value),
- shared: document.getElementById('timelimit_shared').classList.contains('on'),
- },
- ranked: document.getElementById('ranked_enabled').classList.contains('on'),
- };
- this.props.setGameRules(rules);
- this.props.hideEditGameRules();
- }}
- >
- Instellingen opslaan
- </Button>
- </DialogBox>;
- }
+ <Input
+ id='timelimit_minutes'
+ type='number'
+ label='min'
+ min={0}
+ max={60}
+ value={props.ruleset.timelimit.minutes}
+ />
+ <Input
+ id='timelimit_seconds'
+ type='number'
+ label='sec'
+ min={0}
+ max={60}
+ value={props.ruleset.timelimit.seconds}
+ />
+ <Input
+ id='timelimit_addmove'
+ type='number'
+ label='plus'
+ min={0}
+ value={props.ruleset.timelimit.addmove}
+ />
+ </div>
+ <CheckBox id='timelimit_shared' state={props.ruleset.timelimit.shared} />
+ <span
+ style={{
+ verticalAlign: 'super',
+ marginLeft: 4,
+ }}
+ >
+ Timer gebruiken voor bijde spelers
+ </span>
+ </GameSettingsSection>
+ {false && <GameSettingsSection title='Regelset' state={false}>
+ <div
+ style={{
+ display: 'grid',
+ gridTemplateColumns: '1fr 1fr',
+ gridGap: 16,
+ margin: '16px 0',
+ }}
+ >
+ <GameRule title='+2' description='Extra kolommen' />
+ <GameRule title='+4' description='Extra kolommen' />
+ </div>
+ <GameRule style={{ marginBottom: 16 }} title='Gravity' description='De zwaartekracht draait soms' />
+ <GameRule title='Flashlight' description='Het veld wordt opgelicht door de vallende fiches' />
+ </GameSettingsSection>}
+ <GameSettingsSection
+ title='Gerangschikt spel'
+ state={props.ruleset.ranked}
+ id='ranked'
+ noMarginBottom
+ />
+ </div>
+ <Button
+ style={{
+ textAlign: 'center',
+ marginTop: 24,
+ }}
+ onclick={() => {
+ var rules: ruleset = {
+ timelimit: {
+ enabled: document.getElementById('timelimit_enabled').classList.contains('on'),
+ minutes: Number((document.getElementById('timelimit_minutes') as HTMLInputElement).value),
+ seconds: Number((document.getElementById('timelimit_seconds') as HTMLInputElement).value),
+ addmove: Number((document.getElementById('timelimit_addmove') as HTMLInputElement).value),
+ shared: document.getElementById('timelimit_shared').classList.contains('on'),
+ },
+ ranked: document.getElementById('ranked_enabled').classList.contains('on'),
+ };
+ props.setGameRules(rules);
+ props.hideEditGameRules();
+ }}
+ >
+ Instellingen opslaan
+ </Button>
+ </DialogBox>;
}
diff --git a/styles/ui.css b/styles/ui.css
index b8cd44c..efc96b7 100644
--- a/styles/ui.css
+++ b/styles/ui.css
@@ -65,3 +65,8 @@
bottom: -12px;
transform: translate(-50%, 0%) rotate(0deg);
}
+
+.dialogbox {
+ width: 392px;
+}
+
diff --git a/styles/utility.css b/styles/utility.css
index f8954cd..0393d1d 100644
--- a/styles/utility.css
+++ b/styles/utility.css
@@ -17,6 +17,7 @@
.posabs { position: absolute; }
.posrel { position: relative; }
+.posfix { position: fixed; }
.t0 { top: 0; }
.b0 { bottom: 0; }
@@ -61,3 +62,9 @@
text-overflow: ellipsis;
}
+.abscenter {
+ top: 51%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+