-
{{message?.length}} / {{messageLimit}}
-
-
-
+@if (showMessageInput()) {
+
+
+
{{message()?.length}} / {{messageLimit}}
+
+
+
-
-
+ size="small"
+ (click)="sendRequest()"
+ style="width: 50px; height: 45px"
+ >
+
+
+
-
\ No newline at end of file
+}
diff --git a/src/app/pages/chat-request/chat-request.page.spec.ts b/src/app/pages/chat-request/chat-request.page.spec.ts
index d687f38e..11bce0db 100644
--- a/src/app/pages/chat-request/chat-request.page.spec.ts
+++ b/src/app/pages/chat-request/chat-request.page.spec.ts
@@ -72,7 +72,7 @@ describe('ChatRequestPage', () => {
});
it('should initialize with default values', () => {
- expect(component.message).toBe('Hi, I would like to connect with you.');
+ expect(component.message()).toBe('Hi, I would like to connect with you.');
expect(component.headerConfig).toEqual({
menu: false,
headerColor: 'primary'
@@ -81,7 +81,7 @@ describe('ChatRequestPage', () => {
});
it('should extract id from route params', () => {
- expect(component.id).toBe('123');
+ expect(component.id()).toBe('123');
});
describe('ngOnInit', () => {
@@ -108,7 +108,7 @@ describe('ChatRequestPage', () => {
fixture.whenStable().then(() => {
expect(httpService.post).toHaveBeenCalled();
- expect(component.info.status).toBe('PENDING');
+ expect(component.info().status).toBe('PENDING');
});
}));
@@ -126,7 +126,7 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.message).toBe('');
+ expect(component.message()).toBe('');
});
}));
@@ -165,7 +165,7 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.messages).toEqual(CHAT_MESSAGES.INITIATOR);
+ expect(component.messages()).toEqual(CHAT_MESSAGES.INITIATOR);
});
}));
@@ -182,25 +182,25 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.messages).toEqual(CHAT_MESSAGES.RECEIVER);
+ expect(component.messages()).toEqual(CHAT_MESSAGES.RECEIVER);
});
}));
});
describe('sendRequest', () => {
beforeEach(() => {
- component.id = '123';
- component.message = 'Test message';
+ component.id.set('123');
+ component.message.set('Test message');
});
it('should not send request if message is empty or whitespace', () => {
- component.message = ' ';
+ component.message.set(' ');
component.sendRequest();
expect(httpService.post).not.toHaveBeenCalled();
});
it('should show error toast if message exceeds limit', () => {
- component.message = 'a'.repeat(component.messageLimit + 1);
+ component.message.set('a'.repeat(component.messageLimit + 1));
component.sendRequest();
expect(toastService.showToast).toHaveBeenCalledWith('MESSAGE_TEXT_LIMIT', 'danger');
expect(httpService.post).not.toHaveBeenCalled();
@@ -215,7 +215,7 @@ describe('ChatRequestPage', () => {
fixture.whenStable().then(() => {
expect(httpService.post).toHaveBeenCalled();
- expect(component.info.status).toBe('REQUESTED');
+ expect(component.info().status).toBe('REQUESTED');
expect(component.getConnectionInfo).toHaveBeenCalled();
});
}));
@@ -236,10 +236,10 @@ describe('ChatRequestPage', () => {
describe('acceptRequest', () => {
beforeEach(() => {
- component.id = '123';
- component.info = {
+ component.id.set('123');
+ component.info.set({
user_details: { name: 'Jane Doe' }
- };
+ });
});
it('should accept request and navigate to chat', waitForAsync(() => {
@@ -260,7 +260,7 @@ describe('ChatRequestPage', () => {
'Accepted message request from Jane Doe',
'success'
);
- expect(component.info.status).toBe('ACCEPTED');
+ expect(component.info().status).toBe('ACCEPTED');
expect(router.navigate).toHaveBeenCalledWith(
[CommonRoutes.CHAT, 'room789'],
{ replaceUrl: true, queryParams: { id: 'conn123' } }
@@ -269,7 +269,7 @@ describe('ChatRequestPage', () => {
}));
it('should use default name if user details name is not available', waitForAsync(() => {
- component.info = { user_details: {} };
+ component.info.set({ user_details: {} });
const mockResponse = {
result: {
id: 'conn123',
@@ -330,7 +330,7 @@ describe('ChatRequestPage', () => {
describe('rejectRequest', () => {
beforeEach(() => {
- component.id = '123';
+ component.id.set('123');
});
it('should reject request and show toast', waitForAsync(() => {
@@ -341,8 +341,8 @@ describe('ChatRequestPage', () => {
fixture.whenStable().then(() => {
expect(httpService.post).toHaveBeenCalled();
- expect(component.info.status).toBe('REJECTED');
- expect(component.messages).toEqual(CHAT_MESSAGES.RECEIVER);
+ expect(component.info().status).toBe('REJECTED');
+ expect(component.messages()).toEqual(CHAT_MESSAGES.RECEIVER);
expect(toastService.showToast).toHaveBeenCalledWith('REJECTED_MESSAGE_REQ', 'danger');
});
}));
@@ -362,7 +362,7 @@ describe('ChatRequestPage', () => {
describe('goToProfile', () => {
it('should navigate to mentor details page', () => {
- component.id = '123';
+ component.id.set('123');
component.goToProfile();
expect(router.navigate).toHaveBeenCalledWith([CommonRoutes.MENTOR_DETAILS, '123']);
});
@@ -375,12 +375,12 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.info).toBeNull();
+ expect(component.info()).toBeNull();
});
}));
it('should handle message with exact character limit', () => {
- component.message = 'a'.repeat(component.messageLimit);
+ component.message.set('a'.repeat(component.messageLimit));
const mockResponse = { result: {} };
httpService.post.and.returnValue(Promise.resolve(mockResponse));
spyOn(component, 'getConnectionInfo');
@@ -391,13 +391,13 @@ describe('ChatRequestPage', () => {
});
it('should trim whitespace from message before validation', () => {
- component.message = ' ';
+ component.message.set(' ');
component.sendRequest();
expect(httpService.post).not.toHaveBeenCalled();
});
it('should handle response without meta in acceptRequest', waitForAsync(() => {
- component.info = { user_details: { name: 'Test User' } };
+ component.info.set({ user_details: { name: 'Test User' } });
const mockResponse = {
result: {
id: 'conn123',
@@ -410,7 +410,7 @@ describe('ChatRequestPage', () => {
component.acceptRequest();
fixture.whenStable().then(() => {
- expect(component.info.status).toBe('ACCEPTED');
+ expect(component.info().status).toBe('ACCEPTED');
});
}));
@@ -430,11 +430,11 @@ describe('ChatRequestPage', () => {
describe('Message validation', () => {
beforeEach(() => {
- component.id = '123';
+ component.id.set('123');
});
it('should trim leading whitespace before checking if empty', () => {
- component.message = ' hello';
+ component.message.set(' hello');
const mockResponse = { result: {} };
httpService.post.and.returnValue(Promise.resolve(mockResponse));
@@ -444,7 +444,7 @@ describe('ChatRequestPage', () => {
});
it('should handle message at exactly the limit boundary', () => {
- component.message = 'a'.repeat(component.messageLimit);
+ component.message.set('a'.repeat(component.messageLimit));
const mockResponse = { result: {} };
httpService.post.and.returnValue(Promise.resolve(mockResponse));
@@ -455,7 +455,7 @@ describe('ChatRequestPage', () => {
});
it('should reject message one character over limit', () => {
- component.message = 'a'.repeat(component.messageLimit + 1);
+ component.message.set('a'.repeat(component.messageLimit + 1));
component.sendRequest();
@@ -466,7 +466,7 @@ describe('ChatRequestPage', () => {
describe('Constructor', () => {
it('should subscribe to route params', () => {
- expect(component.id).toBe('123');
+ expect(component.id()).toBe('123');
});
});
@@ -484,7 +484,7 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.info.status).toBe('PENDING');
+ expect(component.info().status).toBe('PENDING');
});
}));
@@ -501,8 +501,63 @@ describe('ChatRequestPage', () => {
component.getConnectionInfo();
fixture.whenStable().then(() => {
- expect(component.info.status).toBe('REJECTED');
+ expect(component.info().status).toBe('REJECTED');
});
}));
});
-});
\ No newline at end of file
+
+ describe('Computed signals', () => {
+ it('should compute status from info', () => {
+ component.info.set({ status: 'PENDING' });
+ expect(component.status()).toBe('PENDING');
+ });
+
+ it('should compute userDetails from info', () => {
+ component.info.set({ user_details: { name: 'Test' } });
+ expect(component.userDetails()).toEqual({ name: 'Test' });
+ });
+
+ it('should compute profileImage with fallback', () => {
+ component.info.set({ user_details: {} });
+ expect(component.profileImage()).toBe('assets/prof-img/user.png');
+
+ component.info.set({ user_details: { image: 'custom.png' } });
+ expect(component.profileImage()).toBe('custom.png');
+ });
+
+ it('should compute isInitiator correctly', () => {
+ component.info.set({ created_by: '123', user_id: '123' });
+ expect(component.isInitiator()).toBeTrue();
+
+ component.info.set({ created_by: '456', user_id: '123' });
+ expect(component.isInitiator()).toBeFalse();
+ });
+
+ it('should wait for participant role resolution before showing current status actions', () => {
+ component.info.set({ status: 'REQUESTED' });
+ expect(component.hasResolvedParticipantRole()).toBeFalse();
+ expect(component.showCurrentStatusActions()).toBeFalse();
+
+ component.info.set({ created_by: '456', user_id: '123', status: 'REQUESTED' });
+ expect(component.hasResolvedParticipantRole()).toBeTrue();
+ expect(component.showCurrentStatusActions()).toBeTrue();
+
+ component.info.set({ created_by: '123', user_id: '123', status: 'REQUESTED' });
+ expect(component.showCurrentStatusActions()).toBeFalse();
+ });
+
+ it('should compute showMessageInput correctly', () => {
+ component.info.set({ created_by: '123', user_id: '123', status: 'PENDING' });
+ expect(component.showMessageInput()).toBeTrue();
+
+ component.info.set({ created_by: '123', user_id: '123', status: 'ACCEPTED' });
+ expect(component.showMessageInput()).toBeFalse();
+ });
+
+ it('should compute statusMessage from messages and status', () => {
+ component.info.set({ status: 'PENDING' });
+ component.messages.set(CHAT_MESSAGES.INITIATOR);
+ expect(component.statusMessage()).toEqual(CHAT_MESSAGES.INITIATOR['PENDING']);
+ });
+ });
+});
diff --git a/src/app/pages/chat-request/chat-request.page.ts b/src/app/pages/chat-request/chat-request.page.ts
index d19beff2..ddbe2730 100644
--- a/src/app/pages/chat-request/chat-request.page.ts
+++ b/src/app/pages/chat-request/chat-request.page.ts
@@ -1,12 +1,12 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, signal, computed } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AlertController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
-import { replace } from 'lodash';
import { CHAT_MESSAGES } from 'src/app/core/constants/chatConstants';
import { urlConstants } from 'src/app/core/constants/urlConstants';
import { HttpService, ToastService, UtilService } from 'src/app/core/services';
import { CommonRoutes } from 'src/global.routes';
+
@Component({
selector: 'app-chat-request',
templateUrl: './chat-request.page.html',
@@ -14,16 +14,41 @@ import { CommonRoutes } from 'src/global.routes';
standalone: false
})
export class ChatRequestPage implements OnInit {
- public headerConfig: any = {
+ readonly headerConfig = {
menu: false,
headerColor: 'primary',
};
- id;
- messageLimit = CHAT_MESSAGES.MESSAGE_TEXT_LIMIT;
- message: string = 'Hi, I would like to connect with you.';
- info: any = {};
- messages = {};
+ readonly messageLimit = CHAT_MESSAGES.MESSAGE_TEXT_LIMIT;
+
+ id = signal
(undefined);
+ message = signal('Hi, I would like to connect with you.');
+ info = signal({});
+ messages = signal({});
+
+ // Computed signals for derived state
+ readonly status = computed(() => this.info()?.status);
+ readonly userDetails = computed(() => this.info()?.user_details);
+ readonly profileImage = computed(() => this.userDetails()?.image || 'assets/prof-img/user.png');
+ readonly statusMessage = computed(() => this.messages()?.[this.status()]);
+ readonly hasResolvedParticipantRole = computed(() => {
+ const i = this.info();
+ return !!(i?.created_by && i?.user_id);
+ });
+ readonly isInitiator = computed(() => {
+ const i = this.info();
+ return i?.created_by && i?.user_id && i.created_by === i.user_id;
+ });
+ readonly showCurrentStatusActions = computed(() =>
+ this.hasResolvedParticipantRole() && this.status() !== 'REJECTED' && !this.isInitiator()
+ );
+ readonly showMessageInput = computed(() => {
+ return this.status() === 'PENDING' || (this.isInitiator() && this.status() !== 'ACCEPTED');
+ });
+ readonly messageInfoBottom = computed(() => {
+ const i = this.info();
+ return i?.hasOwnProperty?.('created_by') && i.created_by !== i.user_id ? '20px' : '100px';
+ });
constructor(
private httpService: HttpService,
@@ -35,7 +60,7 @@ export class ChatRequestPage implements OnInit {
private utilService: UtilService
) {
routerParams.params.subscribe((parameters) => {
- this.id = parameters?.id;
+ this.id.set(parameters?.id);
});
}
@@ -43,95 +68,102 @@ export class ChatRequestPage implements OnInit {
this.getConnectionInfo();
}
-getConnectionInfo() {
- const payload = {
- url: urlConstants.API_URLS.GET_CHAT_INFO,
- payload: {
- user_id: this.id,
- },
- };
- this.httpService.post(payload)
- .then((resp) => {
- const result = resp?.result;
- if (!result) {
- this.info = null;
- return;
- }
- this.info = result;
- this.info.status = result.status ?? 'PENDING';
- if (this.info.status === 'REQUESTED') {
- this.message = '';
- } else if (this.info.status === 'ACCEPTED') {
- const roomId = result.meta?.room_id;
- if (roomId) {
- this.router.navigate(
- [CommonRoutes.CHAT, roomId],
- { queryParams: { id: result.id }, replaceUrl: true }
- );
+ getConnectionInfo() {
+ const payload = {
+ url: urlConstants.API_URLS.GET_CHAT_INFO,
+ payload: {
+ user_id: this.id(),
+ },
+ };
+ this.httpService.post(payload)
+ .then((resp) => {
+ const result = resp?.result;
+ if (!result) {
+ this.info.update(() => null);
+ return;
}
- }
- if (this.info.created_by && this.info.user_id) {
- this.messages =
- this.info.created_by === this.info.user_id
- ? CHAT_MESSAGES.INITIATOR
- : CHAT_MESSAGES.RECEIVER;
- } else {
- this.messages = CHAT_MESSAGES.RECEIVER;
- }
- })
- .catch((err) => {
- console.error('getConnectionInfo error', err);
- });
-}
+ const infoData = { ...result };
+ infoData.status = result.status ?? 'PENDING';
+
+ if (infoData.status === 'REQUESTED') {
+ this.message.set('');
+ } else if (infoData.status === 'ACCEPTED') {
+ const roomId = result.meta?.room_id;
+ if (roomId) {
+ this.router.navigate(
+ [CommonRoutes.CHAT, roomId],
+ { queryParams: { id: result.id }, replaceUrl: true }
+ );
+ }
+ }
+
+ if (infoData.created_by && infoData.user_id) {
+ this.messages.update(() =>
+ infoData.created_by === infoData.user_id
+ ? CHAT_MESSAGES.INITIATOR
+ : CHAT_MESSAGES.RECEIVER
+ );
+ } else {
+ this.messages.update(() => CHAT_MESSAGES.RECEIVER);
+ }
+
+ this.info.update(() => infoData);
+ })
+ .catch((err) => {
+ console.error('getConnectionInfo error', err);
+ });
+ }
+
sendRequest() {
- if(this.message.trim() === ''){
+ if (this.message().trim() === '') {
return;
}
- if(this.message.length >this.messageLimit){
+ if (this.message().length > this.messageLimit) {
this.toast.showToast('MESSAGE_TEXT_LIMIT', 'danger');
return;
}
const payload = {
url: urlConstants.API_URLS.SEND_REQUEST,
payload: {
- user_id: this.id,
- message: this.message,
+ user_id: this.id(),
+ message: this.message(),
},
};
this.httpService.post(payload).then((resp) => {
- this.info.status = 'REQUESTED';
+ this.info.update((prev) => ({ ...prev, status: 'REQUESTED' }));
this.getConnectionInfo();
});
}
- acceptRequest() {
- const payload = {
- url: urlConstants.API_URLS.ACCEPT_MSG_REQ,
- payload: {
- user_id: this.id,
- },
- };
- this.httpService.post(payload)
- .then((resp) => {
- this.info = this.info ?? {};
- const name = this.info.user_details?.name ?? 'the user';
- const message = this.translate.instant('ACCEPTED_MESSAGE_REQ', { name });
- this.toast.showToast(message, 'success');
- this.info.status = 'ACCEPTED';
- const roomId = resp?.result?.meta?.room_id;
- const connId = resp?.result?.id ?? null;
- if (roomId) {
- this.router.navigate([CommonRoutes.CHAT, roomId], {
- replaceUrl: true,
- queryParams: { id: connId },
- });
- }
- })
- .catch((err) => {
- console.error('acceptRequest error', err);
- });
-}
- async rejectConfirmation() {
+ acceptRequest() {
+ const payload = {
+ url: urlConstants.API_URLS.ACCEPT_MSG_REQ,
+ payload: {
+ user_id: this.id(),
+ },
+ };
+ this.httpService.post(payload)
+ .then((resp) => {
+ const currentInfo = this.info() ?? {};
+ const name = currentInfo.user_details?.name ?? 'the user';
+ const message = this.translate.instant('ACCEPTED_MESSAGE_REQ', { name });
+ this.toast.showToast(message, 'success');
+ this.info.update((prev) => ({ ...prev, status: 'ACCEPTED' }));
+ const roomId = resp?.result?.meta?.room_id;
+ const connId = resp?.result?.id ?? null;
+ if (roomId) {
+ this.router.navigate([CommonRoutes.CHAT, roomId], {
+ replaceUrl: true,
+ queryParams: { id: connId },
+ });
+ }
+ })
+ .catch((err) => {
+ console.error('acceptRequest error', err);
+ });
+ }
+
+ async rejectConfirmation() {
let texts: any;
this.translate
.get(['MESSAGE_REQ_REJECT', 'REJECT', 'CANCEL'])
@@ -144,27 +176,29 @@ getConnectionInfo() {
cancel: 'CANCEL',
submit: 'Reject',
};
- const response:any = await this.utilService.alertPopup(msg);
+ const response: any = await this.utilService.alertPopup(msg);
if (response) {
- this.rejectRequest();
+ this.rejectRequest();
} else {
console.log('User canceled the rejection');
}
}
+
rejectRequest() {
const payload = {
url: urlConstants.API_URLS.REJECT_MSG_REQ,
payload: {
- user_id: this.id,
+ user_id: this.id(),
},
};
this.httpService.post(payload).then((resp) => {
- this.info.status = 'REJECTED';
- this.messages = CHAT_MESSAGES.RECEIVER;
+ this.info.update((prev) => ({ ...prev, status: 'REJECTED' }));
+ this.messages.update(() => CHAT_MESSAGES.RECEIVER);
this.toast.showToast('REJECTED_MESSAGE_REQ', 'danger');
});
}
- goToProfile(){
- this.router.navigate([CommonRoutes.MENTOR_DETAILS, this.id]);
+
+ goToProfile() {
+ this.router.navigate([CommonRoutes.MENTOR_DETAILS, this.id()]);
}
}
diff --git a/src/app/pages/chat-window/chat-window.page.html b/src/app/pages/chat-window/chat-window.page.html
index 05e68a0a..187b62dd 100644
--- a/src/app/pages/chat-window/chat-window.page.html
+++ b/src/app/pages/chat-window/chat-window.page.html
@@ -1,4 +1,12 @@
-
-
+ @if (showChat()) {
+
+
+ }
diff --git a/src/app/pages/chat-window/chat-window.page.spec.ts b/src/app/pages/chat-window/chat-window.page.spec.ts
index 33cee025..4258912c 100644
--- a/src/app/pages/chat-window/chat-window.page.spec.ts
+++ b/src/app/pages/chat-window/chat-window.page.spec.ts
@@ -77,32 +77,33 @@ describe('ChatWindowPage', () => {
it('should create', () => {
expect(component).toBeTruthy();
- expect(component.showChat).toBeTruthy();
+ expect(component.showChat()).toBeFalsy();
expect(component.headerConfig).toBeDefined();
});
- it('should react to params emission: set rid and call ngOnInit', fakeAsync(() => {
- const initSpy = spyOn(component, 'ngOnInit').and.callThrough();
+ it('should react to params emission: set rid and initialize chat', fakeAsync(() => {
+ const initSpy = spyOn(component, 'initializeChat').and.callThrough();
paramsSubject.next({ id: 'room-1' });
tick();
- expect(component.rid).toBe('room-1');
+ expect(component.rid()).toBe('room-1');
expect(initSpy).toHaveBeenCalled();
}));
it('should set id from queryParams', fakeAsync(() => {
queryParamsSubject.next({ id: 'external-1' });
tick();
- expect(component.id).toBe('external-1');
+ expect(component.id()).toBe('external-1');
}));
it('ngOnInit should call getChatToken, set showChat true and load translations', async () => {
const fakeTranslations = { 'KEY1': 'one', 'KEY2': 'two' };
mockTranslate.get.and.returnValue(of(fakeTranslations));
mockProfileService.getChatToken.and.returnValue(Promise.resolve(true));
+ component.rid.set('room-1');
await component.ngOnInit();
expect(mockProfileService.getChatToken).toHaveBeenCalled();
- expect(component.showChat).toBeTrue();
- expect(component.translations).toEqual(fakeTranslations);
+ expect(component.showChat()).toBeTrue();
+ expect(component.translations()).toEqual(fakeTranslations);
});
it('onBack should call location.back', () => {
@@ -139,21 +140,21 @@ describe('ChatWindowPage', () => {
});
it('ionViewWillLeave should set rocket.isWebSocketInitialized false when rid exists', () => {
- component.rid = 'abc';
+ component.rid.set('abc');
(mockRocket as any).isWebSocketInitialized = true;
component.ionViewWillLeave();
expect((mockRocket as any).isWebSocketInitialized).toBeFalse();
});
it('ngOnDestroy should set rocket.isWebSocketInitialized false when rid exists', () => {
- component.rid = 'room-2';
+ component.rid.set('room-2');
(mockRocket as any).isWebSocketInitialized = true;
component.ngOnDestroy();
expect((mockRocket as any).isWebSocketInitialized).toBeFalse();
});
it('ngOnDestroy should not throw when no rid present (defensive)', () => {
- component.rid = null;
+ component.rid.set(null);
(mockRocket as any).isWebSocketInitialized = true;
expect(() => component.ngOnDestroy()).not.toThrow();
expect((mockRocket as any).isWebSocketInitialized).toBeTrue();
@@ -162,16 +163,17 @@ describe('ChatWindowPage', () => {
it('constructor queryParams subscription updates id when later emitted', fakeAsync(() => {
queryParamsSubject.next({ id: 'first' });
tick();
- expect(component.id).toBe('first');
+ expect(component.id()).toBe('first');
queryParamsSubject.next({ id: 'second' });
tick();
- expect(component.id).toBe('second');
+ expect(component.id()).toBe('second');
}));
it('translate.get should be called with keys from CHAT_LIB_META_KEYS', async () => {
const keys = Object.values(CHAT_LIB_META_KEYS);
mockTranslate.get.and.returnValue(of({}));
+ component.rid.set('room-1');
await component.ngOnInit();
expect(mockTranslate.get).toHaveBeenCalledWith(keys);
});
diff --git a/src/app/pages/chat-window/chat-window.page.ts b/src/app/pages/chat-window/chat-window.page.ts
index 8251433b..d4bf3df6 100644
--- a/src/app/pages/chat-window/chat-window.page.ts
+++ b/src/app/pages/chat-window/chat-window.page.ts
@@ -1,5 +1,5 @@
import { Location } from '@angular/common';
-import { Component, OnInit } from '@angular/core';
+import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { CHAT_LIB_META_KEYS } from 'src/app/core/constants/formConstant';
import { urlConstants } from 'src/app/core/constants/urlConstants';
@@ -15,64 +15,84 @@ import { RocketChatApiService } from 'sl-chat-library';
styleUrls: ['./chat-window.page.scss'],
standalone: false
})
-export class ChatWindowPage implements OnInit {
- showChat: boolean = false;
+export class ChatWindowPage implements OnInit, OnDestroy {
+ private readonly routerParams = inject(ActivatedRoute);
+ private readonly location = inject(Location);
+ private readonly profileService = inject(ProfileService);
+ private readonly router = inject(Router);
+ private readonly apiServer = inject(HttpService);
+ private readonly toastService = inject(ToastService);
+ private readonly translate = inject(TranslateService);
+ private readonly rocket = inject(RocketChatApiService);
+
+ readonly showChat = signal(false);
public headerConfig: any = {
menu: false,
headerColor: 'primary',
};
- rid: any;
- id : any;
- translations: any;
- constructor(
- private routerParams: ActivatedRoute,
- private location: Location,
- private profileService: ProfileService,
- private router: Router,
- private apiServer : HttpService,
- private toastService: ToastService,
- private translate: TranslateService,
- private rocket: RocketChatApiService
- ) {
- routerParams.params.subscribe((parameters) => {
- this.rid = parameters?.id;
- this.ngOnInit();
+ readonly rid = signal(null);
+ readonly id = signal(null);
+ readonly translations = signal>({});
+
+ constructor() {
+ this.routerParams.params.subscribe((parameters) => {
+ this.rid.set(parameters?.id ?? null);
+ void this.initializeChat();
});
- routerParams.queryParams.subscribe((parameters) => {
- this.id = parameters?.id;
- })
+
+ this.routerParams.queryParams.subscribe((parameters) => {
+ this.id.set(parameters?.id ?? null);
+ });
+ }
+
+ async ngOnInit(): Promise {
+ if (!this.rid()) {
+ return;
+ }
+
+ await this.initializeChat();
}
- async ngOnInit() {
+ private async initializeChat(): Promise {
+ if (!this.rid()) {
+ return;
+ }
+
await this.profileService.getChatToken();
- this.showChat = true;
+ this.showChat.set(true);
const keys = Object.values(CHAT_LIB_META_KEYS);
this.translate.get(keys).subscribe(res => {
- this.translations = res;
+ this.translations.set(res);
});
}
- onBack() {
+
+ onBack(): void {
this.location.back();
}
- onClickProfile(externalId){
- this.apiServer.post({url:urlConstants.API_URLS.GETUSERIDBYRID, payload:{"external_user_id":externalId}}).then((resp) =>{
+ async onClickProfile(externalId: string): Promise {
+ const resp = await this.apiServer.post({
+ url: urlConstants.API_URLS.GETUSERIDBYRID,
+ payload: { external_user_id: externalId }
+ });
+ if (resp?.result?.user_id) {
this.router.navigate([CommonRoutes.MENTOR_DETAILS, resp?.result?.user_id]);
- })
+ }
}
- limitExceeded(event){
+ limitExceeded(_event: unknown): void {
this.toastService.showToast('MESSAGE_TEXT_LIMIT','danger');
}
ngOnDestroy(): void {
- if(this.rid)
- this.rocket.isWebSocketInitialized =false;
-
+ if (this.rid()) {
+ this.rocket.isWebSocketInitialized = false;
+ }
}
- ionViewWillLeave() {
- if(this.rid)
- this.rocket.isWebSocketInitialized =false;
+ ionViewWillLeave(): void {
+ if (this.rid()) {
+ this.rocket.isWebSocketInitialized = false;
+ }
}
}
diff --git a/src/app/pages/login-activity/login-activity.page.ts b/src/app/pages/login-activity/login-activity.page.ts
index afd683c3..822ddc98 100644
--- a/src/app/pages/login-activity/login-activity.page.ts
+++ b/src/app/pages/login-activity/login-activity.page.ts
@@ -8,7 +8,7 @@ import {
import { MenuController } from '@ionic/angular';
import { SessionService } from 'src/app/core/services/session/session.service';
import { localKeys } from 'src/app/core/constants/localStorage.keys';
-import jwt_decode from 'jwt-decode';
+import { jwtDecode } from 'jwt-decode';
import { paginatorConstants } from 'src/app/core/constants/paginatorConstants';
import { MatPaginator } from '@angular/material/paginator';
@@ -49,7 +49,7 @@ export class LoginActivityPage implements OnInit {
async ngOnInit() {
this.sessionActivities();
let token = await this.localStorage.getLocalData(localKeys.TOKEN);
- this.sessionData = jwt_decode(token.access_token);
+ this.sessionData = jwtDecode(token.access_token);
this.sessionId = this.sessionData?.data?.session_id;
}
diff --git a/src/app/pages/mentor-search-directory/mentor-search-directory.page.ts b/src/app/pages/mentor-search-directory/mentor-search-directory.page.ts
index d31163bb..3b97d2c4 100644
--- a/src/app/pages/mentor-search-directory/mentor-search-directory.page.ts
+++ b/src/app/pages/mentor-search-directory/mentor-search-directory.page.ts
@@ -140,10 +140,14 @@ export class MentorSearchDirectoryPage implements OnInit {
}
async onClearSearch($event: string) {
- const current = this.searchAndCriterias();
- current.headerData.searchText = '';
- current.headerData.criterias = undefined;
- this.searchAndCriterias.set({ ...current });
+ this.searchAndCriterias.update(current => ({
+ ...current,
+ headerData: {
+ ...current.headerData,
+ searchText: '',
+ criterias: undefined
+ }
+ }));
this.router.navigate([], {
relativeTo: this.route,
@@ -223,9 +227,13 @@ export class MentorSearchDirectoryPage implements OnInit {
eventHandler(event: any) {
this.valueFromChipAndFilter.set(event);
- const current = this.searchAndCriterias();
- current.headerData.criterias = { name: undefined, label: undefined };
- this.searchAndCriterias.set({ ...current });
+ this.searchAndCriterias.update(current => ({
+ ...current,
+ headerData: {
+ ...current.headerData,
+ criterias: { name: undefined, label: undefined }
+ }
+ }));
}
onPageChange(event) {
@@ -235,14 +243,12 @@ export class MentorSearchDirectoryPage implements OnInit {
}
removeFilteredData(chip) {
- const updatedFilterData = this.filterData().map((filter) => {
- filter.options.map((option) => {
- if (option.value === chip) {
- option.selected = false;
- }
- });
- return filter;
- });
+ const updatedFilterData = this.filterData().map(filter => ({
+ ...filter,
+ options: filter.options.map(option => (
+ option.value === chip ? { ...option, selected: false } : option
+ ))
+ }));
this.filterData.set(updatedFilterData);
const currentFiltered = { ...this.filteredDatas() };
@@ -323,4 +329,4 @@ export class MentorSearchDirectoryPage implements OnInit {
this.chips.set([]);
this.urlQueryData.set(null);
}
-}
\ No newline at end of file
+}
diff --git a/src/app/pages/session-request-details/session-request-details.page.html b/src/app/pages/session-request-details/session-request-details.page.html
index 632baf83..550c0759 100644
--- a/src/app/pages/session-request-details/session-request-details.page.html
+++ b/src/app/pages/session-request-details/session-request-details.page.html
@@ -1,223 +1,238 @@
-
-
-
-
+ @if (apiResponse(); as response) {
+ @let details = sessionDetails();
+ @let schedule = scheduledSessionDetals();
+
+
+
+
-
{{apiResponse?.user_details?.name | titlecase}}
-
-
-
- {{ item.label | titlecase }},
-
-
-
-
{{"VIEW_PROFILE" | translate}}
-
- {{"AGENDA" | translate }}
-
- {{ showFullText ? (apiResponse.agenda | titlecase) : (apiResponse.agenda | titlecase | slice:0:150 ) }}{{ apiResponse.agenda.length > 150 && !showFullText ? '...' : '' }}
+
{{ response?.user_details?.name | titlecase }}
+
+ @if (response?.user_details?.designation?.length) {
+ @for (item of response.user_details.designation; track item.label; let last = $last) {
+ {{ item.label | titlecase }}
+ @if (!last) {
+ ,
+ }
+ }
+ }
-
-
-
150"
- class="viewMore"
- (click)="toggleText()">
- {{ showFullText ? 'View Less' : 'View More' }}
-
+
{{ 'VIEW_PROFILE' | translate }}
+
+ {{ 'AGENDA' | translate }}
+
+ {{ showFullText() ? (response.agenda | titlecase) : (response.agenda | titlecase | slice:0:150) }}{{ response.agenda.length > 150 && !showFullText() ? '...' : '' }}
+
+
-
- {{
- apiResponse?.created_by == apiResponse?.user_details?.user_id
- ? (apiResponse?.user_details?.name | titlecase) + ' ' + ("IS_REQUESTING" | translate)
- : ("YOU_HAVE" | translate)
- }}
- {{"A_SLOT" | translate}}
- {{
- formatUnixTime(apiResponse.start_date)
- }} -
- {{
- formatUnixTime(apiResponse.end_date)
- }}
- {{"ON" | translate}}
- {{ apiResponse.start_date * 1000 | date : "EEEE (dd MMM yyyy)" }}
-
-
+ @if (response.agenda.length > 150) {
+
+ {{ showFullText() ? 'View Less' : 'View More' }}
+
+ }
-
-
- {{"SLOT_BOOKED" | translate}} {{
- apiResponse?.created_by == apiResponse?.user_details?.user_id
- ? (apiResponse?.user_details?.name | titlecase)
- : ("YOU_HAVE" | translate)
- }}
- at
- {{
- formatUnixTime(apiResponse.start_date)
- }} -
- {{
- formatUnixTime(apiResponse.end_date)
- }}
- {{"ON" | translate}}
- {{ apiResponse.start_date * 1000 | date : "EEEE (dd MMM yyyy)" }}
-
-
+ @if (response.status !== 'ACCEPTED') {
+
+ {{
+ response?.created_by == response?.user_details?.user_id
+ ? (response?.user_details?.name | titlecase) + ' ' + ('IS_REQUESTING' | translate)
+ : ('YOU_HAVE' | translate)
+ }}
+ {{ 'A_SLOT' | translate }}
+ {{ formatUnixTime(response.start_date) }} -
+ {{ formatUnixTime(response.end_date) }}
+ {{ 'ON' | translate }}
+ {{ response.start_date * 1000 | date : 'EEEE (dd MMM yyyy)' }}
+
+
+ } @else {
+
+ {{ 'SLOT_BOOKED' | translate }}
+ {{
+ response?.created_by == response?.user_details?.user_id
+ ? (response?.user_details?.name | titlecase)
+ : ('YOU_HAVE' | translate)
+ }}
+ at
+ {{ formatUnixTime(response.start_date) }} -
+ {{ formatUnixTime(response.end_date) }}
+ {{ 'ON' | translate }}
+ {{ response.start_date * 1000 | date : 'EEEE (dd MMM yyyy)' }}
+
+
+ }
-
-
-
{{"MEETING_LINK" | translate}}
- @if (sessionDetails && sessionDetails?.meeting_info?.value === 'Zoom') {
+ @if (response && response.requestor_id === response.user_details.user_id && response.status === 'ACCEPTED') {
+
+
{{ 'MEETING_LINK' | translate }}
+ @if (details && details?.meeting_info?.value === 'Zoom') {
- {{"MEETING_TAKE_PLACE" | translate}} {{sessionDetails?.meeting_info?.platform}}
- {{"MEETING_ID" | translate}} : {{sessionDetails?.meeting_info?.meta?.meetingId}}
- {{"PASSCODE" | translate}} : {{sessionDetails?.meeting_info?.meta?.password}}
+ {{ 'MEETING_TAKE_PLACE' | translate }} {{ details?.meeting_info?.platform }}
+ {{ 'MEETING_ID' | translate }} : {{ details?.meeting_info?.meta?.meetingId }}
+ {{ 'PASSCODE' | translate }} : {{ details?.meeting_info?.meta?.password }}
- } @else if (sessionDetails?.meeting_info?.value === 'Gmeet') {
+ } @else if (details?.meeting_info?.value === 'Gmeet') {
- {{sessionDetails?.meeting_info?.platform}} : {{sessionDetails?.meeting_info?.link}}
+ {{ details?.meeting_info?.platform }} : {{ details?.meeting_info?.link }}
- } @else if(sessionDetails?.meeting_info?.value === 'Whatsapp') {
+ } @else if (details?.meeting_info?.value === 'Whatsapp') {
- {{sessionDetails?.meeting_info?.platform}} : {{sessionDetails?.meeting_info?.link}}
+ {{ details?.meeting_info?.platform }} : {{ details?.meeting_info?.link }}
- } @else if(sessionDetails?.meeting_info?.value === 'BBB' || sessionDetails?.meeting_info?.value === 'Default') {
+ } @else if (details?.meeting_info?.value === 'BBB' || details?.meeting_info?.value === 'Default') {
- {{sessionDetails?.meeting_info?.platform}} : Default
+ {{ details?.meeting_info?.platform }} : Default
- } @else if(sessionDetails?.meeting_info?.value ==='OFF') {
+ } @else if (details?.meeting_info?.value === 'OFF') {
} @else {
- {{sessionDetails?.meeting_info?.platform}} : {{sessionDetails?.meeting_info?.link}}
+ {{ details?.meeting_info?.platform }} : {{ details?.meeting_info?.link }}
}
-
{{"ADD_LINK" | translate}}
-
{{"EDIT_LINK" | translate}}
-
+ @if (!isMeetingLinkAdded()) {
+
{{ 'ADD_LINK' | translate }}
+ } @else {
+
{{ 'EDIT_LINK' | translate }}
+ }
+
+ }
- @if (isRejected) {
- {{"SLOT_REJECT" | translate}}
- } @else if (isAccepted) {
- {{"START_BTN_ENABLE" | translate}}
- } @else if (apiResponse && apiResponse.user_details.user_id === apiResponse.requestor_id) {
- {{"SLOT_AVAILABLE" | translate}}
+ @if (isRejected()) {
+ {{ 'SLOT_REJECT' | translate }}
+ } @else if (isAccepted()) {
+ {{ 'START_BTN_ENABLE' | translate }}
+ } @else if (response && response.user_details.user_id === response.requestor_id) {
+ {{ 'SLOT_AVAILABLE' | translate }}
} @else {
- {{ "PENDING" | translate}}
+ {{ 'PENDING' | translate }}
}
-
- 0 && apiResponse && apiResponse.user_details.user_id === apiResponse.requestor_id">
-
-
-
-
-
- {{"SELECT_MEETING_PLATFORM" | translate}}
-
-
-
-
-
- {{ option.name }}
-
-
-
-
- {{selectedHint}}
-
-
-
-
+
+ @if (details && schedule.length > 0 && response && response.user_details.user_id === response.requestor_id) {
+
+
+
+
+
+
+ {{ 'SELECT_MEETING_PLATFORM' | translate }}
+
+
+
+
+ @for (option of meetingPlatforms; track option.value) {
+
+ {{ option.name }}
+
+ }
+
+
+
+ {{ selectedHint }}
+
+
+ @for (option of meetingPlatforms; track option.value) {
+ @if (selectedLink == option) {
+
+ }
+ }
+
+
+
+
+
+
+
+ {{ 'ADD_NOW' | translate }}
+ {{ 'ADD_LATER' | translate }}
-
-
-
-
-
-
-
- {{"ADD_NOW" | translate}}
- {{"ADD_LATER" | translate}}
-
-
-
-
-
-
0 && apiResponse && apiResponse.user_details.user_id === apiResponse.requestor_id">
-
-
-
-
-
-
- {{"SCHEDULE" | translate}}
-
-
-
-
- {{event.date}}
-
-
-
-
-
-
+
+
+
+
+ }
-
-
- {{ formatUnixTime(event?.startTime) }}
- {{ formatUnixTime(event?.endTime) }}
-
- {{event?.title | titlecase}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ @if (schedule.length > 0 && response && response.user_details.user_id === response.requestor_id) {
+
+
+
+
+
+
+
+ {{ 'SCHEDULE' | translate }}
+
+
+ @for (dateEvent of schedule; track dateEvent.date) {
+
+
+ {{ dateEvent.date }}
+
+
+
+
+ @for (slotEvent of dateEvent.bookedSlots; track slotEvent.startTime) {
+
+
+
+ {{ formatUnixTime(slotEvent?.startTime) }}
+ {{ formatUnixTime(slotEvent?.endTime) }}
+
+
+ {{ slotEvent?.title | titlecase }}
+
+
+
+ }
+
+
+
+ }
+
+
+ }
+
+ }
+
+@if (apiResponse(); as response) {
+ @let details = sessionDetails();
+ @if (response.user_details.user_id === response.requestor_id && response.status !== 'REJECTED') {
+
+ }
+}
diff --git a/src/app/pages/session-request-details/session-request-details.page.spec.ts b/src/app/pages/session-request-details/session-request-details.page.spec.ts
index f0f7cec6..6c376879 100644
--- a/src/app/pages/session-request-details/session-request-details.page.spec.ts
+++ b/src/app/pages/session-request-details/session-request-details.page.spec.ts
@@ -62,7 +62,7 @@ describe('SessionRequestDetailsPage', () => {
fixture = TestBed.createComponent(SessionRequestDetailsPage);
component = fixture.componentInstance;
component.modal = mockModal as any;
- component.params = { id: '123' };
+ component.params.set({ id: '123' });
// Default mocks/spies
mockFormService.getForm.and.returnValue(Promise.resolve({ data: { fields: { forms: [{ name: 'zoom', hint: 'zoom_hint', value: 'zoom_val' }] } } }));
@@ -77,7 +77,7 @@ describe('SessionRequestDetailsPage', () => {
mockSessionService.requestSessionUserAvailability.and.returnValue(Promise.resolve({ result: [] }));
// Initialize component data to prevent template errors
- component.apiResponse = {
+ component.apiResponse.set({
id: 'req_1',
session_id: 'sess_1',
start_date: 100,
@@ -92,9 +92,9 @@ describe('SessionRequestDetailsPage', () => {
image: 'img.png',
designation: [{ label: 'dev' }]
}
- };
- component.userId = 'user_123';
- component.scheduledSessionDetals = []; // Initialize to prevent template error
+ });
+ component.userId.set('user_123');
+ component.scheduledSessionDetals.set([]); // Initialize to prevent template error
fixture.detectChanges();
}));
@@ -112,10 +112,10 @@ describe('SessionRequestDetailsPage', () => {
component.ionViewWillEnter();
tick();
- expect(component.userId).toBeDefined();
- expect(component.params).toEqual({ id: '123' });
+ expect(component.userId()).toBeDefined();
+ expect(component.params()).toEqual({ id: '123' });
expect(mockSessionService.getReqSessionDetails).toHaveBeenCalledWith('123');
- expect(component.apiResponse).toBeDefined();
+ expect(component.apiResponse()).toBeDefined();
}));
it('should fetch session details if ACCEPTED', fakeAsync(() => {
@@ -127,18 +127,18 @@ describe('SessionRequestDetailsPage', () => {
tick();
expect(mockSessionService.getSessionDetailsAPI).toHaveBeenCalledWith('sess_1');
- expect(component.isMeetingLinkAdded).toBeTrue();
- expect(component.isEnabled).toBeFalse(); // far future
+ expect(component.isMeetingLinkAdded()).toBeTrue();
+ expect(component.isEnabled()).toBeFalse(); // far future
}));
});
describe('toggleText', () => {
it('should toggle showFullText', () => {
- component.showFullText = false;
+ component.showFullText.set(false);
component.toggleText();
- expect(component.showFullText).toBeTrue();
+ expect(component.showFullText()).toBeTrue();
component.toggleText();
- expect(component.showFullText).toBeFalse();
+ expect(component.showFullText()).toBeFalse();
});
});
@@ -153,7 +153,7 @@ describe('SessionRequestDetailsPage', () => {
expect(mockSessionService.requestSessionAccept).toHaveBeenCalledWith('req_1');
expect(mockToastService.showToast).toHaveBeenCalledWith('Accepted', 'success');
expect(mockSessionService.requestSessionUserAvailability).toHaveBeenCalled(); // via getAllUpdatedSession
- expect(component.isAccepted).toBeTrue();
+ expect(component.isAccepted()).toBeTrue();
}));
});
@@ -169,7 +169,7 @@ describe('SessionRequestDetailsPage', () => {
expect(mockUtilService.alertPopup).toHaveBeenCalled();
expect(mockSessionService.requestSessionReject).toHaveBeenCalledWith('req_1', 'Busy');
expect(mockToastService.showToast).toHaveBeenCalledWith('Rejected', 'danger');
- expect(component.isRejected).toBeTrue();
+ expect(component.isRejected()).toBeTrue();
}));
it('should not reject if cancelled', fakeAsync(() => {
@@ -186,8 +186,8 @@ describe('SessionRequestDetailsPage', () => {
describe('addLink', () => {
it('should open modal and set session id', () => {
component.addLink(true, 'sess_1');
- expect(component.isModalOpen).toBeTrue();
- expect(component.sessionId).toBe('sess_1');
+ expect(component.isModalOpen()).toBeTrue();
+ expect(component.sessionId()).toBe('sess_1');
});
});
@@ -201,8 +201,8 @@ describe('SessionRequestDetailsPage', () => {
value: { link: 'http://zoom.us', password: 'pass', meetingId: '123' }
}
} as any;
- component.sessionId = 'sess_1';
- component.params = { id: 'req_1' };
+ component.sessionId.set('sess_1');
+ component.params.set({ id: 'req_1' });
mockSessionService.createSession.and.returnValue(Promise.resolve({}));
mockSessionService.getReqSessionDetails.and.returnValue(Promise.resolve({
@@ -235,8 +235,8 @@ describe('SessionRequestDetailsPage', () => {
}
});
expect(mockSessionService.createSession).toHaveBeenCalledWith(component.meetingInfo, 'sess_1');
- expect(component.isMeetingLinkAdded).toBeTrue();
- expect(component.editSessionBtn).toBeTrue();
+ expect(component.isMeetingLinkAdded()).toBeTrue();
+ expect(component.editSessionBtn()).toBeTrue();
}));
});
@@ -256,17 +256,17 @@ describe('SessionRequestDetailsPage', () => {
}
}
];
- component.sessionDetails = {
+ component.sessionDetails.set({
meeting_info: {
platform: 'Google Meet',
link: 'http://meet.google.com',
meta: { meetingId: 'm1', password: 'p1' }
}
- };
+ });
component.editLink(true, 'sess_1');
- expect(component.isModalOpen).toBeTrue();
+ expect(component.isModalOpen()).toBeTrue();
expect(component.selectedLink.name).toBe('Google Meet');
// Verify controls were updated (by reference)
const controls = component.meetingPlatforms[0].form.controls;
@@ -280,7 +280,7 @@ describe('SessionRequestDetailsPage', () => {
component.modal = mockModal; // Ensure modal is set
component.addLater();
expect(mockModal.dismiss).toHaveBeenCalled();
- expect(component.isModalOpen).toBeFalse();
+ expect(component.isModalOpen()).toBeFalse();
});
});
diff --git a/src/app/pages/session-request-details/session-request-details.page.ts b/src/app/pages/session-request-details/session-request-details.page.ts
index 390f9c54..dd2918fe 100644
--- a/src/app/pages/session-request-details/session-request-details.page.ts
+++ b/src/app/pages/session-request-details/session-request-details.page.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, ViewChild } from '@angular/core';
+import { Component, OnInit, ViewChild, inject, signal } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { IonModal } from '@ionic/angular';
import * as moment from 'moment';
@@ -17,34 +17,42 @@ import { CommonRoutes } from 'src/global.routes';
standalone: false
})
export class SessionRequestDetailsPage implements OnInit {
+ private readonly form = inject(FormService);
+ private readonly sessionService = inject(SessionService);
+ private readonly toast = inject(ToastService);
+ private readonly utilService = inject(UtilService);
+ private readonly activateRoute = inject(ActivatedRoute);
+ private readonly router = inject(Router);
+ private readonly http = inject(HttpService);
+
@ViewChild('platformForm') platformForm: DynamicFormComponent;
@ViewChild(IonModal) modal!: IonModal;
- showFullText: boolean;
- isAccepted: boolean;
- meetingPlatforms: any;
+ readonly showFullText = signal(false);
+ readonly isAccepted = signal(false);
+ meetingPlatforms: any[] = [];
selectedLink: any;
- selectedHint: any;
- editSessionBtn: boolean = false;
- isMeetingLinkAdded: boolean =false;
- isModalOpen: boolean = false;
- isRejected: boolean = false;
- params: any;
- apiResponse: any;
- scheduledSessionDetals: any;
- meetingInfo: { meeting_info: { platform: any; link: any; value: any; meta: { password: any; meetingId: any; }; }; };
- sessionId: any;
- sessionDetails: any;
- isEnabled: boolean;
- userId : any;
- constructor(
- private form: FormService,
- private sessionService: SessionService,
- private toast: ToastService,
- private utilService: UtilService,
- private activateRoute: ActivatedRoute,
- private router: Router,
- private http: HttpService
- ) { }
+ selectedHint = '';
+ readonly editSessionBtn = signal(false);
+ readonly isMeetingLinkAdded = signal(false);
+ readonly isModalOpen = signal(false);
+ readonly isRejected = signal(false);
+ readonly params = signal
({});
+ readonly apiResponse = signal(null);
+ readonly scheduledSessionDetals = signal([]);
+ meetingInfo: {
+ meeting_info: {
+ platform: any;
+ link: any;
+ value: any;
+ meta: { password: any; meetingId: any };
+ };
+ };
+ readonly sessionId = signal(null);
+ readonly sessionDetails = signal(null);
+ readonly isEnabled = signal(false);
+ readonly userId = signal(null);
+
+ constructor() {}
public headerConfig: any = {
backButton: true,
headerColor: 'primary'
@@ -54,56 +62,61 @@ export class SessionRequestDetailsPage implements OnInit {
ionViewWillEnter() {
this.getPlatformFormDetails();
- this.userId = localStorage.getItem('userId');
- this.activateRoute.queryParams.subscribe((params) => {this.params = params});
- this.sessionService.getReqSessionDetails(this.params.id).then((res) => {
- this.apiResponse = res.result;
- if (this.apiResponse?.status === 'ACCEPTED') {
- this.sessionService.getSessionDetailsAPI(this.apiResponse.session_id).then((res) => {
-
- this.sessionDetails = res.result;
- this.isMeetingLinkAdded = true;
- let currentTimeInSeconds=Math.floor(Date.now()/1000);
- this.isEnabled = ((this.sessionDetails.start_date - currentTimeInSeconds) < 600 || this.sessionDetails?.status?.value=='LIVE') ? true : false;
- })
- }
+ this.userId.set(localStorage.getItem('userId'));
+ this.activateRoute.queryParams.subscribe((params) => {
+ this.params.set(params);
+ this.loadRequestDetails(params.id);
});
this.getAllUpdatedSession();
}
+ private async loadRequestDetails(id: any): Promise {
+ const res = await this.sessionService.getReqSessionDetails(id);
+ this.apiResponse.set(res.result);
+ if (this.apiResponse()?.status === 'ACCEPTED') {
+ const sessionRes = await this.sessionService.getSessionDetailsAPI(this.apiResponse()?.session_id);
+ this.sessionDetails.set(sessionRes.result);
+ this.isMeetingLinkAdded.set(true);
+ const currentTimeInSeconds = Math.floor(Date.now() / 1000);
+ const details = this.sessionDetails();
+ this.isEnabled.set(
+ ((details.start_date - currentTimeInSeconds) < 600 || details?.status?.value === 'LIVE')
+ );
+ }
+ }
+
getAllUpdatedSession() {
- const currentEpoch = Math.floor(Date.now() / 1000);
+ const currentEpoch = Math.floor(Date.now() / 1000);
const thirtyDaysLaterEpoch = Math.floor((Date.now() + 30 * 24 * 60 * 60 * 1000) / 1000);
this.sessionService.requestSessionUserAvailability(currentEpoch, thirtyDaysLaterEpoch).then((res) => {
- this.scheduledSessionDetals = res.result;
+ this.scheduledSessionDetals.set(res.result);
});
}
toggleText() {
- this.showFullText = !this.showFullText;
+ this.showFullText.update((value) => !value);
}
- accept(id:any){
-
+ accept(id: any) {
this.sessionService.requestSessionAccept(id).then((res) => {
if (res) {
- this.isAccepted = true;
+ this.isAccepted.set(true);
this.toast.showToast(res.message, 'success');
- this.sessionService.getReqSessionDetails(this.params.id).then((res) => {
- this.apiResponse = res.result;
- if(res){
+ this.sessionService.getReqSessionDetails(this.params().id).then((requestRes) => {
+ this.apiResponse.set(requestRes.result);
+ if (requestRes) {
this.getAllUpdatedSession();
- this.sessionService.getSessionDetailsAPI(this.apiResponse.session_id).then((res) => {
- this.sessionDetails = res.result;
- })
+ this.sessionService.getSessionDetailsAPI(this.apiResponse().session_id).then((sessionRes) => {
+ this.sessionDetails.set(sessionRes.result);
+ });
}
});
}
- })
+ });
}
- async reject(id:any, name: string) {
- let msg = {
+ async reject(id: any, name: string) {
+ const msg = {
header: 'Reject ?',
message: 'Are you sure you want to reject this session request?',
cancel: 'CANCEL',
@@ -123,100 +136,107 @@ export class SessionRequestDetailsPage implements OnInit {
if (response) {
this.sessionService.requestSessionReject(id, response?.reason).then((res) => {
if (res) {
- this.isRejected = true;
- this.sessionService.getReqSessionDetails(this.params.id).then((res) => {
- this.apiResponse = res.result;});
+ this.isRejected.set(true);
+ this.sessionService.getReqSessionDetails(this.params().id).then((requestRes) => {
+ this.apiResponse.set(requestRes.result);
+ });
this.toast.showToast(res.message, 'danger');
}
- })
+ });
} else {
console.log('User canceled the rejection');
}
}
- addLink(isOpen: boolean, id:any) {
- this.isModalOpen = isOpen;
- this.sessionId = id;
+ addLink(isOpen: boolean, id: any) {
+ this.isModalOpen.set(isOpen);
+ this.sessionId.set(id);
}
async getPlatformFormDetails() {
- let form = await this.form.getForm(PLATFORMS);
+ const form = await this.form.getForm(PLATFORMS);
this.meetingPlatforms = form.data.fields.forms;
this.selectedLink = this.meetingPlatforms[0];
this.selectedHint = this.meetingPlatforms[0].hint;
}
- clickOptions(event:any){
+ clickOptions(event: any) {
this.selectedHint = event.detail.value.hint;
}
- compareWithFn(o1, o2) {
+ compareWithFn(o1: any, o2: any) {
return o1 === o2;
- };
+ }
- addNow(){
+ addNow() {
this.modal.dismiss();
- this.isModalOpen =false;
- if (this.platformForm?.myForm?.valid){
+ this.isModalOpen.set(false);
+ if (this.platformForm?.myForm?.valid) {
this.meetingInfo = {
- 'meeting_info':{
- 'platform': this.selectedLink.name,
- 'link': this.platformForm.myForm.value?.link,
- 'value': this.selectedLink.value,
- "meta": {
- "password": this.platformForm.myForm.value?.password,
- "meetingId":this.platformForm.myForm.value?.meetingId
+ meeting_info: {
+ platform: this.selectedLink.name,
+ link: this.platformForm.myForm.value?.link,
+ value: this.selectedLink.value,
+ meta: {
+ password: this.platformForm.myForm.value?.password,
+ meetingId: this.platformForm.myForm.value?.meetingId
+ }
}
+ };
+ }
+ this.sessionService.createSession(this.meetingInfo, this.sessionId()).then((res) => {
+ if (res) {
+ this.sessionService.getReqSessionDetails(this.params().id).then((requestRes) => {
+ this.apiResponse.set(requestRes.result);
+ if (this.apiResponse()?.status === 'ACCEPTED') {
+ this.sessionService.getSessionDetailsAPI(this.apiResponse().session_id).then((sessionRes) => {
+ this.sessionDetails.set(sessionRes.result);
+ this.isMeetingLinkAdded.set(true);
+ });
+ }
+ });
+ }
+ });
+ this.editSessionBtn.set(true);
+ }
- }}
+ editLink(isOpen: boolean, id: any) {
+ if (!this.sessionDetails()?.meeting_info) {
+ return;
}
- this.sessionService.createSession(this.meetingInfo,this.sessionId).then((res) => {
- if (res) {
- this.sessionService.getReqSessionDetails(this.params.id).then((res) => {
- this.apiResponse = res.result;
- });
- if (this.apiResponse?.status === 'ACCEPTED') {
- this.sessionService.getSessionDetailsAPI(this.apiResponse.session_id).then((res) => {
- this.sessionDetails = res.result;
- this.isMeetingLinkAdded = true;
- })
- }
- }});
- this.editSessionBtn = true;
- }
-
- editLink(isOpen: boolean, id:any) {
- this.isModalOpen = isOpen;
- this.sessionId = id;
- for(let j=0;j link?.name == 'link')
- let meetingId = this?.meetingPlatforms[j]?.form?.controls.find( (meetingId:any) => meetingId?.name == 'meetingId')
- let password = this?.meetingPlatforms[j]?.form?.controls.find( (password:any) => password?.name == 'password')
- if(obj && this.sessionDetails?.meeting_info?.link){
- obj.value = this.sessionDetails?.meeting_info?.link;
+ this.isModalOpen.set(isOpen);
+ this.sessionId.set(id);
+ for (let j = 0; j < this?.meetingPlatforms?.length; j++) {
+ if (this.sessionDetails().meeting_info.platform === this?.meetingPlatforms[j].name) {
+ this.selectedLink = this?.meetingPlatforms[j];
+ this.selectedHint = this.meetingPlatforms[j].hint;
+ const obj = this?.meetingPlatforms[j]?.form?.controls.find((link: any) => link?.name === 'link');
+ const meetingId = this?.meetingPlatforms[j]?.form?.controls.find((meet: any) => meet?.name === 'meetingId');
+ const password = this?.meetingPlatforms[j]?.form?.controls.find((pass: any) => pass?.name === 'password');
+ if (obj && this.sessionDetails()?.meeting_info?.link) {
+ obj.value = this.sessionDetails()?.meeting_info?.link;
}
- if(this.sessionDetails?.meeting_info?.meta?.meetingId){
- meetingId.value = this.sessionDetails?.meeting_info?.meta?.meetingId;
- password.value = this.sessionDetails?.meeting_info?.meta?.password;
+ if (this.sessionDetails()?.meeting_info?.meta?.meetingId) {
+ meetingId.value = this.sessionDetails()?.meeting_info?.meta?.meetingId;
+ password.value = this.sessionDetails()?.meeting_info?.meta?.password;
}
}
}
}
- addLater(){
+ addLater() {
this.modal.dismiss();
- this.isModalOpen = false;
+ this.isModalOpen.set(false);
}
- viewProfile(id: any){
+ viewProfile(id: any) {
this.router.navigate([CommonRoutes.MENTOR_DETAILS, id]);
}
async onStart(data) {
- let result = await this.sessionService.startSession(data);
- result?this.router.navigate([`/${CommonRoutes.TABS}/${CommonRoutes.HOME}`]):null;
+ const result = await this.sessionService.startSession(data);
+ if (result) {
+ this.router.navigate([`/${CommonRoutes.TABS}/${CommonRoutes.HOME}`]);
+ }
}
formatUnixTime(unixTimestamp: number): string {
diff --git a/src/app/pages/tabs/requests/requests.page.html b/src/app/pages/tabs/requests/requests.page.html
index e63612d5..77a3227e 100644
--- a/src/app/pages/tabs/requests/requests.page.html
+++ b/src/app/pages/tabs/requests/requests.page.html
@@ -1,9 +1,15 @@
+ @let currentSegment = segmentType();
+ @let cardConfig = mentorForm();
+ @let messageRequests = data();
+ @let sessionRequests = slotRequests();
+ @let hasNoResults = currentSegment === 'slot-requests' ? !sessionRequests.length : !messageRequests.length;
+
-
+
{{ "SLOT_REQUESTS" | translate }}
@@ -13,49 +19,56 @@
-
-
-
-
-
-
-
-
+
+ @switch (currentSegment) {
+ @case ('slot-requests') {
+
+
+ @for (value of sessionRequests; track value.id) {
+
+
+
+
+ }
-
-
-
-
-
-
-
-
-
-
+ }
+ @case ('message-requests') {
+
+
+ @for (value of messageRequests; track value.id) {
+
+
+
+
+ }
-
-
-
-
-
-
-
-
\ No newline at end of file
+ }
+ }
+
+
+
+
+
+
+ @if (hasNoResults && isDataAvailable()) {
+
+ }
+
diff --git a/src/app/pages/tabs/requests/requests.page.spec.ts b/src/app/pages/tabs/requests/requests.page.spec.ts
index d66b7a84..de9e3388 100644
--- a/src/app/pages/tabs/requests/requests.page.spec.ts
+++ b/src/app/pages/tabs/requests/requests.page.spec.ts
@@ -72,11 +72,11 @@ describe('RequestsPage', () => {
await component.ionViewWillEnter();
expect(formServiceSpy.getForm).toHaveBeenCalled();
- expect(component.mentorForm).toEqual(_.get(fakeFormResult, 'data.fields.controls'));
- expect(component.buttonConfig).toBeDefined();
- expect(component.slotBtnConfig).toBeDefined();
+ expect(component.mentorForm()).toEqual(_.get(fakeFormResult, 'data.fields.controls'));
+ expect(component.buttonConfig()).toBeDefined();
+ expect(component.slotBtnConfig()).toBeDefined();
expect(sessionServiceSpy.requestSessionList).toHaveBeenCalledWith(1);
- expect(component.isLoading).toBeFalse();
+ expect(component.isLoading()).toBeFalse();
}));
it('segmentChanged should switch to message-requests and call pendingRequest', waitForAsync(async () => {
@@ -85,7 +85,7 @@ describe('RequestsPage', () => {
await component.segmentChanged(event);
- expect(component.segmentType).toBe('message-requests');
+ expect(component.segmentType()).toBe('message-requests');
expect(component.page).toBe(1);
expect(component.pendingRequest).toHaveBeenCalled();
}));
@@ -97,10 +97,10 @@ describe('RequestsPage', () => {
const result = await component.pendingRequest();
expect(httpServiceSpy.get).toHaveBeenCalled();
- expect(component.data.length).toBe(0);
- expect(component.noResult).toBe(component.routeData?.noDataFound?.noMessage);
- // when response count is 0, component.data.length >= totalCount -> true
- expect(component.isInfiniteScrollDisabled).toBeTrue();
+ expect(component.data().length).toBe(0);
+ expect(component.noResult()).toBe(component.routeData()?.noDataFound?.noMessage);
+ // when response count is 0, component.data().length >= totalCount -> true
+ expect(component.isInfiniteScrollDisabled()).toBeTrue();
expect(result).toBe(resp);
}));
@@ -117,10 +117,10 @@ describe('RequestsPage', () => {
await component.slotRequestData();
expect(sessionServiceSpy.requestSessionList).toHaveBeenCalledWith(component.page);
- expect(component.slotRequests.length).toBe(2);
+ expect(component.slotRequests().length).toBe(2);
- const expired = component.slotRequests.find((s: any) => s.id === 'expired');
- const active = component.slotRequests.find((s: any) => s.id === 'active');
+ const expired = component.slotRequests().find((s: any) => s.id === 'expired');
+ const active = component.slotRequests().find((s: any) => s.id === 'active');
expect(expired.showTag).toEqual(component.expiryTag);
expect(expired.disableButton).toBeTrue();
@@ -145,7 +145,7 @@ describe('RequestsPage', () => {
spyOn(component, 'slotRequestData').and.returnValue(Promise.resolve());
const event = { target: { complete: jasmine.createSpy('complete') } } as any;
- component.segmentType = 'slot-requests';
+ component.segmentType.set('slot-requests');
component.page = 1;
await component.loadMore(event);
@@ -160,7 +160,7 @@ describe('RequestsPage', () => {
const resp = await component.pendingRequest();
- expect(component.isInfiniteScrollDisabled).toBeTrue();
+ expect(component.isInfiniteScrollDisabled()).toBeTrue();
expect(resp).toBe('err');
}));
diff --git a/src/app/pages/tabs/requests/requests.page.ts b/src/app/pages/tabs/requests/requests.page.ts
index ae50dfee..a8d4c01d 100644
--- a/src/app/pages/tabs/requests/requests.page.ts
+++ b/src/app/pages/tabs/requests/requests.page.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, signal } from '@angular/core';
import { urlConstants } from 'src/app/core/constants/urlConstants';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
@@ -23,23 +23,25 @@ export class RequestsPage implements OnInit {
headerColor: 'primary',
notification: false,
};
- segmentType = 'slot-requests';
- buttonConfig: any;
- data: any[] = [];
- noResult: any;
- routeData: any;
- slotBtnConfig: any;
- slotRequests: any[] = [];
- mentorForm:any;
+
+ segmentType = signal<'slot-requests' | 'message-requests'>('slot-requests');
+ buttonConfig = signal(null);
+ data = signal([]);
+ noResult = signal('');
+ routeData = signal(null);
+ slotBtnConfig = signal(null);
+ slotRequests = signal([]);
+ mentorForm = signal(null);
+ isInfiniteScrollDisabled = signal(false);
+ isLoading = signal(false);
+ isDataAvailable = signal(false);
+
expiryTag = {
label: 'EXPIRED',
cssClass: 'expired-tag'
};
page = 1;
- isInfiniteScrollDisabled = false;
- isLoading: boolean = false;
- isDataAvailable: boolean;
-
+
constructor(
private httpService: HttpService,
private route: ActivatedRoute,
@@ -48,44 +50,46 @@ export class RequestsPage implements OnInit {
private form: FormService,
) {}
- async ionViewWillEnter(){
- if(this.isLoading)
- return;
- this.isDataAvailable = false;
- this.isLoading = true;
+ async ionViewWillEnter() {
+ if (this.isLoading()) return;
+
+ this.isDataAvailable.set(false);
+ this.isLoading.set(true);
+
const result = await this.form.getForm(MENTOR_REQ_CARD_FORM);
- this.mentorForm = _.get(result, 'data.fields.controls');
+ this.mentorForm.set(_.get(result, 'data.fields.controls'));
+
this.route.data.subscribe((data) => {
- this.routeData = data;
- this.buttonConfig = this.routeData?.button_config;
- this.slotBtnConfig = this.routeData.slotButtonConfig;
+ this.routeData.set(data);
+ this.buttonConfig.set(data?.button_config);
+ this.slotBtnConfig.set(data?.slotButtonConfig);
});
-
+
this.page = 1;
- this.slotRequests = [];
- this.data = [];
- this.isInfiniteScrollDisabled = false;
-
- if (this.segmentType === 'slot-requests') {
+ this.slotRequests.set([]);
+ this.data.set([]);
+ this.isInfiniteScrollDisabled.set(false);
+
+ if (this.segmentType() === 'slot-requests') {
await this.slotRequestData();
} else {
await this.pendingRequest();
}
- this.isLoading = false;
- }
-
- ngOnInit() {
+ this.isLoading.set(false);
}
+ ngOnInit() {}
+
async segmentChanged(event: any) {
- this.segmentType = event.target.value;
+ this.segmentType.set(event.target.value);
this.page = 1;
- this.isInfiniteScrollDisabled = false;
- this.noResult = '';
- this.slotRequests = [];
- this.data = [];
- this.isDataAvailable = false;
- if (this.segmentType === 'slot-requests') {
+ this.isInfiniteScrollDisabled.set(false);
+ this.noResult.set('');
+ this.slotRequests.set([]);
+ this.data.set([]);
+ this.isDataAvailable.set(false);
+
+ if (this.segmentType() === 'slot-requests') {
await this.slotRequestData();
} else {
await this.pendingRequest();
@@ -95,34 +99,34 @@ export class RequestsPage implements OnInit {
async pendingRequest(isLoadMore: boolean = false) {
const config = {
url: urlConstants.API_URLS.CONNECTION_REQUEST +
- '?pageNo=' + this.page +
- '&pageSize=100',
+ '?pageNo=' + this.page +
+ '&pageSize=100',
};
-
+
try {
let response: any = await this.httpService.get(config);
- this.isDataAvailable = true;
- let newData = response?.result?.data || [];
-
+ this.isDataAvailable.set(true);
+ const newData = response?.result?.data || [];
+
if (isLoadMore) {
- this.data = [...this.data, ...newData];
+ this.data.update(prev => [...prev, ...newData]);
} else {
- this.data = newData;
+ this.data.set(newData);
}
-
+
const totalCount = response?.result?.count || 0;
- this.isInfiniteScrollDisabled = this.data.length >= totalCount;
-
- if (this.data.length === 0 && this.page === 1) {
- this.noResult = this.routeData?.noDataFound?.noMessage;
+ this.isInfiniteScrollDisabled.set(this.data().length >= totalCount);
+
+ if (this.data().length === 0 && this.page === 1) {
+ this.noResult.set(this.routeData()?.noDataFound?.noMessage);
} else {
- this.noResult = '';
+ this.noResult.set('');
}
-
+
return response;
} catch (error) {
console.error('Error fetching pending requests:', error);
- this.isInfiniteScrollDisabled = true;
+ this.isInfiniteScrollDisabled.set(true);
return error;
}
}
@@ -130,20 +134,20 @@ export class RequestsPage implements OnInit {
async slotRequestData(isLoadMore: boolean = false) {
try {
const res = await this.sessionService.requestSessionList(this.page);
- this.isDataAvailable = true;
- let data = [];
-
+ this.isDataAvailable.set(true);
+
+ let data: any[];
if (isLoadMore) {
- data = [...this.slotRequests, ...(res?.result?.data || [])];
+ data = [...this.slotRequests(), ...(res?.result?.data || [])];
} else {
data = res?.result?.data || [];
}
-
+
const totalCount = res?.result?.count || 0;
- this.isInfiniteScrollDisabled = data.length >= totalCount;
-
+ this.isInfiniteScrollDisabled.set(data.length >= totalCount);
+
if (data.length === 0 && this.page === 1) {
- this.noResult = this.routeData?.noDataFound?.noSession;
+ this.noResult.set(this.routeData()?.noDataFound?.noSession);
return;
}
@@ -154,11 +158,11 @@ export class RequestsPage implements OnInit {
disableButton: this.isSessionExpired(value)
}));
- this.slotRequests = formattedData;
+ this.slotRequests.set(formattedData);
} catch (error) {
console.error('Error fetching session list:', error);
- this.isInfiniteScrollDisabled = true;
+ this.isInfiniteScrollDisabled.set(true);
}
}
@@ -171,32 +175,40 @@ export class RequestsPage implements OnInit {
};
}
- isSessionExpired(meta): boolean {
+ getMessageRequestMeta(value: any) {
+ return {
+ isSent: value?.created_by === value?.user_id,
+ message: value?.meta?.message,
+ timeStamp: ''
+ };
+ }
+
+ isSessionExpired(meta: any): boolean {
const endDate = meta?.end_date;
- if (!endDate) return false;
+ if (!endDate) return false;
return Date.now() > endDate * 1000;
}
-
- onCardClick(event, data?) {
+
+ onCardClick(event: any, data?: any) {
switch (event.type) {
case 'viewMessage':
this.router.navigate([CommonRoutes.CHAT_REQ, event.data]);
break;
case 'viewDetails':
- this.router.navigate([CommonRoutes.SESSION_REQUEST_DETAILS], {queryParams: {id: data}});
+ this.router.navigate([CommonRoutes.SESSION_REQUEST_DETAILS], { queryParams: { id: data } });
break;
}
}
async loadMore($event: any) {
this.page = this.page + 1;
-
- if (this.segmentType === 'slot-requests') {
+
+ if (this.segmentType() === 'slot-requests') {
await this.slotRequestData(true);
} else {
await this.pendingRequest(true);
}
-
+
$event.target.complete();
}
-}
\ No newline at end of file
+}
diff --git a/src/app/shared/components/generic-profile-header/generic-profile-header.component.ts b/src/app/shared/components/generic-profile-header/generic-profile-header.component.ts
index 6dbe08fb..4fc2caa8 100644
--- a/src/app/shared/components/generic-profile-header/generic-profile-header.component.ts
+++ b/src/app/shared/components/generic-profile-header/generic-profile-header.component.ts
@@ -61,13 +61,15 @@ export class GenericProfileHeaderComponent implements OnInit {
}
async action(event) {
+ const header = this.headerData();
+ const meta = this.buttonConfig()?.meta;
switch (event) {
case 'edit':
this.router.navigate([`/${CommonRoutes.EDIT_PROFILE}`], {replaceUrl:true});
break;
case 'role':
- if (this.headerData()?.about != null || environment['isAuthBypassed']) {
+ if (header?.about != null || environment['isAuthBypassed']) {
this.router.navigate([`/${CommonRoutes.MENTOR_QUESTIONNAIRE}`]);
} else {
this.profileService.upDateProfilePopup();
@@ -75,11 +77,11 @@ export class GenericProfileHeaderComponent implements OnInit {
break;
case 'share':
- if (this.isMobile && navigator.share && this.buttonConfig()?.meta) {
+ if (this.isMobile && navigator.share && meta) {
this.translateText();
- let url = `/mentoring/${CommonRoutes.MENTOR_DETAILS}/${this.buttonConfig().meta.id}`;
+ let url = `/mentoring/${CommonRoutes.MENTOR_DETAILS}/${meta.id}`;
let link = await this.utilService.getDeepLink(url);
- const name = (this.headerData()?.name || '').trim();
+ const name = (header?.name || '').trim();
let params = {
link: link,
subject: name,
@@ -92,17 +94,17 @@ export class GenericProfileHeaderComponent implements OnInit {
}
break;
case 'requestSession':
- this.router.navigate([`/${CommonRoutes.SESSION_REQUEST}`], {queryParams: {data: this.headerData().id}});
+ this.router.navigate([`/${CommonRoutes.SESSION_REQUEST}`], {queryParams: {data: header?.id}});
break;
case 'chat':
- this.headerData().is_connected
+ header?.is_connected
? this.router.navigate([
`/${CommonRoutes.CHAT}`,
- this.headerData().connection_details?.room_id,
- ],{queryParams: {id: this.headerData().id}})
+ header?.connection_details?.room_id,
+ ],{queryParams: {id: header?.id}})
: this.router.navigate([
`/${CommonRoutes.CHAT_REQ}`,
- this.headerData().id,
+ header?.id,
]);
}
}
@@ -130,7 +132,8 @@ export class GenericProfileHeaderComponent implements OnInit {
};
async viewRoles(){
- const titlesArray = this.headerData().organizations[0].roles.map(item => item.title);
+ const roles = this.headerData()?.organizations?.[0]?.roles || [];
+ const titlesArray = roles.map(item => item.title);
this.profileService.viewRolesModal(titlesArray);
}
}
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index e8ea3df7..50d5c71f 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -412,6 +412,8 @@
"CLUSTER":"Cluster",
"DISTRICT":"District",
"BLOCK":"Block",
+ "YOU_HAVE_BLOCKED":"You have blocked {{name}}",
+ "DO_YOU_WISH_TO_UNBLOCK":"Do you wish to unblock?",
"SCHOOL":"School",
"LOADING": "Loading more data...",
"YOU_HAVE" :"You have requested",
@@ -430,5 +432,6 @@
"DESELECT_ALL" : "Deselect all",
"SELECTED" : "Selected",
"SELECT_PAGE" : "Select page",
- "DESELECT_PAGE" : "Deselect page"
+ "DESELECT_PAGE" : "Deselect page",
+ "TYPE_MESSAGE_HERE": "Type a message ..."
}
diff --git a/src/assets/i18n/hi.json b/src/assets/i18n/hi.json
index 23467711..d30aeb7e 100644
--- a/src/assets/i18n/hi.json
+++ b/src/assets/i18n/hi.json
@@ -388,4 +388,8 @@
"SELECTED": "चयनित",
"SELECT_PAGE": "पेज चुनें",
"DESELECT_PAGE": "पेज चयन हटाएँ"
+ ,
+ "YOU_HAVE_BLOCKED": "आपने {{name}} को ब्लॉक किया है",
+ "DO_YOU_WISH_TO_UNBLOCK": "क्या आप अनब्लॉक करना चाहते हैं?",
+ "TYPE_MESSAGE_HERE": "यहाँ संदेश टाइप करें..."
}