Guest User

Untitled

a guest
Jan 21st, 2019
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.99 KB | None | 0 0
  1. import React, { Component, Fragment } from 'react';
  2. import { connect } from 'react-redux';
  3. import { FieldArray, Field, withFormik } from 'formik';
  4. import { TextField } from 'redux-form-material-ui';
  5. import Button from '@material-ui/core/Button';
  6. import SvgIcon from '@material-ui/core/SvgIcon';
  7. import { withStyles } from '@material-ui/core/styles';
  8. import CircularProgress from '@material-ui/core/CircularProgress';
  9. import Dropzone from 'react-dropzone';
  10. import PropTypes from 'prop-types';
  11. import { DropZoneTitle, AttachmentItem } from '../../components/DropZone';
  12. import { svgIconPath, countDays } from '../../helpers';
  13. import { playerActions, revisionActions, videoActions } from '../../actions';
  14.  
  15. const styles = {
  16. colorPrimary: {
  17. backgroundColor: '#2C8B3F',
  18. borderRadius: '50%'
  19. },
  20. circleStatic: {
  21. color: 'rgba(0,0,0,0.2)',
  22. borderRadius: 5
  23. },
  24. raised: {
  25. backgroundColor: '#212121',
  26. color: '#fff'
  27. },
  28. outlined: {
  29. backgroundColor: 'rgba(98,2,238,0)',
  30. border: '1px solid rgba(0,0,0,0.12)',
  31. marginRight: 10
  32. }
  33. };
  34.  
  35. class RevisionPage extends Component {
  36. componentDidMount() {
  37. const {
  38. currentVideo: { _id: videoId },
  39. match: {
  40. params: { id }
  41. },
  42. getVideoById,
  43. getRevision,
  44. videoContentId
  45. } = this.props;
  46. if (!videoId && id) {
  47. getVideoById(id).then(() => {
  48. if (!videoContentId) getRevision(id);
  49. });
  50. }
  51. }
  52.  
  53. componentWillUnmount() {
  54. this.props.clearCurVideo();
  55. this.props.clearContentId();
  56. }
  57.  
  58. addRevision = (fields) => {
  59. const {
  60. player: { markerPosition },
  61. addMarker
  62. } = this.props;
  63. fields.push({
  64. timeCode: markerPosition,
  65. request: '',
  66. files: []
  67. });
  68. addMarker(markerPosition, fields.length);
  69. };
  70.  
  71. deleteRevision = (arrayHelpers, ind) => {
  72. const { deleteMarker } = this.props;
  73. arrayHelpers.remove(ind);
  74. deleteMarker(ind);
  75. };
  76.  
  77. onChange = setFieldValue => (name, value) => setFieldValue(name, value);
  78.  
  79. renderRevisionFields = (arrayHelpers) => {
  80. const {
  81. player: { durationInt },
  82. updateMarker,
  83. values: { revisions: values },
  84. setFieldValue
  85. } = this.props;
  86. return (
  87. <Fragment>
  88. {values.map((revision, ind) => (
  89. <div key={`revision${ind}`} className="d-flex p-30-0 revision-fields">
  90. <div className="d-flex w-50 align-items-start revision-fields-title">
  91. <div className="d-flex flex-row align-items-center">
  92. <p>Revision 4.2.1</p>
  93. <SvgIcon onClick={() => this.deleteRevision(arrayHelpers, ind)}>
  94. <path d={svgIconPath.cancel.path} />
  95. </SvgIcon>
  96. </div>
  97. </div>
  98. <div className="w-50">
  99. <Field
  100. name={`revisions[${ind}].timeCode`}
  101. helperText="You can choose time code or full video"
  102. margin="none"
  103. variant="filled"
  104. label="Time Code"
  105. fullWidth
  106. value={revision.timeCode}
  107. onChange={({ currentTarget: { value } }) => setFieldValue(`revisions[${ind}].timeCode`, value)}
  108. onBlur={({ currentTarget: { value } }) => updateMarker(value, ind, durationInt)}
  109. component={TextField}
  110. style={{ marginBottom: 20 }}
  111. />
  112. <Field
  113. name={`revisions[${ind}].request`}
  114. helperText="Please add description of revision"
  115. margin="none"
  116. variant="filled"
  117. label="Revision"
  118. fullWidth
  119. value={revision.request}
  120. onChange={({ currentTarget: { value } }) => setFieldValue(`revisions[${ind}].request`, value)}
  121. component={TextField}
  122. style={{ marginBottom: 20 }}
  123. />
  124. <Field
  125. name={`revisions${[ind]}.files`}
  126. component={() => (
  127. <Dropzone
  128. name={`revisions[${ind}].files`}
  129. className="react-drop-zone"
  130. onDrop={file => setFieldValue(`revisions[${ind}].files`, revision.files.concat(file))}
  131. >
  132. <DropZoneTitle />
  133. </Dropzone>
  134. )}
  135. />
  136. <div className="d-flex flex-column">
  137. {revision.files.map(f => (
  138. <AttachmentItem
  139. key={f.name}
  140. file={f}
  141. onDelete={() => setFieldValue(`revisions[${ind}].files`, revision.files.filter(rf => rf.name !== f.name))
  142. }
  143. />
  144. ))}
  145. </div>
  146. </div>
  147. </div>
  148. ))}
  149. <div className="d-flex add-revision-block p-30-0 with-border-top with-border-bottom add-revision-button">
  150. <div className="w-50" />
  151. <div className="d-flex w-50" onClick={() => this.addRevision(values)}>
  152. <SvgIcon>
  153. <path d={svgIconPath.addCircle.path} />
  154. </SvgIcon>
  155. Add Another Revision
  156. </div>
  157. </div>
  158. </Fragment>
  159. );
  160. };
  161.  
  162. render() {
  163. const {
  164. currentVideo,
  165. classes: { colorPrimary, circleStatic, raised, outlined },
  166. handleSubmit,
  167. setFieldValue
  168. } = this.props;
  169. return (
  170. <div className="revision-video-page p-0-20">
  171. <div className="d-flex justify-content-between align-items-center video-brief-title">
  172. <h1>{currentVideo ? 'Revision 4.2' : 'New Video Revision:'}</h1>
  173. <CircularProgress
  174. variant="static"
  175. value={-75}
  176. thickness={10}
  177. size={60}
  178. classes={{ colorPrimary, circleStatic }}
  179. />
  180. </div>
  181. <div className="d-flex video-brief-subtitle align-items-start">
  182. <div className="d-flex w-50">
  183. <div className="d-flex align-items-center video-brief-subtitle-icon">
  184. <SvgIcon style={{ fontSize: 40 }}>
  185. <path d={svgIconPath.accountCircle.path} />
  186. </SvgIcon>
  187. </div>
  188. <div className="d-flex flex-column video-brief-subtitle-info">
  189. <span>Reviewed by:</span>
  190. <h3>Unknown</h3>
  191. {/** TODO should be admin name here */}
  192. </div>
  193. </div>
  194. <div className="d-flex w-50">
  195. <div className="d-flex align-items-center video-brief-subtitle-icon">
  196. <SvgIcon style={{ fontSize: 40 }}>
  197. <path d={svgIconPath.calendarToday.path} />
  198. </SvgIcon>
  199. </div>
  200. <div className="d-flex flex-column video-brief-subtitle-info w-100">
  201. <span>Revision on:</span>
  202. <h3>{currentVideo ? countDays(currentVideo.createdAt) : ''}</h3>
  203. </div>
  204. </div>
  205. </div>
  206. <div className="d-flex flex-column with-border-bottom p-30-0">
  207. <div className="d-flex revision-question-block revision-data-block">
  208. <div className="w-50">
  209. <span>Video Title:</span>
  210. </div>
  211. <div className="w-50">
  212. <p>{currentVideo.title || ''}</p>
  213. </div>
  214. </div>
  215. </div>
  216. <form onSubmit={handleSubmit}>
  217. <FieldArray name="revisions" render={arrayHelpers => this.renderRevisionFields(arrayHelpers)} />
  218. <div className="d-flex justify-content-end p-30-0">
  219. <Button classes={{ outlined }} variant="outlined" type="submit">
  220. Save
  221. </Button>
  222. <Button
  223. classes={{ raised }}
  224. variant="contained"
  225. type="submit"
  226. onClick={() => setFieldValue('revisionState', 'inEdit')}
  227. >
  228. Submit
  229. </Button>
  230. </div>
  231. </form>
  232. </div>
  233. );
  234. }
  235. }
  236.  
  237. RevisionPage.propTypes = {
  238. player: PropTypes.objectOf(PropTypes.any).isRequired,
  239. currentVideo: PropTypes.objectOf(PropTypes.any).isRequired,
  240. videoContentId: PropTypes.string,
  241. addMarker: PropTypes.func.isRequired,
  242. updateMarker: PropTypes.func.isRequired,
  243. deleteMarker: PropTypes.func.isRequired,
  244. clearCurVideo: PropTypes.func.isRequired,
  245. clearContentId: PropTypes.func.isRequired,
  246. getRevision: PropTypes.func.isRequired
  247. };
  248.  
  249. RevisionPage.defaultProps = {
  250. videoContentId: undefined
  251. };
  252.  
  253. const WithStyles = withStyles(styles)(RevisionPage);
  254.  
  255. WithStyles.propTypes = {
  256. saveRevisions: PropTypes.func.isRequired
  257. };
  258.  
  259. const withFormikForm = withFormik({
  260. mapPropsToValues: () => ({
  261. revisions: [
  262. {
  263. timeCode: 0,
  264. request: '',
  265. files: []
  266. }
  267. ],
  268. revisionState: 'clientEditReview'
  269. }),
  270. handleSubmit: (values, { props, setSubmitting }) => {
  271. const {
  272. saveRevisions,
  273. user: {
  274. userData: { _id: userId }
  275. },
  276. videoContentId,
  277. match: {
  278. params: { id: videoDraftId }
  279. }
  280. } = props;
  281. setSubmitting(false);
  282. return saveRevisions({ ...values, userId, videoDraftId, videoContentId });
  283. },
  284.  
  285. displayName: 'revisionForm'
  286. })(WithStyles);
  287.  
  288. const mapStateToProps = ({ user, video: { currentVideo }, player, revision: { videoContentId } }) => ({
  289. user,
  290. currentVideo,
  291. player,
  292. videoContentId
  293. });
  294.  
  295. const mapDispatchToProps = dispatch => ({
  296. addMarker: (markerTime, revisionIndex) => dispatch(playerActions.addRevisionMarker(markerTime, revisionIndex)),
  297. updateMarker: (markerTime, revisionIndex, duration) => dispatch(playerActions.updateRevisionMarkerPosition(markerTime, revisionIndex, duration)),
  298. deleteMarker: ind => dispatch(playerActions.removeRevisionMarker(ind)),
  299. saveRevisions: data => dispatch(revisionActions.saveRevision(data)),
  300. getVideoById: videoId => dispatch(videoActions.getVideoById(videoId)),
  301. clearCurVideo: () => dispatch(videoActions.leaveVideoPage()),
  302. clearContentId: () => dispatch(revisionActions.leaveVideoPage()),
  303. getRevision: videoId => dispatch(revisionActions.getRevisionByVideoDraftId(videoId))
  304. });
  305.  
  306. const connected = connect(
  307. mapStateToProps,
  308. mapDispatchToProps
  309. )(withFormikForm);
  310.  
  311. export { connected as RevisionPage };
Add Comment
Please, Sign In to add comment