parent
0eb4f3fc5b
commit
335413fdcd
@ -1,412 +0,0 @@
|
|||||||
import crypto, { randomUUID } from 'crypto';
|
|
||||||
import { z } from 'zod';
|
|
||||||
import { Prisma } from '@prisma/client';
|
|
||||||
|
|
||||||
import { createRouter } from './context';
|
|
||||||
|
|
||||||
import type { offersProfile } from '~/types/offers-profile';
|
|
||||||
|
|
||||||
const valuation = z.object({
|
|
||||||
currency: z.string(),
|
|
||||||
value: z.number(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: handle both full time and intern
|
|
||||||
const offer = z.object({
|
|
||||||
comments: z.string().optional(),
|
|
||||||
companyId: z.string(),
|
|
||||||
job: z.object({
|
|
||||||
base: valuation.optional(), // Full time
|
|
||||||
bonus: valuation.optional(), // Full time
|
|
||||||
internshipCycle: z.string().optional(), // Intern
|
|
||||||
level: z.string().optional(), // Full time
|
|
||||||
monthlySalary: valuation.optional(), // Intern
|
|
||||||
specialization: z.string(),
|
|
||||||
startYear: z.number().optional(), // Intern
|
|
||||||
stocks: valuation.optional(), // Full time
|
|
||||||
title: z.string(),
|
|
||||||
totalCompensation: valuation.optional(), // Full time
|
|
||||||
}),
|
|
||||||
jobType: z.string(),
|
|
||||||
location: z.string(),
|
|
||||||
monthYearReceived: z.date(),
|
|
||||||
negotiationStrategy: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const experience = z.object({
|
|
||||||
companyId: z.string().optional(),
|
|
||||||
durationInMonths: z.number().optional(),
|
|
||||||
jobType: z.string().optional(),
|
|
||||||
level: z.string().optional(),
|
|
||||||
monthlySalary: valuation.optional(),
|
|
||||||
specialization: z.string().optional(),
|
|
||||||
title: z.string().optional(),
|
|
||||||
totalCompensation: valuation.optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const education = z.object({
|
|
||||||
endDate: z.date().optional(),
|
|
||||||
field: z.string().optional(),
|
|
||||||
school: z.string().optional(),
|
|
||||||
startDate: z.date().optional(),
|
|
||||||
type: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
type WithIsEditable<T> = T & {
|
|
||||||
isEditable: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
function computeIsEditable(
|
|
||||||
profileInput: offersProfile,
|
|
||||||
editToken?: string
|
|
||||||
): WithIsEditable<offersProfile> {
|
|
||||||
return {
|
|
||||||
...profileInput,
|
|
||||||
isEditable: profileInput.editToken === editToken,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function exclude<Key extends keyof WithIsEditable<offersProfile>>(
|
|
||||||
profile: WithIsEditable<offersProfile>,
|
|
||||||
...keys: Array<Key>
|
|
||||||
): Omit<WithIsEditable<offersProfile>, Key> {
|
|
||||||
for (const key of keys) {
|
|
||||||
delete profile[key]
|
|
||||||
}
|
|
||||||
return profile
|
|
||||||
}
|
|
||||||
|
|
||||||
export const offersProfileRouter = createRouter()
|
|
||||||
.query('listOne', {
|
|
||||||
input: z.object({
|
|
||||||
profileId: z.string(),
|
|
||||||
token: z.string().optional()
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
const result = await ctx.prisma.offersProfile.findFirst({
|
|
||||||
include: {
|
|
||||||
background: {
|
|
||||||
include: {
|
|
||||||
educations: true,
|
|
||||||
experiences: {
|
|
||||||
include: {
|
|
||||||
company: true,
|
|
||||||
monthlySalary: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
specificYoes: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
discussion: {
|
|
||||||
include: {
|
|
||||||
replies: true,
|
|
||||||
replyingTo: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offers: {
|
|
||||||
include: {
|
|
||||||
OffersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OffersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
company: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
id: input.profileId,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result ? exclude(computeIsEditable(result, input.token), 'editToken') : result;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation('create', {
|
|
||||||
input: z.object({
|
|
||||||
background: z.object({
|
|
||||||
educations: z.array(education),
|
|
||||||
experiences: z.array(experience),
|
|
||||||
specificYoes: z.array(
|
|
||||||
z.object({
|
|
||||||
domain: z.string(),
|
|
||||||
yoe: z.number(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
totalYoe: z.number().optional(),
|
|
||||||
}),
|
|
||||||
offers: z.array(offer),
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
// TODO: add more
|
|
||||||
const token = crypto
|
|
||||||
.createHash('sha256')
|
|
||||||
.update(Date.now().toString())
|
|
||||||
.digest('hex');
|
|
||||||
|
|
||||||
const profile = await ctx.prisma.offersProfile.create({
|
|
||||||
data: {
|
|
||||||
background: {
|
|
||||||
create: {
|
|
||||||
educations: {
|
|
||||||
create: input.background.educations.map((x) => ({
|
|
||||||
endDate: x.endDate,
|
|
||||||
field: x.field,
|
|
||||||
school: x.school,
|
|
||||||
startDate: x.startDate,
|
|
||||||
type: x.type,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
experiences: {
|
|
||||||
create: input.background.experiences.map((x) => {
|
|
||||||
if (
|
|
||||||
x.jobType === 'FULLTIME' &&
|
|
||||||
x.totalCompensation?.currency !== undefined &&
|
|
||||||
x.totalCompensation.value !== undefined
|
|
||||||
) {
|
|
||||||
if (x.companyId) {
|
|
||||||
return {
|
|
||||||
company: {
|
|
||||||
connect: {
|
|
||||||
id: x.companyId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
durationInMonths: x.durationInMonths,
|
|
||||||
jobType: x.jobType,
|
|
||||||
level: x.level,
|
|
||||||
specialization: x.specialization,
|
|
||||||
title: x.title,
|
|
||||||
totalCompensation: {
|
|
||||||
create: {
|
|
||||||
currency: x.totalCompensation?.currency,
|
|
||||||
value: x.totalCompensation?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
durationInMonths: x.durationInMonths,
|
|
||||||
jobType: x.jobType,
|
|
||||||
level: x.level,
|
|
||||||
specialization: x.specialization,
|
|
||||||
title: x.title,
|
|
||||||
totalCompensation: {
|
|
||||||
create: {
|
|
||||||
currency: x.totalCompensation?.currency,
|
|
||||||
value: x.totalCompensation?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
x.jobType === 'INTERN' &&
|
|
||||||
x.monthlySalary?.currency !== undefined &&
|
|
||||||
x.monthlySalary.value !== undefined
|
|
||||||
) {
|
|
||||||
if (x.companyId) {
|
|
||||||
return {
|
|
||||||
company: {
|
|
||||||
connect: {
|
|
||||||
id: x.companyId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
durationInMonths: x.durationInMonths,
|
|
||||||
jobType: x.jobType,
|
|
||||||
monthlySalary: {
|
|
||||||
create: {
|
|
||||||
currency: x.monthlySalary?.currency,
|
|
||||||
value: x.monthlySalary?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
specialization: x.specialization,
|
|
||||||
title: x.title,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
durationInMonths: x.durationInMonths,
|
|
||||||
jobType: x.jobType,
|
|
||||||
monthlySalary: {
|
|
||||||
create: {
|
|
||||||
currency: x.monthlySalary?.currency,
|
|
||||||
value: x.monthlySalary?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
specialization: x.specialization,
|
|
||||||
title: x.title,
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Prisma.PrismaClientKnownRequestError;
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
specificYoes: {
|
|
||||||
create: input.background.specificYoes.map((x) => {
|
|
||||||
return {
|
|
||||||
domain: x.domain,
|
|
||||||
yoe: x.yoe,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
totalYoe: input.background.totalYoe,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
editToken: token,
|
|
||||||
offers: {
|
|
||||||
create: input.offers.map((x) => {
|
|
||||||
if (
|
|
||||||
x.jobType === 'INTERN' &&
|
|
||||||
x.job.internshipCycle !== undefined &&
|
|
||||||
x.job.monthlySalary?.currency !== undefined &&
|
|
||||||
x.job.monthlySalary.value !== undefined &&
|
|
||||||
x.job.startYear !== undefined
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
OffersIntern: {
|
|
||||||
create: {
|
|
||||||
internshipCycle: x.job.internshipCycle,
|
|
||||||
monthlySalary: {
|
|
||||||
create: {
|
|
||||||
currency: x.job.monthlySalary?.currency,
|
|
||||||
value: x.job.monthlySalary?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
specialization: x.job.specialization,
|
|
||||||
startYear: x.job.startYear,
|
|
||||||
title: x.job.title,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
comments: x.comments,
|
|
||||||
company: {
|
|
||||||
connect: {
|
|
||||||
id: x.companyId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jobType: x.jobType,
|
|
||||||
location: x.location,
|
|
||||||
monthYearReceived: x.monthYearReceived,
|
|
||||||
negotiationStrategy: x.negotiationStrategy,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
x.jobType === 'FULLTIME' &&
|
|
||||||
x.job.base?.currency !== undefined &&
|
|
||||||
x.job.base?.value !== undefined &&
|
|
||||||
x.job.bonus?.currency !== undefined &&
|
|
||||||
x.job.bonus?.value !== undefined &&
|
|
||||||
x.job.stocks?.currency !== undefined &&
|
|
||||||
x.job.stocks?.value !== undefined &&
|
|
||||||
x.job.totalCompensation?.currency !== undefined &&
|
|
||||||
x.job.totalCompensation?.value !== undefined &&
|
|
||||||
x.job.level !== undefined
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
OffersFullTime: {
|
|
||||||
create: {
|
|
||||||
baseSalary: {
|
|
||||||
create: {
|
|
||||||
currency: x.job.base?.currency,
|
|
||||||
value: x.job.base?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
bonus: {
|
|
||||||
create: {
|
|
||||||
currency: x.job.bonus?.currency,
|
|
||||||
value: x.job.bonus?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
level: x.job.level,
|
|
||||||
specialization: x.job.specialization,
|
|
||||||
stocks: {
|
|
||||||
create: {
|
|
||||||
currency: x.job.stocks?.currency,
|
|
||||||
value: x.job.stocks?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
title: x.job.title,
|
|
||||||
totalCompensation: {
|
|
||||||
create: {
|
|
||||||
currency: x.job.totalCompensation?.currency,
|
|
||||||
value: x.job.totalCompensation?.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
comments: x.comments,
|
|
||||||
company: {
|
|
||||||
connect: {
|
|
||||||
id: x.companyId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jobType: x.jobType,
|
|
||||||
location: x.location,
|
|
||||||
monthYearReceived: x.monthYearReceived,
|
|
||||||
negotiationStrategy: x.negotiationStrategy,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw error
|
|
||||||
throw Prisma.PrismaClientKnownRequestError;
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
profileName: randomUUID().substring(0, 10),
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
background: {
|
|
||||||
include: {
|
|
||||||
educations: true,
|
|
||||||
experiences: {
|
|
||||||
include: {
|
|
||||||
company: true,
|
|
||||||
monthlySalary: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
specificYoes: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offers: {
|
|
||||||
include: {
|
|
||||||
OffersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OffersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// TODO: add analysis to profile object then return
|
|
||||||
return profile;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.mutation('delete', {
|
|
||||||
input: z.object({
|
|
||||||
id: z.string(),
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
return await ctx.prisma.offersProfile.delete({
|
|
||||||
where: {
|
|
||||||
id: input.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,342 +0,0 @@
|
|||||||
import assert from 'assert';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { createRouter } from './context';
|
|
||||||
|
|
||||||
const yoeCategoryMap: Record<number, string> = {
|
|
||||||
0: 'Internship',
|
|
||||||
1: 'Fresh Grad',
|
|
||||||
2: 'Mid',
|
|
||||||
3: 'Senior',
|
|
||||||
};
|
|
||||||
|
|
||||||
const getYoeRange = (yoeCategory: number) => {
|
|
||||||
return yoeCategoryMap[yoeCategory] === 'Fresh Grad'
|
|
||||||
? { maxYoe: 3, minYoe: 0 }
|
|
||||||
: yoeCategoryMap[yoeCategory] === 'Mid'
|
|
||||||
? { maxYoe: 7, minYoe: 4 }
|
|
||||||
: yoeCategoryMap[yoeCategory] === 'Senior'
|
|
||||||
? { maxYoe: null, minYoe: 8 }
|
|
||||||
: null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ascOrder = '+';
|
|
||||||
const descOrder = '-';
|
|
||||||
const sortingKeys = ['monthYearReceived', 'totalCompensation', 'totalYoe'];
|
|
||||||
|
|
||||||
const createSortByValidationRegex = () => {
|
|
||||||
const startsWithPlusOrMinusOnly = '^[+-]{1}';
|
|
||||||
const sortingKeysRegex = sortingKeys.join('|');
|
|
||||||
return new RegExp(startsWithPlusOrMinusOnly + '(' + sortingKeysRegex + ')');
|
|
||||||
};
|
|
||||||
|
|
||||||
export const offersRouter = createRouter().query('list', {
|
|
||||||
input: z.object({
|
|
||||||
company: z.string().nullish(),
|
|
||||||
dateEnd: z.date().nullish(),
|
|
||||||
dateStart: z.date().nullish(),
|
|
||||||
limit: z.number().nonnegative(),
|
|
||||||
location: z.string(),
|
|
||||||
offset: z.number().nonnegative(),
|
|
||||||
salaryMax: z.number().nullish(),
|
|
||||||
salaryMin: z.number().nonnegative().nullish(),
|
|
||||||
sortBy: z.string().regex(createSortByValidationRegex()).nullish(),
|
|
||||||
title: z.string().nullish(),
|
|
||||||
yoeCategory: z.number().min(0).max(3),
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
const yoeRange = getYoeRange(input.yoeCategory);
|
|
||||||
|
|
||||||
let data = !yoeRange
|
|
||||||
? await ctx.prisma.offersOffer.findMany({
|
|
||||||
// Internship
|
|
||||||
include: {
|
|
||||||
OffersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OffersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
company: true,
|
|
||||||
profile: {
|
|
||||||
include: {
|
|
||||||
background: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
AND: [
|
|
||||||
{
|
|
||||||
location: input.location,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersIntern: {
|
|
||||||
isNot: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersFullTime: {
|
|
||||||
is: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
: yoeRange.maxYoe
|
|
||||||
? await ctx.prisma.offersOffer.findMany({
|
|
||||||
include: {
|
|
||||||
OffersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OffersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
company: true,
|
|
||||||
profile: {
|
|
||||||
include: {
|
|
||||||
background: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Junior, Mid
|
|
||||||
where: {
|
|
||||||
AND: [
|
|
||||||
{
|
|
||||||
location: input.location,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersIntern: {
|
|
||||||
is: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersFullTime: {
|
|
||||||
isNot: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: {
|
|
||||||
gte: yoeRange.minYoe,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: {
|
|
||||||
gte: yoeRange.maxYoe,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
: await ctx.prisma.offersOffer.findMany({
|
|
||||||
// Senior
|
|
||||||
include: {
|
|
||||||
OffersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
OffersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
company: true,
|
|
||||||
profile: {
|
|
||||||
include: {
|
|
||||||
background: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
AND: [
|
|
||||||
{
|
|
||||||
location: input.location,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersIntern: {
|
|
||||||
is: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
OffersFullTime: {
|
|
||||||
isNot: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: {
|
|
||||||
gte: yoeRange.minYoe,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// FILTERING
|
|
||||||
data = data.filter((offer) => {
|
|
||||||
let validRecord = true;
|
|
||||||
|
|
||||||
if (input.company) {
|
|
||||||
validRecord = validRecord && offer.company.name === input.company;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.title) {
|
|
||||||
validRecord =
|
|
||||||
validRecord &&
|
|
||||||
(offer.OffersFullTime?.title === input.title ||
|
|
||||||
offer.OffersIntern?.title === input.title);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.dateStart && input.dateEnd) {
|
|
||||||
validRecord =
|
|
||||||
validRecord &&
|
|
||||||
offer.monthYearReceived.getTime() >= input.dateStart.getTime() &&
|
|
||||||
offer.monthYearReceived.getTime() <= input.dateEnd.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.salaryMin && input.salaryMax) {
|
|
||||||
const salary = offer.OffersFullTime?.totalCompensation.value
|
|
||||||
? offer.OffersFullTime?.totalCompensation.value
|
|
||||||
: offer.OffersIntern?.monthlySalary.value;
|
|
||||||
|
|
||||||
assert(salary);
|
|
||||||
|
|
||||||
validRecord =
|
|
||||||
validRecord && salary >= input.salaryMin && salary <= input.salaryMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
return validRecord;
|
|
||||||
});
|
|
||||||
|
|
||||||
// SORTING
|
|
||||||
data = data.sort((offer1, offer2) => {
|
|
||||||
const defaultReturn =
|
|
||||||
offer2.monthYearReceived.getTime() - offer1.monthYearReceived.getTime();
|
|
||||||
|
|
||||||
if (!input.sortBy) {
|
|
||||||
return defaultReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const order = input.sortBy.charAt(0);
|
|
||||||
const sortingKey = input.sortBy.substring(1);
|
|
||||||
|
|
||||||
if (order === ascOrder) {
|
|
||||||
return (() => {
|
|
||||||
if (sortingKey === 'monthYearReceived') {
|
|
||||||
return (
|
|
||||||
offer1.monthYearReceived.getTime() -
|
|
||||||
offer2.monthYearReceived.getTime()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortingKey === 'totalCompensation') {
|
|
||||||
const salary1 = offer1.OffersFullTime?.totalCompensation.value
|
|
||||||
? offer1.OffersFullTime?.totalCompensation.value
|
|
||||||
: offer1.OffersIntern?.monthlySalary.value;
|
|
||||||
|
|
||||||
const salary2 = offer2.OffersFullTime?.totalCompensation.value
|
|
||||||
? offer2.OffersFullTime?.totalCompensation.value
|
|
||||||
: offer2.OffersIntern?.monthlySalary.value;
|
|
||||||
|
|
||||||
if (salary1 && salary2) {
|
|
||||||
return salary1 - salary2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortingKey === 'totalYoe') {
|
|
||||||
const yoe1 = offer1.profile.background?.totalYoe;
|
|
||||||
const yoe2 = offer2.profile.background?.totalYoe;
|
|
||||||
|
|
||||||
if (yoe1 && yoe2) {
|
|
||||||
return yoe1 - yoe2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultReturn;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (order === descOrder) {
|
|
||||||
return (() => {
|
|
||||||
if (sortingKey === 'monthYearReceived') {
|
|
||||||
return (
|
|
||||||
offer2.monthYearReceived.getTime() -
|
|
||||||
offer1.monthYearReceived.getTime()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortingKey === 'totalCompensation') {
|
|
||||||
const salary1 = offer1.OffersFullTime?.totalCompensation.value
|
|
||||||
? offer1.OffersFullTime?.totalCompensation.value
|
|
||||||
: offer1.OffersIntern?.monthlySalary.value;
|
|
||||||
|
|
||||||
const salary2 = offer2.OffersFullTime?.totalCompensation.value
|
|
||||||
? offer2.OffersFullTime?.totalCompensation.value
|
|
||||||
: offer2.OffersIntern?.monthlySalary.value;
|
|
||||||
|
|
||||||
if (salary1 && salary2) {
|
|
||||||
return salary2 - salary1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortingKey === 'totalYoe') {
|
|
||||||
const yoe1 = offer1.profile.background?.totalYoe;
|
|
||||||
const yoe2 = offer2.profile.background?.totalYoe;
|
|
||||||
|
|
||||||
if (yoe1 && yoe2) {
|
|
||||||
return yoe2 - yoe1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultReturn;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
return defaultReturn;
|
|
||||||
});
|
|
||||||
|
|
||||||
const startRecordIndex: number = input.limit * input.offset;
|
|
||||||
const endRecordIndex: number =
|
|
||||||
startRecordIndex + input.limit <= data.length
|
|
||||||
? startRecordIndex + input.limit
|
|
||||||
: data.length;
|
|
||||||
const paginatedData = data.slice(startRecordIndex, endRecordIndex);
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: paginatedData,
|
|
||||||
paging: {
|
|
||||||
currPage: input.offset,
|
|
||||||
numOfItemsInPage: paginatedData.length,
|
|
||||||
numOfPages: Math.ceil(data.length / input.limit),
|
|
||||||
totalNumberOfOffers: data.length,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
Loading…
Reference in new issue