make filters work (almost)

This commit is contained in:
b1ek 2023-05-11 23:11:38 +10:00
parent 395cfa0e3b
commit c91eba0a62
Signed by: blek
GPG Key ID: 14546221E3595D0C
4 changed files with 106 additions and 16 deletions

View File

@ -59,17 +59,24 @@ class ApartmentFilter(viewsets.ViewSet):
def list(self, req: Request): def list(self, req: Request):
filters = dict(req.data); filters = dict(req.data);
unfiltered = ApartamentDetailSerializer(Apartament.objects.all()[:100], many=True).data; unfiltered = Apartament.objects.all();
filtered = []; filtered = [];
# TODO: Some better converting practice?
filters['price_range']['from'] = int(filters['price_range']['from']);
filters['price_range']['to'] = int(filters['price_range']['to']);
filters['area_range']['from'] = int(filters['area_range']['from']);
filters['area_range']['to'] = int(filters['area_range']['to']);
filters['rooms'] = int(filters['rooms'])
for entry in unfiltered: for entry in unfiltered:
if (filters['price_range']['from'] >= entry['price'] and (filters['price_range']['to'] != -1 and filters['price_range']['to'] <= entry['price'])): if (filters['price_range']['from'] >= entry.price and (filters['price_range']['to'] != -1 and filters['price_range']['to'] <= entry.price)):
continue; continue;
if (filters['area_range']['from'] >= entry['perimetrs'] and (filters['area_range']['to'] != -1 and filters['area_range']['to'] <= entry['perimetrs'])): if (filters['area_range']['from'] >= entry.perimetrs and (filters['area_range']['to'] != -1 and filters['area_range']['to'] <= entry.perimetrs)):
continue; continue;
if (filters['rooms'] != -1 and entry['rooms'] != filters['rooms']): if (filters['rooms'] != -1 and entry.rooms != filters['rooms']):
continue; continue;
filtered.append(entry); filtered.append(entry);
return Response(filtered); return Response(ApartamentListSerializer(filtered, many=True).data);

View File

@ -25,7 +25,7 @@ SECRET_KEY = 'django-insecure-=(7b+4ka=5jak-mokuh4#-6_14f58#^0kjwqsz7wyon$4i@sel
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['*']
# Application definition # Application definition

View File

@ -0,0 +1,34 @@
class Range {
/** @type {number} */
from;
/** @type {number} */
to;
}
class Filters {
/** @type { Range } */
price_range;
/** @type { Range } */
area_range;
/** @type { string[] } */
lease_period;
/** @type { string } */
address;
/** @type { number } */
rooms;
constructor() {
this.price_range = new Range();
this.area_range = new Range();
this.lease_period = [];
this.address = '';
this.rooms = 0;
}
}
export { Filters, Range }

View File

@ -4,6 +4,7 @@ import { Scrollbar, Navigation } from 'swiper/core';
import ISVGIcon from '../../components/UI/Icon/SVGIcon'; import ISVGIcon from '../../components/UI/Icon/SVGIcon';
import Select from 'react-select'; import Select from 'react-select';
import ApartmentsList from "../../components/ApartmentsList"; import ApartmentsList from "../../components/ApartmentsList";
import { Filters } from "../../API/Filters";
import styled from 'styled-components'; import styled from 'styled-components';
import 'swiper/css'; import 'swiper/css';
@ -15,6 +16,9 @@ import './swiper.css';
import ApartamentService from "../../API/ApartamentService"; import ApartamentService from "../../API/ApartamentService";
import { HashLoader } from 'react-spinners'; import { HashLoader } from 'react-spinners';
import constants from "../../constants";
const API_ROOT = constants.API_ROOT;
const SVGIcon = styled(ISVGIcon)` const SVGIcon = styled(ISVGIcon)`
margin-left:0; margin-left:0;
@ -37,7 +41,7 @@ const SwiperImage = styled.div`
height: 100%; height: 100%;
`; `;
const Filters = styled.div` const FiltersEl = styled.div`
background: url(/images/filter.png); background: url(/images/filter.png);
height: 300px; height: 300px;
width: 1150px; width: 1150px;
@ -163,7 +167,7 @@ const Splash = styled.h3`
text-align: center; text-align: center;
`; `;
const FiltersForm = () => { const FiltersForm = (props) => {
const apart_sizes = [ const apart_sizes = [
{ value: 0, label: "Гостинка" }, { value: 0, label: "Гостинка" },
@ -175,7 +179,7 @@ const FiltersForm = () => {
const def_form = { const def_form = {
per_day: false, per_day: false,
per_month: false, per_month: true,
area_from: '', area_from: '',
area_to: '', area_to: '',
@ -185,7 +189,9 @@ const FiltersForm = () => {
address: '', address: '',
rooms: 0, rooms: { value: -1, label: 'Выберите' },
form_err: false
}; };
@ -195,8 +201,28 @@ const FiltersForm = () => {
return setState_({...state, ...new_state}); return setState_({...state, ...new_state});
} }
const onSumbit = () => {
let transformed = new Filters();
transformed.address = state.address;
transformed.area_range = {
from: state.area_from,
to: state.area_to
};
transformed.price_range = {
from: state.price_from,
to: state.price_to
};
if (state.per_day) transformed.lease_period.push('day');
if (state.per_month) transformed.lease_period.push('month');
if (state.rooms.value != -1) transformed.rooms = state.rooms.value;
if (props.onSubmit) props.onSubmit(transformed);
}
return ( return (
<Filters> <FiltersEl>
<FilterText>Фильтры</FilterText> <FilterText>Фильтры</FilterText>
<PeriodFilter> <PeriodFilter>
@ -280,11 +306,11 @@ const FiltersForm = () => {
</SearchBarText> </SearchBarText>
</SearchBarFilter> </SearchBarFilter>
<SubmitBtn onClick={() => console.log(state)}> <SubmitBtn onClick={onSumbit}>
<SVGIcon src='/images/icons/search.svg' width='14' height='14' /> <SVGIcon src='/images/icons/search.svg' width='14' height='14' />
Показать варианты Показать варианты
</SubmitBtn> </SubmitBtn>
</Filters> </FiltersEl>
); );
} }
@ -295,6 +321,7 @@ export default class IndexPage extends React.Component {
this.state = { this.state = {
apartments: [], apartments: [],
unfiltered: [],
pageSize: 10, pageSize: 10,
page: 0, page: 0,
data_loaded: false, data_loaded: false,
@ -302,10 +329,32 @@ export default class IndexPage extends React.Component {
}; };
ApartamentService.getAll(100).then(data => { ApartamentService.getAll(100).then(data => {
this.setState({apartments: data.data.results, data_loaded: true}); this.setState({apartments: data.data.results, unfiltered: data.data.results, data_loaded: true});
}).catch(err => { }).catch(err => {
this.setState({data_loaded: true, apartments: [], load_err: err.message}); this.setState({data_loaded: true, apartments: [], unfiltered: data.data.results, load_err: err.message});
}); });
this.filterData = this.filterData.bind(this);
}
/**
*
* @param {Filters} filters
*/
async filterData(filters) {
const filtered_raw = await fetch(API_ROOT + '/api/apartaments/filters/', {
method: 'POST',
body: JSON.stringify(filters),
headers: {
'Content-Type': 'application/json'
}
}).catch(err => console.error(err));
const filtered = await filtered_raw.json();
this.setState({apartments: filtered, data_loaded: true, load_err: false});
;
} }
render() { render() {
@ -340,7 +389,7 @@ export default class IndexPage extends React.Component {
<span style={{color: '#0066ff'}}> Владивостоке</span> <span style={{color: '#0066ff'}}> Владивостоке</span>
</Title> </Title>
<FiltersForm /> <FiltersForm onSubmit={this.filterData} />
<ApartmentsList list={current_data} /> <ApartmentsList list={current_data} />
{ {