LasTres/js-src/components/pj-creation-menu.tsx

124 lines
4.6 KiB
TypeScript

import * as React from 'react'
import type { PJ } from '@lastres/pj'
import { fetchMyPjs } from '@lastres/pj'
export interface PJCreationMenuProps {
error: string | null
setSelectedPJ: (set: PJ | null) => void
setUserWantsToCreatePJ: (set: boolean) => void
setError: (set: string | null) => void
setPJs: (set: PJ[] | null) => void
}
export interface Race {
identifier: string
name_selection: string
description: string
}
export type Races = Record<string, Race>
export default function PJCreationMenu (props: PJCreationMenuProps): JSX.Element {
const longNameInputRef = React.useRef<HTMLInputElement>(null)
const shortNameInputRef = React.useRef<HTMLInputElement>(null)
const nickInputRef = React.useRef<HTMLInputElement>(null)
const raceSelectRef = React.useRef<HTMLSelectElement>(null)
const [playableRaces, setPlayableRaces] = React.useState<Races | null>(null)
if (playableRaces === null) {
fetch('/races/playable', {
method: 'GET',
mode: 'same-origin',
cache: 'no-cache'
}).then(async (response) => {
const statusCode = response.status
const data = await response.json()
if (statusCode !== 200) {
props.setError(data.error)
return
}
setPlayableRaces(data)
props.setError(null)
}).catch((error) => {
console.log(error)
props.setError('Imposible conectar al servidor para recibir las razas.')
})
}
function createPJ (): void {
if (longNameInputRef.current === null) {
return
}
if (shortNameInputRef.current === null) {
return
}
if (nickInputRef.current === null) {
return
}
if (raceSelectRef.current === null || raceSelectRef.current.selectedOptions.length < 1) {
return
}
fetch('/pj/create', {
method: 'POST',
mode: 'same-origin',
cache: 'no-cache',
body: JSON.stringify({
full_name: longNameInputRef.current.value,
short_name: shortNameInputRef.current.value,
nick: nickInputRef.current.value,
race: raceSelectRef.current.selectedOptions[0].value
})
}).then(async (response) => {
const statusCode = response.status
const data = await response.json()
if (statusCode !== 200) {
props.setError(data.error)
return
}
props.setError(null)
props.setUserWantsToCreatePJ(false)
const pjs = await fetchMyPjs(props.setError)
props.setPJs(pjs)
}).catch((error) => {
console.log(error)
props.setError('Imposible crear pj, no se pudo conectar al servidor.')
})
}
function renderRaces (): JSX.Element[] {
if (playableRaces !== null) {
return Object.keys(playableRaces)
.map((item, i) => {
return <option key={i} value={playableRaces[item].identifier}>
{`${playableRaces[item].name_selection} (${playableRaces[item].description})`}
</option>
})
}
return ([])
}
return (
<>
<div className="login-container">
<div className="login-contained">
<h1>Crea tu personaje.</h1>
{(props.error !== null
? (<p style={{ background: 'red' }}>{props.error}</p>)
: (<></>)
)}
<div className="login-form">
<label>Nombre largo. (Se usará en la historia en situaciones formales)</label>
<input ref={longNameInputRef} type="text"/>
<label>Nombre corto. (Se usará de forma coloquial)</label>
<input ref={shortNameInputRef} type="text"/>
<label>Apodo. (Se usará en las conversaciones más distendidas)</label>
<input ref={nickInputRef} type="text"/>
<label>Raza. (Determina tu localización inicial y tus estadísticas)</label>
<select ref={raceSelectRef}>{ renderRaces() }</select>
<div className="width-max-content align-self-end">
<button onClick={createPJ}>Crear Personaje</button>
</div>
</div>
</div>
</div>
</>
)
}