Advertisement
Guest User

te

a guest
Oct 27th, 2020
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.69 KB | None | 0 0
  1. import React from 'react';
  2.  
  3. import Container from '@material-ui/core/Container';
  4. import Grid from '@material-ui/core/Grid';
  5.  
  6. import { withStyles } from '@material-ui/core/styles';
  7. import CssBaseline from '@material-ui/core/CssBaseline';
  8.  
  9. import './App.css';
  10.  
  11.  
  12. import config from './config'
  13.  
  14. import Login from './components/Login';
  15. import Signup from './components/Signup';
  16. import Projects from './components/Projects';
  17. import Config from './components/Config';
  18.  
  19. class App extends React.Component {
  20. constructor(props) {
  21. super(props);
  22.  
  23. this.state = {
  24. user: null,
  25. showSignUp: false,
  26. };
  27.  
  28. this.loggedIn = this.loggedIn.bind(this);
  29. this.content = this.content.bind(this);
  30. this.handleLogout = this.handleLogout.bind(this);
  31. this.handleLogin = this.handleLogin.bind(this);
  32. this.toggleSignupForm = this.toggleSignupForm.bind(this);
  33. }
  34.  
  35. componentDidMount() {
  36. const token = localStorage.getItem(config.localStorageTokenKey);
  37.  
  38. this.handleLogin(token ? {} : null)
  39. }
  40.  
  41. loggedIn() {
  42. return !!this.state.user;
  43. }
  44.  
  45. handleLogout() {
  46. localStorage.removeItem(config.localStorageTokenKey);
  47. return this.setState({ user: null });
  48. }
  49.  
  50. handleLogin(user) {
  51. return this.setState({ user });
  52. }
  53.  
  54. toggleSignupForm() {
  55. this.setState({ showSignUp: !this.state.showSignUp });
  56. }
  57.  
  58. content() {
  59. if (this.loggedIn()) {
  60. return (
  61. <Projects
  62. handleLogout={this.handleLogout}
  63. user={this.state.user}
  64. projects={this.state.user.projects}
  65. />
  66. )
  67. }
  68.  
  69. if (this.state.showSignUp) {
  70. return (<Signup onClose={this.toggleSignupForm}/>)
  71. }
  72.  
  73. return (<Login onLogin={this.handleLogin} onShowSignup={this.toggleSignupForm}/>)
  74. }
  75.  
  76. render() {
  77. const { classes } = this.props;
  78.  
  79. return (
  80. <Container fixed>
  81. <CssBaseline />
  82.  
  83. <Grid container justify="flex-end">
  84. <Config config={config} />
  85. </Grid>
  86.  
  87. <Grid className={classes.root} justify="center" container spacing={3}>
  88. <Grid item sm={6}>
  89. { this.content() }
  90. </Grid>
  91. </Grid>
  92. </Container>
  93. );
  94. }
  95. }
  96.  
  97. const styles = {
  98. root: {
  99. marginTop: 40,
  100. },
  101. };
  102.  
  103. export default withStyles(styles)(App);
  104.  
  105.  
  106.  
  107.  
  108.  
  109. PROJECT ++++++++++=========++++++++++=========++++++++++=========++++++++++=========++++++++++=========++++++++++=========
  110.  
  111. import React from 'react';
  112.  
  113. import Card from '@material-ui/core/Card';
  114. import CardHeader from '@material-ui/core/CardHeader';
  115. import CardContent from '@material-ui/core/CardContent';
  116. import CardActions from '@material-ui/core/CardActions';
  117. import DeleteIcon from '@material-ui/icons/Delete';
  118.  
  119. import Tasks from './Tasks'
  120.  
  121. import { withStyles } from '@material-ui/core/styles';
  122.  
  123. import moment from 'moment';
  124. import { IconButton } from '@material-ui/core';
  125.  
  126.  
  127. class Project extends React.Component {
  128. constructor(props) {
  129. super(props);
  130.  
  131. this.state = {
  132. project: null,
  133. loading: false
  134. }
  135. }
  136.  
  137. componentDidMount() {
  138. this.setState({ project: this.props.project })
  139. }
  140.  
  141. renderRemoveBtn() {
  142. const { project } = this.state
  143. const { onRemove } = this.props
  144.  
  145. return (
  146. <IconButton onClick={() => onRemove(project)}>
  147. <DeleteIcon />
  148. </IconButton>
  149. )
  150. }
  151.  
  152.  
  153. render() {
  154. const { project } = this.state
  155. const { classes } = this.props
  156.  
  157. if (!project) {
  158. return null
  159. }
  160.  
  161. return (
  162. <Card className={classes.root}>
  163. <CardHeader
  164. title={project.name}
  165. subheader={moment(project.created_at).format('MMMM Do YYYY, h:mm:ss a')}
  166. action={this.renderRemoveBtn()}
  167. />
  168. <CardContent>
  169. <Tasks project={project} />
  170.  
  171. </CardContent>
  172. <CardActions disableSpacing>
  173.  
  174. </CardActions>
  175. </Card>
  176. );
  177. }
  178. }
  179.  
  180. const styles = {
  181. root: {
  182. marginTop: 20,
  183. },
  184. };
  185.  
  186.  
  187. export default withStyles(styles)(Project);
  188.  
  189. PROJECTS============================================++++++++++=========++++++++++=========++++++++++=========++++++++++=========
  190.  
  191. import React from 'react';
  192.  
  193. import Button from '@material-ui/core/Button';
  194. import Typography from '@material-ui/core/Typography';
  195. import ButtonGroup from '@material-ui/core/ButtonGroup';
  196. import Grid from '@material-ui/core/Grid';
  197. import Snackbar from '@material-ui/core/Snackbar';
  198. import MuiAlert from '@material-ui/lab/Alert';
  199. import Container from '@material-ui/core/Container';
  200. import RefreshIcon from '@material-ui/icons/Refresh';
  201.  
  202. import { withStyles } from '@material-ui/core/styles';
  203.  
  204. import api from '../services/api'
  205. import Project from './Project';
  206. import NewProject from './NewProject'
  207. import config from '../config'
  208.  
  209. function Alert(props) {
  210. return <MuiAlert elevation={6} variant="filled" {...props} />;
  211. }
  212.  
  213. class Projects extends React.Component {
  214. constructor(props) {
  215. super(props);
  216.  
  217. this.state = {
  218. projects: [],
  219. snackopen: false,
  220. snackmsg: '',
  221. snackerrormsg: ''
  222. }
  223.  
  224. this.refreshProjects = this.refreshProjects.bind(this);
  225. this.removeProject = this.removeProject.bind(this);
  226. this.handleClose = this.handleClose.bind(this);
  227. this.showSuccessMsg = this.showSuccessMsg.bind(this);
  228. this.showErrorMsg = this.showErrorMsg.bind(this);
  229. }
  230.  
  231. componentDidMount() {
  232. this.refreshProjects()
  233. }
  234.  
  235. showSuccessMsg(message) {
  236. return this.setState({snackopen: true, snackmsg: message })
  237. }
  238.  
  239. showErrorMsg(message) {
  240. return this.setState({snackopen: true, snackerrormsg: message })
  241. }
  242.  
  243. refreshProjects() {
  244. this.setState({ projects: [] })
  245.  
  246. return api.get(config.urls.projects).then((response) => {
  247. this.setState({ projects: response.data })
  248. }).catch((error) => {
  249. debugger
  250. const { detail } = error.response.data;
  251. this.showErrorMsg(detail)
  252. })
  253. }
  254.  
  255. removeProject(project) {
  256. this.setState({snackopen: true})
  257. return api.delete(`${config.urls.projects}${project.id}`).then((response) => {
  258. // this.refreshProjects()
  259. const projects = this.state.projects.filter((item) => item.id !== project.id)
  260.  
  261. this.setState({ projects })
  262. this.showSuccessMsg('Project successfully removed')
  263. }).catch((error) => {
  264. const { detail } = error.response.data;
  265.  
  266. this.showErrorMsg(detail)
  267. })
  268. }
  269.  
  270. renderProjects() {
  271. const { projects } = this.state;
  272.  
  273. if (projects.length === 0) {
  274. return (<Typography variant="overline" display="block" gutterBottom>No projects</Typography>)
  275. }
  276.  
  277. return projects.map((project) => <Project project={project} key={project.id} onRemove={this.removeProject} />)
  278. }
  279.  
  280. handleClose (event, reason) {
  281. if (reason === 'clickaway') {
  282. return;
  283. }
  284.  
  285. this.setState({snackopen: false, snackerrormsg: '', snackmsg: ''});
  286. }
  287.  
  288. render() {
  289. const { snackopen, snackerrormsg, snackmsg } = this.state;
  290.  
  291. return (
  292. <Container>
  293. <Grid container justify="flex-end">
  294. <ButtonGroup disableElevation>
  295. <Button onClick={this.refreshProjects} startIcon={<RefreshIcon />}>
  296. Refresh
  297. </Button>
  298. <Button onClick={this.props.handleLogout}>
  299. Logout
  300. </Button>
  301. </ButtonGroup>
  302. </Grid>
  303.  
  304. { this.renderProjects() }
  305.  
  306. <NewProject onCreated={this.refreshProjects} />
  307.  
  308. <Snackbar open={snackopen} onClose={this.handleClose} autoHideDuration={3000}>
  309. <Alert severity={snackmsg.length > 0 ? 'success' : 'error'}> { snackmsg.length > 0 ? snackmsg : snackerrormsg }</Alert>
  310. </Snackbar>
  311. </Container>
  312. );
  313. }
  314. }
  315.  
  316. const styles = {
  317. root: {
  318. marginTop: 20,
  319. },
  320. addProjectBtn: {
  321. marginTop: 20,
  322. }
  323. };
  324.  
  325.  
  326. export default withStyles(styles)(Projects);
  327.  
  328. ++++++++++=========++++++++++=========++++++++++=========++++++++++=========++++++++++=========++++++++++=========
  329.  
  330.  
  331. TASK
  332.  
  333.  
  334. import React from 'react';
  335.  
  336. import DeleteIcon from '@material-ui/icons/Delete';
  337. import List from '@material-ui/core/List';
  338. import ListItem from '@material-ui/core/ListItem';
  339. import ListItemText from '@material-ui/core/ListItemText';
  340. import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
  341. import IconButton from '@material-ui/core/IconButton';
  342. import EditIcon from '@material-ui/icons/Edit';
  343. import AddIcon from '@material-ui/icons/Add';
  344. import TextField from '@material-ui/core/TextField';
  345.  
  346. import { withStyles } from '@material-ui/core/styles';
  347.  
  348. import api from '../services/api'
  349. import config from '../config';
  350.  
  351. class Tasks extends React.Component {
  352. constructor(props) {
  353. super(props);
  354.  
  355. this.state = {
  356. project: null,
  357. tasks: [],
  358. newTask: {
  359. name: {
  360. value: '',
  361. error: null
  362. }
  363. }
  364. }
  365.  
  366. this.addTask = this.addTask.bind(this)
  367. this.removeTask = this.removeTask.bind(this)
  368. this.editTask = this.editTask.bind(this)
  369. this.renderList = this.renderList.bind(this)
  370. this.updateNewTaskName = this.updateNewTaskName.bind(this)
  371. this.onSubmit = this.onSubmit.bind(this)
  372. }
  373.  
  374. componentDidMount() {
  375. this.setState({ project: this.props.project }, this.refreshTasks)
  376. }
  377.  
  378. addTask() {
  379.  
  380. const params = {
  381. project: this.state.project.url,
  382. name: this.state.newTask.name.value,
  383. }
  384.  
  385.  
  386. return api.post(config.urls.tasks, params).then((resp) => {
  387. this.refreshTasks()
  388.  
  389. this.setState({
  390. newTask: {
  391. name: {
  392. value: '',
  393. error: null
  394. }
  395. }
  396. })
  397. }).catch((error) => {
  398. this.setState({
  399. newTask: {
  400. ...this.state.newTask,
  401. name: {
  402. ...this.state.newTask.name,
  403. error: error.response.data.name
  404. }
  405. }
  406. })
  407.  
  408. })
  409. }
  410.  
  411. refreshTasks() {
  412. return api.get(config.urls.tasks, { params: { project: this.state.project.id }}).then((tasks) => {
  413. this.setState({ tasks: tasks.data })
  414. })
  415. }
  416.  
  417. removeTask(task) {
  418. return api.delete(`${config.urls.tasks}${task.id}`).then(response => {
  419. const tasks = this.state.tasks.filter((item) => item.id !== task.id)
  420. this.setState({ tasks })
  421. })
  422. }
  423.  
  424. editTask(task) {
  425. const t = this.state.tasks.find((item) => item.id === task.id)
  426.  
  427. t.edit = !t.edit
  428.  
  429. if (t.edit === false) {
  430. return api.put(`${config.urls.tasks}${task.id}/`, task).then((resp) => {
  431. this.refreshTasks()
  432. })
  433. }
  434.  
  435. this.setState({ tasks: this.state.tasks })
  436. }
  437.  
  438. updateTaskName(task, newName) {
  439. task.name = newName
  440. this.setState({ tasks: this.state.tasks })
  441. }
  442.  
  443. onSubmit(event) {
  444. event.preventDefault();
  445. this.addTask();
  446. }
  447.  
  448. renderList() {
  449. const { newTask: { name } } = this.state
  450. return (<List component="nav" aria-label="main mailbox folders">
  451. {this.state.tasks.map((task) => (
  452. <ListItem button key={task.id}>
  453. { task.edit && <TextField label="Name" size="small" value={task.name} onChange={(event) => this.updateTaskName(task, event.target.value)} />}
  454. { !task.edit && <ListItemText primary={task.name} />}
  455. <ListItemSecondaryAction>
  456. <IconButton edge="end" aria-label="delete" color="primary" onClick={() => this.editTask(task)}>
  457. <EditIcon />
  458. </IconButton>
  459. <IconButton edge="end" aria-label="delete" color="secondary" onClick={() => this.removeTask(task)}>
  460. <DeleteIcon />
  461. </IconButton>
  462. </ListItemSecondaryAction>
  463. </ListItem>
  464. ))}
  465. <ListItem button>
  466. <form onSubmit={this.onSubmit}>
  467. <TextField
  468. label="Name"
  469. size="small"
  470. value={name.value}
  471. error={!!name.error}
  472. helperText={name.error}
  473. onChange={this.updateNewTaskName}
  474. />
  475.  
  476. <ListItemSecondaryAction>
  477. <IconButton type="submit" edge="end" aria-label="delete" color="primary">
  478. <AddIcon />
  479. </IconButton>
  480. </ListItemSecondaryAction>
  481. </form>
  482.  
  483.  
  484. </ListItem>
  485. </List>)
  486. }
  487.  
  488. updateNewTaskName(event) {
  489. const newName = event.target.value;
  490. return this.setState({
  491. newTask: {
  492. ...this.state.newTask,
  493. name: {
  494. value: newName,
  495. error: null
  496. }
  497. }
  498. })
  499. }
  500.  
  501. render() {
  502.  
  503. return (
  504. <div>
  505. {this.renderList()}
  506. </div>
  507. )
  508. }
  509. }
  510.  
  511. const styles = {
  512. root: {
  513. marginTop: 20,
  514. },
  515. };
  516.  
  517.  
  518. export default withStyles(styles)(Tasks);
  519.  
  520.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement