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

Win25/issue 376 #377

Merged
merged 2 commits into from
Jan 26, 2025
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 @@ -12,7 +12,10 @@ import { DeepReadonly, STATES } from '@involvemint/shared/util';
import { IonSlides } from '@ionic/angular';
import { FormControl, FormGroup } from '@ngneat/reactive-forms';
import { subYears } from 'date-fns';
import { takeUntil, tap } from 'rxjs/operators';
import { takeUntil, tap, take } from 'rxjs/operators';
import { ChangeMakerService } from '@involvemint/server/core/application-services';
import { ImAuthTokenStorage } from '@involvemint/client/shared/data-access';


/**
* Schema to create ChangeMaker Profile
Expand Down Expand Up @@ -58,13 +61,35 @@ export class CreateCmProfileComponent extends StatefulComponent<State> implement
constructor(
private readonly uf: UserFacade,
private readonly handleRestClient: HandleRestClient,
private readonly route: ActivatedRoute
private readonly route: ActivatedRoute,
private readonly changeMakerService: ChangeMakerService
) {
super({ verifyingHandle: false });
}

ngOnInit(): void {
// Get auth token from storage, similar to user-session.effects.ts
const authToken = ImAuthTokenStorage.getValue()?.token;

if (authToken) {
// Pre-populate form with data from the backend
this.changeMakerService.getPrePopulatedData(authToken).then((data) => {
if (data) {
this.createProfileForm.patchValue({
firstName: data.firstName || '',
lastName: data.lastName || '',
phone: data.phone || '',
});
}
});
} else {
console.error('Authentication token is missing');
}

// Verify handle uniqueness
this.effect(() => verifyHandleUniqueness(this.createProfileForm, this.handleRestClient, this));

// Check for onboarding state from query parameters
this.route.queryParams
.pipe(
tap((q) => {
Expand Down
36 changes: 21 additions & 15 deletions libs/server/api/src/lib/change-maker/change-maker.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,34 @@ import {
UserQuery,
} from '@involvemint/shared/domain';
import {
Controller,
Post,
Body,
UseInterceptors,
UploadedFile,
Headers
} from '@nestjs/common';
Controller,
Post,
Get,
Body,
Headers,
UseInterceptors,
UploadedFile,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { QueryValidationPipe, ValidationPipe } from '../pipes';

@Controller(InvolvemintRoutes.changeMaker)
export class ChangeMakerController {
constructor(private readonly cmService: ChangeMakerService) {}
constructor(private readonly cmService: ChangeMakerService) {}

@Post('createProfile')
createProfile(
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@Body(DTO_KEY, new ValidationPipe()) dto: CreateChangeMakerProfileDto
) {
return this.cmService.createProfile(query, token, dto);
return this.cmService.createProfile(query, token, dto);
}

@Post('editProfile')
async editProfile(
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@Body(DTO_KEY, new ValidationPipe()) dto: EditCmProfileDto
) {
return this.cmService.editProfile(query, token, dto);
Expand All @@ -47,10 +48,15 @@ export class ChangeMakerController {
@Post('updateProfileImage')
@UseInterceptors(FileInterceptor(FILES_KEY))
async updateProfileImage(
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@Body(QUERY_KEY, new QueryValidationPipe(UserQuery.changeMaker)) query: IQuery<ChangeMaker>,
@Headers(TOKEN_KEY) token: string,
@UploadedFile() file: Express.Multer.File
) {
return this.cmService.updateProfileImage(query, token, file);
}

@Get('prepopulate')
async getPrePopulatedData(@Headers(TOKEN_KEY) token: string) {
return this.cmService.getPrePopulatedData(token);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { ChangeMakerRepository, HandleRepository } from '@involvemint/server/core/domain-services';
import { ExchangePartnerRepository } from '@involvemint/server/core/domain-services';
import { ServePartnerRepository } from '@involvemint/server/core/domain-services';
import {
ChangeMaker,
CreateChangeMakerProfileDto,
Expand All @@ -17,6 +19,8 @@ import { StorageService } from '../storage/storage.service';
export class ChangeMakerService {
constructor(
private readonly cmRepo: ChangeMakerRepository,
private readonly exchangePartnerRepo: ExchangePartnerRepository,
private readonly servePartnerRepo: ServePartnerRepository,
private readonly auth: AuthService,
private readonly handle: HandleRepository,
private readonly storage: StorageService,
Expand All @@ -30,8 +34,31 @@ export class ChangeMakerService {
* @param dto Essential ChangeMaker profile data.
*/
async createProfile(query: IQuery<ChangeMaker>, token: string, dto: CreateChangeMakerProfileDto) {

const user = await this.auth.validateUserToken(token);
await this.handle.verifyHandleUniqueness(dto.handle);


let existingPartnerData;
// Fetch relevant data based on the user's role
if (user.exchangeAdmins.length > 0) {
const exchangePartner = user.exchangeAdmins[0].exchangePartner;
existingPartnerData = exchangePartner;
} else if (user.serveAdmins.length > 0) {
const servePartner = user.serveAdmins[0].servePartner;
existingPartnerData = servePartner;
}

// Pre-populate Changemaker profile if existing data is available
if (existingPartnerData) {
const [firstName, ...lastNameParts] = existingPartnerData.name.split(' ');
const lastName = lastNameParts.join(' ') || 'N/A'; // Default to 'N/A' if last name is missing

dto.firstName = dto.firstName || firstName;
dto.lastName = dto.lastName || lastName;
dto.phone = dto.phone || existingPartnerData.phone;
}

return this.cmRepo.upsert(
{
id: uuid.v4(),
Expand Down Expand Up @@ -100,4 +127,39 @@ export class ChangeMakerService {

return this.cmRepo.update(user.changeMaker.id, { profilePicFilePath: path }, query);
}

// This is for the frontend
async getPrePopulatedData(token: string): Promise<{ firstName: string; lastName: string; phone: string }> {
const user = await this.auth.validateUserToken(token);

let existingPartnerData;
if (user.exchangeAdmins.length > 0) {
const exchangePartner = user.exchangeAdmins[0].exchangePartner;
existingPartnerData = exchangePartner;
} else if (user.serveAdmins.length > 0) {
const servePartner = user.serveAdmins[0].servePartner;
existingPartnerData = servePartner;
}

if (existingPartnerData) {
const [firstName, ...lastNameParts] = existingPartnerData.name.split(' ');
const lastName = lastNameParts.join(' ') || 'N/A';
const phone = existingPartnerData.phone || '';

return {
firstName,
lastName,
phone,
};
}

// If no existing data, return default empty values
return {
firstName: '',
lastName: '',
phone: '',
};
}


}