<div data-react="find-installer" data-props="{&quot;placesEndpoint&quot;:&quot;/mocks/api/findInstaller.json&quot;,&quot;lang&quot;:{&quot;startTitle&quot;:&quot;Hitta installatör&quot;,&quot;startDescription&quot;:&quot;Behöver du hjälp att installera? Eller är du kanske osäker på vilka produkter och lösningar som är bäst för dina behov i hemmet? Tala med en erfaren auktoriserad installatör så får du hjälp att skapa inomhusklimat i världsklass i ditt eget hem.&quot;}}" class="find-installer"></div>
<div data-react="find-installer" data-props="{{jsonEncode props}}" class="find-installer"></div>
{
  "props": {
    "placesEndpoint": "/mocks/api/findInstaller.json",
    "lang": {
      "startTitle": "Hitta installatör",
      "startDescription": "Behöver du hjälp att installera? Eller är du kanske osäker på vilka produkter och lösningar som är bäst för dina behov i hemmet? Tala med en erfaren auktoriserad installatör så får du hjälp att skapa inomhusklimat i världsklass i ditt eget hem."
    }
  }
}
  • Content:
    import React from 'react';
    import PropTypes from 'prop-types';
    import StartView from './StartView';
    import MapView from './MapView';
    
    const FindInstaller = (props) => {
        const [selectedLocationCords, setSelectedLocationCords] = React.useState();
    
        const onSelect = (cords) => setSelectedLocationCords(() => cords);
    
        return (
            <>
                {selectedLocationCords
                    ? <MapView
                        selectedLocationCords={selectedLocationCords}
                        placesEndpoint={props.placesEndpoint}
                    />
                    : <StartView
                        lang={props.lang}
                        onSelect={onSelect}
                    />
                }
            </>
        );
    };
    
    FindInstaller.propTypes = {
        placesEndpoint: PropTypes.string.isRequired
    };
    
    export default FindInstaller;
    
  • URL: /components/raw/find-installer/FindInstaller.jsx
  • Filesystem Path: src/components/find-installer/FindInstaller.jsx
  • Size: 824 Bytes
  • Content:
    import React from 'react';
    import PropTypes from 'prop-types';
    import GoogleMap from '../google-map/GoogleMap';
    import SearchFieldPlaces from './SearchFieldPlaces';
    import MapContactCard from '../map-contact-card/MapContactCard';
    import { installersToContactInfoProps } from './utils/parsers';
    
    const MapView = (props) => {
        const [selectedLocationCords, setSelectedLocationCords] = React.useState(props.selectedLocationCords);
        const [places, setPlaces] = React.useState();
        const [visiblePlaces, setVisiblePlaces] = React.useState([]);
        const [selectedPlace, setSelectedPlace] = React.useState('');
        const mapRef = React.useRef();
    
        const openInfoWindow = (id) => {
            mapRef.current.openInfoWindow(id);
        };
    
        React.useEffect(() => {
            if (mapRef.current) {
                openInfoWindow(selectedPlace);
            }
        }, [selectedPlace, mapRef]);
    
        React.useEffect(() => {
            fetch(props.placesEndpoint)
                .then((res) => res.json())
                .then((data) => setPlaces(data.Result));
        }, []);
    
        return (
            <div className="find-installer-map">
                <aside className="find-installer-map__result">
                    <div className="row">
                        <div className="col col--span-12">
                            <div className="find-installer-map__search">
                                <SearchFieldPlaces
                                    onSelect={(cords) => setSelectedLocationCords(cords)}
                                />
                            </div>
                        </div>
                    </div>
                    <div className="find-installer-map__cards">
                        <div className="row">
                            {places
                                ? installersToContactInfoProps(places, selectedLocationCords).map(({ contactInfo, key, title }) => (
                                    visiblePlaces.includes(key) &&
                                    <div className="col col--span-12 col--span-m-6 col--span-xl-12" key={key}>
                                        <MapContactCard
                                            key={key}
                                            id={String(key)}
                                            title={title}
                                            contactInfo={contactInfo}
                                            active={selectedPlace === key}
                                            onClick={() => setSelectedPlace(key)}
                                        />
                                    </div>
                                ))
                                // ToDo: Add loading state
                                : null}
                        </div>
                    </div>
                </aside>
                <div className="find-installer-map__map">
                    {places
                        ? <GoogleMap
                            ref={mapRef}
                            places={places}
                            targetPlaceCords={selectedLocationCords}
                            onVisibleMarkersUpdate={setVisiblePlaces}
                            onInfoWindowClose={() => setSelectedPlace(() => '')}
                            onMarkerClick={(marker) => setSelectedPlace(() => marker.Id)}
                        />
                        // ToDo: Add loading state
                        : null}
                </div>
            </div>
        );
    };
    
    MapView.propTypes = {
        selectedLocationCords: PropTypes.object.isRequired,
        setSearchLatLon: PropTypes.shape({
            lat: PropTypes.number,
            lon: PropTypes.number
        }),
        placesEndpoint: PropTypes.string.isRequired
    };
    
    export default MapView;
    
  • URL: /components/raw/find-installer/MapView.jsx
  • Filesystem Path: src/components/find-installer/MapView.jsx
  • Size: 3.6 KB
  • Content:
    import React from 'react';
    import PropTypes from 'prop-types';
    import { GoogleMapsContext } from '../../context/GoogleMapsProvider';
    import SearchField, { Geolocation } from '../search-field';
    
    const ItemComponent = (props) => (
        <>
            <svg className="search-field-places__icon-wrapper" focusable="false">
                <use xlinkHref="#icon-map-pin"/>
            </svg>
            {props.description}
        </>
    );
    
    const SearchFieldPlaces = (props) => {
        const { autocompleteService, googleMapsApi } = React.useContext(GoogleMapsContext);
        const [searchResult, setSearchResult] = React.useState([]);
    
        const updateSearchResult = (e) => {
            const input = e.target.value || '';
            if (input.length > 0) {
                autocompleteService.getPlacePredictions({ input }, (places) => {
                    setSearchResult(() => (
                        places
                            ? places.map((place) => ({
                                ...place,
                                value: place.description,
                                id: place.place_id
                            }))
                            : []
                    ));
                });
            } else {
                // Reset statae when there's no search result
                setSearchResult(() => []);
            }
        };
    
        const getCords = async (e) => {
            const service = new googleMapsApi.places.PlacesService(document.createElement('div'));
            const cords = await new Promise((resolve, reject) => {
                try {
                    service.getDetails({ placeId: e.place_id }, (data) => {
                        resolve(data.geometry.location);
                    });
                } catch (e) {
                    reject(e);
                }
            });
            props.onSelect(cords);
        };
    
        const onGeolocation = (latLng) => {
            props.onSelect(new googleMapsApi.LatLng(...latLng));
        };
    
        return (
            <>
                {googleMapsApi &&
                    <SearchField
                        onChange={getCords}
                        items={searchResult}
                        onInputChange={updateSearchResult}
                        itemStyle="search-field-places__result"
                        className={props.className}
                        itemComponent={ItemComponent}
                    >
                        <Geolocation onGeolocation={onGeolocation} />
                    </SearchField>
                }
            </>
        );
    };
    
    SearchFieldPlaces.propTypes = {
        onChange: PropTypes.func
    };
    
    SearchFieldPlaces.defaultProps = {
        onChange: () => {}
    };
    
    export default SearchFieldPlaces;
    
  • URL: /components/raw/find-installer/SearchFieldPlaces.jsx
  • Filesystem Path: src/components/find-installer/SearchFieldPlaces.jsx
  • Size: 2.6 KB
  • Content:
    import React from 'react';
    import PropTypes from 'prop-types';
    import SearchFieldPlaces from './SearchFieldPlaces';
    
    const StartView = (props) => {
        return (
            <div className="find-installer-start">
                <div className="find-installer-start__panel">
                    <h1>{props.lang.startTitle}</h1>
                    <p className="preamble">
                        {props.lang.startDescription}
                    </p>
                    <SearchFieldPlaces
                        onSelect={props.onSelect}
                        className="search-field--big-m h-no-margin-bottom"
                    />
                </div>
            </div>
        );
    };
    
    StartView.propTypes = {
        onSelect: PropTypes.func
    };
    
    StartView.defaultProps = {
        onSelect: () => {}
    };
    
    export default StartView;
    
  • URL: /components/raw/find-installer/StartView.jsx
  • Filesystem Path: src/components/find-installer/StartView.jsx
  • Size: 780 Bytes
  • Content:
    .find-installer {
        display: flex;
        width: 100%;
        align-items: center;
        justify-content: space-around;
    
        @include breakpoint($xl) {
            height: 70vh;
            min-height: size(60);
        }
    }
    
    // start view
    .find-installer-start {
        display: flex;
        align-items: center;
        justify-content: space-around;
        width: 100%;
        height: 100%;
        background: url("./img/start-background.png") center no-repeat;
        background-size: cover;
    }
    
    .find-installer-start__panel {
        width: 100%;
        max-width: size(116);
        background: $color-white;
        padding: size(4) size(2);
        margin: size(5) size(1);
        @include breakpoint($m) {
            padding: size(10) size(15);
            margin: size(6) size(2);
        }
    }
    
    // map view
    .find-installer-map {
        display: flex;
        flex: 1;
        height: 100%;
        flex-direction: column;
        flex-direction: column-reverse;
    
        @include breakpoint($xl) {
            flex-direction: row;
            flex-direction: initial;
        }
    }
    
    .find-installer-map__map {
        flex: 1 0 auto;
        height: 50vh;
    
        @include breakpoint($xl) {
            display: flex;
            flex-direction: column;
            height: 100%;
            width: size(52);
            padding: 0;
        }
    }
    
    // sidebar
    
    .find-installer-map__result {
        background: $color-gray-1;
        width: 100%;
        padding-top: size(2);
    
        @include breakpoint($xl) {
            display: flex;
            flex-direction: column;
            width: size(52);
            padding-top: size(3);
        }
    }
    
    .find-installer-map__search {
        margin-bottom: size(-2);
    
        @include breakpoint($xl) {
            margin-bottom: size(-1);
        }
    }
    
    .find-installer-map__cards {
        flex: 1;
        overflow: auto;
    }
    
  • URL: /components/raw/find-installer/find-installer.scss
  • Filesystem Path: src/components/find-installer/find-installer.scss
  • Size: 1.7 KB
  • Content:
    .search-field-places__result {
        min-height: size(8);
        padding: size(2);
    }
    
    .search-field-places__icon-wrapper {
        width: size(4);
        height: size(4);
        margin-right: size(2);
        color: $color-green;
        flex-shrink: 0;
    }
    
  • URL: /components/raw/find-installer/search-field-places.scss
  • Filesystem Path: src/components/find-installer/search-field-places.scss
  • Size: 233 Bytes

No notes defined.