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

Features/task 360 exclusao conta #1

Merged
merged 2 commits into from
Dec 10, 2024
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
2 changes: 1 addition & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ generator client {

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
url = env("DATABASE_URL_LOCAL")
}

model mentors {
Expand Down
38 changes: 38 additions & 0 deletions src/modules/mails/mail.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,44 @@ export class MailService {
return;
}

/**
* Criar método que envie uma notificação via email informando que a conta será desativada em 30 dias.
* @input mentor: MentorEntity
* @processamento
** tenta chamar o método this.mailerService.sendMail passando os dados desestruturados do mentor.
* @output
** email enviado para o mentor || catch (error) console.log(error.message)
*/

async mentorSendAccountDeletionNotice(mentor: MentorEntity): Promise<void> {
// Desestruturar mentor
const { email, fullName, code } = mentor;

// url para logar e reativar a conta
const loginUrl = process.env.LOGIN_URL;
// TODO: SOLICITAR A URL PARA LOGIN

try {
await this.mailerService.sendMail({
to: email,
subject: 'Conta em processo de exclusão - SouJunior',
template: './firstAccountDeletionReminder',
context: {
name: fullName,
loginUrl,
// Para testar, irei deixar a hora de exclusão daqui a 1 hora.
deletionDate: new Date(
Date.now() + 1 * 60 * 1000, // 1 minuto (para fins de testes)
).toLocaleDateString('pt-BR'),
},
});
} catch (error) {
console.log(error.message);
}

return;
}

async userSendEmailConfirmation(user: UserEntity): Promise<void> {
const { email, fullName, code } = user;
const url = `${process.env.URL_CONFIRM_EMAIL}?code=${code}&email=${email}`;
Expand Down
211 changes: 211 additions & 0 deletions src/modules/mails/templates/firstAccountDeletionReminder.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
<!DOCTYPE html>
<html lang="pt-br">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
@import url('https://fonts.googleapis.com/css2?family=Radio+Canada:ital,wght@0,300..700;1,300..700&display=swap');

.table-container {
padding: 56px 64px;
}

.td-logo {
padding-bottom: 16px;
}

h2 {
font-size: 32px;
line-height: 38.4px;
padding-bottom: 8px;
}

h3 {
font-size: 24px;
line-height: 28.8px;
}

.td-ilustration {
padding: 40px 0;
}

.td-message {
padding-bottom: 16px;
}

.p-message {
font-size: 16px;
line-height: 22.4px;
font-family: 'Radio Canada', sans-serif;
margin: 0;
}

.td-button {
padding: 40px 0;
}

.p-footer {
font-family: 'Radio Canada', sans-serif;
margin: 0;
font-size: 12px;
font-weight: 500;
}

@media screen and (max-width: 480px) {
.table-container {
padding: 40px 32px;
}

.td-logo {
padding-bottom: 8px;
}

h2 {
font-size: 24px;
line-height: 28.8px;
padding-bottom: 4px;
}

h3 {
font-size: 20px;
line-height: 24px;
}

.td-ilustration {
padding: 24px 0 32px 0;
}

.td-message {
padding-bottom: 8px;
}

.p-message {
font-size: 14px;
line-height: 16.8px;
}

.td-button {
padding: 24px 0;
}
}
</style>
</head>

<body style="
margin: 0;
padding: 0;
font-family: 'Radio Canada', sans-serif;
background-color: #F5F5F7;
color: #323232;">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center">
<table class="table-container" cellpadding="0" cellspacing="0" border="0" style="
font-family: 'Radio Canada', sans-serif;
max-width: 800px;
background-color: #ffffff;">
<!-- Logo -->
<tr>
<td class="td-logo" align="center">
<img src="logo.svg" alt="Logo da SouJunior" style="max-width: 100%">
</td>
</tr>
<!-- Title -->
<tr>
<td align="center">
<h2 style="
font-family: 'Radio Canada', sans-serif;
margin: 0;
font-weight: 600;">
Pedido de exclusão enviado
</h2>
</td>
</tr>
<!-- Subtitle -->
<tr>
<td align="center">
<h3 style="
font-family: 'Radio Canada', sans-serif;
margin: 0;
font-weight: 500;">
Sua conta foi desativada e será removida em breve
</h3>
</td>
</tr>
<!-- Ilustration -->
<tr>
<td class="td-ilustration" align="center">
<img src="ilustration.svg" alt="Imagem ilustrativa de um robô" style="max-width: 100%;">
</td>
</tr>
<!-- Message -->
<tr>
<td class="td-message" align="left">
<p class="p-message">
Sua conta para mentor(a) da SouJunior recebeu um pedido de exclusão. A partir de agora, <strong>seu
perfil não ficará visível</strong> para agendamentos de mentorias.
</p>
</td>
</tr>
<tr>
<td class="td-message" align="left">
<p class="p-message">
Lembrando que essa ação ainda não é definitiva. Você terá <strong>30 dias para reconsiderar</strong> sua
saída da SouJunior. Caso deseje reativar, faça o login novamente.
</p>
</td>
</tr>
<tr>
<td align="left">
<p class="p-message">
Após esse período, não será possível recuperar sua conta.
</p>
</td>
</tr>
<!-- Button -->
<tr>
<td align="center">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="td-button" align="center">
<a href="http://localhost:3000/login" style="
display: block;
font-family: 'Radio Canada', sans-serif;
padding: 12.5px 24px;
border: 2px solid #003986;
border-radius: 8px;
color: #003986;
font-size: 16px;
font-weight: 500;
text-decoration: none;">
Realizar login e reativar conta
</a>
</td>
</tr>
</table>
</td>
</tr>
<!-- Footer -->
<tr>
<td align="center">
<p class="p-footer">
Caso não tenha sido você quem solicitou a exclusão, entre em contato com o <a
href="http://localhost:3000/faq" style="color: #003986;">suporte</a>.
</p>
</td>
</tr>
<tr>
<td align="center">
<p class="p-footer" style="margin-top: 16px;">
Por favor, não responda a este e-mail.
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DesactivateLoggedMentorService } from '../../services/deactivateLoggedMentor.service';
import { DeactivateLoggedMentorService } from '../../services/deactivateLoggedMentor.service';

describe('Desactivate Logged Mentor Tests', () => {

});
describe('Desactivate Logged Mentor Tests', () => {});
2 changes: 1 addition & 1 deletion src/modules/mentors/entities/mentor.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ export class MentorEntity {
createdAt?: string | Date;
updatedAt?: string | Date;
deleted?: boolean;
}
}
8 changes: 4 additions & 4 deletions src/modules/mentors/mentor.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { MentorChangePassDto } from './dtos/mentor-change-pass.dto';
import { ActivateMentorService } from './services/activateMentor.service';
import { ChangeMentorPasswordService } from './services/changeMentorPassword.service';
import { CreateMentorService } from './services/createMentor.service';
import { DesactivateLoggedMentorService } from './services/deactivateLoggedMentor.service';
import { DeactivateLoggedMentorService } from './services/deactivateLoggedMentor.service';
import { GetMentorByIdService } from './services/getMentorById.service';
import { GetMentorByNameAndRoleService } from './services/getMentorByNameAndRole.service';
import { ListAllMentorsService } from './services/listAllMentors.service';
Expand All @@ -57,7 +57,7 @@ export class MentorController {
private activateMentorService: ActivateMentorService,
private changeMentorPasswordService: ChangeMentorPasswordService,
private createMentorService: CreateMentorService,
private deactivateLoggedMentorService: DesactivateLoggedMentorService,
private deactivateLoggedMentorService: DeactivateLoggedMentorService,
private getMentorByIdService: GetMentorByIdService,
private getMentorByNameAndRoleService: GetMentorByNameAndRoleService,
private listAllMentorsService: ListAllMentorsService,
Expand All @@ -66,7 +66,7 @@ export class MentorController {
private updateMentorService: UpdateMentorService,
private uploadProfileImageService: UploadProfileImageService,
private finishMentorRegisterService: FinishMentorRegisterService,
private getRegisteredMentorsService: ListAllRegisteredMentorsService
private getRegisteredMentorsService: ListAllRegisteredMentorsService,
) {}

@Post()
Expand Down Expand Up @@ -166,7 +166,7 @@ export class MentorController {

@ApiExcludeEndpoint()
@Patch(':id')
async desactivateLoggedEntity(@Param() { id }: GetByIdDto) {
async deactivateLoggedEntity(@Param() { id }: GetByIdDto) {
return this.deactivateLoggedMentorService.execute(id);
}

Expand Down
6 changes: 3 additions & 3 deletions src/modules/mentors/mentor.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { GetMentorByIdService } from './services/getMentorById.service';
import { GetMentorByNameAndRoleService } from './services/getMentorByNameAndRole.service';
import { ActivateMentorService } from './services/activateMentor.service';
import { ChangeMentorPasswordService } from './services/changeMentorPassword.service';
import { DesactivateLoggedMentorService } from './services/deactivateLoggedMentor.service';
import { DeactivateLoggedMentorService } from './services/deactivateLoggedMentor.service';
import { FinishMentorRegisterService } from './services/finishMentorRegisterService.service';
import { RedefineMentorPasswordService } from './services/redefineMentorPassword.service';
import { SendRestorationEmailService } from './services/sendRestorationEmail.service';
Expand All @@ -32,15 +32,15 @@ import { ListAllRegisteredMentorsService } from './services/listAllRegisteredMen
GetMentorByNameAndRoleService,
ActivateMentorService,
ChangeMentorPasswordService,
DesactivateLoggedMentorService,
DeactivateLoggedMentorService,
FinishMentorRegisterService,
RedefineMentorPasswordService,
SendRestorationEmailService,
UploadProfileImageService,
MentorRepository,
GenerateCodeUtil,
FileUploadService,
JwtService
JwtService,
],
exports: [MentorRepository],
})
Expand Down
6 changes: 4 additions & 2 deletions src/modules/mentors/repository/mentor.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export class MentorRepository extends PrismaClient {
}

async findAllRegisteredMentors(): Promise<MentorEntity[]> {
return this.mentors.findMany({where: { registerComplete: true }}).catch(handleError);
return this.mentors
.findMany({ where: { registerComplete: true } })
.catch(handleError);
}

async findMentorByEmail(email: string): Promise<MentorEntity> {
Expand Down Expand Up @@ -79,7 +81,7 @@ export class MentorRepository extends PrismaClient {
return mentors;
}

async desativateMentorById(id: string): Promise<MentorEntity> {
async deactivateMentorById(id: string): Promise<MentorEntity> {
return this.mentors
.update({
where: {
Expand Down
22 changes: 19 additions & 3 deletions src/modules/mentors/services/deactivateLoggedMentor.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import { MailService } from 'src/modules/mails/mail.service';
import { MentorRepository } from '../repository/mentor.repository';
import { Injectable } from '@nestjs/common';

@Injectable()
export class DesactivateLoggedMentorService {
constructor(private mentorRepository: MentorRepository) {}
export class DeactivateLoggedMentorService {
constructor(
private mentorRepository: MentorRepository,
private mailService: MailService,
) {}

async execute(id: string): Promise<{ message: string }> {
await this.mentorRepository.desativateMentorById(id);
const mentor = await this.mentorRepository.findMentorById(id);

if (!mentor) {
throw new Error('Mentor not found');
}

await this.mailService.mentorSendAccountDeletionNotice({
...mentor,
password: '',
role: 'mentor',
});

await this.mentorRepository.deactivateMentorById(id);

return { message: 'Mentor deactivated successfully' };
}
Expand Down