Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.10 KB | None | 0 0
  1. import React from 'react';
  2. import { connect } from 'react-redux';
  3. import { ContentLoader, Form, Select, Table, TextInput } from '@xanda/react-components';
  4. import { api, fn } from 'app/utils';
  5. import { url } from 'app/constants';
  6. import { fetchData } from 'app/actions';
  7. import { Block, ButtonStandard, Link, Meta, PageTitle, FormButton, ConfirmDialog } from 'app/components';
  8.  
  9. @connect((store, ownProps) => {
  10. return {
  11. collection: store.player,
  12. player: store.player.collection[ownProps.params.playerId] || {},
  13. skills: store.skill
  14. };
  15. })
  16. export default class View extends React.PureComponent {
  17.  
  18. constructor(props) {
  19. super(props);
  20.  
  21. this.playerId = this.props.params.playerId;
  22.  
  23. this.state = {};
  24. }
  25.  
  26. componentWillMount() {
  27. this.fetchData();
  28.  
  29. if (!this.props.skills.fetched) {
  30. this.props.dispatch(fetchData({
  31. type: 'SKILL',
  32. url: '/skills',
  33. }));
  34. }
  35. }
  36.  
  37. fetchData = () => {
  38. this.props.dispatch(fetchData({
  39. type: 'PLAYER',
  40. url: `/players/${this.playerId}`,
  41. }));
  42. }
  43.  
  44. handleInputChange = (name, value) => {
  45. this.setState({ [name]: value })
  46. }
  47.  
  48. saveSize = async (kit) => {
  49. const size = this.state[`size${kit.id}`]
  50.  
  51. if (!size) {
  52. return false
  53. }
  54.  
  55. const formData = {
  56. size
  57. };
  58.  
  59. const response = await api.update(`/kit_users/${kit.id}`, formData)
  60.  
  61. if (!api.error(response)) {
  62. fn.showAlert('Size has been selected!', 'success');
  63. this.fetchData()
  64. }
  65. }
  66.  
  67. saveStatus = async (kitItem) => {
  68. const id = kitItem.id;
  69. const status = kitItem.status === 1 ? 0 : 1;
  70. const formData = {
  71. type: 'status',
  72. status: status
  73. };
  74.  
  75. const response = await api.update(`/kit_users/${id}`, formData)
  76.  
  77. if (!api.error(response)) {
  78. this.fetchData()
  79. }
  80. }
  81.  
  82. renderKitSize = (kit) => {
  83. let size = kit.size
  84.  
  85. if (!kit.size) {
  86. let saveButton = null
  87.  
  88. // check if size is set for that id
  89. if (this.state[`size${kit.id}`]) {
  90. saveButton = <span key="saveSize"
  91. className="button"
  92. onClick={() => this.saveSize(kit)}>
  93. <img className="icon-save" src={"/images/icon/save.png"} />
  94. </span>
  95. }
  96.  
  97. size = (
  98. <div className="flex">
  99. <Select name={`size${kit.id}`}
  100. valueKey="value"
  101. options={kit.kit && kit.kit.available_sizes}
  102. onChange={this.handleInputChange} />{saveButton}
  103. </div>
  104. );
  105. }
  106.  
  107. return <td className="kit-size-select">{size}</td>
  108. }
  109.  
  110.  
  111.  
  112. handleSubmitPlayerNote = async () => {
  113. const { playerNotes } = this.state
  114. const { player } = this.props
  115.  
  116. let formData = new FormData()
  117. playerNotes && formData.append('note', playerNotes)
  118. const response = await api.update(`${url.player}/${player.player_id}/notes`, formData)
  119. this.refNoteForm.hideLoader()
  120. if (!api.error(response)) {
  121. this.fetchData()
  122.  
  123. if (!this.props.skills.fetched) {
  124. this.props.dispatch(fetchData({
  125. type: 'SKILL',
  126. url: '/skills',
  127. }));
  128. }
  129. }
  130. }
  131.  
  132. /**
  133. *
  134. * Remove kit item from player base on rel_kit_user.id
  135. *
  136. */
  137. handleDeleteKitItem = async (relKitUser, del) => {
  138. const deleteUrl = `kit_users/${relKitUser.id}`
  139.  
  140. if (del) {
  141. const response = await api.delete(`/kits/${relKitUser}/${this.playerId}`)
  142. if (!api.error(response)) {
  143. this.fetchData()
  144. }
  145. return
  146. }
  147.  
  148. const response = await api.delete(deleteUrl)
  149. if (!api.error(response)) {
  150. this.fetchData()
  151. }
  152. }
  153.  
  154. renderPlayerStatus = (team) => {
  155. switch (team.player_status) {
  156. case 'trial':
  157. return 'Awaiting Trial'
  158.  
  159. case 'trialist':
  160. return 'Trialists'
  161.  
  162. case 'waiting':
  163. return 'Waiting List'
  164.  
  165. case 'assigned':
  166. return 'Currently Assigned'
  167.  
  168. default:
  169. return ''
  170. }
  171. }
  172.  
  173. render() {
  174. const {
  175. collection,
  176. player,
  177. skills,
  178. } = this.props;
  179.  
  180. const sessionDates = _(player.sessions).map('start_time').value();
  181. const { sessionsOnDate } = this.state;
  182. const billingGuardian = _.find(player.guardians, guardian => guardian.user_id === player.billing_guardian) || {};
  183. const livingGuardian = _.find(player.guardians, guardian => guardian.user_id === player.living_guardian) || {};
  184. return (
  185. <div id="content" className="site-content-inner">
  186. <ContentLoader
  187. data={player.player_id}
  188. forceRefresh
  189. isLoading={collection.isLoading}
  190. notFound="No Data"
  191. >
  192. {/* Teams & skill groups section */}
  193. <Block title="Teams & Skill groups">
  194. {fn.isAdmin() &&
  195. <ButtonStandard to={`${url.player}/${this.playerId}/skill-group`}
  196. icon={<i className="ion-ios-people" />}
  197. className="mb-30">Assign to skill group
  198. </ButtonStandard>
  199. }
  200.  
  201. {'teams' in player && player.teams.length > 0 ? (
  202. <div className="grid">
  203. {player.teams.map((team, teamIndex) => {
  204. const teamSkills = player.skills && player.skills[team.team_id] ? player.skills[team.team_id] : {};
  205. const teamLogoUrlClass = _.isEmpty(team.logo_url) ? ' no-badge' : ''
  206.  
  207. return (
  208. <div className={`grid-xs-12 grid-m-4`}
  209. key={`team_${team.team_id}`}>
  210. <div className="grid-inner">
  211. <div className={`player-skill-wrapper${teamLogoUrlClass}`}>
  212. <div className="player-team">
  213. <span className="icon-legend team-badge"
  214. style={{ backgroundImage: `url(${team.logo_url})` }} />
  215. {fn.isAdmin() ?
  216. <React.Fragment>
  217. <div className={"player-team-title"}>
  218. <Link to={`${url.team}/${team.team_id}/players`}>
  219. <h5 className="team-name text-primary">
  220. {team.type === 'skill-group' ? 'Soccer school: ' : 'Football club: '}
  221. {team.title}
  222. <i className="icon ion-edit"></i>
  223. </h5>
  224. </Link>
  225.  
  226. <div>
  227. <div>Status: {this.renderPlayerStatus(team)}</div>
  228. <div>Age group: {team.agegroup_title}</div>
  229. </div>
  230. </div>
  231. </React.Fragment>
  232. :
  233. <h5 className="team-name text-primary">{team.title}</h5>
  234. }
  235. </div>
  236.  
  237. {/* Skills here */}
  238. <div className="player-skills">
  239. {skills.currentCollection && _.map(skills.currentCollection, (skillId) => {
  240. const skill = skills.collection[skillId];
  241. const grade = teamSkills[skill.skill_id] ? teamSkills[skill.skill_id].grade : 0;
  242. return (
  243. grade > 0 && (<div className="player-skill"
  244. key={`skill_${skill.skill_id}`}>
  245. <span className="skill-name">
  246. {skill.title}
  247. {grade > 0 && <span
  248. className="grade">{Math.round(grade * 10) / 10}</span>}
  249. </span>
  250. <div className="skill-bar-wrapper">
  251. <div className="skill-bar"
  252. style={{ width: `${grade * 10}%` }} />
  253. </div>
  254. </div>)
  255. );
  256. })}
  257. </div>
  258. </div>
  259. </div>
  260. </div>
  261. );
  262. })}
  263. </div>
  264. ) : (
  265. <p>{player.display_name} is not assigned to any teams or skill groups</p>
  266. )}
  267. </Block>
  268.  
  269. {/* Timetable section */}
  270. <Block title="Timetable">
  271. {player.sessions && player.sessions.length > 0 ? (
  272. <Table className="header-transparent"
  273. headers={['', 'Time', 'Venue', 'Programme']}
  274. icon="ion-clock">
  275. {player.sessions.map(session => (
  276. <tr key={`sessions_${session.session_id}`}>
  277. <td><Link
  278. to={`${url.session}/${session.session_id}/player/${player.player_id}`}>{fn.formatDate(session.start_time)}</Link>
  279. </td>
  280. <td>{`${fn.formatDate(session.start_time, 'HH:mm')} - ${fn.formatDate(session.end_time, 'HH:mm')}`}</td>
  281. <td><Link
  282. to={`${url.session}/${session.session_id}/player/${player.player_id}`}>{session.address}</Link>
  283. </td>
  284. <td>{session.is_trial ? `${session.programme_name} - Trial` : session.programme_name}, {session.programme_type}</td>
  285. </tr>
  286. ))}
  287. </Table>
  288. ) : (
  289. <p>{player.display_name} has no sessions</p>
  290. )}
  291. </Block>
  292.  
  293. {/* Home works secion */}
  294. <Block title="Homeworks">
  295. {player.homeworks && player.homeworks.length > 0 ? (
  296. <Table headers={['', 'Date', 'Coach']}>
  297. {player.homeworks.map(homework => (
  298. <tr key={`homework_${homework.homework_id}`}>
  299. <td><Link to={`${url.homework}/${homework.homework_id}`}>{homework.title}</Link>
  300. </td>
  301. <td>{fn.formatDate(homework.homework_date)}</td>
  302. <td>{homework.coach_name}</td>
  303. </tr>
  304. ))}
  305. </Table>
  306. ) : (
  307. <p>{player.display_name} has no homeworks</p>
  308. )}
  309. </Block>
  310.  
  311. {/* Kit item section */}
  312. <Block title="Kit items">
  313. {
  314. fn.isAdmin() &&
  315. <ButtonStandard to={`${url.player}/${this.playerId}/kit-assignment`}
  316. className="mb-25"
  317. icon={<i className="ion-tshirt" />}>Assign kit
  318. </ButtonStandard>
  319. }
  320.  
  321. {player.kits && player.kits.length > 0 ? (
  322. <Table headers={['Name', 'Team', 'Type', 'Size', 'Given', `${fn.isAdmin() ? "Delete" : ""}`]}
  323. className="header-transparent "
  324. icon="ion-tshirt">
  325. {player.kits.map(kit => {
  326. return <tr key={`kit_${kit.id}`}>
  327. <td className="td-large">
  328. <Link to={`${url.kit}/${kit.kit_id}`}>{kit.kit && kit.kit.title}</Link>
  329. </td>
  330. <td>{kit.team && kit.team.title}</td>
  331. <td>{kit.kit && kit.kit.type && kit.kit.type.title}</td>
  332. {this.renderKitSize(kit)}
  333. <td className={"td-small"}>
  334. {kit.status === 1 ?
  335. <button className={"button no-padding"} disabled>
  336. <i className="icon ion-checkmark-round"></i>
  337. </button>
  338. :
  339. <button className={"button no-padding"}
  340. onClick={() => this.saveStatus(kit)}>
  341. <i title="Not Assign" className="ion-android-expand" />
  342. </button>
  343. }
  344.  
  345. {!kit.size && <ConfirmDialog
  346. onlyContent={true}
  347. body={<div>You want to delete this kit item.</div>}
  348. onConfirm={() => this.handleDeleteKitItem(kit)}>
  349. <button className="button">
  350. <i className="ion ion-android-delete"></i>
  351. </button>
  352. </ConfirmDialog>
  353. }
  354.  
  355. </td>
  356.  
  357. {fn.isAdmin() ? (
  358. <td className="short table-options">
  359. <ConfirmDialog
  360. showCloseButton={false}
  361. // onConfirm={() => this.deleteData(kit.id)}
  362. onConfirm={() => this.handleDeleteKitItem(kit.kit_id, true)}
  363. title=""
  364. body={
  365. <React.Fragment>
  366. <h3>Confirm</h3>
  367. <p>Are you sure you want to delete?</p>
  368. </React.Fragment>
  369. }
  370. >
  371. <span className="button icon"><i title="Delete" className="ion-trash-b" /></span>
  372. </ConfirmDialog>
  373. </td>) : ""}
  374.  
  375.  
  376.  
  377. </tr>
  378. }
  379. )
  380. }
  381. </Table>
  382. ) : (
  383. <p>{player.display_name} has no assigned kit items</p>
  384. )}
  385. </Block>
  386. {fn.isAdmin() &&
  387. <Block title="Player Consent">
  388. {player.consents && player.consents.length > 0 ? (
  389. <Table headers={['Type', 'Agreed by', 'Date']}>
  390. {player.consents.map(consent => (
  391. <tr key={consent.consent_id}>
  392. <td>{consent.title}</td>
  393. <td>{consent.agreed_by}</td>
  394. <td>{fn.formatDate(consent.agreed_at, 'DD MMM YYYY')}</td>
  395. </tr>
  396. ))}
  397. </Table>
  398. ) : (
  399. <p>{player.display_name} has no consent</p>
  400. )}
  401. </Block>
  402. }
  403. {fn.isAdmin() &&
  404. <Block title="Player Notes">
  405. <Form
  406. loader
  407. wide
  408. className="form-section"
  409. onSubmit={this.handleSubmitPlayerNote}
  410. ref={ref => this.refNoteForm = ref}
  411. >
  412. <TextInput
  413. wide
  414. textarea
  415. name="playerNotes"
  416. label="Notes"
  417. value={player.note}
  418. onChange={this.handleInputChange}
  419. />
  420. <div className="form-actions">
  421. <FormButton label="Save Player Notes" />
  422. </div>
  423. </Form>
  424.  
  425. {/*{player.notes && player.notes.length > 0 ? (*/}
  426. {/* <Table headers={['Note', 'Coach', 'Date']}>*/}
  427.  
  428. {/* {player.notes.map(note => (*/}
  429. {/* <tr key={note.note_id}>*/}
  430. {/* <td>{note.note}</td>*/}
  431. {/* <td>{note.coach_name}</td>*/}
  432. {/* <td>{fn.formatDate(note.created_at, 'DD MMM YYYY')}</td>*/}
  433. {/* </tr>*/}
  434. {/* ))}*/}
  435. {/* </Table>*/}
  436. {/*) : (*/}
  437. {/* <p>{player.display_name} has no notes</p>*/}
  438. {/*)}*/}
  439. </Block>
  440. }
  441. </ContentLoader>
  442. </div>
  443. );
  444. }
  445.  
  446. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement