diff --git a/src/components/AddressSearchBGroup/index.js b/src/components/AddressSearchBGroup/index.js new file mode 100644 index 0000000000000000000000000000000000000000..ca18c2910996cda31b035021196777dcb6080e1f --- /dev/null +++ b/src/components/AddressSearchBGroup/index.js @@ -0,0 +1,161 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Geocoder from 'react-mapbox-gl-geocoder'; +import { Row, Col, Nav, NavItem, Button } from 'reactstrap'; +import './styles.css'; + + +const mapAccess = { + mapboxApiAccessToken: process.env.REACT_APP_MAPBOX_TOKEN, +}; + +const queryParams = { + country: 'us', +}; + +class AddressSearchBGroup extends Component { + constructor(props) { + super(props); + this.state = { + viewport: {}, + addressFound: false, + address: '', + searchClicked: false, + addClicked: false, + bGroupBuildings: this.props.bGroupBuildings, + }; + } + + componentWillReceiveProps(nextProps) { + if (this.props.buildings !== nextProps.buildings && nextProps.buildings.length > 0) { + this.setState({ + bGroupBuildings: this.props.bGroupBuildings, + address: nextProps.buildings[0].placeName, + }); + } + } + + handleOnSelected = (viewport, item) => { + this.setState({ + viewport, + address: item.place_name, + addressFound: true, + searchClicked: true, + }, () => { + this.props.searchBuildings(this.state.address); + }); + } + + handleOnAddBuilding = () => { + this.props.addSelectedAddress(); + this.setState({ addClicked: true }); + } + + handleOnChange = (event) => { + this.setState({ + address: event.target.value, + addressFound: false, + searchClicked: false, + addClicked: false, + }); + } + + render() { + let addressData = ''; + const { viewport } = this.state; + if (!this.state.addressFound) { + addressData = ( + + ); + } else { + addressData = ( + + ); + } + + let result = ''; + console.log(this.props.buildings); + const bGroupBuildingIDs = this.state.bGroupBuildings.map(building => building.building_id); + if (this.props.buildings !== undefined && this.props.buildings.length > 0) { + if (this.state.searchClicked) { + if (bGroupBuildingIDs.includes(this.props.buildings[0].building_id)) { + result = ( +
+ This address already exists in the building group, please enter another one. +
+ ); + } else { + result = ( + + ); + } + } + if (this.state.addClicked && + !bGroupBuildingIDs.includes(this.props.buildings[0].building_id)) { + result = ( +
+ Building has been successfully added to the group! +
+ ); + } + } + + if (this.state.searchClicked && + (this.props.buildings === undefined || this.props.buildings.length === 0)) { + result = ( +
+ There is an error in building address search, please contact admin. +
+ ); + } + const content = ( +
+ + + {addressData} + {result} + + +
+ ); + + return ( + + ); + } +} + +AddressSearchBGroup.propTypes = { + bGroupBuildings: PropTypes.arrayOf, + buildings: PropTypes.objectOf, + searchBuildings: PropTypes.func, + buildingsSearched: PropTypes.func, + addSelectedAddress: PropTypes.func, +}; + +export default AddressSearchBGroup; diff --git a/src/containers/SearchBarBGroup/styles.css b/src/components/AddressSearchBGroup/styles.css similarity index 94% rename from src/containers/SearchBarBGroup/styles.css rename to src/components/AddressSearchBGroup/styles.css index ae86686a139407b1f88e251b5cb16dc36901c784..b826324588edb44ecb3e94fd8d13f1bbb8975d40 100644 --- a/src/containers/SearchBarBGroup/styles.css +++ b/src/components/AddressSearchBGroup/styles.css @@ -95,6 +95,18 @@ li.navbar-input>form { background: #EEEEEE; } +.successMessage { + color: #336633; + font-size: 0.8em; + font-weight: bold; +} + +.errorMessage { + color: #B92828; + font-size: 0.8em; + font-weight: bold; +} + @media screen and (max-width: 992px) { .addressSearchInputBGroup { width: 600px !important; diff --git a/src/containers/SearchBarBGroup/index.js b/src/components/AddressSearchBuildings/index.js similarity index 79% rename from src/containers/SearchBarBGroup/index.js rename to src/components/AddressSearchBuildings/index.js index d3a48cf92fbd01dcfa14c08a6d89f72d53793403..f2465456e0ce333c8f5d7043ad2a42b05134ea4f 100644 --- a/src/containers/SearchBarBGroup/index.js +++ b/src/components/AddressSearchBuildings/index.js @@ -2,14 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Geocoder from 'react-mapbox-gl-geocoder'; import { Row, Col, Nav, NavItem } from 'reactstrap'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; -import { - searchBuildings, - buildingsSearched, -} from './actions'; import './styles.css'; -import { buildingListPropTypes } from './propTypes'; const mapAccess = { @@ -20,7 +13,7 @@ const queryParams = { country: 'us', }; -class SearchBar extends Component { +class AddressSearchBuildings extends Component { constructor(props) { super(props); this.state = { @@ -99,7 +92,7 @@ class SearchBar extends Component { const content = (
- + {addressData} @@ -118,21 +111,10 @@ class SearchBar extends Component { } } -SearchBar.propTypes = { - buildingList: buildingListPropTypes, +AddressSearchBuildings.propTypes = { + buildingList: PropTypes.objectOf, searchBuildings: PropTypes.func, buildingsSearched: PropTypes.func, }; -function mapDispatchToProps(dispatch) { - return bindActionCreators({ - searchBuildings, - buildingsSearched, - }, dispatch); -} - -function mapStateToProps({ buildingList }) { - return { buildingList }; -} - -export default connect(mapStateToProps, mapDispatchToProps)(SearchBar); +export default AddressSearchBuildings; diff --git a/src/containers/SearchBarBuildings/styles.css b/src/components/AddressSearchBuildings/styles.css similarity index 100% rename from src/containers/SearchBarBuildings/styles.css rename to src/components/AddressSearchBuildings/styles.css diff --git a/src/components/BuildingListTable/index.js b/src/components/BuildingListTable/index.js index 34d2d89912079ff039d8cf296b760bc5ebb1b209..71366629b302c6faa644f56ae2fca3c6f7347c90 100644 --- a/src/components/BuildingListTable/index.js +++ b/src/components/BuildingListTable/index.js @@ -3,7 +3,7 @@ import ReactGA from 'react-ga'; import PropTypes from 'prop-types'; import { browserHistory } from 'react-router'; import './styles.css'; -import { buildingList, loadErrorPropTypes } from '../../containers/SearchBarBGroup/propTypes'; +import { buildingList, loadErrorPropTypes } from '../../containers/SearchBar/propTypes'; import Loading from '../../components/Loading'; /* eslint-disable no-param-reassign */ diff --git a/src/components/NavBar/index.js b/src/components/NavBar/index.js index 008167fc0e0b70e5e46289418f1bb645a6a3c714..9d0190b3eabe68e5add36c102fc65c6d9533f192 100644 --- a/src/components/NavBar/index.js +++ b/src/components/NavBar/index.js @@ -27,6 +27,13 @@ export default class NavBar extends Component { this.setState({ collapsed }) ) + buildingsSearched = buildings => ( + this.props.buildingsSearched(buildings) + ) + + searchBuildings = address => ( + this.props.searchBuildings(address) + ) toggleNavbar = () => ( this.setState({ @@ -54,6 +61,9 @@ export default class NavBar extends Component { {this.props.SearchBar ? : null}
- {props.upperFirstLetter(props.data.firstName)} + {props.data.firstName}
@@ -48,7 +48,7 @@ const BuildingInfo = (props) => { Last Name
- {props.upperFirstLetter(props.data.lastName)} + {props.data.lastName}
@@ -164,7 +164,6 @@ BuildingInfo.propTypes = { tableHeader: PropTypes.objectOf, title: PropTypes.string, data: PropTypes.objectOf, - upperFirstLetter: PropTypes.func, }; export default BuildingInfo; diff --git a/src/components/Questionnaire/ReviewAnswers/FinancialInitial.js b/src/components/Questionnaire/ReviewAnswers/FinancialInitial.js index 672c6a8081c16bd9deca4e29c03a1bf0bf28d281..3d384cc3b016bd10a1ab7e5dd37b8979b47b5ff8 100644 --- a/src/components/Questionnaire/ReviewAnswers/FinancialInitial.js +++ b/src/components/Questionnaire/ReviewAnswers/FinancialInitial.js @@ -30,9 +30,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.legalOwnership.answer_id === -1 ? + '--' : props.answers[props.data.legalOwnership.answer_id] - ) }
@@ -44,9 +44,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.numberOfDobViolations.answer_id === -1 ? + '--' : props.answers[props.data.numberOfDobViolations.answer_id] - ) }
@@ -58,9 +58,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.bankruptcyPast.answer_id === -1 ? + '--' : props.answers[props.data.bankruptcyPast.answer_id] - ) }
@@ -72,9 +72,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.currentOnEnergyBills.answer_id === -1 ? + '--' : props.answers[props.data.currentOnEnergyBills.answer_id] - ) }
@@ -86,9 +86,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.currentMortgageBalance.answer_id === -1 ? + '--' : props.answers[props.data.currentMortgageBalance.answer_id] - ) }
@@ -100,9 +100,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.profitable.answer_id === -1 ? + '--' : props.answers[props.data.profitable.answer_id] - ) }
@@ -114,9 +114,9 @@ const FinancialInitial = (props) => {
{ - props.upperFirstLetter( + props.data.budgetForDownPayment.answer_id === -1 ? + '--' : props.answers[props.data.budgetForDownPayment.answer_id] - ) }
@@ -131,7 +131,6 @@ FinancialInitial.propTypes = { tableHeader: PropTypes.objectOf, title: PropTypes.string, data: PropTypes.objectOf, - upperFirstLetter: PropTypes.func, answers: PropTypes.objectOf, }; diff --git a/src/components/Questionnaire/ReviewAnswers/RemoteSurvey.js b/src/components/Questionnaire/ReviewAnswers/RemoteSurvey.js index df4aec6d60f65006a5da75cdff64d21f79d04ac0..a85e8508dc394e263e9f11dfdcc58e9c3a1cb655 100644 --- a/src/components/Questionnaire/ReviewAnswers/RemoteSurvey.js +++ b/src/components/Questionnaire/ReviewAnswers/RemoteSurvey.js @@ -28,11 +28,7 @@ const RemoteSurvey = (props) => { Heating System
- { - props.upperFirstLetter( - props.answers[props.data.heatingSystem.answer_id] - ) - } + { props.answers[props.data.heatingSystem.answer_id] }
@@ -40,11 +36,7 @@ const RemoteSurvey = (props) => { Heating Fuel Source
- { - props.upperFirstLetter( - props.answers[props.data.heatingFuelSource.answer_id] - ) - } + { props.answers[props.data.heatingFuelSource.answer_id] }
@@ -54,11 +46,7 @@ const RemoteSurvey = (props) => { Is Domestic Hot Water (DHW) and heat prepared by the same boiler?
- { - props.upperFirstLetter( - props.answers[props.data.DHWSameBoiler.answer_id] - ) - } + { props.answers[props.data.DHWSameBoiler.answer_id] }
@@ -68,11 +56,7 @@ const RemoteSurvey = (props) => { Age of heat generating system?
- { - props.upperFirstLetter( - props.answers[props.data.ageOfHeatGenerateSystem.answer_id] - ) - } + { props.answers[props.data.ageOfHeatGenerateSystem.answer_id] }
@@ -82,11 +66,7 @@ const RemoteSurvey = (props) => { When do you plan to replace the heating system?
- { - props.upperFirstLetter( - props.answers[props.data.planToReplaceHS.answer_id] - ) - } + { props.answers[props.data.planToReplaceHS.answer_id] }
@@ -96,11 +76,7 @@ const RemoteSurvey = (props) => { Hallways heated?
- { - props.upperFirstLetter( - props.answers[props.data.hallwaysHeated.answer_id] - ) - } + { props.answers[props.data.hallwaysHeated.answer_id] }
@@ -108,11 +84,7 @@ const RemoteSurvey = (props) => { Basement heated?
- { - props.upperFirstLetter( - props.answers[props.data.basementHeated.answer_id] - ) - } + { props.answers[props.data.basementHeated.answer_id] }
@@ -122,11 +94,7 @@ const RemoteSurvey = (props) => { Stairwells heated?
- { - props.upperFirstLetter( - props.answers[props.data.stairwellsHeated.answer_id] - ) - } + { props.answers[props.data.stairwellsHeated.answer_id] }
@@ -134,11 +102,7 @@ const RemoteSurvey = (props) => { Floors heated?
- { - props.upperFirstLetter( - props.answers[props.data.floorsHeated.answer_id] - ) - } + { props.answers[props.data.floorsHeated.answer_id] }
@@ -149,9 +113,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.accessibleByStairwell.answer_id === -1 ? + '--' : props.answers[props.data.accessibleByStairwell.answer_id] - ) }
@@ -163,9 +127,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.backFacadeAttached.answer_id === -1 ? + '--' : props.answers[props.data.backFacadeAttached.answer_id] - ) }
@@ -178,9 +142,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.exteriorWallsAttached.answer_id === -1 ? + '--' : props.answers[props.data.exteriorWallsAttached.answer_id] - ) }
@@ -192,9 +156,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.tenantComplaintsComfort.answer_id === -1 ? + '--' : props.answers[props.data.tenantComplaintsComfort.answer_id] - ) }
@@ -206,9 +170,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.tenantComplaintsWindows.answer_id === -1 ? + '--' : props.answers[props.data.tenantComplaintsWindows.answer_id] - ) }
@@ -220,9 +184,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.meteredForElectricity.answer_id === -1 ? + '--' : props.answers[props.data.meteredForElectricity.answer_id] - ) }
@@ -234,9 +198,9 @@ const RemoteSurvey = (props) => {
{ - props.upperFirstLetter( + props.data.numberOfHeatingViolations.answer_id === -1 ? + '--' : props.answers[props.data.numberOfHeatingViolations.answer_id] - ) }
@@ -251,7 +215,6 @@ RemoteSurvey.propTypes = { tableHeader: PropTypes.objectOf, title: PropTypes.string, data: PropTypes.objectOf, - upperFirstLetter: PropTypes.func, answers: PropTypes.objectOf, }; diff --git a/src/components/Questionnaire/ReviewAnswers/index.js b/src/components/Questionnaire/ReviewAnswers/index.js index b83b0223b951edb271af09ed3c58387332c9ab82..3f22dae1992b03bcb8380c0674539efd5bd830b8 100644 --- a/src/components/Questionnaire/ReviewAnswers/index.js +++ b/src/components/Questionnaire/ReviewAnswers/index.js @@ -7,10 +7,6 @@ import FinancialInitial from './FinancialInitial'; const ReviewAnswers = (props) => { - const upperFirstLetter = (str) => { - return str.charAt(0).toUpperCase() + str.slice(1); - }; - return (
@@ -19,7 +15,6 @@ const ReviewAnswers = (props) => { tableHeader={props.tableHeader} title={'Building Info'} data={props.buildingInfo} - upperFirstLetter={upperFirstLetter} /> @@ -28,7 +23,6 @@ const ReviewAnswers = (props) => { title={'Remote Survey'} data={props.remoteSurvey} answers={props.answers} - upperFirstLetter={upperFirstLetter} /> @@ -37,7 +31,6 @@ const ReviewAnswers = (props) => { title={'Financial Initial Go/NoGo'} data={props.financialInitials} answers={props.answers} - upperFirstLetter={upperFirstLetter} /> diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index 8e9dc14746c09247f44353a410fce3cd1fd9b4e2..601400d3635bdcf7fe91beefe22dc51442fbb225 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -18,6 +18,10 @@ import { deleteBuildingFromBGroup, deleteBGroup, } from './actions'; +import { + searchBuildings, + buildingsSearched, +} from '../SearchBar/actions'; // import { loadBuildings } from '../Building/actions'; import BGroupProjectOverview from './BGroupProjectOverview'; import BGroupBuildingTable from './BGroupBuildingTable'; @@ -415,7 +419,9 @@ export class BGroup extends Component { bGroupId={this.props.params.bGroupId} user={this.props.user} projects={this.props.projects} - buildings={this.props.buildings} + buildings={this.props.buildings.buildings} + // searchedBuildings={this.props.searchedBuildings} + searchBuildings={this.props.searchBuildings} bGroup={this.props.bGroup} addBuildingToBGroup={this.props.addBuildingToBGroup} deleteBuildingFromBGroup={this.props.deleteBuildingFromBGroup} @@ -451,7 +457,11 @@ export class BGroup extends Component { return (
- {this.props.displayNavBar ? : null} + {this.props.displayNavBar ? : null}
@@ -516,6 +526,7 @@ BGroup.propTypes = { params: PropTypes.shape({ bGroupId: PropTypes.string, }), + searchBuildings: PropTypes.func, bGroup: PropTypes.object, // eslint-disable-line loadBGroupBuildings: PropTypes.func, loadBGroupDetail: PropTypes.func, @@ -565,11 +576,14 @@ const mapStateToProps = state => ( bGroup: state.bGroup, projects: state.projectList, report: state.report, + buildings: state.buildingList, } ); const mapDispatchToProps = dispatch => ( bindActionCreators({ + searchBuildings, + buildingsSearched, loadBGroupBuildings, loadBGroupDetail, addBuildingToBGroup, diff --git a/src/containers/BGroup/BGroupBuildingTable.js b/src/containers/BGroup/BGroupBuildingTable.js index a3961b931fc4de31eff23adf5b87b536f5a7849b..f6e1f820c9e25a4a1125f20459c3372eb005bccc 100644 --- a/src/containers/BGroup/BGroupBuildingTable.js +++ b/src/containers/BGroup/BGroupBuildingTable.js @@ -12,9 +12,9 @@ import { UncontrolledTooltip, } from 'reactstrap'; import userPropTypes from '../User/propTypes'; -import SearchBar from '../SearchBarBGroup'; import completeProjectPropTypes from '../Project/propTypes'; -// import buildingPropTypes from '../Building/propTypes'; +import buildingPropTypes from '../Building/propTypes'; +import AddressSearchBGroup from '../../components/AddressSearchBGroup'; /* eslint-disable no-param-reassign */ export default class BGroupBuildingTable extends Component { @@ -32,18 +32,25 @@ export default class BGroupBuildingTable extends Component { recommendedRetrofitsToggle: {}, recommendedDeemedToggle: {}, completedDeemedToggle: {}, + increaseNum: false, }; componentWillUnmount() { clearTimeout(this.updateNumRows); } - handleAddBuilding = (item) => { + handleSearchBuildings = (address) => { + this.props.searchBuildings(address); + } + + handleAddBuilding = () => { + const item = this.props.buildings[0]; this.props.addBuildingToBGroup( this.props.bGroupId, { building_ids: [item.building_id] }, - item.street_address, + item.placeName, ); + this.setState({ increaseNum: true }); } handleDeleteBuilding = (buildingId) => { @@ -55,7 +62,6 @@ export default class BGroupBuildingTable extends Component { } } - renderDeleteBuildingButton = (id) => { if (this.props.bGroup.deleteBGroupBuildingLoading[id]) { return ( @@ -854,7 +860,6 @@ export default class BGroupBuildingTable extends Component { val.projected_deemed_savings = []; val.completed_deemed_savings = []; } - return val; }); @@ -862,6 +867,21 @@ export default class BGroupBuildingTable extends Component { lineHeight: 1.15, }; + let rowNum = this.state.numRows; + if (this.state.increaseNum === true) { + rowNum = ( +
+
{this.state.numRows + 1} buildings
+
+ ); + } else if (this.state.increaseNum === false) { + rowNum = ( +
+
{this.state.numRows} buildings
+
+ ); + } + return (
@@ -872,12 +892,17 @@ export default class BGroupBuildingTable extends Component { > Search and add address   - +
= 0 ? '' : 'none' }}>
-
{this.state.numRows} buildings
+ {rowNum}
{ - if (['buildingInfo', 'remoteSurvey', 'financialInitials'].includes(formData[0])) { Object.entries(formData[1]).forEach(fieldData => { - if (fieldData[0] !== 'other' && - fieldData[0] !== 'address' && - fieldData[0] !== 'buildingId' && - fieldData[0] !== 'phone' && + if (requiredInformation.includes(fieldData[0]) && fieldData[1].toString().replace(/^\s+|\s+$/g, '') === '') { emptyFields.push(this.nameMapping[fieldData[0]]); } @@ -157,7 +154,8 @@ class Questionnaire extends Component { if (typeof fieldData[1] === 'object' && fieldData[1].answer_id !== undefined && parseInt(fieldData[1].answer_id, 10) === -1 && - parseInt(fieldData[1].question_id, 10) !== 16) { + parseInt(fieldData[1].question_id, 10) !== 10 && + requiredSurveyQuestions.includes(fieldData[1].question_id)) { emptyFields.push(this.nameMapping[fieldData[0]]); } }); diff --git a/src/containers/SearchBarBGroup/actions.js b/src/containers/SearchBar/actions.js similarity index 100% rename from src/containers/SearchBarBGroup/actions.js rename to src/containers/SearchBar/actions.js diff --git a/src/containers/SearchBarBGroup/constants.js b/src/containers/SearchBar/constants.js similarity index 100% rename from src/containers/SearchBarBGroup/constants.js rename to src/containers/SearchBar/constants.js diff --git a/src/containers/SearchBarBuildings/index.js b/src/containers/SearchBar/index.js similarity index 100% rename from src/containers/SearchBarBuildings/index.js rename to src/containers/SearchBar/index.js diff --git a/src/containers/SearchBarBGroup/propTypes.js b/src/containers/SearchBar/propTypes.js similarity index 100% rename from src/containers/SearchBarBGroup/propTypes.js rename to src/containers/SearchBar/propTypes.js diff --git a/src/containers/SearchBarBuildings/reducer.js b/src/containers/SearchBar/reducer.js similarity index 93% rename from src/containers/SearchBarBuildings/reducer.js rename to src/containers/SearchBar/reducer.js index 2ebaffd796a900764f45d065a821d08e7d93c177..fbef0b65b62a9e76e59273d6d7b8006791f98f9f 100644 --- a/src/containers/SearchBarBuildings/reducer.js +++ b/src/containers/SearchBar/reducer.js @@ -18,13 +18,14 @@ export default function (state = initState, action) { loading: true, error: false, }; - case SEARCH_BUILDINGS_SUCCESS: + case SEARCH_BUILDINGS_SUCCESS: { return { ...state, buildings: action.payload, loading: false, error: false, }; + } case SEARCH_BUILDINGS_ERROR: return { ...state, diff --git a/src/containers/SearchBarBuildings/ring.svg b/src/containers/SearchBar/ring.svg similarity index 100% rename from src/containers/SearchBarBuildings/ring.svg rename to src/containers/SearchBar/ring.svg diff --git a/src/containers/SearchBar/sagas.js b/src/containers/SearchBar/sagas.js new file mode 100644 index 0000000000000000000000000000000000000000..47288ccd931caee895b2bfe4c58e0752705e833b --- /dev/null +++ b/src/containers/SearchBar/sagas.js @@ -0,0 +1,39 @@ +import { call, put, takeLatest } from 'redux-saga/effects'; +import request from '../../utils/request'; +import { getHeaders, buildingsURL } from '../../utils/restServices'; + +import { + SEARCH_BUILDINGS, +} from './constants'; + +import { + buildingsSearched, + buildingsSearchingError, +} from './actions'; + +/** + * TODO: doctring + */ +function* getBuildingsByFilter(action) { + const placeName = action.address; + const res = yield call( + request, + `${buildingsURL}?place_name=${placeName}&limit=300`, { + method: 'GET', + headers: getHeaders(), + } + ); + + if (!res.err) { + yield put(buildingsSearched(res.data, placeName)); + } else { + yield put(buildingsSearchingError(res.err, placeName)); + } +} + +/** + * TODO: docstring + */ +export default function* buildingsWatcher() { + yield takeLatest(SEARCH_BUILDINGS, getBuildingsByFilter); +} diff --git a/src/containers/SearchBar/styles.css b/src/containers/SearchBar/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..684107179c3e110b819bb3882d3c2f3035f9dd87 --- /dev/null +++ b/src/containers/SearchBar/styles.css @@ -0,0 +1,129 @@ + +.building-search { + background-color: #222; + padding: 40px; +} + +.input-group { + width: inherit !important; +} + +.btn.dropdown-toggle:hover { + background-color: #E9E4E4 !important; +} + +.dropdown-selection { + height: 100%; + display: table-cell; + vertical-align: middle; + background-color: white; + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + line-height: 1.5; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; +} + +li.navbar-input { + -webkit-padding-start: 20px; +} + +li.navbar-input>form { + height: 100%; +} + +.addressSearchInputBuildings { + width: 700px !important; + position: relative; + padding-left: '15px'; + margin-top: '2px'; +} + +.addressSearchInputBuildings .addressDisplay { + height: 35px; + font-size: 16px; + font-weight: bold; + width: 100% !important; + padding: 10px; + margin-top: 5px; + margin-bottom: 5px; +} + +.addressSearchInputBuildings .react-geocoder { + position: relative; +} + +.addressSearchInputBuildings .react-geocoder input { + height: 35px; + width: 100% !important; + padding: 5px; + margin-top: 5px; + margin-bottom: 5px; + font-weight: bold; + font-size: 16px; +} + +.addressSearchInputBuildings .react-geocoder-results { + position: absolute; + background: #333333; + width: 100% !important; +} + +.addressSearchInputBuildings .react-geocoder-item { + width: 100% !important; + margin-left: 0px; + height: auto !important; + border-bottom: 0.5px solid rgba(160, 160, 160, .5) !important; + height: 30px !important; + font-weight: 700; + padding: 1% 2% 5% 2% !important; + font-size: 16px !important; + margin-left: 0px; + cursor: pointer; + color: #DDDDDD; + overflow: visible; + position: relative; +} + +.addressSearchInputBuildings .react-geocoder-item:hover { + color: #FFFFFF; + border-bottom: 0.5px solid #555555 !important; +} + +@media screen and (max-width: 992px) { + .addressSearchInput { + width: 600px !important; + } + .react-geocoder-item { + font-size: 13px !important; + font-weight: normal; + } + .react-geocoder input { + font-size: 13px !important; + font-weight: normal; + } + .addressDisplay { + height: 35px; + font-size: 13px; + } +} + +@media screen and (max-width: 600px) { + .addressSearchInput { + width: 420px !important; + } + .react-geocoder-item { + font-size: 11px !important; + font-weight: normal; + } + .react-geocoder input { + font-size: 11px !important; + font-weight: normal; + } + .addressDisplay { + height: 35px; + font-size: 11px; + } +} diff --git a/src/containers/SearchBarBGroup/sagas.js b/src/containers/SearchBarBGroup/sagas.js deleted file mode 100644 index d74337fe0c31af29fd5888ebf7342c73b07004de..0000000000000000000000000000000000000000 --- a/src/containers/SearchBarBGroup/sagas.js +++ /dev/null @@ -1,56 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; -// import request from '../../utils/request'; -// import { getHeaders, buildingsURL } from '../../utils/restServices'; - -import { - SEARCH_BUILDINGS, -} from './constants'; - -import { - buildingsSearched, - buildingsSearchingError, -} from './actions'; - -/** - * TODO: doctring - */ -function* getBuildingsByFilter(action) { - const placeName = action.address; - // const res = yield call( - // request, - // `${buildingsURL}?$place_name=${placeName}limit=300`, { - // method: 'GET', - // headers: getHeaders(), - // } - // ); - - // For now, we commented out http call and hard coded the response data - const res = { - data: [ - { - bbl: 3012410005, - bin: 3031524, - borough: 'BROOKLYN', - building_id: 181794, - lot_id: 759242, - street_address: '838 PARK PLACE', - targeting_score: 73.9496248660236, - zipcode: '11216', - placeName, - }, - ], - }; - - if (!res.err) { - yield put(buildingsSearched(res.data, placeName)); - } else { - yield put(buildingsSearchingError(res.err, placeName)); - } -} - -/** - * TODO: docstring - */ -export default function* buildingsWatcher() { - yield takeLatest(SEARCH_BUILDINGS, getBuildingsByFilter); -} diff --git a/src/containers/SearchBarBuildings/actions.js b/src/containers/SearchBarBuildings/actions.js deleted file mode 100644 index 623714c82f02a98eca78aee661e7f07ec46d7cdf..0000000000000000000000000000000000000000 --- a/src/containers/SearchBarBuildings/actions.js +++ /dev/null @@ -1,46 +0,0 @@ -import ReactGA from 'react-ga'; - -import { - SEARCH_BUILDINGS, - SEARCH_BUILDINGS_SUCCESS, - SEARCH_BUILDINGS_ERROR, -} from './constants'; - -/** - * Load the list of buildings, this action starts the request saga - * - * @param {dict} args The args to send to the backend - * @returns {object} An action object with a type of LOAD_BUILDINGS - * and filterName and value - */ -export function searchBuildings(address) { - return { - type: SEARCH_BUILDINGS, - address, - }; -} - -// TODO: Add doctring -export function buildingsSearched(buildings, args) { - if (args) { - const address = `Address searched: ${args.address}`; - if (buildings.length > 0) { - ReactGA.event({ category: 'Search', action: 'Success', label: `${address}` }); - } else { - ReactGA.event({ category: 'Search', action: 'Fail', label: `${address} not found` }); - } - } - return { - type: SEARCH_BUILDINGS_SUCCESS, - payload: buildings, - }; -} - -// TODO: Add doctring -export function buildingsSearchingError(error, args) { - ReactGA.event({ category: 'Search', action: 'Error', label: `Searched for ${args.address}, Failed due to ${error}` }); - return { - type: SEARCH_BUILDINGS_ERROR, - error, - }; -} diff --git a/src/containers/SearchBarBuildings/constants.js b/src/containers/SearchBarBuildings/constants.js deleted file mode 100644 index b0a679aade6039ffeee9046c19a158697d64d6a6..0000000000000000000000000000000000000000 --- a/src/containers/SearchBarBuildings/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -export const FETCH_BUILDINGS = 'FETCH_BUILDINGS'; -export const UPDATE_BUILDING_SEARCH_PARAMS = 'UPDATE_BUILDING_SEARCH_PARAMS'; -export const SEARCH_BUILDINGS = 'SEARCH_BUILDINGS'; -export const SEARCH_BUILDINGS_SUCCESS = 'SEARCH_BUILDINGS_SUCCESS'; -export const SEARCH_BUILDINGS_ERROR = 'SEARCH_BUILDINGS_ERROR'; diff --git a/src/containers/SearchBarBuildings/propTypes.js b/src/containers/SearchBarBuildings/propTypes.js deleted file mode 100644 index 2eafabeacf08308372414b0225b061c701c531c6..0000000000000000000000000000000000000000 --- a/src/containers/SearchBarBuildings/propTypes.js +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; - -const { string, number, bool, shape, arrayOf, oneOfType } = PropTypes; - -export const loadErrorPropTypes = { - loading: bool, - error: oneOfType([ - bool, - PropTypes.instanceOf(Error), - ]), -}; - -export const buildingList = arrayOf( - shape({ - street_address: string, - bbl: number, - bin: number, - building_id: number, - lot_id: number, - borough_id: number, - zipcode: string, - }) -); - -export const searchParams = shape({ - type: string, - borough: string, - term: string, -}); - -export const buildingListPropTypes = PropTypes.shape({ - ...searchParams, - buildings: buildingList, - ...loadErrorPropTypes, -}); diff --git a/src/containers/SearchBarBuildings/sagas.js b/src/containers/SearchBarBuildings/sagas.js deleted file mode 100644 index d74337fe0c31af29fd5888ebf7342c73b07004de..0000000000000000000000000000000000000000 --- a/src/containers/SearchBarBuildings/sagas.js +++ /dev/null @@ -1,56 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; -// import request from '../../utils/request'; -// import { getHeaders, buildingsURL } from '../../utils/restServices'; - -import { - SEARCH_BUILDINGS, -} from './constants'; - -import { - buildingsSearched, - buildingsSearchingError, -} from './actions'; - -/** - * TODO: doctring - */ -function* getBuildingsByFilter(action) { - const placeName = action.address; - // const res = yield call( - // request, - // `${buildingsURL}?$place_name=${placeName}limit=300`, { - // method: 'GET', - // headers: getHeaders(), - // } - // ); - - // For now, we commented out http call and hard coded the response data - const res = { - data: [ - { - bbl: 3012410005, - bin: 3031524, - borough: 'BROOKLYN', - building_id: 181794, - lot_id: 759242, - street_address: '838 PARK PLACE', - targeting_score: 73.9496248660236, - zipcode: '11216', - placeName, - }, - ], - }; - - if (!res.err) { - yield put(buildingsSearched(res.data, placeName)); - } else { - yield put(buildingsSearchingError(res.err, placeName)); - } -} - -/** - * TODO: docstring - */ -export default function* buildingsWatcher() { - yield takeLatest(SEARCH_BUILDINGS, getBuildingsByFilter); -} diff --git a/src/reducers.js b/src/reducers.js index ab87b30201b77ea76c2126c16c0b981b00f15c53..1cf26ccab1c433a6480c75b43073611c31ca1cf9 100644 --- a/src/reducers.js +++ b/src/reducers.js @@ -1,7 +1,7 @@ import { combineReducers } from 'redux'; import { routerReducer } from 'react-router-redux'; -import SearchBarReducer from './containers/SearchBarBuildings/reducer'; +import SearchBarReducer from './containers/SearchBar/reducer'; import ProjectSearchBarReducer from './containers/Project/reducer'; import BuildingReducer from './containers/Building/reducer'; import DimensionsReducer from './containers/Dimensions/reducer'; diff --git a/src/sagas.js b/src/sagas.js index cb7dca6ebcc808fafa6abf53ebd9d5079754172c..364d621ad15a4d561579a54531409413a3d1e3ad 100644 --- a/src/sagas.js +++ b/src/sagas.js @@ -1,7 +1,6 @@ import buildingSaga from './containers/Building/sagas'; import dimensionsSaga from './containers/Dimensions/sagas'; -import buildingsSearchSaga from './containers/SearchBarBuildings/sagas'; -import bGroupSearchSaga from './containers/SearchBarBGroup/sagas'; +import buildingsSearchSaga from './containers/SearchBar/sagas'; import projectsSearchSaga from './containers/Project/sagas'; import reportsSaga from './containers/Reports/sagas'; import documentsSaga from './containers/Documents/sagas'; @@ -24,7 +23,6 @@ export default function* rootSaga() { buildingSaga(), dimensionsSaga(), buildingsSearchSaga(), - bGroupSearchSaga(), projectsSearchSaga(), documentsSaga(), engSaga(), diff --git a/src/screens/BuildingsHomePage/index.js b/src/screens/BuildingsHomePage/index.js index 6dacc26f2fac4c18916f9b539642bab8ad2fb5e3..23e5c100aa73b935bf8132f71c7ae29d4b597cd8 100644 --- a/src/screens/BuildingsHomePage/index.js +++ b/src/screens/BuildingsHomePage/index.js @@ -3,13 +3,13 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import NavBar from '../../components/NavBar'; -import SearchBar from '../../containers/SearchBarBuildings'; +import AddressSearchBuildings from '../../components/AddressSearchBuildings'; import BuildingListTable from '../../components/BuildingListTable'; -import { buildingListPropTypes } from '../../containers/SearchBarBuildings/propTypes'; +import { buildingListPropTypes } from '../../containers/SearchBar/propTypes'; import { searchBuildings, buildingsSearched, -} from '../../containers/SearchBarBuildings/actions'; +} from '../../containers/SearchBar/actions'; import userPropType from '../../containers/User/propTypes'; import NotAuthorized from '../../components/NotAuthorized'; @@ -24,7 +24,9 @@ class BuildingsHomePage extends Component { return (
{ const buildingList = localStorage.activeBuildings; if (buildingList !== undefined) {