import React from "react"; import Layout from "../components/Layout"; import { Map, Marker, Popup, TileLayer, FeatureGroup, } from "react-leaflet-universal"; import Typewriter from "typewriter-effect"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSearch } from "@fortawesome/free-solid-svg-icons"; export default class IndexPage extends React.Component { constructor() { super(); this.state = { searchRendered: false, value: "", violations: [], geoCoords: {}, }; this.handleSearch = this.handleSearch.bind(this); this.handleZoom = this.handleZoom.bind(this); this.mapRef = React.createRef(); this.groupRef = React.createRef(); } componentDidUpdate() { this.handleZoom(); } putSearch() { const value = this.state.value; return fetch("/api/search", { method: "PUT", credentials: "same-origin", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ search: value }), }).then((res) => res); } getSearch() { if (this.state.value !== "") { fetch("/api/search/results", { method: "GET", credentials: "same-origin", headers: { "Content-Type": "application/json", }, }) .then((res) => res.json()) .then((res) => this.setState({ violations: res.location, searchRendered: true, geoCoords: res.geoCoords, }) ); } } async handleZoom() { if (this.state.searchRendered) { const map = await this.mapRef.current.leafletElement; const group = await this.groupRef.current.leafletElement; map.fitBounds(group.getBounds()); } } handleSearch() { this.setState( { value: document.querySelector(".search-txt").value }, async () => { this.putSearch().then(() => { this.getSearch(); }); } ); } renderLeaflet() { return ( <Map center={[38.7849, -76.8721]} zoom={9.5} ref={this.mapRef}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' /> {this.renderSearch()} </Map> ); } renderSearch() { if (this.state.searchRendered) { const violations = this.state.violations; const geoCoords = this.state.geoCoords; return ( <FeatureGroup ref={this.groupRef}> <Marker position={[parseFloat(geoCoords.lat), parseFloat(geoCoords.lng)]} > <Popup> {violations.address.street_number}{" "} {violations.address.street_name}{" "} {violations.address.street_suffix} {violations.address.city}{" "} {violations.address.state} {violations.address.zip} <br /> <b>Inspection ID: </b> {violations.violations[0].inspectionID} <br /> <b>Violation ID: </b> {violations.violations[0].violationID} <br /> <b>Code: </b> {violations.violations[0].code} <br /> <b>Description: </b> {violations.violations[0].desc} <br /> <b>Count: </b> {violations.count} </Popup> </Marker> </FeatureGroup> ); } } render() { return ( <Layout> <div className="container"> <div className="wrapper"> <div className="slogan"> <h1>Don't Be a Fool, </h1> <h1> Check Before You <div className="green"> <Typewriter options={{ strings: ["Buy", "Rent"], autoStart: true, loop: true, }} /> </div> </h1> </div> <div className="search-inst"> <Typewriter options={{ strings: [ "Type in address, street name, and street suffix", "then press the button!", ], autoStart: true, loop: true, }} /> </div> <div className="search-box"> <input className="search-txt" type="text" name="" placeholder="Type to search" onKeyPress={(event) => { if (event.key === "Enter") { this.handleSearch(); } }} /> <a className="search-btn" href="#" onClick={this.handleSearch}> <FontAwesomeIcon icon={faSearch} /> </a> </div> <div className="map">{this.renderLeaflet()}</div> </div> </div> </Layout> ); } }