-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(approveActivities): add approve activities page
- add ApproveActivitiesComponent - add ApproveActivitiesContainer - add activities sidebar item - add tests
- Loading branch information
Chris Maina
committed
Apr 16, 2019
1 parent
782f1bf
commit 79c0c64
Showing
11 changed files
with
293 additions
and
12 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
src/app/ApproveActivities/components/ApproveActivitiesComponent.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React from 'react'; | ||
import dateFns from 'date-fns'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import ActionsComponent from '../../VerifyActivities/components/ActionsComponent'; | ||
import { TableComponent, TruncateDescriptionContainer } from '../../common/components'; | ||
|
||
const ApproveActivitiesComponent = ({ activities }) => { | ||
let tableBodyHtml; | ||
const columnNames = ['Activity', 'Date', 'Points', 'Description', 'Actions']; | ||
if (!activities.length) { | ||
tableBodyHtml = ( | ||
<tr className='myactivities__table__row'> | ||
<td colSpan={6} className='myactivities__table__data'> | ||
There is no activities to approve | ||
</td> | ||
</tr> | ||
); | ||
} else { | ||
tableBodyHtml = activities.map((activity) => { | ||
const { | ||
id, activityDate, points, description, category, | ||
} = activity; | ||
return ( | ||
<tr key={id} className='myactivities__table__row'> | ||
<td>{category}</td> | ||
<td>{dateFns.format(new Date(activityDate), 'MMM DD YYYY')}</td> | ||
<td>{points}</td> | ||
<td> | ||
<TruncateDescriptionContainer description={description} wordCount={80} /> | ||
</td> | ||
<td> | ||
<ActionsComponent /> | ||
</td> | ||
</tr> | ||
); | ||
}); | ||
} | ||
return ( | ||
<TableComponent tableClassName='myactivities__table' tableHeadings={columnNames}> | ||
{tableBodyHtml} | ||
</TableComponent> | ||
); | ||
}; | ||
|
||
ApproveActivitiesComponent.defaultProps = { | ||
activities: [], | ||
}; | ||
|
||
ApproveActivitiesComponent.propTypes = { | ||
activities: PropTypes.arrayOf(PropTypes.shape({})), | ||
}; | ||
|
||
export default ApproveActivitiesComponent; |
105 changes: 105 additions & 0 deletions
105
src/app/ApproveActivities/components/ApproveActivitiesContainer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React, { Component } from 'react'; | ||
import { connect } from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import societyActions from '../../Societies/operations/actions'; | ||
|
||
import ApproveActivitiesComponent from './ApproveActivitiesComponent'; | ||
import { ButtonComponent, SocietyStatsComponent, TabsComponent } from '../../common/components'; | ||
|
||
import ACTIVITY_STATUS from '../../common/constants'; | ||
|
||
export class ApproveActivitiesContainer extends Component { | ||
static defaultProps = { | ||
society: {}, | ||
fetchSocietyInfoRequest: null, | ||
fetchSocietyRedemptionsRequest: null, | ||
}; | ||
|
||
static propTypes = { | ||
society: PropTypes.shape({}), | ||
fetchSocietyInfoRequest: PropTypes.func, | ||
fetchSocietyRedemptionsRequest: PropTypes.func, | ||
}; | ||
|
||
state = { | ||
selectedSociety: 'istelle', | ||
}; | ||
|
||
componentDidMount() { | ||
const { selectedSociety } = this.state; | ||
const { fetchSocietyRedemptionsRequest, fetchSocietyInfoRequest } = this.props; | ||
fetchSocietyInfoRequest(selectedSociety.toLowerCase()); | ||
fetchSocietyRedemptionsRequest(selectedSociety.toLowerCase()); | ||
} | ||
|
||
componentDidUpdate(prevProps, prevState) { | ||
const { selectedSociety } = this.state; | ||
const { fetchSocietyRedemptionsRequest, fetchSocietyInfoRequest } = this.props; | ||
|
||
if (prevState.selectedSociety !== selectedSociety && !prevProps.society[selectedSociety].redemptions.length) { | ||
fetchSocietyInfoRequest(selectedSociety.toLowerCase()); | ||
fetchSocietyRedemptionsRequest(selectedSociety.toLowerCase()); | ||
} | ||
} | ||
|
||
changeSelectedSociety = (societyName) => { | ||
this.setState({ selectedSociety: societyName }); | ||
}; | ||
|
||
filterActivitiesByPendingStatus = activities => ( | ||
activities.filter(item => item.status === ACTIVITY_STATUS.PENDING)) | ||
|
||
render() { | ||
const { society } = this.props; | ||
const { selectedSociety } = this.state; | ||
const { | ||
usedPoints, pointsEarned, remainingPoints, activitiesLogged, loggedActivities, | ||
} = society[selectedSociety]; | ||
const tabNames = ['istelle', 'invictus', 'phoenix', 'sparks']; | ||
const pendingActivities = this.filterActivitiesByPendingStatus(loggedActivities); | ||
|
||
return ( | ||
<div> | ||
<div className='profile-overview profile-overview--society'> | ||
<div className={`profile-overview__image--society ${selectedSociety.toLowerCase()}`} /> | ||
<SocietyStatsComponent | ||
usedPoints={usedPoints} | ||
totalPoints={pointsEarned} | ||
remainingPoints={remainingPoints} | ||
activitiesLogged={activitiesLogged} | ||
className='society-page__stats' | ||
/> | ||
</div> | ||
<div className='user-dashboard__actions user-dashboard__actions--society col-sm-12'> | ||
<TabsComponent | ||
tabNames={tabNames} | ||
selectedTab={selectedSociety} | ||
changeSelectedTab={this.changeSelectedSociety} | ||
/> | ||
<div> | ||
<ButtonComponent className='button__filter'> | ||
<span>Filter</span> | ||
<span className='fa fa-filter' /> | ||
</ButtonComponent> | ||
</div> | ||
</div> | ||
<ApproveActivitiesComponent activities={pendingActivities} /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
const mapStateToProps = ({ society }) => ({ | ||
society, | ||
}); | ||
|
||
const mapDispatchToProps = { | ||
fetchSocietyInfoRequest: societyActions.fetchSocietyInfoRequest, | ||
fetchSocietyRedemptionsRequest: societyActions.fetchSocietyRedemptionsRequest, | ||
}; | ||
|
||
export default connect( | ||
mapStateToProps, | ||
mapDispatchToProps, | ||
)(ApproveActivitiesContainer); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './ApproveActivitiesContainer'; |
36 changes: 36 additions & 0 deletions
36
src/app/ApproveActivities/components/tests/ApproveActivitiesComponent.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
|
||
import ApproveActivitiesComponent from '../ApproveActivitiesComponent'; | ||
|
||
import activities from '../../../Dashboard/operations/tests/fixtures'; | ||
|
||
describe('<ApproveActivitiesComponent />', () => { | ||
const setUpWrapper = ({ activities = [] } = {}) => { | ||
const props = { | ||
activities, | ||
}; | ||
return shallow(<ApproveActivitiesComponent {...props} />); | ||
}; | ||
|
||
it('should have a TableComponent', () => { | ||
const shallowWrapper = setUpWrapper(); | ||
expect(shallowWrapper.find('TableComponent')).toHaveLength(1); | ||
}); | ||
|
||
it('should have a description of no activities when activities prop is empty', () => { | ||
const shallowWrapper = setUpWrapper(); | ||
expect(shallowWrapper.find('TableComponent').html()).toContain('There is no activities to approve'); | ||
}); | ||
|
||
it('should have activity table column names', () => { | ||
const shallowWrapper = setUpWrapper({ activities }); | ||
expect(shallowWrapper.find('TableComponent').props().tableHeadings).toEqual([ | ||
'Activity', | ||
'Date', | ||
'Points', | ||
'Description', | ||
'Actions', | ||
]); | ||
}); | ||
}); |
62 changes: 62 additions & 0 deletions
62
src/app/ApproveActivities/components/tests/ApproveActivitiesContainer.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
|
||
import { ApproveActivitiesContainer } from '../ApproveActivitiesContainer'; | ||
|
||
import ACTIVITY_STATUS from '../../../common/constants'; | ||
import activities from '../../../Dashboard/operations/tests/fixtures'; | ||
import { redemptions } from '../../../Redemptions/components/tests/fixtures'; | ||
|
||
describe('<ApproveActivitiesContainer />', () => { | ||
const props = { | ||
society: { | ||
phoenix: { | ||
usedPoints: 100, | ||
remainingPoints: 100, | ||
totalPoints: 200, | ||
activitiesLogged: activities.length, | ||
loggedActivities: activities, | ||
redemptions, | ||
}, | ||
istelle: { | ||
usedPoints: 100, | ||
remainingPoints: 100, | ||
totalPoints: 200, | ||
activitiesLogged: activities.length, | ||
loggedActivities: activities, | ||
redemptions, | ||
} | ||
}, | ||
fetchSocietyInfoRequest: jest.fn(), | ||
fetchSocietyRedemptionsRequest: jest.fn() | ||
}; | ||
const shallowWrapper = shallow(<ApproveActivitiesContainer {...props} />); | ||
|
||
it('has a 1 ButtonComponent', () => { | ||
expect(shallowWrapper.find('ButtonComponent')).toHaveLength(1); | ||
}); | ||
|
||
it('has TabsComponent', () => { | ||
expect(shallowWrapper.find('TabsComponent')).toHaveLength(1); | ||
}); | ||
|
||
it('changes selectedSociety state when changeSelectedSociety is called with a society name', () => { | ||
const instance = shallowWrapper.instance(); | ||
instance.setState({ selectedSociety: 'istelle' }); | ||
instance.changeSelectedSociety('phoenix'); | ||
expect(instance.state.selectedSociety).toEqual('phoenix'); | ||
}); | ||
|
||
it('returns activities with pending status', () => { | ||
const instance = shallowWrapper.instance(); | ||
const pendingActivities = activities.filter(item => item.status === ACTIVITY_STATUS.PENDING); | ||
expect(instance.filterActivitiesByPendingStatus(activities)).toEqual(pendingActivities); | ||
}); | ||
|
||
it('invokes fetchSocietyInfoRequest when selectedSociety state change', () => { | ||
const instance = shallowWrapper.instance(); | ||
const spy = jest.spyOn(instance.props, 'fetchSocietyInfoRequest'); | ||
instance.setState({ selectedSociety: 'phoenix' }); | ||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters