import Checkbox from '@material-ui/core/Checkbox' ; import FormControl from '@material-ui/core/FormControl' ; import FormControlLabel from '@material-ui/core/FormControlLabel' ; import FormLabel from '@material-ui/core/FormLabel' ; import InputLabel from '@material-ui/core/InputLabel' ; import NativeSelect from '@material-ui/core/NativeSelect' ; import TextField from '@material-ui/core/TextField' ; import { numPlayers } from 'app/actions/Settings' ; import * as React from 'react' ; import { CONTENT_RATING_DESC , ContentRating , enumValues , Expansion , Genre , Language } from 'shared/schema/Constants' ; import { PLAYTIME_MINUTES_BUCKETS } from '../../Constants' ; import { ContentSetsType , SearchParams , SettingsType , UserState } from '../../reducers/StateTypes' ; import Button from '../base/Button' ; import Card from '../base/Card' ; import ExpansionCheckbox from '../base/ExpansionCheckbox' ; const pluralize = require ( 'pluralize' ) ; export interface StateProps { params : SearchParams ; settings : SettingsType ; contentSets : Set < keyof ContentSetsType > ; user : UserState ; } export interface DispatchProps { onChangeParams : ( params : Partial < SearchParams > ) => void ; onSearch : ( params : SearchParams ) => void ; } export interface Props extends StateProps , DispatchProps { } export class SearchSettings extends React . Component < Props , { } > { constructor ( props ) { super ( props ) ; } public onChange ( delta ) { for ( const key in delta ) { if ( delta . hasOwnProperty ( key ) ) { const value = delta [ key ] ; if ( value === 'null' || Number . isNaN ( value ) ) { this . props . onChangeParams ( { [ key ] : undefined } ) ; } else { this . props . onChangeParams ( { [ key ] : value } ) ; } } } } public onCheckboxChange ( attrib , v ) { if ( v === false ) { this . onChange ( { [ attrib ] : false } ) ; } else { this . onChange ( { [ attrib ] : true } ) ; } } public submit ( e ) { if ( e ) { e . preventDefault ( ) ; } this . props . onSearch ( this . props . params ) ; } public render ( ) { const players = numPlayers ( this . props . settings ) ; const rating = ( this . props . params . contentrating ) ? CONTENT_RATING_DESC [ this . props . params . contentrating ] : undefined ; const timeBuckets = PLAYTIME_MINUTES_BUCKETS . map ( ( minutes , index ) => { return < option key = { index } value = { minutes } > { `${ minutes } min` } < /option>; } ) ; const visibleGenres = [ Genre . comedy , Genre . drama , Genre . horror , Genre . mystery ] ; return ( < Card title = "Quest Search" > < form className = "searchForm" autoComplete = "off" onSubmit = { ( e ) => { this . submit ( e ) ; } } > < div className = "searchDescription" > For { players } { pluralize ( 'players' , players ) } < /div> < FormControl fullWidth = { true } > < FormLabel htmlFor = "expansion" > Expansions < /FormLabel> < ExpansionCheckbox onChange = { ( values ) => this . onChange ( { expansions : values as Expansion [ ] } ) } contentSets = { this . props . contentSets } value = { this . props . params . expansions || [ ] } / > < /FormControl> < FormControl fullWidth = { true } > < TextField id = "text" className = "textfield" fullWidth = { true } label = "text search - title, author, ID" onChange = { ( e ) => this . onChange ( { text : e . target . value } ) } onFocus = { ( e ) => e . target . scrollIntoView ( ) } value = { this . props . params . text } / > < /FormControl> < FormControl className = "selectfield" fullWidth = { true } > < InputLabel htmlFor = "order" > Sort by < /InputLabel> < NativeSelect id = "order" onChange = { ( e , c ) => this . onChange ( { order : e . target . value } ) } value = { this . props . params . order } > < option value = "+ratingavg" > Highest rated < /option> < option value = "-created" > Newest < /option> < option value = "+title" > Title ( A - Z ) < /option> < option value = "-title" > Title ( Z - A ) < /option> < option value = "" > Compatibility < /option> < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfLeft ranged" > < InputLabel htmlFor = "mintimeminutes" > Minimum time < /InputLabel> < NativeSelect id = "mintimeminutes" onChange = { ( e , c ) => this . onChange ( { mintimeminutes : Number ( e . target . value ) } ) } value = { this . props . params . mintimeminutes } > < option value = { 'null' } > Any length < /option> { timeBuckets } < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfRight" > < InputLabel htmlFor = "maxtimeminutes" > Maximum time < /InputLabel> < NativeSelect id = "maxtimeminutes" onChange = { ( e , c ) => this . onChange ( { maxtimeminutes : Number ( e . target . value ) } ) } value = { this . props . params . maxtimeminutes } > < option value = { 'null' } > Any length < /option> { timeBuckets } < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfLeft" > < InputLabel htmlFor = "age" > Recency < /InputLabel> < NativeSelect id = "age" onChange = { ( e , c ) => this . onChange ( { age : Number ( e . target . value ) } ) } value = { this . props . params . age } > < option value = { 'null' } > All time < /option> < option value = { 31536000 } > Published this year < /option> < option value = { 2592000 } > Published this month < /option> < option value = { 604800 } > Published this week < /option> < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfRight" > < InputLabel htmlFor = "language" > Language < /InputLabel> < NativeSelect id = "language" onChange = { ( e , c ) => this . onChange ( { language : e . target . value as Language } ) } value = { this . props . params . language } > { enumValues ( Language ) . map ( ( l , i ) => < option key = { i } value = { l } > { l } < /option>)} < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfLeft" > < InputLabel htmlFor = "genre" > Genre < /InputLabel> < NativeSelect id = "genre" onChange = { ( e , c ) => this . onChange ( { genre : e . target . value as Genre } ) } value = { this . props . params . genre } > < option value = { 'null' } > All genres < /option> { visibleGenres . map ( ( genre , i ) => < option key = { i } value = { genre } > { genre } < /option>)} < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfRight" > < InputLabel htmlFor = "contentrating" > Content Rating < /InputLabel> < NativeSelect id = "contentrating" onChange = { ( e , c ) => this . onChange ( { contentrating : e . target . value as ContentRating } ) } value = { this . props . params . contentrating } > < option value = { 'null' } > All ratings < /option> < option value = "Kid-friendly" > Kid - friendly < /option> < option value = "Teen" > Teen < /option> < option value = "Adult" > Adult < /option> < /NativeSelect> < /FormControl> < FormControl className = "selectfield halfLeft" > < InputLabel htmlFor = "requirespenpaper" > Requires Pen & Paper < /InputLabel> < NativeSelect id = "requirespenpaper" onChange = { ( e , c ) => this . onChange ( { requirespenpaper : e . target . value } ) } value = { this . props . params . requirespenpaper } > < option value = { 'null' } > No Preference < /option> < option value = "true" > Yes < /option> < option value = "false" > No < /option> < /NativeSelect> < /FormControl> < FormControl className = "showOfficialControl checkbox halfLeft" > < FormControlLabel control = { < Checkbox id = "showOfficial" checked = { this . props . params . showOfficial === true ? true : false } onChange = { ( _ , v ) => this . onCheckboxChange ( 'showOfficial' , v ) } />} label={'Only show official quests'}></FormControlLabel > < /FormControl> < FormControl className = "showPrivateControl checkbox halfRight" > < FormControlLabel control = { < Checkbox id = "showPrivate" checked = { ! this . props . params . showOfficial && this . props . params . showPrivate === true ? true : false } onChange = { ( _ , v ) => this . onCheckboxChange ( 'showPrivate' , v ) } disabled = { this . props . params . showOfficial } / > } label = { 'Show my private quests' } > < /FormControlLabel> < /FormControl> { rating && < div className = "ratingDescription" > < span > "{this.props.params.contentrating}" rating means : { rating . summary } < /span> < /div>} < Button onClick = { ( e ) => { this . submit ( e ) ; } } id = "search" > Search < /Button> < /form> < /Card>); } } export default SearchSettings ;