Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Price filter #709

Merged
merged 6 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { SetWithDisabilityOption } from './../../store/filter.actions';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Store, Select } from '@ngxs/store';
import { Subject} from 'rxjs';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, skip, takeUntil } from 'rxjs/operators';
import { FilterChange, FilterClear, SetClosedRecruitment, SetOpenRecruitment } from '../../store/filter.actions';
import { FilterState } from '../../store/filter.state';
Expand All @@ -16,20 +16,19 @@ export class FiltersListComponent implements OnInit, OnDestroy {
@Select(FilterState.filterList)
@Input()
set filtersList(filters) {
const {withDisabilityOption,ageFilter,categoryCheckBox,priceFilter,workingHours} = filters
const { withDisabilityOption, ageFilter, categoryCheckBox, priceFilter, workingHours } = filters;
this.priceFilter = priceFilter;
this.workingHours = workingHours;
this.categoryCheckBox = categoryCheckBox;
this.ageFilter = ageFilter;
this.WithDisabilityOptionControl.setValue(withDisabilityOption,{emitEvent:false})
this.WithDisabilityOptionControl.setValue(withDisabilityOption, { emitEvent: false });
};

public priceFilter;
public workingHours;
public categoryCheckBox;
public ageFilter;


OpenRecruitmentControl = new FormControl(false);
ClosedRecruitmentControl = new FormControl(false);
WithDisabilityOptionControl = new FormControl(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
<p class="filter-text title">Вартість</p>
<div class="wrapper" fxLayout='column' fxLayoutAlign='center space-between'>
<mat-checkbox color="primary" [formControl]="isFreeControl"> Безкоштовно</mat-checkbox>
<div class="input-wrapper" fxLayout='row' fxLayoutAlign='start' fxLayoutGap='1rem'>
<div class="wrapper" fxLayout="column" fxLayoutAlign="center space-between">
<mat-checkbox color="primary" [formControl]="isFreeControl"> Безкоштовно </mat-checkbox>
<mat-checkbox color="primary" [formControl]="isPaidControl"> Платні </mat-checkbox>

<div class="input-wrapper" [ngClass]="{'input-wrapper-disable': !isPaidControl.value}" fxLayout="row"
fxLayoutAlign="start" fxLayoutGap="1rem">
<mat-form-field>
<div fxLayout='row' fxLayoutAlign='start center'>
<div fxLayout="row" fxLayoutAlign="start center">
<p class="filter-text">Від</p>
<input matInput class="price-input" type="number" appDigitOnly maxlength="4" [min]="constants.MIN_PRICE"
[max]="constants.MAX_PRICE" [directiveFormControl]="minPriceControl" [formControl]="minPriceControl"
appMinMax>
</div>
</mat-form-field>
<mat-form-field>
<div fxLayout='row' fxLayoutAlign='start center'>
<div fxLayout="row" fxLayoutAlign="start center">
<p class="filter-text">До</p>
<input matInput class="price-input" type="number" appDigitOnly maxlength="4" [min]="constants.MIN_PRICE"
[max]="constants.MAX_PRICE" [directiveFormControl]="maxPriceControl" [formControl]="maxPriceControl"
appMinMax>
</div>
</mat-form-field>
</div>
<div class="filter-slider" fxLayout='column' fxLayoutAlign='space-between' fxLayoutGap='1rem'>
<ngx-slider (userChange)="priceHandler($event)"
[value]="minValue" [highValue]="maxValue" [options]="options">
<div class="filter-slider" [ngClass]="{'input-wrapper-disable': !isPaidControl.value}" fxLayout="column"
fxLayoutAlign="space-between" fxLayoutGap="1rem">
<ngx-slider (userChange)="priceHandler($event)" [value]="minValue" [highValue]="maxValue" [options]="options">
</ngx-slider>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
.input-wrapper{
margin-top: 13px;
margin-bottom: 0 !important;
&-disable{
opacity: 0.5;
cursor: initial;
color:#FFFFFF;
}
}
::ng-deep .mat-form-field-underline {
display: none;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { element } from 'protractor';
import { Options } from '@angular-slider/ngx-slider';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators, } from '@angular/forms';
import { Select, Store } from '@ngxs/store';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, skip, takeUntil } from 'rxjs/operators';
import { FormControl, Validators, } from '@angular/forms';
import { Store } from '@ngxs/store';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
import { Constants } from 'src/app/shared/constants/constants';
import { SetIsFree, SetMaxPrice, SetMinPrice } from 'src/app/shared/store/filter.actions';
import { SetIsFree, SetIsPaid, SetMaxPrice, SetMinPrice } from 'src/app/shared/store/filter.actions';

@Component({
selector: 'app-price-filter',
Expand All @@ -17,21 +16,25 @@ export class PriceFilterComponent implements OnInit, OnDestroy {

@Input()
set priceFilter(filter) {
const {minPrice,maxPrice,isFree} = filter;
this.minPriceControl.setValue(minPrice,{emitEvent: false});
const { minPrice, maxPrice, isFree, isPaid } = filter;
this.minPriceControl.setValue(minPrice, { emitEvent: false });
this.minValue = minPrice;
this.maxPriceControl.setValue(maxPrice,{emitEvent: false});
this.maxPriceControl.setValue(maxPrice, { emitEvent: false });
this.maxValue = maxPrice;
this.isFreeControl.setValue(isFree,{emitEvent: false});
this.isFreeControl.setValue(isFree, { emitEvent: false });
this.isPaidControl.setValue(isPaid, { emitEvent: false });
};

readonly constants: typeof Constants = Constants;

isFreeControl = new FormControl(false);
maxPriceControl = new FormControl(0, [Validators.maxLength(4)]);
minPriceControl = new FormControl(0, [Validators.maxLength(4)]);
minValue = 0;
maxValue = 0;
isPaidControl = new FormControl(false);

minPriceControl = new FormControl(Constants.MIN_PRICE, [Validators.maxLength(4)]);
maxPriceControl = new FormControl(Constants.MAX_PRICE, [Validators.maxLength(4)]);

minValue = Constants.MIN_PRICE;
maxValue = Constants.MAX_PRICE;
options: Options = {
floor: Constants.MIN_PRICE,
ceil: Constants.MAX_PRICE,
Expand All @@ -45,15 +48,27 @@ export class PriceFilterComponent implements OnInit, OnDestroy {
*/
ngOnInit(): void {

this.isFreeControl.valueChanges.subscribe((val: boolean) => this.store.dispatch(new SetIsFree(val)));
this.isFreeControl.valueChanges
.pipe(
takeUntil(this.destroy$),
debounceTime(300),
distinctUntilChanged(),
).subscribe((val: boolean) => this.store.dispatch(new SetIsFree(val)));

this.isPaidControl.valueChanges
.pipe(
takeUntil(this.destroy$),
debounceTime(300),
distinctUntilChanged(),
).subscribe((val: boolean) => this.store.dispatch(new SetIsPaid(val)));

this.minPriceControl.valueChanges
.pipe(
takeUntil(this.destroy$),
debounceTime(300),
distinctUntilChanged(),
).subscribe((val: number) => {
!val && this.isFreeControl.setValue(!!val);
!this.isPaidControl.value && this.isPaidControl.setValue(true);
this.store.dispatch(new SetMinPrice(val));
});

Expand All @@ -63,14 +78,12 @@ export class PriceFilterComponent implements OnInit, OnDestroy {
debounceTime(300),
distinctUntilChanged()
).subscribe((val: number) => {

!this.isPaidControl.value && this.isPaidControl.setValue(true);
this.store.dispatch(new SetMaxPrice(val));
});

}



priceHandler(e) {
e.pointerType && this.maxPriceControl.setValue(e.highValue);
!e.pointerType && this.minPriceControl.setValue(e.value);
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class Constants {
static readonly CLASS_AMOUNT_MAX = 7;
static readonly AGE_MIN = 0;
static readonly AGE_MAX = 18;
static readonly MIN_PRICE = 0;
static readonly MIN_PRICE = 1;
static readonly MAX_PRICE = 10000;
static readonly MIN_TIME = '00:00';
static readonly MAX_TIME = '23:59';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ export class AppWorkshopsService {
params = params.set('Longitude', filters.city.longitude.toString());
}

if (filters.maxPrice) {
params = params.set('MaxPrice', filters.maxPrice.toString());
if (filters.isFree) {
params = params.set('IsFree', 'true');
}

if (filters.minPrice) {
params = params.set('MinPrice', filters.minPrice.toString());
if (filters.isPaid) {
params = this.setIsPaid(filters, params);
}

if ((filters.isFree && filters.isPaid) || (!filters.isFree && !filters.isPaid)) {
params = params.set('IsFree', 'true');
params = this.setIsPaid(filters, params);
}

if (filters.searchQuery) {
Expand All @@ -58,7 +63,7 @@ export class AppWorkshopsService {
filters.workingDays.forEach((day: string) => params = params.append('Workdays', day));
}

if (filters.isFree || !filters.minAge) {
if (filters.isFree || !filters.minPrice) {
params = params.set('IsFree', 'true');
}

Expand Down Expand Up @@ -89,6 +94,20 @@ export class AppWorkshopsService {
return params;
}

/**
* This method applied min and max price filter options
*/
private setIsPaid(filters: FilterStateModel, params: HttpParams): HttpParams {
if (filters.maxPrice) {
params = params.set('MaxPrice', filters.maxPrice.toString());
}

if (filters.minPrice) {
params = params.set('MinPrice', filters.minPrice.toString());
}
return params;
}

/**
* This method get workshops with applied filter options
*/
Expand Down
5 changes: 5 additions & 0 deletions src/app/shared/store/filter.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export class SetIsFree {
static readonly type = '[filter] Set Is Free type of payment';
constructor(public payload: boolean) { }
}

export class SetIsPaid {
static readonly type = '[filter] Set Is Paid type of payment';
constructor(public payload: boolean) { }
}
export class SetMinPrice {
static readonly type = '[filter] Set Min Price';
constructor(public payload: number) { }
Expand Down
34 changes: 23 additions & 11 deletions src/app/shared/store/filter.state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { State, Action, StateContext, Selector } from '@ngxs/store';
import { tap } from 'rxjs/operators';
import { Constants } from '../constants/constants';
import { Direction } from '../models/category.model';
import { City } from '../models/city.model';
import { PaginationElement } from '../models/paginationElement.model';
Expand Down Expand Up @@ -29,7 +30,8 @@ import {
ConfirmCity,
CleanCity,
FilterClear,
SetFirstPage
SetFirstPage,
SetIsPaid
} from './filter.actions';

export interface FilterStateModel {
Expand All @@ -40,6 +42,7 @@ export interface FilterStateModel {
startTime: string;
endTime: string;
isFree: boolean;
isPaid: boolean;
maxPrice: number;
minPrice: number;
isOpenRecruitment: boolean;
Expand All @@ -64,8 +67,9 @@ export interface FilterStateModel {
endTime: null,
workingDays: [],
isFree: false,
maxPrice: 0,
minPrice: 0,
isPaid: false,
maxPrice: Constants.MAX_PRICE,
minPrice: Constants.MIN_PRICE,
isOpenRecruitment: false,
isClosedRecruitment: false,
city: undefined,
Expand Down Expand Up @@ -117,15 +121,16 @@ export class FilterState {

@Selector()
static filterList(state: FilterStateModel): any {
const {withDisabilityOption,minAge,maxAge,directions,minPrice,maxPrice,isFree,workingDays,startTime,endTime,currentPage,order} = state
const { withDisabilityOption, minAge, maxAge, directions, minPrice, maxPrice, isFree, isPaid, workingDays, startTime, endTime, currentPage, order } = state
return {
withDisabilityOption,
categoryCheckBox: directions,
ageFilter: {minAge,maxAge},
ageFilter: { minAge, maxAge },
priceFilter: {
minPrice,
maxPrice,
isFree
isFree,
isPaid
},
workingHours: {
workingDays,
Expand Down Expand Up @@ -194,6 +199,11 @@ export class FilterState {
patchState({ isFree: payload });
dispatch(new FilterChange());
}
@Action(SetIsPaid)
setIsPaid({ patchState, dispatch }: StateContext<FilterStateModel>, { payload }: SetIsPaid) {
patchState({ isPaid: payload });
dispatch(new FilterChange());
}

@Action(SetMinPrice)
setMinPrice({ patchState, dispatch }: StateContext<FilterStateModel>, { payload }: SetMinPrice) {
Expand Down Expand Up @@ -273,14 +283,14 @@ export class FilterState {

@Action(SetFirstPage)
setFirstPage({ patchState }: StateContext<FilterStateModel>) {
patchState({ currentPage: {element: 1,isActive: true} });
patchState({ currentPage: { element: 1, isActive: true } });
}

@Action(FilterChange)
filterChange({ }: StateContext<FilterStateModel>, { }: FilterChange) { }

@Action(FilterClear)
FilterClear({ patchState }: StateContext<FilterStateModel>, { }: FilterChange) {
FilterClear({ patchState }: StateContext<FilterStateModel>, { }: FilterChange) {
patchState({
directions: [],
maxAge: null,
Expand All @@ -289,8 +299,9 @@ export class FilterState {
endTime: null,
workingDays: [],
isFree: false,
maxPrice: 0,
minPrice: 0,
isPaid: false,
maxPrice: Constants.MAX_PRICE,
minPrice: Constants.MIN_PRICE,
isOpenRecruitment: false,
isClosedRecruitment: false,
searchQuery: '',
Expand All @@ -299,6 +310,7 @@ export class FilterState {
currentPage: {
element: 1,
isActive: true
}});
}
});
}
}
13 changes: 8 additions & 5 deletions src/app/shell/main/main.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,13 @@ app-footer {
visibility: visible;
position: static;
}
}

@media (max-width: 415px) {
.main_title {
.main_title, .main_link {
font-size: 16px !important;
}
}
.main-header{
padding: 0 1rem;
h3{
width: 50%;
}
}
}
Loading