Skip to content

Commit

Permalink
Add application validations (#119)
Browse files Browse the repository at this point in the history
Good Job
  • Loading branch information
anjula-sack authored Jun 5, 2024
1 parent a859f04 commit 627e646
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 30 deletions.
5 changes: 2 additions & 3 deletions src/entities/category.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ class Category extends BaseEntity {
category: string

@OneToMany(() => Mentor, (mentor) => mentor.category)
mentors: Mentor[]
mentors?: Mentor[]

constructor(category: string, mentors: Mentor[]) {
constructor(category: string) {
super()
this.category = category
this.mentors = mentors
}
}

Expand Down
13 changes: 6 additions & 7 deletions src/entities/mentor.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm'
import profileEntity from './profile.entity'
import Profile from './profile.entity'
import Mentee from './mentee.entity'
import Category from './category.entity'
import { ApplicationStatus } from '../enums'
Expand All @@ -15,6 +15,7 @@ class Mentor extends BaseEntity {
state: ApplicationStatus

@ManyToOne(() => Category, (category) => category.mentors)
@JoinColumn()
category: Category

@Column({ type: 'json' })
Expand All @@ -23,28 +24,26 @@ class Mentor extends BaseEntity {
@Column({ type: 'boolean' })
availability: boolean

@ManyToOne(() => profileEntity)
@ManyToOne(() => Profile)
@JoinColumn()
profile: profileEntity
profile: Profile

@OneToMany(() => Mentee, (mentee) => mentee.mentor)
mentees: Mentee[]
mentees?: Mentee[]

constructor(
state: ApplicationStatus,
category: Category,
application: Record<string, unknown>,
availability: boolean,
profile: profileEntity,
mentees: Mentee[]
profile: Profile
) {
super()
this.state = state
this.category = category
this.application = application
this.availability = availability
this.profile = profile
this.mentees = mentees
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/services/admin/category.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const createCategory = async (
try {
const categoryRepository = dataSource.getRepository(Category)

const newCategory = new Category(categoryName, [])
const newCategory = new Category(categoryName)

const saveCategory = await categoryRepository.save(newCategory)

Expand Down
16 changes: 16 additions & 0 deletions src/services/mentee.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ export const addMentee = async (
}
}

const userMentorProfile = await mentorRepository.findOne({
where: {
profile: {
uuid: user.uuid
}
}
})

if (userMentorProfile) {
return {
statusCode: 409,
message:
'A mentor cannot become a mentee, Please contact [email protected]'
}
}

const existingMentees: Mentee[] = await menteeRepository.find({
where: { profile: { uuid: user.uuid } }
})
Expand Down
29 changes: 23 additions & 6 deletions src/services/mentor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ApplicationStatus } from '../enums'
import Category from '../entities/category.entity'
import { getEmailContent, getMentorPublicData } from '../utils'
import { sendEmail } from './admin/email.service'
import Mentee from '../entities/mentee.entity'

export const createMentor = async (
user: Profile,
Expand All @@ -18,6 +19,23 @@ export const createMentor = async (
try {
const mentorRepository = dataSource.getRepository(Mentor)
const categoryRepository = dataSource.getRepository(Category)
const menteeRepository = dataSource.getRepository(Mentee)

const mentee = await menteeRepository.findOne({
where: {
profile: {
uuid: user.uuid
}
}
})

if (mentee) {
return {
statusCode: 409,
message:
'A mentee cannot become a mentor, Please contact [email protected]'
}
}

const existingMentorApplications = await mentorRepository.find({
where: { profile: { uuid: user.uuid } }
Expand Down Expand Up @@ -58,11 +76,10 @@ export const createMentor = async (
category,
application,
true,
user,
[]
user
)

await mentorRepository.save(newMentor)
const savedMentor = await mentorRepository.save(newMentor)

const content = getEmailContent(
'mentor',
Expand All @@ -80,7 +97,7 @@ export const createMentor = async (

return {
statusCode: 201,
mentor: newMentor,
mentor: savedMentor,
message: 'Mentor application is successful'
}
} catch (err) {
Expand Down Expand Up @@ -116,8 +133,8 @@ export const updateAvailability = async (
message: 'Mentor availability updated successfully'
}
} catch (err) {
console.error('Error creating mentor', err)
throw new Error('Error creating mentor')
console.error('Error updating mentor availability', err)
throw new Error('Error updating mentor availability')
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/templates/emailTemplate.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,22 @@
color: #363636;
"
>
<p style="margin-top: 0; margin-bottom: 22px">
<%- message %>
<p><%- message %></p>
<p>
To ensure that you receive our emails and they do not go
to your spam folder, please add
[email protected] to your email
whitelist.
</p>
<p>
Please join our slack channel
<a
href="https://join.slack.com/t/sefheadquarters/shared_invite/zt-1jwub1lpd-RXYAMG46qXRUhOGZ7u_ewg"
>link</a
>
to provide any feedback on the platform. You may use the
#scholarx-feedback to provide any issues in the platform
so we can quickly fix them.
</p>
<p style="margin-top: 0; margin-bottom: 18px">
Best regards,<br />
Expand Down
19 changes: 8 additions & 11 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import ejs from 'ejs'
import { ApplicationStatus } from './enums'

export const signAndSetCookie = (res: Response, uuid: string): void => {
const token = jwt.sign({ userId: uuid }, JWT_SECRET ?? '', {
expiresIn: '10h' // To-Do: Change value in production
})
const token = jwt.sign({ userId: uuid }, JWT_SECRET ?? '')

res.cookie('jwt', token, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000,
maxAge: 5 * 24 * 60 * 60 * 1000,
secure: false // TODO: Set to true when using HTTPS
})
}
Expand Down Expand Up @@ -93,7 +91,7 @@ export const getEmailContent = (
subject: 'Your ScholarX Mentor Application Status',
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. To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
Please reach out to us via <a href="mailto:[email protected]">[email protected]</a> for any clarifications.`
}
case ApplicationStatus.APPROVED:
return {
Expand All @@ -104,8 +102,7 @@ export const getEmailContent = (
We received a large number of qualified applicants, and after a thorough review of all candidates, we are thrilled to invite you to accept a place in our program. Your profile stood out amongst the others, and we are confident that you will contribute positively to our program.<br /><br />
We understand that your hard work and dedication have brought you to this moment, and we recognize your exceptional talent, experience, and potential in your respective fields. We are excited to have you join our community of learners and scholars.<br /><br />
We look forward to seeing the unique perspective and insights you will bring to the mentees and to the program. We believe that you will flourish in this year's edition of ScholarX, and we are thrilled to be a part of your academic or professional journey.<br /><br />
Once again, congratulations on your selection! We cannot wait to have you on board. We will keep you informed on the next steps, and in the meantime would like to invite you to go through some of the resources that would be useful to thrive as a great mentor in ScholarX. <br /><br />
To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
Once again, congratulations on your selection! We cannot wait to have you on board. We will keep you informed on the next steps, and in the meantime would like to invite you to go through some of the resources that would be useful to thrive as a great mentor in ScholarX.`
}
case ApplicationStatus.REJECTED:
return {
Expand All @@ -115,7 +112,7 @@ export const getEmailContent = (
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 />
We understand that this news may be disappointing, and we encourage you not to be discouraged by this decision. Please know that this does not reflect on your abilities, potential, or value as an individual. As you progress ahead on your academic or professional journey, we would be glad to have you as a mentor for future ScholarX programs.<br /><br />
We appreciate your interest in our program and would like to wish you all the best in your future endeavors. We are grateful for the opportunity to consider you for our program and encourage you to keep pursuing your goals and aspirations.<br /><br />
Thank you again for considering our program and for the time you invested in your application. We hope you find success and fulfillment in your academic and professional pursuits. To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
Thank you again for considering our program and for the time you invested in your application. We hope you find success and fulfillment in your academic and professional pursuits. `
}
default:
return undefined
Expand All @@ -126,7 +123,7 @@ export const getEmailContent = (
return {
subject: 'Your ScholarX Mentee Application Status',
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. To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
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. `
}
case ApplicationStatus.APPROVED:
return {
Expand All @@ -136,7 +133,7 @@ export const getEmailContent = (
We received a large number of qualified applicants, and after a thorough review of all candidates, we are thrilled to offer you a place in our program. Your application stood out amongst the others, and we are confident that you will contribute positively to our program.<br /><br />
We believe that you have great potential to succeed in your academic and professional pursuits, and we are excited to have you join our community of learners and scholars.<br /><br />
To emphasize the importance of completing the program, you have received a valuable opportunity. If, for any reason, you are uncertain about completing the program within the 6-month timeline, please inform our admissions team as soon as possible, so we can provide the opportunity to another deserving student.<br /><br />
Once again, congratulations on your selection! We cannot wait to have you on board. To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
Once again, congratulations on your selection! We cannot wait to have you on board. `
}
case ApplicationStatus.REJECTED:
return {
Expand All @@ -146,7 +143,7 @@ export const getEmailContent = (
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. To ensure that you receive our emails and they do not go to your spam folder, please add [email protected] to your email whitelist.`
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 Down

0 comments on commit 627e646

Please sign in to comment.