Skip to content

Commit ec4e7d8

Browse files
committed
change detail profile page to unified detail page module
1 parent 46fa2e7 commit ec4e7d8

8 files changed

Lines changed: 189 additions & 475 deletions

File tree

projects/social_platform/src/app/office/features/detail/detail.component.html

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,23 @@
2020
alt="cover"
2121
/>
2222
<div class="info__avatar" [class.info__avatar--program]="listType === 'program'">
23+
@if (chatService.userOnlineStatusCache | async; as cache) {
2324
<app-avatar
24-
[url]="info.imageAddress"
25+
[url]="listType === 'profile' ? info.avatar : info.imageAddress"
2526
[hasBorder]="true"
2627
[borderColor]="listType === 'project' ? 'white' : 'dark-grey'"
27-
[size]="listType === 'project' ? 110 : 123"
28+
[progress]="info.progress"
29+
[onlineBadgeSize]="15"
30+
[onlineBadgeBorder]="0"
31+
[onlineBadgeOffset]="8"
32+
[size]="listType === 'project' || listType === 'profile' ? 110 : 123"
33+
[isOnline]="cache[info.id] !== undefined ? cache[info.id] : info.isOnline"
2834
></app-avatar>
29-
@if (listType === 'project') {
30-
<h1 class="info__title text-body-12">{{ info.name }}</h1>
31-
}
35+
@if (listType === 'project' || listType === 'profile') {
36+
<h1 class="info__title text-body-12">
37+
{{ listType === "project" ? info.name : info.firstName + " " + info.lastName }}
38+
</h1>
39+
} }
3240
</div>
3341
</div>
3442

@@ -334,6 +342,111 @@ <h3>Выход из проекта</h3>
334342
}
335343
</ng-template>
336344

345+
<ng-template #profileTpl>
346+
@if (profile) { @if (profile.id !== info.id) {
347+
<a
348+
class="info__send-message"
349+
[routerLink]="['/office/chats', profile.id + '_' + info.id]"
350+
>
351+
<app-button size="medium" customTypographyClass="text-body-12"> Написать </app-button>
352+
</a>
353+
} @else {
354+
<div class="profile__btns">
355+
<a class="profile__cv">
356+
@if(isSubscriptionActive()){
357+
<app-button
358+
(click)="sendCVEmail()"
359+
customTypographyClass="text-body-12"
360+
color="primary"
361+
>
362+
Скачать CV
363+
</app-button>
364+
}
365+
</a>
366+
367+
<a
368+
class="profile__edit"
369+
routerLink="/office/profile/edit"
370+
[queryParams]="{ editingStep: 'main' }"
371+
>
372+
<app-button size="medium" customTypographyClass="text-body-12">
373+
{{
374+
info.progress! === 100 ? "Редактировать профиль" : "Закончить заполнение резюме"
375+
}}
376+
@if (info.progress !== 100) {
377+
<i
378+
appIcon
379+
icon="accent-error"
380+
appSquare="16"
381+
(mouseenter)="showTooltip()"
382+
(mouseleave)="hideTooltip()"
383+
style="color: var(--accent); margin-left: 5px"
384+
></i>
385+
<span
386+
class="profile__tooltip text-body-12"
387+
[class.profile__tooltip--visible]="isTooltipVisible"
388+
>{{ tooltipText }}</span
389+
>
390+
}
391+
</app-button>
392+
</a>
393+
</div>
394+
} } @if (profile) { @if (profile.id === info.id) {
395+
<app-modal [open]="isProfileFill" (openChange)="isProfileFill = !isProfileFill">
396+
<div class="cancel">
397+
<img
398+
alt="profile unfill image"
399+
class="cancel__image"
400+
src="/assets/images/profile/profile-unfill.png"
401+
/>
402+
<div class="cancel__top">
403+
<i (click)="isProfileFill = false" appIcon icon="cross" class="cancel__cross"></i>
404+
<p class="cancel__title text-body-12">
405+
Заполни все поля, чтобы использовать Procollab на максимум
406+
</p>
407+
</div>
408+
<p class="text-body-12 cancel__text">Заполни все поля, чтобы иметь сильное резюме</p>
409+
410+
<a routerLink="/office/profile/edit" [queryParams]="{ editingStep: 'main' }">
411+
<app-button size="big" customTypographyClass="text-body-12"
412+
>Продолжить заполнение</app-button
413+
>
414+
</a>
415+
</div>
416+
</app-modal>
417+
} }
418+
419+
<app-modal [open]="isDelayModalOpen" (openChange)="isDelayModalOpen = !isDelayModalOpen">
420+
<div class="cancel">
421+
<div class="cancel__top">
422+
<i
423+
(click)="isDelayModalOpen = false"
424+
appIcon
425+
icon="cross"
426+
class="cancel__cross"
427+
></i>
428+
<p class="cancel__title text-bold-body-16">Повторите загрузку позже</p>
429+
</div>
430+
<p class="text-body-14 cancel__text">
431+
Скачивание будет доступно через {{ errorMessageModal() }} секунд.
432+
</p>
433+
</div>
434+
</app-modal>
435+
436+
<app-modal [open]="isSended" (openChange)="isSended = !isSended">
437+
<div class="cancel">
438+
<div class="cancel__top">
439+
<i (click)="isSended = false" appIcon icon="cross" class="cancel__cross"></i>
440+
<p class="cancel__title text-bold-body-16">Твое CV уже ждет тебя на почте :)</p>
441+
</div>
442+
<p class="text-body-14 cancel__text">
443+
Кстати, оно часто залетает в папку «Спам» — обязательно проверь и там тоже.<br />
444+
Технические сложности? Мы всегда на связи в Telegram — {{ "@procollab_support" }}
445+
</p>
446+
</div>
447+
</app-modal>
448+
</ng-template>
449+
337450
<router-outlet></router-outlet>
338451
</div>
339452
</div>

projects/social_platform/src/app/office/features/detail/detail.component.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import { ProjectAssign } from "@office/projects/models/project-assign.model";
1919
import { ProjectAdditionalService } from "@office/projects/edit/services/project-additional.service";
2020
import { ProjectDataService } from "@office/projects/detail/services/project-data.service";
2121
import { ProgramDataService } from "@office/program/services/program-data.service";
22+
import { ChatService } from "@office/services/chat.service";
23+
import { calculateProfileProgress } from "@utils/calculateProgress";
24+
import { ProfileDataService } from "@office/profile/detail/services/profile-date.service";
25+
import { ProfileService } from "projects/skills/src/app/profile/services/profile.service";
2226

2327
@Component({
2428
selector: "app-detail",
@@ -46,19 +50,26 @@ export class DeatilComponent implements OnInit, OnDestroy {
4650
private readonly projectAdditionalService = inject(ProjectAdditionalService);
4751
private readonly router = inject(Router);
4852
private readonly location = inject(Location);
53+
private readonly profileDataService = inject(ProfileDataService);
54+
public readonly skillsProfileService = inject(ProfileService);
55+
public readonly chatService = inject(ChatService);
4956

5057
// Основные данные(типы данных, данные)
5158
info?: any;
59+
loggedUserId?: number;
5260
profile?: User;
5361
listType: "project" | "program" | "profile" = "project";
5462

5563
// Переменная для подсказок
5664
isTooltipVisible = false;
5765

66+
tooltipText = "Заполни до конца — и открой весь функционал платформы!";
67+
5868
// Переменные для отображения данных в зависимости от url
5969
isProjectsPage = false;
6070
isMembersPage = false;
6171
isProjectsRatingPage = false;
72+
6273
isTeamPage = false;
6374
isVacanciesPage = false;
6475

@@ -67,13 +78,18 @@ export class DeatilComponent implements OnInit, OnDestroy {
6778
registerDateExpired?: boolean;
6879
isInProject?: boolean;
6980

81+
isSended = false;
82+
isSubscriptionActive = signal(false);
83+
isProfileFill = false;
84+
7085
// Переменные для работы с модалкой подачи проекта
7186
selectedProjectId = 0;
7287
dubplicatedProjectId = 0;
7388
memberProjects: Project[] = [];
7489

7590
// Сигналы для работы с модальными окнами с текстом
7691
assignProjectToProgramModalMessage = signal<ProjectAssign | null>(null);
92+
errorMessageModal = signal("");
7793

7894
// Переменные для работы с модалками
7995
isAssignProjectToProgramModalOpen = signal(false);
@@ -83,6 +99,7 @@ export class DeatilComponent implements OnInit, OnDestroy {
8399
isEditDisableModal = false; // Флаг недоступности редактирования для модалки
84100
openSupport = false; // Флаг модального окна поддержки
85101
leaderLeaveModal = false; // Флаг модального окна предупреждения лидера
102+
isDelayModalOpen = false;
86103

87104
subscriptions: Subscription[] = [];
88105

@@ -256,6 +273,24 @@ export class DeatilComponent implements OnInit, OnDestroy {
256273
);
257274
}
258275

276+
/**
277+
* Отправка CV пользователя на email
278+
* Проверяет ограничения по времени и отправляет CV на почту пользователя
279+
*/
280+
sendCVEmail() {
281+
this.authService.sendCV().subscribe({
282+
next: () => {
283+
this.isSended = true;
284+
},
285+
error: err => {
286+
if (err.status === 400) {
287+
this.isDelayModalOpen = true;
288+
this.errorMessageModal.set(err.error.seconds_after_retry);
289+
}
290+
},
291+
});
292+
}
293+
259294
/**
260295
* Обновляет состояния страниц на основе URL
261296
*/
@@ -266,6 +301,8 @@ export class DeatilComponent implements OnInit, OnDestroy {
266301
currentUrl.includes("/projects") && !currentUrl.includes("/projects-rating");
267302
this.isMembersPage = currentUrl.includes("/members");
268303
this.isProjectsRatingPage = currentUrl.includes("/projects-rating");
304+
this.isTeamPage = currentUrl.includes("/team");
305+
this.isVacanciesPage = currentUrl.includes("/vacancies");
269306
}
270307

271308
private initializeInfo() {
@@ -304,6 +341,36 @@ export class DeatilComponent implements OnInit, OnDestroy {
304341

305342
this.subscriptions.push(program$);
306343
this.subscriptions.push(memeberProjects$);
344+
} else {
345+
const profileDataSub$ = this.profileDataService
346+
.getProfile()
347+
.pipe(
348+
map(user => ({ ...user, progress: calculateProfileProgress(user!) })),
349+
filter(user => !!user)
350+
)
351+
.subscribe({
352+
next: user => {
353+
this.info = user as User;
354+
this.isProfileFill =
355+
user.progress! < 100 ? (this.isProfileFill = true) : (this.isProfileFill = false);
356+
},
357+
});
358+
359+
const profileIdDataSub$ = this.profileDataService
360+
.getProfileId()
361+
.pipe(filter(userId => !!userId))
362+
.subscribe({
363+
next: profileId => {
364+
this.loggedUserId = profileId;
365+
},
366+
});
367+
368+
this.skillsProfileService.getSubscriptionData().subscribe(r => {
369+
this.isSubscriptionActive.set(r.isSubscribed);
370+
});
371+
372+
profileDataSub$ && this.subscriptions.push(profileDataSub$);
373+
profileIdDataSub$ && this.subscriptions.push(profileIdDataSub$);
307374
}
308375
}
309376

@@ -316,7 +383,7 @@ export class DeatilComponent implements OnInit, OnDestroy {
316383
} else if (this.listType === "program") {
317384
this.backPath = "/office/program/all";
318385
} else {
319-
this.backPath = "/office/members/all";
386+
this.backPath = "/office/members";
320387
}
321388
}
322389
}

0 commit comments

Comments
 (0)