SHARE
TWEET

Untitled

a guest Jun 26th, 2019 65 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { h, Component } from 'preact';
  2. import MeasurementUnit from './MeasurmentUnits';
  3. import Dropdown from './Dropdown';
  4.  
  5. export default class FilterForm extends Component<any, any> {
  6.   private readonly fetchURL = '/json/real-estate';
  7.  
  8.   constructor(props) {
  9.     super(props);
  10.  
  11.     const {
  12.       filters,
  13.       filters: { area, city },
  14.       areas,
  15.     } = props;
  16.  
  17.     const preselectedCity = Boolean(city);
  18.     const preselectedArea = Boolean(area && area.length === 1);
  19.  
  20.     this.state = {
  21.       filters,
  22.       areas,
  23.       preselectedCity,
  24.       preselectedArea,
  25.     };
  26.   }
  27.  
  28.   async componentDidMount() {
  29.     const { city } = this.state.filters;
  30.     if (city) {
  31.       await this.fetchCityAreas('city', city);
  32.     }
  33.   }
  34.  
  35.   filterProperties = async event => {
  36.     event.preventDefault();
  37.     this.props.toggleLoading();
  38.     const { filters } = this.state;
  39.     const response = await fetch(this.fetchURL, {
  40.       method: 'POST',
  41.       headers: { 'Content-Type': 'application/json' },
  42.       body: JSON.stringify(filters),
  43.     });
  44.     const data: {
  45.       propertiesList: IRealEstateTeaser[];
  46.       propertiesCount: number;
  47.     } = await response.json();
  48.  
  49.     const { city, area } = filters;
  50.     this.props.onFilterProperties(data, { city, area });
  51.   };
  52.  
  53.   handleChange = (name: string, value: string): void => {
  54.     this.setState({ filters: { ...this.state.filters, [name]: value } });
  55.   };
  56.  
  57.   handleRangeChange = (name: string) => (event: any): void => {
  58.     const filter = this.state.filters[name] || {};
  59.     filter[event.target.name] = event.target.value || null;
  60.     this.setState({ filters: { ...this.state.filters, [name]: filter } });
  61.   };
  62.  
  63.   fetchCityAreas = async (name = 'city', cityCandidate: string): Promise<void> => {
  64.     if (this.state.filters.city !== cityCandidate) {
  65.       const city = cityCandidate;
  66.       const response = await fetch(`${this.fetchURL}/${city}`);
  67.       const areas = await response.json();
  68.       const area = [];
  69.       const filters = { ...this.state.filters, city, area };
  70.  
  71.       this.setState({ areas, filters });
  72.     } else if (!this.state.preselectedCity) {
  73.       const [area, areas] = Array(2).fill([]);
  74.       // Remove city from filters
  75.       const { city, ...newFilters } = this.state.filters;
  76.       const filters = { ...newFilters, area };
  77.       this.setState({ areas, filters });
  78.     }
  79.   };
  80.  
  81.   render({ cities, types }, { filters, areas, preselectedArea }) {
  82.     return (
  83.       <div className="c-realestate-filters u-mam">
  84.         <form className="c-realestate-filters__form" onSubmit={this.filterProperties}>
  85.           <Dropdown
  86.             options={cities}
  87.             name="city"
  88.             label="Sted/By"
  89.             option={filters.city || null}
  90.             onInput={this.fetchCityAreas}
  91.           />
  92.           <Dropdown
  93.             options={(preselectedArea && []) || areas}
  94.             name="area"
  95.             label="Område"
  96.             option={(preselectedArea && filters.area[0]) || null}
  97.             multiselect
  98.             onInput={this.handleChange}
  99.           />
  100.           <Dropdown
  101.             options={types}
  102.             name="type"
  103.             label="Type"
  104.             multiselect
  105.             onInput={this.handleChange}
  106.           />
  107.  
  108.           <Dropdown name="size" label="Størrelse" value={filters.size}>
  109.             <RangeValues
  110.               handleChange={this.handleRangeChange('size')}
  111.               unit="sqaure-meter"
  112.               value={filters.size}
  113.             />
  114.           </Dropdown>
  115.  
  116.           <Dropdown name="price" label="Pris" value={filters.price}>
  117.             <RangeValues
  118.               handleChange={this.handleRangeChange('price')}
  119.               unit="kr"
  120.               value={filters.price}
  121.             />
  122.           </Dropdown>
  123.           <button className="c-realestate-filters__submit-btn" type="submit">
  124.             Søk
  125.           </button>
  126.         </form>
  127.       </div>
  128.     );
  129.   }
  130. }
  131.  
  132. function RangeValues({ handleChange, unit, value }) {
  133.   const unitValue = unit === 'sqaure-meter' ? <MeasurementUnit name={unit} /> : unit;
  134.   return (
  135.     <div className="c-realestate-filters__range">
  136.       <div className="c-realestate-filters__range__item">
  137.         <label>Fra {unitValue}</label>
  138.         <NumberInput handleChange={handleChange} name="min" value={value && value.min} />
  139.       </div>
  140.       <div className="c-realestate-filters__range__item">
  141.         <label>Til {unitValue}</label>
  142.         <NumberInput handleChange={handleChange} name="max" value={value && value.max} />
  143.       </div>
  144.     </div>
  145.   );
  146. }
  147.  
  148. function NumberInput({ handleChange, value, name }) {
  149.   return (
  150.     <input
  151.       type="number"
  152.       onKeyUp={handleChange}
  153.       onMouseUp={handleChange}
  154.       value={value}
  155.       name={name}
  156.     />
  157.   );
  158. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top