Extract wonder selector component

This commit is contained in:
Kenneth Allen 2021-10-21 23:23:27 +11:00
parent 262036d2ff
commit 8577e36852
2 changed files with 39 additions and 32 deletions

View File

@ -1,9 +1,9 @@
import { Dispatch } from 'ketchup-react' import { Dispatch } from 'ketchup-react'
import { Action, chooseWonderAction, maxPlayers, minPlayers, Player, startGameAction, State, structures, wonders } from 'wonders-common' import { Action, maxPlayers, minPlayers, Player, startGameAction, State, structures } from 'wonders-common'
import Civ from '../Civ/Civ' import Civ from '../Civ/Civ'
import Card from '../Card/Card' import Card from '../Card/Card'
import { ErrorMessage, Field, Form, Formik } from 'formik'
import './Game.css' import './Game.css'
import WonderSelector from '../WonderSelector/WonderSelector'
function getDistant<T>(arr: T[], idx: number) { function getDistant<T>(arr: T[], idx: number) {
switch (idx) { switch (idx) {
@ -22,10 +22,6 @@ export default function Game({ state, playerName, dispatch }: { state: State, pl
distant: getDistant(state.players, playerIdx), distant: getDistant(state.players, playerIdx),
} }
function isWonderInUse(wonder: string) {
return state.players.filter(p => p.name !== playerName).map(p => p.wonder).includes(wonder)
}
let gameElem: JSX.Element let gameElem: JSX.Element
if (!player || !started) { if (!player || !started) {
gameElem = <div className='wonder-lobby'> gameElem = <div className='wonder-lobby'>
@ -33,35 +29,11 @@ export default function Game({ state, playerName, dispatch }: { state: State, pl
<Civ key={p.name} player={p} displayStyle='distant' /> <Civ key={p.name} player={p} displayStyle='distant' />
)} )}
</div> </div>
if (!started) { if (player) {
gameElem = <> gameElem = <>
{gameElem} {gameElem}
<Formik
initialValues={{ wonder: player.wonder ?? [...wonders.keys()][0] }}
validate={values => {
const errors: Partial<typeof values> = {}
if (values.wonder.length === 0) {
errors.wonder = 'Wonder not selected.'
}
if (isWonderInUse(values.wonder)) {
errors.wonder = 'Wonder already in use.'
}
return errors
}}
onSubmit={({ wonder }) => dispatch(chooseWonderAction(player.name, wonder))}>
<Form>
<button type="submit">Choose wonder</button>
{' '}
<Field as="select" name="wonder">
{[...wonders.keys()].map(w =>
<option key={w} disabled={isWonderInUse(w)}>{w}</option>
)}
</Field>
{' '}
<ErrorMessage name="wonder" />
</Form>
</Formik>
<div> <div>
<WonderSelector state={state} player={player} dispatch={dispatch} />
<button onClick={() => dispatch(startGameAction(state.players.length))} <button onClick={() => dispatch(startGameAction(state.players.length))}
disabled={started !== undefined disabled={started !== undefined
|| state.players.length < minPlayers || state.players.length < minPlayers

View File

@ -0,0 +1,35 @@
import { ErrorMessage, Field, Form, Formik } from 'formik'
import { Dispatch } from 'ketchup-react'
import { Action, chooseWonderAction, Player, State, wonders } from 'wonders-common'
export default function WonderSelector({ state, player, dispatch }: { state: State, player: Player, dispatch: Dispatch<Action> }) {
function isWonderInUse(wonder: string) {
return state.players.filter(p => p.name !== player.name).map(p => p.wonder).includes(wonder)
}
return <Formik
initialValues={{ wonder: player.wonder ?? [...wonders.keys()][0] }}
validate={values => {
const errors: Partial<typeof values> = {}
if (values.wonder.length === 0) {
errors.wonder = 'Wonder not selected.'
}
if (isWonderInUse(values.wonder)) {
errors.wonder = 'Wonder already in use.'
}
return errors
}}
onSubmit={({ wonder }) => dispatch(chooseWonderAction(player.name, wonder))}>
<Form>
<button type="submit">Choose wonder</button>
{' '}
<Field as="select" name="wonder">
{[...wonders.keys()].map(w =>
<option key={w} disabled={isWonderInUse(w)}>{w}</option>
)}
</Field>
{' '}
<ErrorMessage name="wonder" />
</Form>
</Formik>
}