Skip to content

Commit 84cb709

Browse files
committed
Add a completion mode to grid master board
1 parent 9d242a0 commit 84cb709

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

src/components/GridMasterBoard.tsx

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import WikiLink from './WikiLink';
66
import { useGridMasterContext } from '../context/GridMasterContext';
77
import type { GridMasterTile } from '../types/grid-master';
88

9+
const cols = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
10+
const rows = ['1', '2', '3', '4', '5', '6', '7'];
11+
912
export default function GridMasterBoard() {
1013
const { tiles } = useGridMasterContext();
1114
return (
@@ -26,15 +29,19 @@ export default function GridMasterBoard() {
2629
}
2730

2831
function GridMasterTaskTile({ tile }: { tile: GridMasterTile }) {
29-
const { flipped, hideUnconfirmed } = useGridMasterContext();
32+
const { checked, checkable, flipped, hideUnconfirmed, toggleChecked } =
33+
useGridMasterContext();
3034
const cell = `${tile.col}${tile.row}`;
3135
const unknown =
3236
(flipped ? !Boolean(tile.reward) : !Boolean(tile.task)) ||
3337
Boolean(tile.unconfirmed && hideUnconfirmed);
3438
return (
3539
<TooltipWrapper
3640
id={cell}
37-
className="grid-master__cell"
41+
className={classNames('grid-master__cell', {
42+
unchecked: checkable && !Boolean(checked[cell]),
43+
checked: checkable && Boolean(checked[cell]),
44+
})}
3845
tooltip={
3946
flipped && !unknown && tile.rewardDescription ? (
4047
<div style={{ maxWidth: '360px' }}>
@@ -70,6 +77,17 @@ function GridMasterTaskTile({ tile }: { tile: GridMasterTile }) {
7077
[`grid-master__tile--${tile.type}`]: tile.type,
7178
'grid-master__tile--unknown': unknown,
7279
})}
80+
draggable={false}
81+
onClick={
82+
checkable
83+
? e => {
84+
if (!e.ctrlKey) {
85+
e.preventDefault();
86+
toggleChecked(cell);
87+
}
88+
}
89+
: undefined
90+
}
7391
wikiId={
7492
(!unknown && (flipped ? tile.rewardLink : tile.taskLink)) ||
7593
'Grid_Master'
@@ -87,14 +105,21 @@ function GridMasterTaskTile({ tile }: { tile: GridMasterTile }) {
87105
}
88106

89107
function GridMasterRewardTile({ tile }: { tile: GridMasterTile }) {
90-
const { hideUnconfirmed } = useGridMasterContext();
108+
const { checked, checkable, hideUnconfirmed } = useGridMasterContext();
91109
const cell = `${tile.col}${tile.row}`;
92110
const unknown =
93111
!Boolean(tile.reward) || Boolean(tile.unconfirmed && hideUnconfirmed);
112+
const completed =
113+
tile.col === 'R'
114+
? cols.every(col => Boolean(checked[`${col}${tile.row}`]))
115+
: rows.every(row => Boolean(checked[`${tile.col}${row}`]));
94116
return (
95117
<TooltipWrapper
96118
id={cell}
97-
className="grid-master__cell"
119+
className={classNames('grid-master__cell', {
120+
unchecked: checkable && !completed,
121+
checked: checkable && completed,
122+
})}
98123
tooltip={
99124
!unknown && tile.rewardDescription ? (
100125
<div style={{ maxWidth: '360px' }}>

src/components/GridMasterHeader.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, Stack, Text, TooltipWrapper } from '@zigurous/forge-react';
1+
import { Button, Stack, Text, Toggle, TooltipWrapper } from '@zigurous/forge-react'; // prettier-ignore
22
import React from 'react';
33
import { useGridMasterContext } from '../context/GridMasterContext';
44

@@ -13,7 +13,14 @@ export default function GridMasterHeader() {
1313
<Text className="ml-2xxl" type="title">
1414
{context.flipped ? 'Rewards' : 'Tasks'}
1515
</Text>
16-
<Stack align="center">
16+
<Stack align="center" spacing="md">
17+
<Toggle
18+
label="Completion Mode"
19+
labelAlignment="leading"
20+
size="sm"
21+
toggled={context.checkable}
22+
onToggle={toggled => context.setCheckable(toggled)}
23+
/>
1724
{/* <TooltipWrapper
1825
tooltip={
1926
context.hideUnconfirmed ? 'Show Unconfirmed' : 'Hide Unconfirmed'

src/components/GridMasterTileImage.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export default function GridMasterTileImage({
4242
className={classNames(rest.className, {
4343
smooth: icon.includes('_detail'),
4444
})}
45+
draggable={false}
4546
icon={icon}
4647
size={48}
4748
/>
@@ -53,13 +54,15 @@ export default function GridMasterTileImage({
5354
'inline-flex justify-center align-center shrink-0',
5455
rest.className,
5556
)}
56-
style={{ ...rest.style, width: 56, height: 56 }}
57+
draggable={false}
58+
style={{ ...rest.style, width: 48, height: 48 }}
5759
{...rest}
5860
>
5961
<img
6062
alt=""
6163
aria-hidden
6264
className="object-contain w-full h-full"
65+
draggable={false}
6366
src={
6467
unknown
6568
? type === 'reward'

src/context/GridMasterContext.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
import { graphql, useStaticQuery } from 'gatsby';
2-
import React, { createContext, useContext, useState } from 'react';
2+
import React, { createContext, useCallback, useContext, useState } from 'react';
33
import type { GridMasterTile } from '../types/grid-master';
44

55
interface GridMasterContextData {
66
tiles: GridMasterTile[];
77
flipped: boolean;
8+
checkable: boolean;
9+
checked: Partial<Record<string, boolean>>;
810
hideUnconfirmed: boolean;
911
setFlipped: React.Dispatch<React.SetStateAction<boolean>>;
12+
setCheckable: React.Dispatch<React.SetStateAction<boolean>>;
1013
setHideUnconfirmed: React.Dispatch<React.SetStateAction<boolean>>;
14+
toggleChecked: (cell: string) => void;
1115
}
1216

1317
const defaultData: GridMasterContextData = {
1418
tiles: [],
1519
flipped: false,
20+
checkable: false,
21+
checked: { D4: true },
1622
hideUnconfirmed: true,
1723
setFlipped: () => defaultData.flipped,
24+
setCheckable: () => defaultData.checkable,
1825
setHideUnconfirmed: () => defaultData.hideUnconfirmed,
26+
toggleChecked: () => undefined,
1927
};
2028

2129
const GridMasterContext = createContext<GridMasterContextData>(defaultData);
@@ -30,17 +38,30 @@ export function GridMasterContextProvider({
3038
}: React.PropsWithChildren) {
3139
const data = useStaticQuery<GridMasterQueryData>(dataQuery);
3240
const [flipped, setFlipped] = useState(defaultData.flipped);
41+
const [checked, setChecked] = useState(defaultData.checked);
42+
const [checkable, setCheckable] = useState(defaultData.flipped);
3343
const [hideUnconfirmed, setHideUnconfirmed] = useState(
3444
defaultData.hideUnconfirmed,
3545
);
46+
47+
const toggleChecked = useCallback(
48+
(cell: string) =>
49+
setChecked(state => ({ ...state, [cell]: !(state[cell] || false) })),
50+
[],
51+
);
52+
3653
return (
3754
<GridMasterContext.Provider
3855
value={{
3956
tiles: data.tiles.nodes,
4057
flipped,
58+
checked,
59+
checkable,
4160
hideUnconfirmed,
4261
setFlipped,
62+
setCheckable,
4363
setHideUnconfirmed,
64+
toggleChecked,
4465
}}
4566
>
4667
{children}

src/styles/grid-master.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
cursor: pointer;
2020
}
2121

22+
.grid-master__cell.unchecked {
23+
opacity: var(--opacity-disabled);
24+
}
25+
26+
.grid-master__cell.checked {
27+
opacity: 1;
28+
}
29+
2230
.grid-master__tile {
2331
display: inline-flex;
2432
justify-content: center;

0 commit comments

Comments
 (0)