aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/gameBar.tsx53
-rw-r--r--components/notificationsArea.tsx103
-rw-r--r--components/page.tsx27
-rw-r--r--components/recentGames.tsx34
-rw-r--r--components/ui.tsx19
-rw-r--r--pages/_app.tsx2
-rw-r--r--styles/game.css18
-rw-r--r--styles/global.css3
-rw-r--r--styles/notifications.css51
-rw-r--r--styles/recentGames.css21
-rw-r--r--styles/ui.css19
-rw-r--r--styles/utility.css1
12 files changed, 155 insertions, 196 deletions
diff --git a/components/gameBar.tsx b/components/gameBar.tsx
index a3479d5..9a7ca59 100644
--- a/components/gameBar.tsx
+++ b/components/gameBar.tsx
@@ -1,5 +1,5 @@
-import { CSSProperties, ReactNode } from 'react';
-import { Bubble, Vierkant } from './ui';
+import { ReactNode } from 'react';
+import { Vierkant } from './ui';
import ExitToAppRoundedIcon from '@material-ui/icons/ExitToAppRounded';
import NavigateBeforeRoundedIcon from '@material-ui/icons/NavigateBeforeRounded';
@@ -9,21 +9,17 @@ import SettingsRoundedIcon from '@material-ui/icons/SettingsRounded';
function GameBarModule(props: {
children?: ReactNode;
onclick?: () => void;
+ className?: string;
}) {
return <Vierkant
- className={'gameBarButton bg-700 pad-m round-t valigntop ' + (props.onclick ? 'cpointer' : '')}
+ className={'gameBarButton bg-700 pad-m round-t valigntop ' + props.className + ' '
+ + (props.onclick ? 'cpointer' : '')}
onclick={props.onclick}
>
{props.children}
</Vierkant>;
}
-var GameBarSpacer = () => <div style={{ width: 8, display: 'inline-block' }}></div>;
-
-var GameBarAlignStyle: CSSProperties = {
- display: 'inline-block',
-};
-
export function GameBar(props: {
turn: boolean;
player1: boolean;
@@ -32,7 +28,7 @@ export function GameBar(props: {
}) {
return <Vierkant className='gameBar bg-800 w100m2m pad-s'>
<div>
- <div style={{ ...GameBarAlignStyle, float: 'left' }}>
+ <div className='floatl dispinbl'>
{props.active && <div
className={'move dispinbl ' + (props.turn ? 'move-a' : 'move-b')}
/>}
@@ -44,49 +40,22 @@ export function GameBar(props: {
: '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 - .75,
- }}
- >
- 0-0
- </span>
+ <div className='score winning dispnone subtile posabs abscenter'>
+ <span>0-0</span>
</div>
- <div style={{ ...GameBarAlignStyle, float: 'right' }}>
+ <div className='buttons floatr dispinbl'>
<GameBarModule>
<SettingsRoundedIcon />
</GameBarModule>
- <GameBarSpacer />
- <GameBarModule>
- <span
- style={{
- margin: '0 4px',
- fontSize: 20,
- }}
- >
- 00:00
- </span>
+ <GameBarModule className='timer nosel'>
+ <span>00:00</span>
</GameBarModule>
- <GameBarSpacer />
<GameBarModule onclick={props.resignFunction}>
<ExitToAppRoundedIcon />
</GameBarModule>
- <GameBarSpacer />
<GameBarModule>
<NavigateBeforeRoundedIcon />
</GameBarModule>
- <GameBarSpacer />
<GameBarModule>
<NavigateNextRoundedIcon />
</GameBarModule>
diff --git a/components/notificationsArea.tsx b/components/notificationsArea.tsx
index 9573b72..8ee554a 100644
--- a/components/notificationsArea.tsx
+++ b/components/notificationsArea.tsx
@@ -1,5 +1,5 @@
import axios from 'axios';
-import { CSSProperties, ReactNode, useContext, useEffect, useState } from 'react';
+import { ReactNode, useContext, useEffect, useState } from 'react';
import { gameInfo, userInfo } from '../api/api';
import { AccountAvatar } from './account';
@@ -35,52 +35,14 @@ export function NotificationsArea(props: {
setPreviousMessages(messages);
});
- return props.visible && <Bubble
- style={{
- left: 48 + 12,
- top: 92,
- transform: 'translateY(-100%)',
- textAlign: 'left',
- width: 400,
- height: 450,
- }}
- tuitjeStyle={{
- left: 12,
- bottom: 86,
- transform: 'translate(-100%, 100%) rotate(90deg)',
- }}
- >
- <h2 style={{ marginBottom: 24 }}>Meldingen</h2>
- <div
- style={{
- overflowY: 'scroll',
- whiteSpace: 'normal',
- height: 450 - 24 * 4,
- borderRadius: 6,
- }}
- >
+ return props.visible && <Bubble className='notificationsArea bg-700 pad-l'>
+ <h2 className='title'>Meldingen</h2>
+ <div className='inner round-t'>
{props.gameInvites?.map(game => <GameInvite hide={props.rerender} game={game} />)}
{props.friendRequests?.map(user => <FriendRequest hide={props.rerender} user={user} />)}
{messages == 0
- && <div
- style={{
- position: 'absolute',
- left: 0,
- right: 0,
- bottom: 0,
- top: 0,
- }}
- >
- <h1
- style={{
- position: 'absolute',
- top: '50%',
- left: '50%',
- whiteSpace: 'nowrap',
- transform: 'translate(-50%, -50%)',
- opacity: .7,
- }}
- >
+ && <div className='noMsgsWrapper posabs a0'>
+ <h1 className='posabs abscenter subtile'>
Geen meldingen
</h1>
</div>}
@@ -88,48 +50,24 @@ export function NotificationsArea(props: {
</Bubble>;
}
-var FriendRequestButtonStyle: CSSProperties = {
- borderRadius: 6,
- display: 'inline-block',
- marginLeft: 0,
- textAlign: 'center',
-};
-
function Acceptable(props: {
children?: ReactNode;
onAccept?: () => void;
onDeny?: () => void;
}) {
- return <Vierkant
- style={{
- borderRadius: 8,
- background: 'var(--background-alt)',
- margin: 0,
- padding: 12,
- width: '100%',
- marginBottom: 12,
- }}
- >
- <div style={{ position: 'relative' }}>
+ return <Vierkant className='acceptable bg-800 round-t pad-m fullwidth'>
+ <div className='posrel'>
{props.children}
- <div
- style={{
- display: 'grid',
- gridTemplateColumns: '1fr, 1fr',
- gridGap: 12,
- marginTop: 12,
- gridAutoFlow: 'column',
- }}
- >
+ <div className='sidebyside buttons'>
<IconLabelButton
+ className='accept'
onclick={props.onAccept}
- style={FriendRequestButtonStyle}
icon={<DoneIcon />}
text='Accepteren'
/>
<IconLabelButton
+ className='deny'
onclick={props.onDeny}
- style={FriendRequestButtonStyle}
icon={<CloseIcon />}
text='Verwijderen'
/>
@@ -171,14 +109,8 @@ function FriendRequest(props: {
>
<a href={'/user?id=' + props.user.id}>
<AccountAvatar size={48} id={props.user.id} />
- <div
- style={{
- display: 'inline-block',
- verticalAlign: 'top',
- marginLeft: 6,
- }}
- >
- <i style={{ display: 'block' }}>Vriendschapsverzoek</i>
+ <div className='userInfo dispinbl valigntop'>
+ <i className='dispbl'>Vriendschapsverzoek</i>
<b>{props.user.username}</b>
</div>
</a>
@@ -191,13 +123,8 @@ function GameInvite(props: {
}) {
return <Acceptable>
<a>
- <div
- style={{
- display: 'inline-block',
- verticalAlign: 'top',
- }}
- >
- <i style={{ display: 'block' }}>Partijuitnodiging</i>
+ <div className='userInfo dispinbl valigntop'>
+ <i className='dispbl'>Partijuitnodiging</i>
<p>
<b>
<a href={'/user?id=' + props.game.opponent?.id}>{props.game.opponent?.username}</a>
diff --git a/components/page.tsx b/components/page.tsx
index b8e3dac..b8e8770 100644
--- a/components/page.tsx
+++ b/components/page.tsx
@@ -1,26 +1,15 @@
-import { Component, CSSProperties, ReactNode } from 'react';
+import { Component, ReactNode } from 'react';
export function CenteredPage(props: {
width?: number;
children?: ReactNode;
- style?: CSSProperties;
className?: string;
}) {
return <div
className='CenteredPageOuter'
- style={{
- maxWidth: props.width,
- margin: '0 auto',
- }}
+ style={{ maxWidth: props.width }}
>
- <div
- className={'CenteredPageInner ' + props.className}
- style={{
- margin: '0 6px',
- lineHeight: 0,
- ...props.style,
- }}
- >
+ <div className={'CenteredPageInner ' + props.className}>
{props.children}
</div>
</div>;
@@ -28,15 +17,7 @@ export function CenteredPage(props: {
export class PageTitle extends Component {
render() {
- return <h1
- style={{
- color: 'var(--text-alt)',
- marginLeft: 6,
- marginTop: 32,
- marginBottom: 64,
- fontSize: 25,
- }}
- >
+ return <h1 className='pageTitle'>
{this.props.children}
</h1>;
}
diff --git a/components/recentGames.tsx b/components/recentGames.tsx
index d619eeb..6683e20 100644
--- a/components/recentGames.tsx
+++ b/components/recentGames.tsx
@@ -1,18 +1,7 @@
import friendlyTime from 'friendly-time';
-import { CSSProperties } from 'react';
import { gameInfo } from '../api/api';
-var LeftAlignedTableColumn: CSSProperties = {
- textAlign: 'left',
- paddingLeft: 16,
-};
-
-var RightAlignedTableColumn: CSSProperties = {
- textAlign: 'right',
- paddingRight: 16,
-};
-
function GameOutcome(props: { game: gameInfo; }) {
var gameStatus = (() => {
return {
@@ -42,10 +31,10 @@ function GameOutcome(props: { game: gameInfo; }) {
}
export default function RecentGames(props: { games?: Array<gameInfo>; }) {
- return <div>
+ return <div className='recentGames'>
<h2>Recente partijen</h2>
{props.games?.length > 0
- ? <table width='100%' style={{ marginTop: '16px', textAlign: 'center' }}>
+ ? <table width='100%' className='recentGames center'>
<tbody>
<tr>
<th style={{ width: '50%' }}>Tegenstander</th>
@@ -55,19 +44,14 @@ export default function RecentGames(props: { games?: Array<gameInfo>; }) {
</tr>
{props.games?.map(game =>
<tr key={game.id}>
- <td style={LeftAlignedTableColumn}>
- <a
- href={'/user?id=' + game.opponent?.id}
- style={{
- fontWeight: 500,
- }}
- >
+ <td className='leftAlignedColumn'>
+ <a href={'/user?id=' + game.opponent?.id}>
{game.opponent?.username}
</a>
</td>
<GameOutcome game={game} />
<td>{Math.max(0, game.moves.length - 1)}</td>
- <td style={RightAlignedTableColumn}>
+ <td className='rightAlignedColumn'>
{(() => {
var timeCreated = new Date(game.created);
return friendlyTime(timeCreated);
@@ -77,13 +61,7 @@ export default function RecentGames(props: { games?: Array<gameInfo>; }) {
)}
</tbody>
</table>
- : <h1
- style={{
- textAlign: 'center',
- opacity: .6,
- margin: '32px 64px',
- }}
- >
+ : <h1 className='nogames center subtile'>
Deze gebruiker heeft nog geen partijen gespeeld
</h1>}
</div>;
diff --git a/components/ui.tsx b/components/ui.tsx
index 11914c8..7474240 100644
--- a/components/ui.tsx
+++ b/components/ui.tsx
@@ -1,4 +1,4 @@
-import { CSSProperties, ReactNode, useEffect, useState } from 'react';
+import { ReactNode, useEffect, useState } from 'react';
import CheckBoxIcon from '@material-ui/icons/CheckBox';
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
@@ -70,7 +70,6 @@ export function IconLabelButton(props: {
export function Input(props: {
label?: string;
- style?: CSSProperties;
type?: string;
id?: string;
min?: number;
@@ -109,7 +108,6 @@ export function SearchBar(props: { label?: string; }) {
export function CheckBox(props: {
state?: boolean;
- style?: CSSProperties;
id?: string;
onclick?: (state: boolean) => void;
}) {
@@ -130,12 +128,7 @@ export function CheckBox(props: {
return <div
onClick={toggle}
id={props.id}
- className={on ? 'on' : 'off'}
- style={{
- ...props.style,
- display: 'inline-block',
- cursor: 'pointer',
- }}
+ className={'checkbox dispinbl ' + (on ? 'on' : 'off')}
>
{on
? <CheckBoxIcon />
@@ -168,17 +161,15 @@ export function Tuitje() {
xmlns='http://www.w3.org/2000/svg'
className='tuitje posabs'
>
- <path
- d='M18 12C24 12 27 0 36 0L0 0C9 0 12 12 18 12Z'
- fill='var(--background)'
- />
+ <path d='M18 12C24 12 27 0 36 0L0 0C9 0 12 12 18 12Z' />
</svg>;
}
export function Bubble(props: {
children?: ReactNode;
+ className?: string;
}) {
- return <Vierkant className='bubble posabs center drop-2'>
+ return <Vierkant className={'bubble posabs center drop-2 ' + props.className}>
{props.children}
<Tuitje />
</Vierkant>;
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 31bc0e7..317b389 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -8,6 +8,8 @@ import '../styles/disk.css';
import '../styles/footer.css';
import '../styles/global.css';
import '../styles/navbar.css';
+import '../styles/notifications.css';
+import '../styles/recentGames.css';
import '../styles/ui.css';
import '../styles/utility.css';
diff --git a/styles/game.css b/styles/game.css
index 2c1eb94..d482f9b 100644
--- a/styles/game.css
+++ b/styles/game.css
@@ -35,7 +35,10 @@
margin: 3px;
}
-.gameBar .gameBarButton { margin: 0; }
+.gameBar .gameBarButton {
+ margin: 0;
+ margin-left: var(--spacing-small);
+}
.gameBar .move {
width: 32px;
@@ -48,6 +51,19 @@
.gameBar .move.move-a { background-color: var(--error); }
.gameBar .move.move-b { background-color: var(--confirm); }
+.gameBar .timer span {
+ margin: 0 4px;
+ font-size: 20px;
+}
+
+.gameBar .score {
+ font-size: 20px;
+ z-index: 1;
+}
+
+.gameBar .score.winning { color: var(--disk-a-alt); }
+.gameBar .score.losing { color: var(--disk-b-alt); }
+
.voerGame {
max-width: 100vh;
margin: 0 auto;
diff --git a/styles/global.css b/styles/global.css
index 541dd76..79aa026 100644
--- a/styles/global.css
+++ b/styles/global.css
@@ -39,6 +39,9 @@ html, body {
padding: 0;
}
+/* section font size */
+h1 { font-size: 25px; }
+
/* subsection font size */
h2 { font-size: 20px; }
diff --git a/styles/notifications.css b/styles/notifications.css
new file mode 100644
index 0000000..ec47836
--- /dev/null
+++ b/styles/notifications.css
@@ -0,0 +1,51 @@
+.notificationsArea {
+ left: calc(48px + var(--spacing-medium));
+ top: 92px;
+ transform: translateY(-100%);
+ text-align: left;
+ width: 400px;
+ height: 450px;
+}
+
+.notificationsArea .tuitje {
+ left: var(--spacing-medium);
+ bottom: 86px;
+ transform: translate(-100%, 100%) rotate(90deg);
+ fill: var(--gray-700);
+}
+
+.notificationsArea .title {
+ margin-bottom: var(--spacing-large);
+}
+
+.notificationsArea .inner {
+ overflow-y: scroll;
+ white-space: normal;
+ height: calc(450px - 4 * var(--spacing-large));
+}
+
+.notificationsArea .acceptable {
+ margin: 0;
+ margin-bottom: var(--spacing-medium);
+}
+
+.notificationsArea .acceptable:last-child {
+ margin-bottom: 0;
+}
+
+.notificationsArea .buttons .button {
+ margin: 0;
+}
+
+.notificationsArea .buttons {
+ margin-top: var(--spacing-medium);
+}
+
+.notificationsArea .noMsgsWrapper h1 {
+ white-space: nowrap;
+ user-select: none;
+}
+
+.notificationsArea .acceptable .userInfo {
+ margin-left: var(--spacing-small);
+}
diff --git a/styles/recentGames.css b/styles/recentGames.css
new file mode 100644
index 0000000..c7150aa
--- /dev/null
+++ b/styles/recentGames.css
@@ -0,0 +1,21 @@
+table .leftAlignedColumn {
+ text-align: left;
+ padding-left: var(--spacing-medium);
+}
+
+table .rightAlignedColumn {
+ text-align: right;
+ padding-left: var(--spacing-medium);
+}
+
+table.recentGames {
+ margin-top: var(--spacing-medium);
+}
+
+table.recentGames a {
+ font-weight: 500;
+}
+
+div.recentGames .nogames {
+ margin: 32px 64px;
+}
diff --git a/styles/ui.css b/styles/ui.css
index 6dbc388..cb95b36 100644
--- a/styles/ui.css
+++ b/styles/ui.css
@@ -89,3 +89,22 @@ html.dark .dialogbox { background-color: var(--gray-700); }
box-sizing: border-box;
}
+.checkbox {
+ cursor: pointer;
+}
+
+.CenteredPageOuter {
+ margin: 0 auto;
+}
+
+.CenteredPageInner {
+ margin: 0 var(--spacing-small);
+ line-height: 0;
+}
+
+.pageTitle {
+ margin-left: var(--spacing-small);
+ margin-top: 32px;
+ margin-bottom: 64px;
+}
+
diff --git a/styles/utility.css b/styles/utility.css
index 0ff6b10..cc358e6 100644
--- a/styles/utility.css
+++ b/styles/utility.css
@@ -49,6 +49,7 @@
.center { text-align: center; }
.floatr { float: right; }
+.floatl { float: left; }
.w100m2m { width: calc(100% - var(--spacing-medium)); }