Skip to content

Commit 17d6055

Browse files
committed
fix invites service, add filter in programs all page & fix programs service, & add phone_number mask in profile edit
1 parent b52d882 commit 17d6055

6 files changed

Lines changed: 99 additions & 42 deletions

File tree

projects/social_platform/src/app/office/profile/edit/edit.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ <h1 class="profile__title">редактирование профиля</h1>
323323
<app-input
324324
size="big"
325325
id="phoneNumber"
326+
mask="0-000-000-00-00"
326327
[error]="phoneNumber | controlError"
327328
type="text"
328329
placeholder="+79030195823"

projects/social_platform/src/app/office/profile/edit/edit.component.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ export class ProfileEditComponent implements OnInit, OnDestroy, AfterViewInit {
120120
this.profileForm = this.fb.group({
121121
firstName: ["", [Validators.required]],
122122
lastName: ["", [Validators.required]],
123-
email: ["", [Validators.email, Validators.max(50)]],
123+
email: ["", [Validators.email, Validators.maxLength(50)]],
124124
userType: [0],
125125
birthday: ["", [Validators.required]],
126-
city: ["", Validators.max(100)],
127-
phoneNumber: [""],
126+
city: ["", [Validators.required, Validators.maxLength(100)]],
127+
phoneNumber: ["", Validators.maxLength(12)],
128128
additionalRole: [null],
129129
coverImageAddress: [null],
130130

@@ -1037,6 +1037,9 @@ export class ProfileEditComponent implements OnInit, OnDestroy, AfterViewInit {
10371037
* Валидирует всю форму и отправляет данные на сервер
10381038
*/
10391039
saveProfile(): void {
1040+
this.profileForm.markAllAsTouched();
1041+
this.profileForm.updateValueAndValidity();
1042+
10401043
const tempFields = [
10411044
"organizationName",
10421045
"entryYear",
@@ -1055,6 +1058,7 @@ export class ProfileEditComponent implements OnInit, OnDestroy, AfterViewInit {
10551058
"status",
10561059
"year",
10571060
"files",
1061+
"phoneNumber",
10581062
];
10591063

10601064
tempFields.forEach(name => {
@@ -1065,7 +1069,7 @@ export class ProfileEditComponent implements OnInit, OnDestroy, AfterViewInit {
10651069
}
10661070
});
10671071

1068-
const mainFieldsValid = ["firstName", "lastName", "birthday", "speciality"].every(
1072+
const mainFieldsValid = ["firstName", "lastName", "birthday", "speciality", "city"].every(
10691073
name => this.profileForm.get(name)?.valid
10701074
);
10711075

projects/social_platform/src/app/office/program/main/main.component.ts

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
/** @format */
22

3-
import { Component, OnDestroy, OnInit, signal } from "@angular/core";
4-
import { ActivatedRoute, RouterLink } from "@angular/router";
5-
import { map, Subscription } from "rxjs";
3+
import { ChangeDetectorRef, Component, inject, OnDestroy, OnInit, signal } from "@angular/core";
4+
import { ActivatedRoute, Params, Router, RouterLink } from "@angular/router";
5+
import {
6+
combineLatest,
7+
concatMap,
8+
distinctUntilChanged,
9+
map,
10+
of,
11+
Subscription,
12+
switchMap,
13+
} from "rxjs";
614
import { Program } from "@office/program/models/program.model";
715
import { NavService } from "@office/services/nav.service";
816
import Fuse from "fuse.js";
917
import { CheckboxComponent, SelectComponent } from "@ui/components";
1018
import { generateOptionsList } from "@utils/generate-options-list";
1119
import { ClickOutsideModule } from "ng-click-outside";
1220
import { ProgramCardComponent } from "../shared/program-card/program-card.component";
21+
import { HttpParams } from "@angular/common/http";
22+
import { ProgramService } from "../services/program.service";
1323

1424
/**
1525
* Главный компонент списка программ
@@ -59,13 +69,18 @@ import { ProgramCardComponent } from "../shared/program-card/program-card.compon
5969
],
6070
})
6171
export class ProgramMainComponent implements OnInit, OnDestroy {
62-
constructor(private readonly route: ActivatedRoute, private readonly navService: NavService) {}
72+
private readonly navService = inject(NavService);
73+
private readonly route = inject(ActivatedRoute);
74+
private readonly router = inject(Router);
75+
private readonly programService = inject(ProgramService);
76+
private readonly cdref = inject(ChangeDetectorRef);
6377

6478
programCount = 0;
6579

6680
programs: Program[] = [];
6781
searchedPrograms: Program[] = [];
6882
subscriptions$: Subscription[] = [];
83+
isPparticipating = signal<boolean>(false);
6984

7085
readonly programOptionsFilter = generateOptionsList(4, "strings", [
7186
"все",
@@ -77,32 +92,65 @@ export class ProgramMainComponent implements OnInit, OnDestroy {
7792
ngOnInit(): void {
7893
this.navService.setNavTitle("Программы");
7994

80-
const querySearch$ = this.route.queryParams.pipe(map(q => q["search"])).subscribe(search => {
81-
const fuse = new Fuse(this.programs, {
82-
keys: ["name"],
83-
});
95+
const combined$ = combineLatest([
96+
this.route.queryParams.pipe(
97+
map(q => ({ filter: this.buildFilterQuery(q), search: q["search"] || "" })),
98+
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
99+
),
100+
])
101+
.pipe(
102+
switchMap(([{ filter, search }]) => {
103+
this.isPparticipating.set(filter["participating"] === "true");
84104

85-
this.searchedPrograms = search ? fuse.search(search).map(el => el.item) : this.programs;
86-
});
105+
return this.programService
106+
.getAll(0, 20, new HttpParams({ fromObject: filter }))
107+
.pipe(map(response => ({ response, search })));
108+
})
109+
)
110+
.subscribe(({ response, search }) => {
111+
this.programCount = response.count;
112+
this.programs = response.results ?? [];
87113

88-
querySearch$ && this.subscriptions$.push(querySearch$);
114+
if (search) {
115+
const fuse = new Fuse(this.programs, {
116+
keys: ["name"],
117+
threshold: 0.3,
118+
});
119+
this.searchedPrograms = fuse.search(search).map(el => el.item);
120+
} else {
121+
this.searchedPrograms = this.programs;
122+
}
89123

90-
const programs$ = this.route.data.pipe(map(r => r["data"])).subscribe(programs => {
91-
this.programCount = programs.count;
92-
this.programs = programs.results ?? [];
93-
this.searchedPrograms = programs.results ?? [];
94-
});
124+
this.cdref.detectChanges();
125+
});
95126

96-
programs$ && this.subscriptions$.push(programs$);
127+
this.subscriptions$.push(combined$);
97128
}
98129

99-
isPparticipating = signal<boolean>(false);
130+
private buildFilterQuery(q: Params): Record<string, any> {
131+
const reqQuery: Record<string, any> = {};
132+
133+
if (q["participating"]) {
134+
reqQuery["participating"] = q["participating"];
135+
}
136+
137+
return reqQuery;
138+
}
100139

101140
/**
102-
* Переключает состояние чекбокса
141+
* Переключает состояние чекбокса "участвую"
103142
*/
104143
onTogglePparticipating(): void {
105-
this.isPparticipating.set(!this.isPparticipating());
144+
const newValue = !this.isPparticipating();
145+
this.isPparticipating.set(newValue);
146+
147+
this.router.navigate([], {
148+
queryParams: {
149+
participating: newValue ? "true" : null,
150+
},
151+
relativeTo: this.route,
152+
queryParamsHandling: "merge",
153+
});
106154
}
107155

108156
ngOnDestroy(): void {

projects/social_platform/src/app/office/program/services/program.service.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import { Injectable } from "@angular/core";
44
import { ApiService } from "projects/core";
5-
import { BehaviorSubject, map, Observable, tap } from "rxjs";
5+
import { map, Observable } from "rxjs";
66
import { HttpParams } from "@angular/common/http";
77
import { ProgramCreate } from "@office/program/models/program-create.model";
8-
import { Program, ProgramDataSchema, ProgramTag } from "@office/program/models/program.model";
8+
import { Program, ProgramDataSchema } from "@office/program/models/program.model";
99
import { Project } from "@models/project.model";
1010
import { ApiPagination } from "@models/api-pagination.model";
1111
import { User } from "@auth/models/user.model";
@@ -49,11 +49,22 @@ export class ProgramService {
4949

5050
constructor(private readonly apiService: ApiService) {}
5151

52-
getAll(skip: number, take: number): Observable<ApiPagination<Program>> {
53-
return this.apiService.get(
54-
`${this.PROGRAMS_URL}/`,
55-
new HttpParams({ fromObject: { limit: take, offset: skip } })
56-
);
52+
getAll(skip: number, take: number, params?: HttpParams): Observable<ApiPagination<Program>> {
53+
let httpParams = new HttpParams();
54+
55+
httpParams.set("limit", take);
56+
httpParams.set("offset", skip);
57+
58+
if (params) {
59+
params.keys().forEach(key => {
60+
const value = params.get(key);
61+
if (value !== null) {
62+
httpParams = httpParams.set(key, value);
63+
}
64+
});
65+
}
66+
67+
return this.apiService.get(`${this.PROGRAMS_URL}/`, httpParams);
5768
}
5869

5970
getOne(programId: number): Observable<Program> {

projects/social_platform/src/app/office/services/invite.service.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,9 @@ export class InviteService {
9999
* @returns Observable<Invite[]> - массив приглашений, адресованных текущему пользователю
100100
*/
101101
getMy(): Observable<Invite[]> {
102-
return this.authService.profile.pipe(
103-
take(1),
104-
concatMap(profile =>
105-
this.apiService.get<Invite[]>(
106-
`${this.INVITES_URL}/`,
107-
new HttpParams({ fromObject: { user_id: profile.id } })
108-
)
109-
),
110-
map(invites => plainToInstance(Invite, invites))
111-
);
102+
return this.apiService
103+
.get<Invite[]>(`${this.INVITES_URL}/`)
104+
.pipe(map(invites => plainToInstance(Invite, invites)));
112105
}
113106

114107
/**

projects/social_platform/src/app/ui/components/input/input.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
}
4848

4949
&--error {
50-
border-color: var(--red);
50+
border: 0.5px solid var(--red);
5151
}
5252

5353
@include typography.body-10;

0 commit comments

Comments
 (0)