Skip to content
Snippets Groups Projects
Unverified Commit 5e7cd2f8 authored by Awais Jibran's avatar Awais Jibran Committed by GitHub
Browse files

Merge pull request #23898 from edx/aj/msingh/details

Course Content boilerplate blurb (and link to discussions)
parents 87a1c06d ae2c2c47
No related branches found
No related tags found
No related merge requests found
......@@ -14,8 +14,8 @@ class ShowErrors extends React.Component {
<div className="alert alert-danger" role="alert">
<strong>{gettext('Please fix the following errors:')}</strong>
<ul>
{this.props.errorList.map(error =>
<li>{error}</li>,
{this.props.errorList.map((error, i) =>
<li key={i}>{error}</li>,
)}
</ul>
</div>
......
......@@ -2,29 +2,34 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, StatusAlert } from '@edx/paragon';
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
import FileUpload from './file_upload';
function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitForm }) {
function LoggedInUser({ userInformation, onChangeCallback, submitForm, showWarning, showDiscussionButton, reDirectUser }) {
let courseElement;
let detailElement;
let discussionElement = '';
if (userInformation.enrollments) {
courseElement = (<div>
<label className="label-course" htmlFor="course">{gettext('Course Name')}</label>
<p className="message-desc"><i>
{gettext('For inquiries regarding assignments, grades, or structure of a specific course, please post in the discussion forums for that course directly.')}
{gettext('For inquiries regarding assignments, grades, or structure of a specific course, please post in the discussion forums for that course directly.')}
</i></p>
<select className="form-control select-course" id="course" defaultValue={userInformation.course_id}>
<select
className="form-control select-course"
id="course"
defaultValue={userInformation.course_id}
>
<option key="select-course" value="">--------</option>
<option key="not-course-specific" value="Not specific to a course">
{gettext('Not specific to a course')}
</option>
{userInformation.enrollments.map(enrollment =>
(<option key={enrollment.course_id} value={enrollment.course_id}>
{enrollment.course_name}
</option>),
)}
(<option key={enrollment.course_id} value={enrollment.course_id}>
{enrollment.course_name}
</option>),
)}
</select>
</div>);
} else {
......@@ -33,11 +38,9 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
<input type="text" className="form-control" id="course" />
</div>);
}
let topicElement;
topicElement = (<div>
<label htmlFor="topic">{gettext('Topic')}</label>
<select className="form-control select-subject" id="topic">
const subjectElement = (<div>
<label htmlFor="subject">{gettext('Subject')}</label>
<select className="form-control select-subject" id="subject">
<option value="">--------</option>
<option value="Account Settings">{gettext('Account Settings')}</option>
<option value="Billing/Payment Options">{gettext('Billing/Payment Options')}</option>
......@@ -55,10 +58,68 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
<option value="Other">{gettext('Other')}</option>
</select>
</div>);
if (showDiscussionButton) {
discussionElement = (
<div className="row">
<div className="col-sm-12">
<Button
className={['btn', 'btn-primary', 'btn-submit']}
onClick={reDirectUser}
label={gettext('Course Discussion Forum')}
/>
</div>
</div>
);
}
if (showWarning) {
detailElement = (
<div id="warning-msg">
<div className="row">
<div className="col-sm-12">
<div className="form-group">
<StatusAlert
alertType="info"
className={['in', 'pattern-library-shim']}
dismissible={false}
dialog={
gettext('While our support team is happy to assist with the edX platform, the course staff has the expertise for specific assignment questions, grading or the proper procedures in each course. Please post all course related questions within the Discussion Forum where the Course Staff can directly respond.')
}
open
/>
</div>
</div>
</div>
{ discussionElement }
</div>
);
} else {
detailElement = (
<div>
<div className="row">
<div className="col-sm-12">
<div className="form-group">
<label htmlFor="message">{gettext('Details')}</label>
<p className="message-desc">{gettext('the more quickly and helpfully we can respond!')}</p>
<textarea aria-describedby="message" className="form-control" rows="7" id="message" />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<Button
className={['btn', 'btn-primary', 'btn-submit']}
type="submit"
label={gettext('Create Support Ticket')}
/>
</div>
</div>
</div>
);
}
return (<div>
return (<form id="contact-us-form" onSubmit={submitForm} onChange={onChangeCallback}>
<div className="row">
<hr className="col-sm-12"></hr>
<hr className="col-sm-12" />
</div>
<div className="row">
<div
......@@ -78,15 +139,7 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
<div className="row">
<div className="col-sm-12">
<div className="form-group">
{courseElement}
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="form-group">
{topicElement}
{subjectElement}
</div>
</div>
</div>
......@@ -94,43 +147,33 @@ function LoggedInUser({ userInformation, setErrorState, zendeskApiHost, submitFo
<div className="row">
<div className="col-sm-12">
<div className="form-group">
<label htmlFor="message">{gettext('Details')}</label>
<p
className="message-desc"
>{gettext('The more you tell us, the more quickly and helpfully we can respond!')}</p>
<textarea
aria-describedby="message"
className="form-control"
rows="7"
id="message"
/>
{courseElement}
</div>
</div>
</div>
{/* TODO file uploading will be done after initial release */}
{/* <FileUpload */}
{/* setErrorState={setErrorState} */}
{/* zendeskApiHost={zendeskApiHost} */}
{/* accessToken={accessToken} */}
{/* /> */}
<div className="row">
<div className="col-sm-12">
<button
className="btn btn-primary btn-submit"
onClick={submitForm}
>{gettext('Create Support Ticket')}</button>
</div>
</div>
</div>);
{detailElement}
</form>);
}
/* TODO file uploading will be done after initial release */
/* <FileUpload */
/* setErrorState={setErrorState} */
/* zendeskApiHost={zendeskApiHost} */
/* accessToken={accessToken} */
/* /> */
LoggedInUser.propTypes = {
setErrorState: PropTypes.func.isRequired,
submitForm: PropTypes.func.isRequired,
userInformation: PropTypes.arrayOf(PropTypes.object).isRequired,
submitFormUrl: PropTypes.string.isRequired,
onChangeCallback: PropTypes.func.isRequired,
reDirectUser: PropTypes.func.isRequired,
userInformation: PropTypes.shape({
course_id: PropTypes.string,
username: PropTypes.string,
email: PropTypes.string,
enrollments: PropTypes.arrayOf(PropTypes.object),
}).isRequired,
showWarning: PropTypes.bool.isRequired,
showDiscussionButton: PropTypes.bool.isRequired,
};
export default LoggedInUser;
......@@ -5,6 +5,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import { StatusAlert } from '@edx/paragon';
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
......@@ -17,13 +18,24 @@ import Success from './success';
class RenderForm extends React.Component {
constructor(props) {
super(props);
this.userInformation = this.props.context.user;
const course = this.userInformation ? this.userInformation.course_id : '';
this.state = {
currentRequest: null,
errorList: [],
success: false,
formData: {
subject: '',
message: '',
course,
},
};
this.submitForm = this.submitForm.bind(this);
this.reDirectUser = this.reDirectUser.bind(this);
this.setErrorState = this.setErrorState.bind(this);
this.formOnChangeCallback = this.formOnChangeCallback.bind(this);
this.showWarningMessage = this.showWarningMessage.bind(this);
this.showDiscussionButton = this.showDiscussionButton.bind(this);
}
setErrorState(errors) {
......@@ -32,26 +44,48 @@ class RenderForm extends React.Component {
});
}
submitForm() {
formOnChangeCallback(event) {
const eventTarget = event.target;
let formData = this.state.formData;
formData[eventTarget.id] = eventTarget.value;
this.setState({ formData });
}
showWarningMessage() {
return this.state.formData && this.state.formData.subject === 'Course Content';
}
showDiscussionButton() {
const selectCourse = this.state.formData.course;
return this.state.formData && (selectCourse !== '' && selectCourse !== 'Not specific to a course');
}
reDirectUser(event) {
event.preventDefault();
window.location.href = `/courses/${this.state.formData.course}/discussion/forum`;
}
submitForm(event) {
event.preventDefault();
let subject,
course;
const url = this.props.context.submitFormUrl,
$userInfo = $('.user-info'),
request = new XMLHttpRequest(),
$course = $('#course'),
$topic = $('#topic'),
$subject = $('#subject'),
data = {
comment: {
body: $('#message').val(),
body: this.state.formData.message,
},
tags: this.props.context.tags,
},
errors = [];
let course;
this.clearErrors();
data.requester = {
email: $userInfo.data('email'),
name: $userInfo.data('username'),
email: this.userInformation.email,
name: this.userInformation.username,
};
course = $course.find(':selected').val();
......@@ -66,17 +100,15 @@ class RenderForm extends React.Component {
id: this.props.context.customFields.course_id,
value: course,
}];
let topic;
topic = $topic.find(':selected').val();
if (!topic) {
topic = $topic.val();
subject = $subject.find(':selected').val();
if (!subject) {
subject = $subject.val();
}
if (!topic) {
$('#topic').closest('.form-group').addClass('has-error');
errors.push(gettext('Select a topic for your support request.'));
if (!subject) {
$subject.closest('.form-group').addClass('has-error');
errors.push(gettext('Select a subject for your support request.'));
}
data.subject = topic; // Zendesk API requires 'subject'
data.subject = subject; // Zendesk API requires 'subject'
if (this.validateData(data, errors)) {
request.open('POST', url, true);
......@@ -124,19 +156,21 @@ class RenderForm extends React.Component {
platformName={this.props.context.platformName}
homepageUrl={this.props.context.homepageUrl}
dashboardUrl={this.props.context.dashboardUrl}
isLoggedIn={this.props.context.user !== undefined}
isLoggedIn={this.userInformation !== undefined}
/>
);
}
renderSupportForm() {
let userElement;
if (this.props.context.user) {
if (this.userInformation) {
userElement = (<LoggedInUser
userInformation={this.props.context.user}
submitFormUrl={this.props.context.submitFormUrl}
setErrorState={this.setErrorState}
userInformation={this.userInformation}
onChangeCallback={this.formOnChangeCallback}
submitForm={this.submitForm}
showWarning={this.showWarningMessage()}
showDiscussionButton={this.showDiscussionButton()}
reDirectUser={this.reDirectUser}
/>);
} else {
userElement = (<LoggedOutUser
......@@ -149,7 +183,8 @@ class RenderForm extends React.Component {
return (
<div className="contact-us-wrapper">
{/* Note: not using Paragon bc component shows in the DOM but not rendered, even when using version 2.6.4. */}
{/* Note: not using Paragon bc component shows in the DOM but not rendered, even when using
version 2.6.4. */}
<div className="alert alert-warning" role="alert" style={{ marginBottom: '1rem', padding: '1.5rem', left: '0px', fontSize: '16px', backgroundColor: '#fffaed', color: '#171C29', border: '1px solid #FFD875', borderRadius: '0.3rem' }}>
<div>{gettext('Due to the recent increase in interest in online education and edX, we are currently experiencing an unusually high volume of support requests. We appreciate your patience as we work to review each request. Please check the ')}<a href="https://support.edx.org/hc/en-us" className="alert-link">Help Center</a>{gettext(' as many questions may have already been answered.')}</div>
</div>
......@@ -199,7 +234,18 @@ class RenderForm extends React.Component {
}
RenderForm.propTypes = {
context: PropTypes.arrayOf(PropTypes.object).isRequired,
context: PropTypes.shape({
customFields: PropTypes.object,
dashboardUrl: PropTypes.string,
homepageUrl: PropTypes.string,
marketingUrl: PropTypes.string,
loginQuery: PropTypes.string,
platformName: PropTypes.string,
submitFormUrl: PropTypes.string,
supportEmail: PropTypes.string,
tags: PropTypes.arrayOf(PropTypes.string),
user: PropTypes.object,
}).isRequired,
};
export class SingleSupportForm {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment