aboutsummaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorlonkaars <l.leblansch@gmail.com>2021-01-16 11:40:36 +0100
committerlonkaars <l.leblansch@gmail.com>2021-01-16 11:40:36 +0100
commitd2c2cc62a4c2e1ac10f8434bea7bb834da820869 (patch)
treed8d0ed49957d1103a0fd79d4bb2928d7e1b5846e /components
parentbe52cd3265f93b09fc400ecaa58cde0a93ed41e6 (diff)
semi working next project
Diffstat (limited to 'components')
-rw-r--r--components/account.tsx16
-rw-r--r--components/dialogBox.tsx30
-rw-r--r--components/gameBar.tsx88
-rw-r--r--components/gameSettings.tsx134
-rw-r--r--components/logo.tsx28
-rw-r--r--components/navbar.tsx63
-rw-r--r--components/page.tsx32
-rw-r--r--components/toast.tsx78
-rw-r--r--components/ui.tsx132
-rw-r--r--components/voerBord.tsx39
10 files changed, 640 insertions, 0 deletions
diff --git a/components/account.tsx b/components/account.tsx
new file mode 100644
index 0000000..e6ec58f
--- /dev/null
+++ b/components/account.tsx
@@ -0,0 +1,16 @@
+interface AccountAvatarProps {
+ size: number;
+ image: string;
+}
+
+export function AccountAvatar(props: AccountAvatarProps) {
+ return <div style={{
+ width: props.size,
+ height: props.size,
+ backgroundImage: props.image,
+ backgroundSize: "cover",
+ display: "inline-block"
+ }}/>;
+}
+
+
diff --git a/components/dialogBox.tsx b/components/dialogBox.tsx
new file mode 100644
index 0000000..74fe99b
--- /dev/null
+++ b/components/dialogBox.tsx
@@ -0,0 +1,30 @@
+import { ReactNode } from 'react';
+
+import { Vierkant } from './ui';
+
+import CancelIcon from '@material-ui/icons/Cancel';
+
+interface DialogBoxProps {
+ children: ReactNode;
+ title: string;
+}
+
+export function DialogBox(props: DialogBoxProps) {
+ return <Vierkant style={{
+ position: "fixed",
+ top: "50%", left: "50%",
+ transform: "translate(-50%, -50%)",
+ boxShadow: "0 8px 32px -5px #0007",
+ width: 392
+ }}>
+ <h2 style={{ marginBottom: 24 }}>{props.title}</h2>
+ <CancelIcon style={{
+ position: "absolute",
+ top: 25, right: 25,
+ color: "var(--text)",
+ opacity: .85,
+ cursor: "pointer"
+ }}/>
+ {props.children}
+ </Vierkant>
+}
diff --git a/components/gameBar.tsx b/components/gameBar.tsx
new file mode 100644
index 0000000..53eda88
--- /dev/null
+++ b/components/gameBar.tsx
@@ -0,0 +1,88 @@
+import { CSSProperties, ReactNode } from 'react';
+import { Vierkant } from './ui';
+
+import SettingsRoundedIcon from '@material-ui/icons/SettingsRounded';
+import ExitToAppRoundedIcon from '@material-ui/icons/ExitToAppRounded';
+import NavigateNextRoundedIcon from '@material-ui/icons/NavigateNextRounded';
+import NavigateBeforeRoundedIcon from '@material-ui/icons/NavigateBeforeRounded';
+
+interface GameBarModuleProps {
+ children?: ReactNode;
+}
+
+function GameBarModule(props: GameBarModuleProps) {
+ return <Vierkant style={{
+ backgroundColor: "var(--background-alt)",
+ padding: 12,
+ borderRadius: 6,
+ margin: 0,
+ verticalAlign: "top"
+ }}>{props.children}</Vierkant>
+}
+
+var GameBarSpacer = () => <div style={{ width: 8, display: "inline-block" }}></div>;
+
+var GameBarAlignStyle: CSSProperties = {
+ display: "inline-block"
+}
+
+export function GameBar() {
+ return <Vierkant className="gameBar" style={{
+ padding: 8,
+ width: "calc(100% - 12px)"
+ }}>
+ <div style={{ gridAutoColumns: "auto" }}>
+ <div style={{ ...GameBarAlignStyle, float: "left" }}>
+ <div style={{
+ width: 32, height: 32,
+ margin: 8,
+ backgroundColor: "var(--disk-b)",
+ borderRadius: 16,
+ display: "inline-block"
+ }}/>
+ <h2 style={{
+ fontSize: 20,
+ margin: 12,
+ verticalAlign: "top",
+ display: "inline-block"
+ }}>Tegenstander</h2>
+ </div>
+ <div style={{
+ ...GameBarAlignStyle,
+ position: "absolute",
+ top: "50%", left: "50%",
+ transform: "translate(-50%, -50%)"
+ }}>
+ <span style={{
+ color: "var(--text)",
+ fontSize: 20,
+ opacity: .75
+ }}>0-0</span>
+ </div>
+ <div style={{ ...GameBarAlignStyle, float: "right" }}>
+ <GameBarModule>
+ <SettingsRoundedIcon/>
+ </GameBarModule>
+ <GameBarSpacer/>
+ <GameBarModule>
+ <span style={{
+ margin: "0 4px",
+ fontSize: 20
+ }}>00:00</span>
+ </GameBarModule>
+ <GameBarSpacer/>
+ <GameBarModule>
+ <ExitToAppRoundedIcon/>
+ </GameBarModule>
+ <GameBarSpacer/>
+ <GameBarModule>
+ <NavigateBeforeRoundedIcon/>
+ </GameBarModule>
+ <GameBarSpacer/>
+ <GameBarModule>
+ <NavigateNextRoundedIcon/>
+ </GameBarModule>
+ </div>
+ </div>
+ </Vierkant>;
+}
diff --git a/components/gameSettings.tsx b/components/gameSettings.tsx
new file mode 100644
index 0000000..fb5188e
--- /dev/null
+++ b/components/gameSettings.tsx
@@ -0,0 +1,134 @@
+import { ReactNode, CSSProperties } from 'react';
+
+import { Button, Vierkant, CheckBox, Input } from './ui';
+import { DialogBox } from './dialogBox';
+
+import BuildRoundedIcon from '@material-ui/icons/BuildRounded';
+
+export function CurrentGameSettings(/*props: CurrentGameSettingsProps*/) {
+ return <div style={{
+ position: "relative",
+ height: 80
+ }}>
+ <p style={{
+ opacity: .75,
+ fontStyle: "italic",
+ userSelect: "none",
+ position: "absolute",
+ top: "50%",
+ left: 0,
+ transform: "translateY(-50%)"
+ }}>
+ Geen tijdslimiet<br/>
+ Standaardregels<br/>
+ Gerangschikt
+ </p>
+ <Button style={{
+ width: 150,
+ position: "absolute",
+ top: "50%",
+ right: 0,
+ transform: "translateY(-50%)"
+ }}>
+ <BuildRoundedIcon 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>
+ </div>;
+}
+
+function GameSettingsSection(props: {
+ children?: ReactNode;
+ title: string;
+ state: boolean;
+ noMarginBottom?: boolean;
+}) {
+ return <Vierkant style={{
+ backgroundColor: "var(--background-alt)",
+ width: "100%",
+ padding: 16,
+ margin: 0,
+ marginBottom: props.noMarginBottom ? 0 : 24
+ }}>
+ <span style={{
+ verticalAlign: "top",
+ fontSize: 14,
+ fontWeight: 600
+ }}>{props.title}</span>
+ <CheckBox state={props.state} style={{
+ verticalAlign: "top",
+ float: "right",
+ margin: -3
+ }}/>
+ <div>{props.children}</div>
+ </Vierkant>
+}
+
+function GameRule(props: {
+ title: string;
+ description: string;
+ style?: CSSProperties;
+}) {
+ return <div style={{
+ backgroundColor: "var(--page-background)",
+ borderRadius: 8,
+ padding: "16px 0",
+ textAlign: "center",
+ ...props.style
+ }}>
+ <h1 style={{ color: "var(--disk-a)", fontSize: 42 }}>{props.title}</h1>
+ <p style={{ color: "var(--text-alt)", maxWidth: 250, margin: "0 auto" }}>{props.description}</p>
+ </div>;
+}
+
+export function EditGameSettings() {
+ return <DialogBox title="Spelregels aanpassen">
+ <div style={{
+ marginTop: 24,
+ maxHeight: 500,
+ overflowY: "scroll",
+ borderRadius: 8
+ }}>
+ <GameSettingsSection title="Tijdslimiet" state={false}>
+ <div style={{
+ display: "grid",
+ gridTemplateColumns: "1fr 1fr 1fr",
+ gridGap: 16,
+ margin: "16px 0"
+ }}>
+ <Input type="number" label="min"/>
+ <Input type="number" label="sec"/>
+ <Input type="number" label="plus"/>
+ </div>
+ <CheckBox state={false}/>
+ <span style={{
+ verticalAlign: "super",
+ marginLeft: 4
+ }}>Timer gebruiken voor bijde spelers</span>
+ </GameSettingsSection>
+ <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={true} noMarginBottom/>
+ </div>
+ </DialogBox>;
+}
diff --git a/components/logo.tsx b/components/logo.tsx
new file mode 100644
index 0000000..b0f358f
--- /dev/null
+++ b/components/logo.tsx
@@ -0,0 +1,28 @@
+export function LogoDark() {
+ return (
+ <div className="noclick">
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <rect width="24" height="24" fill="var(--background)"/>
+ <circle cx="6.5" cy="6.5" r="4.5" fill="var(--disk-b)"/>
+ <circle cx="6.5" cy="17.5" r="4.5" fill="var(--disk-a)"/>
+ <circle cx="17.5" cy="17.5" r="4.5" fill="var(--disk-b)"/>
+ <circle cx="17.5" cy="6.5" r="3.5" stroke="var(--text)" strokeWidth="2"/>
+ </svg>
+ </div>
+ );
+}
+
+export function LogoLight() {
+ return (
+ <div className="noclick">
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <rect width="24" height="24" fill="var(--page-background)"/>
+ <circle cx="6.5" cy="6.5" r="4.5" fill="var(--disk-b)"/>
+ <circle cx="6.5" cy="17.5" r="4.5" fill="var(--disk-a)"/>
+ <circle cx="17.5" cy="17.5" r="4.5" fill="var(--disk-b)"/>
+ <circle cx="17.5" cy="6.5" r="3.5" stroke="var(--background)" strokeWidth="2"/>
+ </svg>
+ </div>
+ );
+}
+
diff --git a/components/navbar.tsx b/components/navbar.tsx
new file mode 100644
index 0000000..7725ca8
--- /dev/null
+++ b/components/navbar.tsx
@@ -0,0 +1,63 @@
+import { CSSProperties } from "react";
+
+import { LogoDark } from "../components/logo";
+
+import Home from '@material-ui/icons/Home';
+import VideogameAssetIcon from '@material-ui/icons/VideogameAsset';
+import ExtensionIcon from '@material-ui/icons/Extension';
+import SearchIcon from '@material-ui/icons/Search';
+import SettingsIcon from '@material-ui/icons/Settings';
+import PersonIcon from '@material-ui/icons/Person';
+
+var NavBarItemStyle: CSSProperties = {
+ margin: 12,
+ marginBottom: 16,
+ display: "block"
+}
+
+export function NavBar() {
+ return (
+ <div className="navbar" style={{
+ width: 48,
+ height: "100%",
+
+ lineHeight: 0,
+
+ backgroundColor: "var(--background)",
+ display: "inline-block",
+
+ position: "fixed",
+ top: 0,
+ left: 0,
+
+ overflow: "hidden",
+ whiteSpace: "nowrap"
+ }}>
+ <div style={NavBarItemStyle}><LogoDark/></div>
+ <a href="/" style={NavBarItemStyle}><Home/></a>
+ <a href="/game" style={NavBarItemStyle}><VideogameAssetIcon/></a>
+ <a href="/" style={NavBarItemStyle}><ExtensionIcon/></a>
+ <a href="/" style={NavBarItemStyle}><SearchIcon/></a>
+
+ <div style={{
+ position: "absolute",
+ bottom: -4,
+ left: 0,
+ backgroundColor: "var(--background)"
+ }}>
+ <a href="/login" style={NavBarItemStyle}>
+ <div style={{
+ width: 24,
+ height: 24,
+ /* background: "#888888", */
+ borderRadius: 12
+ }}>
+ <PersonIcon/>
+ </div>
+ </a>
+ <a href="/settings" style={NavBarItemStyle}><SettingsIcon/></a>
+ </div>
+ </div>
+ );
+}
+
diff --git a/components/page.tsx b/components/page.tsx
new file mode 100644
index 0000000..d8a4a2b
--- /dev/null
+++ b/components/page.tsx
@@ -0,0 +1,32 @@
+import { Component, CSSProperties, ReactNode } from 'react';
+
+interface CenteredPageProps {
+ width?: number;
+ children?: ReactNode;
+ style?: CSSProperties;
+}
+
+export function CenteredPage (props: CenteredPageProps) {
+ return <div className="CenteredPageOuter" style={{
+ maxWidth: props.width,
+ margin: "0 auto"
+ }}>
+ <div className="CenteredPageInner" style={{
+ margin: "0 6px",
+ lineHeight: 0,
+ ...props.style
+ }}>{props.children}</div>
+ </div>;
+}
+
+export class PageTitle extends Component {
+ render () {
+ return <h1 style={{
+ color: "var(--text-alt)",
+ marginLeft: 6,
+ marginTop: 32,
+ marginBottom: 64,
+ fontSize: 25,
+ }}>{this.props.children}</h1>;
+ }
+}
diff --git a/components/toast.tsx b/components/toast.tsx
new file mode 100644
index 0000000..1d467bd
--- /dev/null
+++ b/components/toast.tsx
@@ -0,0 +1,78 @@
+import { CSSProperties, ReactNode, Component } from "react";
+
+import CloseIcon from '@material-ui/icons/Close';
+
+export function ToastArea(props: {
+ style?: CSSProperties
+ children?: ReactNode
+}) {
+ return <div id="ToastArea" style={{
+ position: "fixed",
+ whiteSpace: "nowrap",
+ bottom: 12,
+ left: "50%",
+ transform: "translateX(-50%)",
+ zIndex: 1,
+ maxWidth: 600,
+ width: "calc(100% - 48px - 48px)",
+ margin: "0 24px",
+ ...props.style
+ }}>{props.children}</div>
+}
+
+export class Toast extends Component<{
+ text?: string
+ icon?: ReactNode
+ children?: ReactNode
+ type?: "normal"|"confirmation"|"error"
+ style?: CSSProperties
+}> {
+ state = { render: true }
+
+ close = () => this.setState({ render: false })
+
+ render () {
+ if (!this.state.render) return null;
+ return <div style={{
+ padding: 0,
+ marginBottom: 12,
+ borderRadius: 8,
+ color: "var(--text)",
+ boxShadow: "0 8px 12px -4px #00000033",
+ backgroundColor:
+ this.props.type === "normal" ? "var(--background)" :
+ this.props.type === "confirmation" ? "var(--disk-a)" :
+ this.props.type === "error" ? "var(--disk-b)" : "var(--background)",
+ ...this.props.style
+ }}>
+ {
+ this.props.children ?
+ this.props.children :
+ <div style={{ lineHeight: 0 }}>
+ <div style={{
+ fontSize: 0,
+ margin: 16,
+ display: "inline-block",
+ verticalAlign: "top",
+ width: 32, height: 32
+ }}>{this.props.icon}</div>
+ <h2 style={{
+ margin: "20px 0",
+ display: "inline-block",
+ width: "calc(100% - 128px)",
+ verticalAlign: "top",
+ fontSize: 20
+ }}>{this.props.text}</h2>
+ <div style={{
+ padding: 20,
+ display: "inline-block",
+ cursor: "pointer"
+ }} onClick={this.close}>
+ <CloseIcon style={{ fontSize: 24 }}/>
+ </div>
+ </div>
+ }
+ </div>
+ }
+}
+
diff --git a/components/ui.tsx b/components/ui.tsx
new file mode 100644
index 0000000..3afd97a
--- /dev/null
+++ b/components/ui.tsx
@@ -0,0 +1,132 @@
+import { Component, CSSProperties, ReactNode } from "react";
+
+import SearchIcon from '@material-ui/icons/Search';
+import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
+import CheckBoxIcon from '@material-ui/icons/CheckBox';
+
+export function Vierkant(props: {
+ href?: string;
+ width?: string;
+ height?: string;
+ style?: CSSProperties;
+ children?: ReactNode;
+ className?: string; })
+{
+ return <a style={{
+ padding: 24,
+ backgroundColor: "var(--background)",
+ borderRadius: 8,
+ color: "var(--text)",
+ margin: 6, // geen margin collapse = 12px marge
+ display: "inline-block",
+ position: "relative",
+ boxSizing: "border-box",
+ width: props.width ? props.width : undefined,
+ height: props.height ? props.height : undefined,
+ ...props.style
+ }} href={props.href} className={props.className}>{props.children}</a>
+}
+
+export function Button(props: {
+ text?: string;
+ children?: ReactNode;
+ style?: CSSProperties;
+ href?: string;
+ onclick?: (() => void); })
+{
+ return <a onClick={props.onclick} href={props.href} style={{
+ padding: props.text ? 8 : 16,
+ textAlign: props.text ? "center" : "left",
+ borderRadius: 8,
+ backgroundColor: "var(--disk-a)",
+ cursor: "pointer",
+ position: "relative",
+ textDecoration: "none",
+ display: "block",
+ ...props.style
+ }}>
+ {
+ props.text ?
+ <span style={{
+ fontWeight: 600,
+ userSelect: "none"
+ }}>{props.text}</span>
+ : undefined
+ }
+ { props.children }
+ </a>;
+}
+
+export function Input(props: {
+ label?: string,
+ style?: CSSProperties,
+ type?: string,
+ id?: string
+}) {
+ return <input id={props.id} type={props.type || "text"} placeholder={props.label} spellCheck={false} style={{
+ padding: 12,
+ border: 0,
+ width: "calc(100% - 24px)",
+ fontSize: 14,
+ backgroundColor: "var(--page-background)",
+ color: "var(--text-alt)",
+ borderRadius: 8,
+ fontFamily: "Inter",
+ ...props.style
+ }}/>
+}
+
+export function SearchBar(props: { label?: string }) {
+ return <div style={{
+ marginTop: 24,
+ borderRadius: 8,
+ overflow: "hidden",
+ width: "100%"
+ }}>
+ <Input label={props.label} style={{
+ width: "calc(100% - 24px - 41px)",
+ borderTopRightRadius: 0,
+ borderBottomRightRadius: 0
+ }}/>
+ <div style={{
+ width: 41,
+ height: 41,
+ backgroundColor: "var(--disk-a)",
+ display: "inline-block",
+ verticalAlign: "top",
+ position: "relative"
+ }}>
+ <SearchIcon style={{
+ fontSize: 24,
+ position: "absolute",
+ top: "50%", left: "50%",
+ transform: "translate(-50%, -50%)"
+ }}/>
+ </div>
+ </div>
+}
+
+export class CheckBox extends Component<{
+ state?: boolean,
+ style?: CSSProperties
+}> {
+ state = { on: this.props.state || false }
+ public toggle = () => this.setState({ on: !this.state.on })
+
+ render() {
+ return <div onClick={this.toggle} style={{
+ ...this.props.style,
+ display: "inline-block",
+ cursor: "pointer"
+ }}>
+ {
+ this.state.on ?
+ <CheckBoxIcon style={{ fontSize: 24 }}/> :
+ <CheckBoxOutlineBlankIcon style={{ fontSize: 24 }}/>
+ }
+ </div>;
+ }
+}
+
+
+
diff --git a/components/voerBord.tsx b/components/voerBord.tsx
new file mode 100644
index 0000000..3e319a1
--- /dev/null
+++ b/components/voerBord.tsx
@@ -0,0 +1,39 @@
+interface VoerBordProps {
+ width: number;
+ height: number;
+}
+
+export function VoerBord(props: VoerBordProps) {
+ return <table style={{
+ borderSpacing: 8,
+ width: "100%"
+ }}>
+ <tbody>
+ {
+ [...Array(props.height)].map(() => (
+ <tr>
+ {[...Array(props.width)].map(() => (
+ <td style={{
+ position: "relative",
+ width: "100%",
+ padding: 0
+ }}>
+ <div style={{
+ display: "block",
+ marginTop: "100%"
+ }}/>
+ <div style={{
+ position: "absolute",
+ top: 0, left: 0, right: 0, bottom: 0,
+ borderRadius: 6,
+ border: "2px solid var(--background-alt)",
+ opacity: .5
+ }}/>
+ </td>
+ ))}
+ </tr>
+ ))
+ }
+ </tbody>
+ </table>
+}