euchre-live

Euchre web-app for the socially distant family
git clone git://git.alexkarle.com/euchre-live.git
Log | Files | Refs | README | LICENSE

TableList.js (10186B) [raw]


      1 import React from 'react';
      2 import PropTypes from 'prop-types';
      3 import { ClickableTile, Button, ModalWrapper, TextInput, Checkbox, ComposedModal,
      4      ModalHeader, ModalBody, ModalFooter } from 'carbon-components-react';
      5 import {Renew16, Locked16} from '@carbon/icons-react';
      6 
      7 export default class TableList extends React.Component {
      8 
      9     constructor(props) {
     10         super(props);
     11         this.state = {
     12             pwdOpen: false,
     13             joinInfo: null
     14         };
     15     }
     16 
     17     conflictHandler = (tableName) => {
     18         const {playerName} = this.props;
     19         alert('The "' + tableName + '" table already has a player named ' + playerName 
     20         + ' -- you must change your name to join this table, or choose another table.');
     21     }
     22 
     23     handleJoin = (tableName, hasPwd) => {
     24         console.log('handleJoin, hasPwd=', hasPwd);
     25         const {playerName} = this.props;
     26         let joinInfo = {
     27             table: tableName,
     28             player_name: playerName
     29         };
     30         if (!hasPwd) {
     31             this.props.joinTable(joinInfo);
     32         } else {
     33             this.setState({
     34                 joinInfo: joinInfo,
     35                 pwdOpen: true
     36             })
     37         }
     38     }
     39 
     40     handleCreate = () => {
     41         const {playerName} = this.props;
     42         console.log('handleCreate, optHpick:', this.optHpick.value);
     43         const tableName = this.ctName.value;
     44         if (!tableName || tableName == ''){
     45             alert('Unnamed tables are not permitted');
     46         } else {
     47             const pwd = this.ctPwd.value;
     48             let settings = {};
     49             settings.hard_order = this.optHorder.checked;
     50             settings.hard_pick = this.optHpick.checked;
     51             settings.stick_dealer = this.optStick.checked;
     52             let joinInfo = {
     53                 table: tableName,
     54                 player_name: playerName,
     55                 settings: settings
     56             }
     57             if (pwd && pwd != ''){
     58                 joinInfo.password = pwd;
     59             }
     60             this.props.joinTable(joinInfo);
     61         }
     62     }
     63 
     64     handleRefresh = () => {
     65         this.refreshButton.blur();
     66         this.props.refresh();
     67     };
     68 
     69     handleModalClose = () => {
     70         console.log('modal close');
     71         this.pmPwd.value='';
     72         this.setState({
     73             pwdOpen: false
     74         });
     75     };
     76 
     77     handleModalSave = () => {
     78         const {joinInfo} = this.state;
     79         const pwd = this.pmPwd.value;
     80         console.log('modal save, pwd=', pwd);
     81         joinInfo.password = pwd;
     82         this.props.joinTable(joinInfo);
     83         this.pmPwd.value='';
     84         this.setState({
     85             pwdOpen: false
     86         });
     87     };
     88 
     89     renderCards = () => {
     90         const {tables, playerName} = this.props;
     91         let retVal = [];
     92         if (tables){
     93             tables.forEach(table => {
     94                 const conflict = table.players.indexOf(playerName) > -1 
     95                     || table.spectators.indexOf(playerName) > -1;
     96                 const conflictWarning = conflict ? 
     97                   (<div className="table__conflict">A user named &quot;{playerName}&quot; is at this table</div>) : null;
     98                 const clickHandler = conflict ? this.conflictHandler : this.handleJoin;
     99                 let seated = '';
    100                 for (let ni = 0; ni < 4; ni++) {
    101                     if (table.players[ni] != 'Empty'){
    102                         if (seated != ''){
    103                             seated += ', ';
    104                         }
    105                         seated += table.players[ni];
    106                     }
    107                 }
    108                 let specs = '';
    109                 table.spectators.forEach(spName => {
    110                     if (specs != ''){
    111                         specs += ', ';
    112                     }
    113                     specs += spName;
    114                 })
    115                 const lockIcon = table.has_password ? (<Locked16 fill="red" description="locked table"/>) : null;
    116                 const nameClass = table.has_password ? "table__name table__name--locked" : "table__name";
    117                 const settings = table.settings;
    118                 let optionSpan = '';
    119                 if (settings.hard_pick || settings.hard_order || settings.stick_dealer){
    120                     const thp = settings.hard_pick ? 'HardPick' : '';
    121                     const tho = settings.hard_order ? 'HardOrder' : '';
    122                     const tsd = settings.stick_dealer ? 'StickDealer' : '';
    123                     optionSpan = (<span className="table__options">&nbsp;&nbsp;&nbsp;{thp} {tho} {tsd}</span>);
    124                 }
    125                 retVal.push(
    126                     <ClickableTile
    127                         key={table.name}
    128                         handleClick={() => clickHandler(table.name, table.has_password)}
    129                         >
    130                         <div className={nameClass}>{lockIcon}{table.name}{optionSpan}</div>
    131                         {conflictWarning}
    132                         <div className="table__players">Seated: {seated}</div>
    133                         <div className="table__spectators">Spectators: {specs}</div>
    134                     </ClickableTile>
    135                 )
    136             });
    137         }
    138         if (retVal.length == 0) {
    139             retVal = (
    140                 <div className="tlist__none">
    141                         No tables yet -- create one or refresh if expecting one...
    142                 </div>
    143             );
    144         }
    145         return retVal;
    146     }
    147 
    148     renderPasswordModal = () => {
    149         const {pwdOpen} = this.state;
    150         return (
    151             <ComposedModal
    152                 className="pm"
    153                 open={pwdOpen}
    154                 onClose={this.handleModalClose}>
    155                 <ModalHeader
    156                     className="pm__head"
    157                     title="Enter Table Password"
    158                     iconDescription="close"
    159                     // closeModal={this.handleModalClose}
    160                     />
    161                 <ModalBody
    162                     className="pm__body"
    163                 >
    164                     <TextInput
    165                         id="pm__pwd"
    166                         placeholder="enter table password"
    167                         labelText="Password"
    168                         ref={(input) => {this.pmPwd = input;}}
    169                     />
    170                 </ModalBody>
    171                 <ModalFooter
    172                     className="pm_foot"
    173                     primaryButtonText="Save"
    174                     // closeModal={this.handleModalClose}
    175                     onRequestSubmit={this.handleModalSave}
    176                 />
    177             </ComposedModal>
    178         );
    179     }
    180 
    181     render () {
    182         const {tables} = this.props;
    183         const showCards = tables.length > 0;
    184         const cards = this.renderCards();
    185         const passwordModal = this.renderPasswordModal(); 
    186         return (
    187             <div className="tlist__outer">
    188                 {passwordModal}
    189                 <div className="tlist__header">
    190                     <div className="tlist__title__row">
    191                         <div className="tlist__title">Click a table to join it... or</div>
    192                         <ModalWrapper
    193                             className="create__modal"
    194                             buttonTriggerText="Create a New Table"
    195                             primaryButtonText="Create"
    196                             modalHeading="New Table"
    197                             handleSubmit={this.handleCreate}
    198                             shouldCloseAfterSubmit={true}
    199                         >
    200                             <TextInput
    201                                 id="ct__name"
    202                                 placeholder="name your table"
    203                                 labelText="Table Name"
    204                                 ref={(input) => {this.ctName = input;}}
    205                             />
    206                             <br/>
    207                             <TextInput
    208                                 id="ct__pwd"
    209                                 placeholder="leave blank for no password"
    210                                 labelText="Table Password (optional)"
    211                                 ref={(input) => {this.ctPwd = input;}}
    212                             />
    213                             <br/>
    214                             <fieldset className="ct__optSet">
    215                                 <legend className="ct__optLabel">Game Options</legend>
    216                                 <Checkbox className="opt__hpick" id="opt__hpick" ref={(input) => {this.optHpick = input}}
    217                                     defaultChecked labelText="HardPick: Dealer must have suit to pick up"/>
    218                                 <Checkbox className="opt__horder" id="opt__horder" ref={(input) => {this.optHorder = input}}
    219                                     defaultChecked labelText="HardOrder: Must play alone if ordering partner"/>
    220                                 <Checkbox className="opt__stick" id="opt__stick" ref={(input) => {this.optStick = input}}
    221                                     labelText="StickDealer: Dealer must name trump if no one has" />
    222                             </fieldset>
    223                         </ModalWrapper>
    224                     </div>
    225                     {/* planned: filterByTableName, filterByPlayerName */}
    226                 </div>
    227                 <div className="tlist__main">
    228                     <div className="tlist__cntl">
    229                         <Button
    230                             className="tlist__refresh"
    231                             hasIconOnly
    232                             onClick={this.handleRefresh}
    233                             renderIcon={Renew16}
    234                             size="small"
    235                             iconDescription="Refresh List"
    236                             tooltipPosition="bottom"
    237                             ref={(button) => {this.refreshButton = button;}}
    238                         />
    239                     </div>
    240                     <div className="tlist__holder">
    241                         <div className="tlist__list">
    242                             {cards}
    243                         </div>
    244                     </div>
    245                 </div>
    246             </div>
    247         )
    248     }
    249 
    250 }
    251 TableList.propTypes = {
    252     tables: PropTypes.array,
    253     playerName: PropTypes.string,
    254     joinTable: PropTypes.func,
    255     refresh: PropTypes.func
    256 }