Skip to content

Commit

Permalink
* profile page sans calculator *
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-USDS-damman committed Feb 27, 2017
1 parent 9b28973 commit 63cdef3
Show file tree
Hide file tree
Showing 17 changed files with 1,016 additions and 30 deletions.
42 changes: 42 additions & 0 deletions src/js/gi/components/AccordionItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';

class AccordionItem extends React.Component {

constructor(props) {
super(props);
this.state = {
expanded: props.expanded,
}
}

toggle() {
this.setState({expanded: !this.state.expanded});
}

render() {
const expanded = this.state.expanded;
return (
<li>
<button onClick={this.toggle.bind(this)} className="usa-accordion-button" aria-expanded={expanded} aria-controls="amendment-1">
<h2>{this.props.button}</h2>
</button>
<div id="amendment-1" className="usa-accordion-content" aria-hidden={!expanded}>
{this.props.children}
</div>
</li>
);
}

}

AccordionItem.propTypes = {
expanded: React.PropTypes.bool.isRequired,
children: React.PropTypes.node.isRequired,
button: React.PropTypes.string.isRequired,
};

AccordionItem.defaultProps = {
expanded: true
};

export default AccordionItem;
166 changes: 166 additions & 0 deletions src/js/gi/components/profile/AdditionalInformation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import React from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';

export class AdditionalInformation extends React.Component {

render() {
const it = this.props.profile.attributes;
const accredited = !!it.cross;
const TypeOfAccreditation = () => {
if (!accredited) return null;
return (
<p>
<strong>Type of accreditation:&nbsp;</strong>
{it.accreditation_type.toUpperCase()}
</p>
);
};
const VetTuitionPolicy = () => {
if (!it.vet_tuition_policy_url) return null;
return (
<p>
<strong>Veterans tuition policy:&nbsp;</strong>
<a href={`http://${it.vet_tuition_policy_url}`} target="_blank">View policy</a>
</p>
);
};

// Formats positive and negative currency values in USD
const formatCurrency = (num) => {
const str = Number(num).toFixed(2).toString().split('.');
// Match a digit if it's followed by 3 other digits,
// appending a comma to each match.
const regex = /\d(?=(\d{3})+$)/g;
return [
'$',
[str[0].replace(regex, '$&,'), str[1]].join('.')
].join('').replace('$-', '-$');
};

const formatNumber = (num) => {
const str = Math.round(Number(num)).toString();
// Match a digit if it's followed by 3 other digits,
// appending a comma to each match.
const regex = /\d(?=(\d{3})+$)/g;
return str.replace(regex, '$&,');
};

return (
<div className="additional-information row">
<div className="medium-6 columns">
<div>
<h3>Institution summary</h3>
<p>
<strong>Accredited:&nbsp;</strong>
{accredited ? 'Yes' : 'No'}
</p>
<TypeOfAccreditation/>
<VetTuitionPolicy/>
<p>
<strong>Single point of contact for veterans:&nbsp;</strong>
{!!it.vet_poc ? 'Yes' : 'No'}
</p>
<p>
<strong>Credit for military training:&nbsp;</strong>
{!!it.credit_for_mil_training ? 'Yes' : 'No'}
</p>
</div>
<div className="historical-information list">
<h3>Historical Information</h3>
<div>
<p>
<strong>Benefit:&nbsp;</strong>
Post-9/11 GI Bill
</p>
<p>
<strong>Recipients:&nbsp;</strong>
{formatNumber(it.p911_recipients)}
</p>
<p>
<strong>Total paid (2014):&nbsp;</strong>
{formatCurrency(it.p911_tuition_fees)}
</p>
</div>
<div>
<p>
<strong>Benefit:&nbsp;</strong>
Yellow Ribbon
</p>
<p>
<strong>Recipients:&nbsp;</strong>
{formatNumber(it.p911_yr_recipients)}
</p>
<p>
<strong>Total paid (2014):&nbsp;</strong>
{formatCurrency(it.p911_yellow_ribbon)}
</p>
</div>
</div>
<div>
<h3>Institution codes</h3>
<p>
<strong>
<a onClick={this.props.showModal.bind(this, 'facilityCode')}>VA facility code:</a>
&nbsp;
</strong>
{+it.facility_code}
</p>
<p>
<strong>
<a onClick={this.props.showModal.bind(this, 'ipedsCode')}>ED IPEDS code:</a>
&nbsp;
</strong>
{+it.cross}
</p>
<p>
<strong>
<a onClick={this.props.showModal.bind(this, 'opeCode')}>ED OPE code:</a>
&nbsp;
</strong>
{+it.ope6}
</p>
</div>
</div>
<div className="medium-6 columns">
<div className="historical-information table">
<h3>Historical Information</h3>
<table className="usa-table-borderless">
<thead>
<tr>
<th>Benefit</th>
<th>Recipients</th>
<th>Total paid (2014)</th>
</tr>
</thead>
<tbody>
<tr>
<th>Post-9/11 GI Bill</th>
<td>{formatNumber(it.p911_recipients)}</td>
<td>{formatCurrency(it.p911_tuition_fees)}</td>
</tr>
<tr>
<th>Yellow Ribbon</th>
<td>{formatNumber(it.p911_yr_recipients)}</td>
<td>{formatCurrency(it.p911_yellow_ribbon)}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
);
}
}

const mapStateToProps = (state, props) => state;

const mapDispatchToProps = (dispatch) => {
return {
showModal: (name) => {
dispatch(actions.displayModal(name));
},
};
};

export default connect(mapStateToProps, mapDispatchToProps)(AdditionalInformation);
26 changes: 26 additions & 0 deletions src/js/gi/components/profile/Calculator.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';

export class Calculator extends React.Component {
render() {
const it = this.props.profile.attributes;
return (
<div>
Calculator
</div>
);
}
}

const mapStateToProps = (state, props) => state;

const mapDispatchToProps = (dispatch) => {
return {
showModal: (name) => {
dispatch(actions.displayModal(name));
},
};
};

export default connect(mapStateToProps, mapDispatchToProps)(Calculator);
128 changes: 128 additions & 0 deletions src/js/gi/components/profile/CautionaryInformation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import AlertBox from '../../../common/components/AlertBox';

export class CautionaryInformation extends React.Component {
render() {
const it = this.props.profile.attributes;
if (!it.complaints) { return null; }

const flagContent = (
<p>
{it.caution_flag_reason}
<br/>
<a onClick={this.props.showModal.bind(this, 'cautionInfo')}>Learn more about these warnings</a>
</p>
);
const complaintData = [
{type: 'Financial Issues (e.g., Tuition/Fee charges)', key: 'financial'},
{type: 'Quality of Education', key: 'quality'},
{type: 'Refund Issues', key: 'refund'},
{type: 'Recruiting/Marketing Practices', key: 'marketing'},
{type: 'Accreditation', key: 'accreditation'},
{type: 'Change in degree plan/requirements', key: 'degree_requirements'},
{type: 'Student Loans', key: 'student_loans'},
{type: 'Grade Policy', key: 'grades'},
{type: 'Transfer of Credits', key: 'credit_transfer'},
{type: 'Post-Graduation Job Opportunities', key: 'job', totalKey: 'jobs'},
{type: 'Release of Transcripts', key: 'transcript'},
{type: 'Other', key: 'other'},
{type: 'Student Complaints', totals: ['facility_code', 'main_campus_roll_up']}
];
const complaints = complaintData.reduce((complaints, complaint) => {
const totals = complaint.totals || {};
const { type, key, totalKey } = complaint;
const hydratedComplaint = {
description: type,
thisCampus: (complaint.totals ? it.complaints[totals[0]] : it.complaints[`${key}_by_fac_code`]),
allCampuses: (complaint.totals ? it.complaints[totals[1]] : it.complaints[`${totalKey || key}_by_ope_id_do_not_sum`]),
};
return [...complaints, hydratedComplaint];
}, []);

const TableRow = ({description, thisCampus, allCampuses}) => {
return (
<tr key={description}>
<th><strong>{description}</strong></th>
<td className="number">{thisCampus}</td>
<td className="number">{allCampuses}</td>
</tr>
);
};

const ListRow = ({description, value}) => {
if (value < 1) return null;
return (
<div className="row" key={description}>
<div className="small-11 columns">
<p>{description}:</p>
</div>
<div className="small-1 columns">
<p className="number">{value}</p>
</div>
</div>
);
};

return (
<div className="cautionary-information">
<AlertBox content={flagContent} isVisible={!!it.caution_flag} status="warning"/>

<div className="table">
<h3>{it.complaints.main_campus_roll_up} student complaints</h3>
<p>(<a href="http://www.benefits.va.gov/gibill/comparison_tool/about_this_tool.asp#sourcedata" target="_blank">Source</a>)</p>
<table className="usa-table-borderless">
<thead>
<tr>
<th>Complaint type</th>
<th>This campus</th>
<th>All campuses</th>
</tr>
</thead>
<tbody>
{complaints.map((c) => <TableRow description={c.description} thisCampus={c.thisCampus} allCampuses={c.allCampuses} />)}
</tbody>
</table>
</div>

<div className="list">
<h4>This campus</h4>
{complaints.map((c) => <ListRow description={c.description} value={c.thisCampus}/>)}
<div className="row">
<div className="small-11 columns">
<p><strong>Total complaints:</strong></p>
</div>
<div className="small-1 columns">
<p className="number"><strong>{it.complaints.facility_code}</strong></p>
</div>
</div>
<h4>All campuses</h4>
{complaints.map((c) => <ListRow description={c.description} value={c.allCampuses}/>)}
<div className="row">
<div className="small-11 columns">
<p><strong>Total complaints:</strong></p>
</div>
<div className="small-1 columns">
<p className="number"><strong>{it.complaints.main_campus_roll_up}</strong></p>
</div>
</div>
</div>

<p>*Each complaint can have multiple types</p>
</div>
);
}
}

const mapStateToProps = (state, props) => state;

const mapDispatchToProps = (dispatch) => {
return {
showModal: (name) => {
dispatch(actions.displayModal(name));
},
};
};

export default connect(mapStateToProps, mapDispatchToProps)(CautionaryInformation);
Loading

0 comments on commit 63cdef3

Please sign in to comment.