Skip to content

Commit

Permalink
Merge pull request #73 from UnbFeelings/support
Browse files Browse the repository at this point in the history
Feature/Support
  • Loading branch information
Rdlenke authored Jul 5, 2018
2 parents 2568f69 + 3dc3705 commit 87e2264
Show file tree
Hide file tree
Showing 12 changed files with 531 additions and 96 deletions.
8 changes: 5 additions & 3 deletions src/__tests__/src/components/structural/Routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ describe('<Routes />', () => {
expect(routes.get(7).props.path).toBe('/feelings-timeline');
expect(routes.get(8).props.path).toBe('/subject-timeline');
expect(routes.get(9).props.path).toBe('/charts');
expect(routes.get(10).props.path).toBe('/my-blocks');
expect(routes.get(10).props.path).toBe('/supports-sent');
expect(routes.get(11).props.path).toBe('/supports-received');
expect(routes.get(12).props.path).toBe('/my-blocks');
});

it('has 11 routes', () => {
it('has 13 routes', () => {
const wrapper = shallow(<Routes
user={initialState.user}
/>);

expect(wrapper.find('Route')).toHaveLength(11);
expect(wrapper.find('Route')).toHaveLength(13);
});
});
6 changes: 3 additions & 3 deletions src/components/pages/feelings-timeline/SubjectTimeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ class SubjectTimeline extends React.Component {
try {
const response = await axios.get('/subjects/');
const subjectList = response.data;
this.setState({
subjectList,
});
// Sort subjects in ascending order by name
subjectList.results.sort((a, b) => (a.name > b.name ? 1 : -1));
this.setState({ subjectList });
// console.log(this.state.subjectList)
} catch (e) {
// console.log(e);
Expand Down
126 changes: 126 additions & 0 deletions src/components/pages/support/SupportTimeline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import React from 'react';
import Snackbar from '@material-ui/core/Snackbar';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';

import axios from '../../../configs/axios';
import Endpoints from '../../../configs/endpoints';
import SupportItem from '../../shared/SupportItem';
import SimpleModalWrapped from '../../shared/ConfirmDeletionModal';

class SupportTimeline extends React.Component {
state = {
supports: { results: [] },
// gettingData: false,
showModal: false,
snackbar: {
display: false,
message: '',
},
};

async componentDidMount() {
this.fetchSupports();
}

fetchSupports = async () => {
let endpoint;
if (this.props.match.url === '/supports-sent') {
endpoint = Endpoints.SUPPORT_FROM_STUDENT;
} else {
endpoint = Endpoints.SUPPORT_TO_STUDENT;
}

// this.setState({ gettingData: true });

try {
const response = await axios.get(`${endpoint}/`);
this.setState({ supports: response.data });
} catch (err) {
// console.log('fetchReceivedSupports - err', err);
this.setState({ snackbar: { display: true, message: 'Ocorreu um erro, tente novamente.' } });
} finally {
// this.setState({ gettingData: false });
}
};

removeSupport = async id => {
this.setState({ showModal: true, supportToRemove: id });
};

confirmRemoval = async id => {
try {
await axios.delete(`${Endpoints.SUPPORT}/${id}/`);
this.setState({ snackbar: { display: true, message: 'Apoio removido com sucesso' } });
this.fetchSupports();
} catch (err) {
// console.log('removeSupport - err', err);
this.setState({ snackbar: { display: true, message: 'Ocorreu um erro, tente novamente.' } });
} finally {
this.setState({ showModal: false, supportToRemove: '' });
}
}

renderSupport = (item) => (
<SupportItem
item={item}
removeItem={id => this.removeSupport(id)}
/>
);

handleCloseSnackbar = () => {
// Hide the successful post creation message
this.setState({ snackbar: { display: false, message: '' } });
};

createSupportList = () => {
if (this.state.supports.results.length === 0) {
return null;
}

return this.state.supports.results.map(item => this.renderSupport(item));
};

render() {
return (
<React.Fragment>
{this.createSupportList()}

<SimpleModalWrapped
visible={this.state.showModal}
title="Deseja excluir este apoio?"
description="Tem certeza que deseja excluir este apoio? Essa ação não poderá ser desfeita"
action="Excluir"
onConfirm={() => this.confirmRemoval(this.state.supportToRemove)}
onCancel={() => this.setState({ showModal: !this.state.showModal })}
/>

<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={this.state.snackbar.display}
autoHideDuration={6000}
onClose={this.handleCloseSnackbar}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">{this.state.snackbar.message}</span>}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
onClick={this.handleCloseSnackbar}
>
<CloseIcon />
</IconButton>,
]}
/>
</React.Fragment>
);
}
}

export default SupportTimeline;
67 changes: 42 additions & 25 deletions src/components/pages/university-posts/UniversityPosts.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import axios from '../../../configs/axios';
import PostListItem from '../../shared/PostListItem';
import SupportForm from '../../shared/SupportForm';

class UniversityPosts extends React.Component {
state = {
posts: [],
}
postsFromUser: false,
};

componentDidMount() {
const { userId } = this.props.match.params;
Expand All @@ -16,36 +18,51 @@ class UniversityPosts extends React.Component {
}
}

fetchUserData(userId) {
axios.get(`/posts/user/${userId}/`).then(resp => {
this.setState({ posts: resp.data.results });
});
}
fetchUserData = async (userId) => {
try {
const response = await axios.get(`/posts/user/${userId}/`);
this.setState({ posts: response.data.results, postsFromUser: true });
} catch (err) {
alert(err);
}
};

fetchUniversityData() {
axios.get('/posts/').then(resp => {
this.setState({ posts: resp.data.results });
});
}
fetchUniversityData = async () => {
try {
const response = await axios.get('/posts/');
this.setState({ posts: response.data.results });
} catch (err) {
alert(err);
}
};

postTimeLine(post) {
return (
<PostListItem
subject={post.subject.name}
emotion={post.emotion}
tags={post.tag}
key={post.id}
author={post.author}
/>
);
}
postTimeLine = (post) => (
<PostListItem
subject={post.subject.name}
emotion={post.emotion}
tags={post.tag}
key={post.id}
author={post.author}
/>
);

render() {
const timeLine = this.state.posts.map(post => this.postTimeLine(post));
supportForm = () => {
if (!this.state.postsFromUser) {
return null;
}

const { userId } = this.props.match.params;

return <SupportForm studentTo={userId} />;
};

createTimeLine = () => this.state.posts.map(post => this.postTimeLine(post));

render() {
return (
<div className="UniversityPosts">
{timeLine}
{this.supportForm()}
{this.createTimeLine()}
</div>
);
}
Expand Down
70 changes: 70 additions & 0 deletions src/components/shared/ConfirmDeletionModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import PropTypes from 'prop-types';

import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import Modal from '@material-ui/core/Modal';
import Button from '@material-ui/core/Button';

function getModalStyle() {
const top = 50;
const left = 50;

return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}

const styles = theme => ({
paper: {
position: 'absolute',
width: theme.spacing.unit * 50,
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[5],
padding: theme.spacing.unit * 4,
},
});

class SimpleModal extends React.Component {
render() {
const { classes } = this.props;

return (
<div>
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={this.props.visible}
onClose={this.onCancel}
>
<div style={getModalStyle()} className={classes.paper}>
<Typography variant="title" id="modal-title">
{this.props.title}
</Typography>
<Typography variant="subheading" id="simple-modal-description">
{this.props.description}
</Typography>
<Button color="secondary" onClick={this.props.onConfirm}>{this.props.action}</Button>
<Button onClick={this.props.onCancel}>Cancelar</Button>
</div>
</Modal>
</div>
);
}
}

SimpleModal.propTypes = {
visible: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
action: PropTypes.string.isRequired,
onConfirm: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
};

// We need an intermediary variable for handling the recursive nesting.
const SimpleModalWrapped = withStyles(styles)(SimpleModal);

export default SimpleModalWrapped;
Loading

0 comments on commit 87e2264

Please sign in to comment.