Skip to content

Commit

Permalink
add entitlement support creation and reissue
Browse files Browse the repository at this point in the history
Learner-3925
  • Loading branch information
iloveagent57 authored and Mjloturco committed Mar 23, 2018
1 parent 187e39f commit 10be8bc
Show file tree
Hide file tree
Showing 21 changed files with 419 additions and 66 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"plugins": [
"transform-object-assign"
"transform-object-assign",
"transform-object-rest-spread"
],
"presets": [
[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { connect } from 'react-redux';

import { createEntitlement, reissueEntitlement } from '../../data/actions/entitlement';
import { closeForm } from '../../data/actions/form';

import EntitlementForm from './index.jsx';

const mapStateToProps = state => ({
formType: state.form.formType,
isOpen: state.form.isOpen,
entitlement: state.form.activeEntitlement,
});

const mapDispatchToProps = dispatch => ({
createEntitlement: ({ username, courseUuid, mode, comments }) =>
dispatch(createEntitlement({ username, courseUuid, mode, comments })),
reissueEntitlement: ({ entitlement, comments }) =>
dispatch(reissueEntitlement({ entitlement, comments })),
closeForm: () => dispatch(closeForm()),
});

const EntitlementFormContainer = connect(
mapStateToProps,
mapDispatchToProps,
)(EntitlementForm);

export default EntitlementFormContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React from 'react';
import PropTypes from 'prop-types';

import { Button, InputSelect, InputText, TextArea } from '@edx/paragon';
import { formTypes } from '../../data/constants/formTypes';

class EntitlementForm extends React.Component {
constructor(props) {
super(props);

if (props.formType === formTypes.REISSUE) {
const { courseUuid, mode, user } = props.entitlement;
this.state = {
courseUuid,
mode,
username: user,
comments: '',
};
} else {
this.state = {
courseUuid: '',
mode: '',
username: '',
comments: '',
};
}

this.onClose = this.onClose.bind(this);
this.handleCourseUUIDChange = this.handleCourseUUIDChange.bind(this);
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handleModeChange = this.handleModeChange.bind(this);
this.handleCommentsChange = this.handleCommentsChange.bind(this);
this.submitForm = this.submitForm.bind(this);
}

onClose() {
this.props.closeForm();
}

handleCourseUUIDChange(courseUuid) {
this.setState({ courseUuid });
}

handleUsernameChange(username) {
this.setState({ username });
}

handleModeChange(mode) {
this.setState({ mode });
}

handleCommentsChange(comments) {
this.setState({ comments });
}

submitForm() {
const { courseUuid, username, mode, comments } = this.state;
const { formType, entitlement } = this.props;
if (formType === formTypes.REISSUE) { // if there is an active entitlement we are updating an entitlement
this.props.reissueEntitlement({ entitlement, comments });
} else { // if there is no active entitlement we are creating a new entitlement
this.props.createEntitlement({ courseUuid, username, mode, comments });
}
}

render() {
const { courseUuid, username, mode, comments } = this.state;
const isReissue = this.props.formType === formTypes.REISSUE;
const title = isReissue ? 'Re-issue Entitlement' : 'Create Entitlement';

const body = (
<div>
<h3> {title} </h3>
<InputText
disabled={isReissue}
name="courseUuid"
label="Course UUID"
value={courseUuid}
onChange={this.handleCourseUUIDChange}
/>
<InputText
disabled={isReissue}
name="username"
label="Username"
value={username}
onChange={this.handleUsernameChange}
/>
<InputSelect
disabled={isReissue}
name="mode"
label="Mode"
value={mode}
options={[
{ label: '--', value: '' },
{ label: 'Verified', value: 'verified' },
{ label: 'Professional', value: 'professional' },
]}
onChange={this.handleModeChange}
/>
<TextArea
name="comments"
label="Comments"
value={comments}
onChange={this.handleCommentsChange}
/>
<div>
<Button
className={['btn', 'btn-secondary']}
label="Close"
onClick={this.onClose}
/>
<Button
className={['btn', 'btn-primary']}
label="Submit"
onClick={this.submitForm}
/>
</div>
</div>
);

return this.props.isOpen && body;
}
}

EntitlementForm.propTypes = {
formType: PropTypes.string.isRequired,
isOpen: PropTypes.bool.isRequired,
entitlement: PropTypes.shape({
uuid: PropTypes.string.isRequired,
courseUuid: PropTypes.string.isRequired,
created: PropTypes.string.isRequired,
modified: PropTypes.string.isRequired,
expiredAt: PropTypes.string,
mode: PropTypes.string.isRequired,
orderNumber: PropTypes.string,
supportDetails: PropTypes.arrayOf(PropTypes.shape({
supportUser: PropTypes.string,
action: PropTypes.string,
comments: PropTypes.string,
unenrolledRun: PropTypes.string,
})),
user: PropTypes.string.isRequired,
}),
createEntitlement: PropTypes.func.isRequired,
reissueEntitlement: PropTypes.func.isRequired,
closeForm: PropTypes.func.isRequired,
};

EntitlementForm.defaultProps = {
entitlement: {
uuid:'',
courseUuid: '',
created: '',
modified: '',
expiredAt: '',
mode: 'verified',
orderNumber: '',
supportDetails: [],
user: '',
}
};

export default EntitlementForm;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';

import { StatusAlert } from '@edx/paragon';
import { Button, StatusAlert } from '@edx/paragon';
import SearchContainer from '../Search/SearchContainer.jsx';
import EntitlementSupportTableContainer from '../Table/EntitlementSupportTableContainer.jsx';
import EntitlementFormContainer from '../EntitlementForm/container.jsx';

const Main = props => (
<div>
Expand All @@ -14,17 +15,45 @@ const Main = props => (
open={!!props.errorMessage}
/>
<h2>
Entitlement Support Page
Student Support: Entitlement
</h2>
<SearchContainer />
<EntitlementSupportTableContainer ecommerceUrl={props.ecommerceUrl} />
<MainContent
isFormOpen={props.isFormOpen}
ecommerceUrl={props.ecommerceUrl}
openCreationForm={props.openCreationForm}
/>
</div>
);

const MainContent = (props) => {
if (props.isFormOpen) {
return <EntitlementFormContainer />;
}
return (
<div>
<SearchContainer />
<Button
className={['btn', 'btn-primary']}
label="Create New Entitlement"
onClick={props.openCreationForm}
/>
<EntitlementSupportTableContainer ecommerceUrl={props.ecommerceUrl} />
</div>
);
};

Main.propTypes = {
errorMessage: PropTypes.string.isRequired,
dismissErrorMessage: PropTypes.func.isRequired,
openCreationForm: PropTypes.func.isRequired,
ecommerceUrl: PropTypes.string.isRequired,
isFormOpen: PropTypes.bool.isRequired,
};

MainContent.propTypes = {
openCreationForm: PropTypes.func.isRequired,
ecommerceUrl: PropTypes.string.isRequired,
isFormOpen: PropTypes.bool.isRequired,
};

export default Main;
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { connect } from 'react-redux';

import { dismissError } from '../../data/actions/error';
import { openCreationForm } from '../../data/actions/form';

import Main from './Main.jsx';


const mapStateToProps = state => ({
errorMessage: state.error,
isFormOpen: state.form.isOpen,
});

const mapDispatchToProps = dispatch => ({
dismissErrorMessage: () => dispatch(dismissError()),
openCreationForm: () => dispatch(openCreationForm()),
});

const MainContainer = connect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';

import { Hyperlink, Table } from '@edx/paragon';
import { Button, Hyperlink, Table } from '@edx/paragon';

const entitlementColumns = [
{
Expand All @@ -13,14 +13,14 @@ const entitlementColumns = [
label: 'Course UUID',
key: 'courseUuid',
},
{
label: 'Enrollment',
key: 'enrollmentCourseRun',
},
{
label: 'Mode',
key: 'mode',
},
{
label: 'Enrollment',
key: 'enrollmentCourseRun',
},
{
label: 'Expired At',
key: 'expiredAt',
Expand All @@ -45,9 +45,9 @@ const entitlementColumns = [
},
];

const parseEntitlementData = (entitlements, ecommerceUrl) =>
const parseEntitlementData = (entitlements, ecommerceUrl, openReissueForm) =>
entitlements.map((entitlement) => {
const { expiredAt, created, modified, orderNumber } = entitlement;
const { expiredAt, created, modified, orderNumber, enrollmentCourseRun } = entitlement;
return Object.assign({}, entitlement, {
expiredAt: expiredAt ? moment(expiredAt).format('lll') : '',
createdAt: moment(created).format('lll'),
Expand All @@ -56,13 +56,18 @@ const parseEntitlementData = (entitlements, ecommerceUrl) =>
destination={`${ecommerceUrl}${orderNumber}/`}
content={orderNumber || ''}
/>,
button: <div> No Actions Currently Available </div>,
button: <Button
disabled={!enrollmentCourseRun}
className={['btn', 'btn-primary']}
label="Reissue"
onClick={() => openReissueForm(entitlement)}
/>,
});
});

const EntitlementSupportTable = props => (
<Table
data={parseEntitlementData(props.entitlements, props.ecommerceUrl)}
data={parseEntitlementData(props.entitlements, props.ecommerceUrl, props.openReissueForm)}
columns={entitlementColumns}
/>
);
Expand All @@ -86,6 +91,7 @@ EntitlementSupportTable.propTypes = {
user: PropTypes.string.isRequired,
})).isRequired,
ecommerceUrl: PropTypes.string.isRequired,
openReissueForm: PropTypes.func.isRequired,
};

export default EntitlementSupportTable;
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { connect } from 'react-redux';

import { openReissueForm } from '../../data/actions/form';
import EntitlementSupportTable from './EntitlementSupportTable.jsx';

const mapStateToProps = state => ({
entitlements: state.entitlements,
});

const mapDispatchToProps = dispatch => ({
openReissueForm: entitlement => dispatch(openReissueForm(entitlement)),
});

const EntitlementSupportTableContainer = connect(
mapStateToProps,
mapDispatchToProps,
)(EntitlementSupportTable);

export default EntitlementSupportTableContainer;

This file was deleted.

Loading

0 comments on commit 10be8bc

Please sign in to comment.