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

Add status update logs #121

Merged
merged 2 commits into from
Jun 30, 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
8 changes: 6 additions & 2 deletions src/controllers/admin/mentee.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Request, Response } from 'express'
import { ApplicationStatus, ProfileTypes } from '../../enums'
import { ApplicationStatus, ProfileTypes, StatusUpdatedBy } from '../../enums'
import type Profile from '../../entities/profile.entity'
import type Mentee from '../../entities/mentee.entity'
import type { ApiResponse } from '../../types'
Expand Down Expand Up @@ -54,7 +54,11 @@ export const updateMenteeStatus = async (
return res.status(403).json({ message: 'Only Admins are allowed' })
}

const { statusCode, message } = await updateStatus(menteeId, state)
const { statusCode, message } = await updateStatus(
menteeId,
state,
StatusUpdatedBy.ADMIN
)
return res.status(statusCode).json({ message })
} catch (err) {
if (err instanceof Error) {
Expand Down
8 changes: 6 additions & 2 deletions src/controllers/mentee.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type ApiResponse } from '../types'
import type Mentee from '../entities/mentee.entity'
import type Profile from '../entities/profile.entity'
import { getMentee, updateStatus } from '../services/admin/mentee.service'
import { ApplicationStatus } from '../enums'
import { ApplicationStatus, StatusUpdatedBy } from '../enums'
import { addMentee } from '../services/mentee.service'

export const menteeApplicationHandler = async (
Expand Down Expand Up @@ -48,7 +48,11 @@ export const updateMenteeStatus = async (
return res.status(403).json({ message: 'Only mentors are allowed' })
}

const { statusCode, message } = await updateStatus(menteeId, state)
const { statusCode, message } = await updateStatus(
menteeId,
state,
StatusUpdatedBy.MENTOR
)
return res.status(statusCode).json({ message })
} catch (err) {
if (err instanceof Error) {
Expand Down
8 changes: 7 additions & 1 deletion src/entities/mentee.entity.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'
import Mentor from './mentor.entity'
import profileEntity from './profile.entity'
import { ApplicationStatus } from '../enums'
import { ApplicationStatus, StatusUpdatedBy } from '../enums'
import BaseEntity from './baseEntity'

@Entity('mentee')
Expand All @@ -13,6 +13,12 @@ class Mentee extends BaseEntity {
})
state: ApplicationStatus

@Column({ type: 'enum', enum: StatusUpdatedBy, nullable: true })
status_updated_by!: StatusUpdatedBy

@Column({ type: 'timestamp', nullable: true })
status_updated_date!: Date

@Column({ type: 'json' })
application: Record<string, unknown>

Expand Down
5 changes: 5 additions & 0 deletions src/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ export enum ApplicationStatus {
REJECTED = 'rejected',
APPROVED = 'approved'
}

export enum StatusUpdatedBy {
ADMIN = 'admin',
MENTOR = 'mentor'
}
14 changes: 11 additions & 3 deletions src/services/admin/mentee.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { dataSource } from '../../configs/dbConfig'
import Mentee from '../../entities/mentee.entity'
import Mentor from '../../entities/mentor.entity'
import { ApplicationStatus } from '../../enums'
import { ApplicationStatus, type StatusUpdatedBy } from '../../enums'
import { getEmailContent } from '../../utils'
import { sendEmail } from './email.service'

Expand Down Expand Up @@ -80,7 +80,8 @@ export const getAllMenteesByMentor = async (

export const updateStatus = async (
menteeId: string,
state: ApplicationStatus
state: ApplicationStatus,
statusUpdatedBy: StatusUpdatedBy
): Promise<{
statusCode: number
updatedMenteeApplication?: Mentee
Expand Down Expand Up @@ -120,7 +121,14 @@ export const updateStatus = async (
message: 'Mentee is already approved'
}
} else {
await menteeRepository.update({ uuid: menteeId }, { state })
await menteeRepository.update(
{ uuid: menteeId },
{
state,
status_updated_by: statusUpdatedBy,
status_updated_date: new Date()
}
)
const content = getEmailContent(
'mentee',
state,
Expand Down
12 changes: 11 additions & 1 deletion src/services/mentee.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Mentee from '../entities/mentee.entity'
import Mentor from '../entities/mentor.entity'
import type Profile from '../entities/profile.entity'
import { ApplicationStatus } from '../enums'
import { getEmailContent } from '../utils'
import { getEmailContent, getMentorNotifyEmailContent } from '../utils'
import { sendEmail } from './admin/email.service'

export const addMentee = async (
Expand Down Expand Up @@ -82,12 +82,22 @@ export const addMentee = async (
application.firstName as string
)

const mentorContent = getMentorNotifyEmailContent(
mentor.application.firstName as string
)

if (content) {
await sendEmail(
application.email as string,
content.subject,
content.message
)

await sendEmail(
mentor.application.email as string,
mentorContent.subject,
mentorContent.message
)
}

return {
Expand Down
26 changes: 20 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
file: Express.Multer.File,
cb: multer.FileFilterCallback
): void => {
const filetypes = /jpeg|jpg|png|gif/
const filetypes = /jpeg|jpg|webp|png|gif/
const extname = filetypes.test(path.extname(file.originalname).toLowerCase())
const mimetype = filetypes.test(file.mimetype)

Expand Down Expand Up @@ -65,7 +65,7 @@
subject: string
message: string
}
): any => {

Check warning on line 68 in src/utils.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
const templatePath = path.join(__dirname, 'templates', `${templateName}.ejs`)

return new Promise<string>((resolve, reject) => {
Expand All @@ -88,7 +88,7 @@
switch (status) {
case ApplicationStatus.PENDING:
return {
subject: 'Your ScholarX Mentor Application Status',
subject: 'Thank you very much for applying to ScholarX',
message: `Dear ${name},<br /><br />
Thank you very much for applying to ScholarX. Your application has been received. Our team will soon review your application, and we will keep you posted on the progress via email.
Please reach out to us via <a href="mailto:[email protected]">[email protected]</a> for any clarifications.`
Expand All @@ -106,7 +106,7 @@
}
case ApplicationStatus.REJECTED:
return {
subject: 'ScholarX Mentor Application Status Update',
subject: 'Thank You for Your Interest in the ScholarX Program',
message: `Dear ${name},<br /><br />
I hope this email finds you well. I wanted to take a moment to thank you for your interest in joining ScholarX as a mentor and for submitting your application. We appreciate the time and effort you put into it.<br /><br />
After careful review of your application and considering all of the candidates, we regret to inform you that we are unable to make you part of the mentor base at this time. We received a large number of qualified applicants, and unfortunately, we could only accept a limited number of mentors.<br /><br />
Expand All @@ -121,7 +121,7 @@
switch (status) {
case ApplicationStatus.PENDING:
return {
subject: 'Your ScholarX Mentee Application Status',
subject: 'Thank you very much for applying to ScholarX',
message: `Dear ${name},<br /><br />
Thank you very much for applying to ScholarX. Your application has been received. Mentor will soon review your application and we will keep you posted on the progress via email. Until then, read more about student experience <a href="https://medium.com/search?q=scholarx">here</a> and reach out to us via <a href="mailto:[email protected]">[email protected]</a> for any clarifications. `
}
Expand All @@ -137,13 +137,13 @@
}
case ApplicationStatus.REJECTED:
return {
subject: 'ScholarX Mentee Application Status Update',
subject: 'Thank You for Your Interest in the ScholarX Program',
message: `Dear ${name},<br /><br />
We wanted to take a moment to thank you for your interest in the ScholarX program and for submitting your application. We appreciate the time and effort you put into it.<br /><br />
After a careful review of your application and considering all of the candidates, we regret to inform you that we are unable to offer you admission at this time. We received a large number of qualified applicants, and unfortunately, we could only accept a limited number of students.<br /><br />
However, we want to encourage you not to be discouraged by this decision. We recognize that the admissions process can be competitive, and we understand that this news may be disappointing. Please know that this does not reflect on your abilities, potential, or value as an individual.<br /><br />
We do offer the possibility for you to apply again next time if you meet the eligibility criteria. We invite you to stay engaged with us by attending our events, reaching out to our admissions team, and taking advantage of any opportunities to connect with our current students and alumni.<br /><br />
Thank you again for considering our program and for the time you invested in your application. We wish you all the best in your future endeavours. `
Thank you again for considering our program and for the time you invested in your application. We wish you all the best in your future endeavours.`
}
default:
return undefined
Expand All @@ -167,6 +167,20 @@
}
}

export const getMentorNotifyEmailContent = (
name: string
): { subject: string; message: string } => {
return {
subject: 'New Mentee Application Received',
message: `Dear ${name},<br /><br />
We wanted to let you know that a new mentee has applied to be mentored by you through the ScholarX program. Please visit your dashboard to review their application at your earliest convenience.<br /><br />
If you have any questions or need assistance, feel free to reach out to us at [email protected].
<br /><br />
Thank you for your continued support and commitment to the ScholarX program.<br /><br />
`
}
}

export const getPasswordChangedEmailContent = (
name: string
): { subject: string; message: string } => {
Expand Down
Loading