fix: resolve issue #715

Signed-off-by: SoulSniper1212 <warush23@gmail.com>
pull/721/head
SoulSniper1212 3 weeks ago
parent 1d62b88a43
commit 9b141b5338

@ -71,7 +71,7 @@ export default function GoogleAnalytics({ children }: Props) {
return () => { return () => {
router.events.off('routeChangeComplete', handleRouteChange); router.events.off('routeChangeComplete', handleRouteChange);
}; };
}, [router.events,]); }, [router.events]);
return ( return (
<GoogleAnalyticsContext.Provider value={{ event }}> <GoogleAnalyticsContext.Provider value={{ event }}>

@ -33,4 +33,4 @@ export default function OffersSubmissionAnalysis({
)} )}
</div> </div>
); );
} }

@ -43,449 +43,451 @@ const getYoeRange = (yoeCategory: number | null | undefined) => {
: null; // Internship : null; // Internship
}; };
export const offerAdminRouter = createProtectedRouter().query('list', { export const offerAdminRouter = createProtectedRouter()
input: z.object({ .query('list', {
companyId: z.string().nullish(), input: z.object({
countryId: z.string().nullish(), companyId: z.string().nullish(),
currency: z.string().nullish(), countryId: z.string().nullish(),
dateEnd: z.date().nullish(), currency: z.string().nullish(),
dateStart: z.date().nullish(), dateEnd: z.date().nullish(),
limit: z.number().positive(), dateStart: z.date().nullish(),
offset: z.number().nonnegative(), limit: z.number().positive(),
salaryMax: z.number().nonnegative().nullish(), offset: z.number().nonnegative(),
salaryMin: z.number().nonnegative().nullish(), salaryMax: z.number().nonnegative().nullish(),
sortBy: z salaryMin: z.number().nonnegative().nullish(),
.string() sortBy: z
.regex(createValidationRegex(Object.keys(sortingKeysMap), '[+-]{1}')) .string()
.nullish(), .regex(createValidationRegex(Object.keys(sortingKeysMap), '[+-]{1}'))
title: z.string().nullish(), .nullish(),
yoeCategory: z.number().min(0).max(3).nullish(), title: z.string().nullish(),
yoeMax: z.number().max(100).nullish(), yoeCategory: z.number().min(0).max(3).nullish(),
yoeMin: z.number().min(0).nullish(), yoeMax: z.number().max(100).nullish(),
}), yoeMin: z.number().min(0).nullish(),
async resolve({ ctx, input }) { }),
const userId = ctx.session.user.id; async resolve({ ctx, input }) {
const adminAccount = await ctx.prisma.offersAdmin.findFirst({ const userId = ctx.session.user.id;
where: { const adminAccount = await ctx.prisma.offersAdmin.findFirst({
userId where: {
} userId,
}) },
if (!adminAccount) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'Not an admin.',
}); });
}
const yoeRange = getYoeRange(input.yoeCategory); if (!adminAccount) {
const yoeMin = input.yoeMin != null ? input.yoeMin : yoeRange?.minYoe; throw new TRPCError({
const yoeMax = input.yoeMax != null ? input.yoeMax : yoeRange?.maxYoe; code: 'UNAUTHORIZED',
message: 'Not an admin.',
});
}
if (!input.sortBy) { const yoeRange = getYoeRange(input.yoeCategory);
input.sortBy = '-' + sortingKeysMap.monthYearReceived; const yoeMin = input.yoeMin != null ? input.yoeMin : yoeRange?.minYoe;
} const yoeMax = input.yoeMax != null ? input.yoeMax : yoeRange?.maxYoe;
const order = getOrder(input.sortBy.charAt(0)); if (!input.sortBy) {
const sortingKey = input.sortBy.substring(1); input.sortBy = '-' + sortingKeysMap.monthYearReceived;
}
const order = getOrder(input.sortBy.charAt(0));
const sortingKey = input.sortBy.substring(1);
const data = !yoeRange const data = !yoeRange
? await ctx.prisma.offersOffer.findMany({ ? await ctx.prisma.offersOffer.findMany({
// Internship // Internship
include: { include: {
company: true, company: true,
location: { location: {
include: { include: {
state: { state: {
include: { include: {
country: true, country: true,
},
}, },
}, },
}, },
}, offersFullTime: {
offersFullTime: { include: {
include: { baseSalary: true,
baseSalary: true, bonus: true,
bonus: true, stocks: true,
stocks: true, totalCompensation: true,
totalCompensation: true, },
}, },
}, offersIntern: {
offersIntern: { include: {
include: { monthlySalary: true,
monthlySalary: true, },
}, },
}, profile: {
profile: { include: {
include: { background: true,
background: true, offers: true,
offers: true, },
}, },
}, },
}, orderBy:
orderBy: sortingKey === sortingKeysMap.monthYearReceived
sortingKey === sortingKeysMap.monthYearReceived ? {
? { monthYearReceived: order,
monthYearReceived: order, }
} : sortingKey === sortingKeysMap.totalCompensation
: sortingKey === sortingKeysMap.totalCompensation ? [
? [ {
{ offersIntern: {
offersIntern: { monthlySalary: {
monthlySalary: { baseValue: order,
baseValue: order, },
}, },
}, },
}, {
{ monthYearReceived: 'desc',
monthYearReceived: 'desc', },
}, ]
] : sortingKey === sortingKeysMap.totalYoe
: sortingKey === sortingKeysMap.totalYoe ? [
? [ {
{ profile: {
profile: { background: {
background: { totalYoe: order,
totalYoe: order, },
}, },
}, },
}, {
{ monthYearReceived: 'desc',
monthYearReceived: 'desc',
},
]
: sortingKey === sortingKeysMap.companyName
? [
{
company: {
name: order,
}, },
}, ]
{ : sortingKey === sortingKeysMap.companyName
monthYearReceived: 'desc', ? [
}, {
] company: {
: sortingKey === sortingKeysMap.jobTitle name: order,
? [ },
{ },
offersIntern: { {
title: order, monthYearReceived: 'desc',
},
]
: sortingKey === sortingKeysMap.jobTitle
? [
{
offersIntern: {
title: order,
},
},
{
monthYearReceived: 'desc',
},
]
: { monthYearReceived: 'desc' },
where: {
AND: [
{
location: {
state: {
countryId:
input.countryId != null && input.countryId.length !== 0
? input.countryId
: undefined,
}, },
}, },
{ },
monthYearReceived: 'desc', {
offersIntern: {
isNot: null,
}, },
] },
: { monthYearReceived: 'desc' }, {
where: { offersIntern: {
AND: [ title:
{ input.title != null && input.title.length !== 0
location: { ? input.title
state: {
countryId:
input.countryId != null && input.countryId.length !== 0
? input.countryId
: undefined, : undefined,
}, },
}, },
}, {
{ offersIntern: {
offersIntern: { monthlySalary: {
isNot: null, baseValue: {
gte: input.salaryMin ?? undefined,
lte: input.salaryMax ?? undefined,
},
},
},
}, },
}, {
{ offersFullTime: {
offersIntern: { is: null,
title: },
input.title != null && input.title.length !== 0 },
? input.title {
companyId:
input.companyId && input.companyId.length !== 0
? input.companyId
: undefined, : undefined,
}, },
}, {
{ profile: {
offersIntern: { background: {
monthlySalary: { totalYoe: {
baseValue: { gte: yoeMin,
gte: input.salaryMin ?? undefined, lte: yoeMax,
lte: input.salaryMax ?? undefined, },
}, },
}, },
}, },
}, {
{ monthYearReceived: {
offersFullTime: { gte: input.dateStart ?? undefined,
is: null, lte: input.dateEnd ?? undefined,
},
}, },
}, ],
{ },
companyId: })
input.companyId && input.companyId.length !== 0 : await ctx.prisma.offersOffer.findMany({
? input.companyId // Junior, Mid, Senior
: undefined, include: {
}, company: true,
{ location: {
profile: { include: {
background: { state: {
totalYoe: { include: {
gte: yoeMin, country: true,
lte: yoeMax,
}, },
}, },
}, },
}, },
{ offersFullTime: {
monthYearReceived: { include: {
gte: input.dateStart ?? undefined, baseSalary: true,
lte: input.dateEnd ?? undefined, bonus: true,
stocks: true,
totalCompensation: true,
}, },
}, },
], offersIntern: {
}, include: {
}) monthlySalary: true,
: await ctx.prisma.offersOffer.findMany({
// Junior, Mid, Senior
include: {
company: true,
location: {
include: {
state: {
include: {
country: true,
},
}, },
}, },
}, profile: {
offersFullTime: { include: {
include: { background: true,
baseSalary: true, offers: true,
bonus: true, },
stocks: true,
totalCompensation: true,
},
},
offersIntern: {
include: {
monthlySalary: true,
},
},
profile: {
include: {
background: true,
offers: true,
}, },
}, },
}, orderBy:
orderBy: sortingKey === sortingKeysMap.monthYearReceived
sortingKey === sortingKeysMap.monthYearReceived ? {
? { monthYearReceived: order,
monthYearReceived: order, }
} : sortingKey === sortingKeysMap.totalCompensation
: sortingKey === sortingKeysMap.totalCompensation ? [
? [ {
{ offersFullTime: {
offersFullTime: { totalCompensation: {
totalCompensation: { baseValue: order,
baseValue: order, },
}, },
}, },
}, {
{ monthYearReceived: 'desc',
monthYearReceived: 'desc', },
}, ]
] : sortingKey === sortingKeysMap.totalYoe
: sortingKey === sortingKeysMap.totalYoe ? [
? [ {
{ profile: {
profile: { background: {
background: { totalYoe: order,
totalYoe: order, },
}, },
}, },
}, {
{ monthYearReceived: 'desc',
monthYearReceived: 'desc',
},
]
: sortingKey === sortingKeysMap.companyName
? [
{
company: {
name: order,
}, },
}, ]
{ : sortingKey === sortingKeysMap.companyName
monthYearReceived: 'desc', ? [
}, {
] company: {
: sortingKey === sortingKeysMap.jobTitle name: order,
? [ },
{ },
offersFullTime: { {
title: order, monthYearReceived: 'desc',
},
]
: sortingKey === sortingKeysMap.jobTitle
? [
{
offersFullTime: {
title: order,
},
},
{
monthYearReceived: 'desc',
},
]
: { monthYearReceived: 'desc' },
where: {
AND: [
{
location: {
state: {
countryId:
input.countryId != null && input.countryId.length !== 0
? input.countryId
: undefined,
}, },
}, },
{ },
monthYearReceived: 'desc', {
offersIntern: {
is: null,
}, },
] },
: { monthYearReceived: 'desc' }, {
where: { offersFullTime: {
AND: [ isNot: null,
{
location: {
state: {
countryId:
input.countryId != null && input.countryId.length !== 0
? input.countryId
: undefined,
}, },
}, },
}, {
{ offersFullTime: {
offersIntern: { title:
is: null, input.title != null && input.title.length !== 0
? input.title
: undefined,
},
}, },
}, {
{ offersFullTime: {
offersFullTime: { totalCompensation: {
isNot: null, baseValue: {
gte: input.salaryMin ?? undefined,
lte: input.salaryMax ?? undefined,
},
},
},
}, },
}, {
{ companyId:
offersFullTime: { input.companyId && input.companyId.length !== 0
title: ? input.companyId
input.title != null && input.title.length !== 0
? input.title
: undefined, : undefined,
}, },
}, {
{ profile: {
offersFullTime: { background: {
totalCompensation: { totalYoe: {
baseValue: { gte: yoeMin,
gte: input.salaryMin ?? undefined, lte: yoeMax,
lte: input.salaryMax ?? undefined, },
}, },
}, },
}, },
}, {
{ monthYearReceived: {
companyId: gte: input.dateStart ?? undefined,
input.companyId && input.companyId.length !== 0 lte: input.dateEnd ?? undefined,
? input.companyId
: undefined,
},
{
profile: {
background: {
totalYoe: {
gte: yoeMin,
lte: yoeMax,
},
}, },
}, },
}, ],
{ },
monthYearReceived: { });
gte: input.dateStart ?? undefined,
lte: input.dateEnd ?? undefined,
},
},
],
},
});
const startRecordIndex: number = input.limit * input.offset; const startRecordIndex: number = input.limit * input.offset;
const endRecordIndex: number = const endRecordIndex: number =
startRecordIndex + input.limit <= data.length startRecordIndex + input.limit <= data.length
? startRecordIndex + input.limit ? startRecordIndex + input.limit
: data.length; : data.length;
let paginatedData = data.slice(startRecordIndex, endRecordIndex); let paginatedData = data.slice(startRecordIndex, endRecordIndex);
// CONVERTING // CONVERTING
const currency = input.currency?.toUpperCase(); const currency = input.currency?.toUpperCase();
if (currency != null && currency in Currency) { if (currency != null && currency in Currency) {
paginatedData = await Promise.all( paginatedData = await Promise.all(
paginatedData.map(async (offer) => { paginatedData.map(async (offer) => {
if (offer.offersFullTime?.totalCompensation != null) { if (offer.offersFullTime?.totalCompensation != null) {
offer.offersFullTime.totalCompensation.value = offer.offersFullTime.totalCompensation.value =
await convertWithDate( await convertWithDate(
offer.offersFullTime.totalCompensation.value, offer.offersFullTime.totalCompensation.value,
offer.offersFullTime.totalCompensation.currency, offer.offersFullTime.totalCompensation.currency,
currency, currency,
offer.offersFullTime.totalCompensation.updatedAt, offer.offersFullTime.totalCompensation.updatedAt,
); );
offer.offersFullTime.totalCompensation.currency = currency; offer.offersFullTime.totalCompensation.currency = currency;
if (offer.offersFullTime?.baseSalary != null) { if (offer.offersFullTime?.baseSalary != null) {
offer.offersFullTime.baseSalary.value = await convertWithDate( offer.offersFullTime.baseSalary.value = await convertWithDate(
offer.offersFullTime.baseSalary.value, offer.offersFullTime.baseSalary.value,
offer.offersFullTime.baseSalary.currency, offer.offersFullTime.baseSalary.currency,
currency, currency,
offer.offersFullTime.baseSalary.updatedAt, offer.offersFullTime.baseSalary.updatedAt,
); );
offer.offersFullTime.baseSalary.currency = currency; offer.offersFullTime.baseSalary.currency = currency;
} }
if (offer.offersFullTime?.stocks != null) { if (offer.offersFullTime?.stocks != null) {
offer.offersFullTime.stocks.value = await convertWithDate( offer.offersFullTime.stocks.value = await convertWithDate(
offer.offersFullTime.stocks.value, offer.offersFullTime.stocks.value,
offer.offersFullTime.stocks.currency, offer.offersFullTime.stocks.currency,
currency, currency,
offer.offersFullTime.stocks.updatedAt, offer.offersFullTime.stocks.updatedAt,
); );
offer.offersFullTime.stocks.currency = currency; offer.offersFullTime.stocks.currency = currency;
} }
if (offer.offersFullTime?.bonus != null) { if (offer.offersFullTime?.bonus != null) {
offer.offersFullTime.bonus.value = await convertWithDate( offer.offersFullTime.bonus.value = await convertWithDate(
offer.offersFullTime.bonus.value, offer.offersFullTime.bonus.value,
offer.offersFullTime.bonus.currency, offer.offersFullTime.bonus.currency,
currency,
offer.offersFullTime.bonus.updatedAt,
);
offer.offersFullTime.bonus.currency = currency;
}
} else if (offer.offersIntern?.monthlySalary != null) {
offer.offersIntern.monthlySalary.value = await convertWithDate(
offer.offersIntern.monthlySalary.value,
offer.offersIntern.monthlySalary.currency,
currency, currency,
offer.offersFullTime.bonus.updatedAt, offer.offersIntern.monthlySalary.updatedAt,
); );
offer.offersFullTime.bonus.currency = currency; offer.offersIntern.monthlySalary.currency = currency;
} else {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Total Compensation or Salary not found',
});
} }
} else if (offer.offersIntern?.monthlySalary != null) {
offer.offersIntern.monthlySalary.value = await convertWithDate(
offer.offersIntern.monthlySalary.value,
offer.offersIntern.monthlySalary.currency,
currency,
offer.offersIntern.monthlySalary.updatedAt,
);
offer.offersIntern.monthlySalary.currency = currency;
} else {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Total Compensation or Salary not found',
});
}
return offer;
}),
);
}
return getAdminOffersResponseMapper( return offer;
paginatedData.map((offer) => adminDashboardOfferDtoMapper(offer)), }),
{ );
currentPage: input.offset,
numOfItems: paginatedData.length,
numOfPages: Math.ceil(data.length / input.limit),
totalItems: data.length,
},
!yoeRange ? JobType.INTERN : JobType.FULLTIME,
);
},
}).query('isAdmin', {
async resolve({ ctx }) {
const userId = ctx.session.user.id;
const result = await ctx.prisma.offersAdmin.findFirst({
where: {
userId
} }
})
return result ? true : false return getAdminOffersResponseMapper(
} paginatedData.map((offer) => adminDashboardOfferDtoMapper(offer)),
}); {
currentPage: input.offset,
numOfItems: paginatedData.length,
numOfPages: Math.ceil(data.length / input.limit),
totalItems: data.length,
},
!yoeRange ? JobType.INTERN : JobType.FULLTIME,
);
},
})
.query('isAdmin', {
async resolve({ ctx }) {
const userId = ctx.session.user.id;
const result = await ctx.prisma.offersAdmin.findFirst({
where: {
userId,
},
});
return result ? true : false;
},
});

@ -37,4 +37,4 @@ export const offersAnalysisRouter = createRouter()
async resolve({ ctx, input }) { async resolve({ ctx, input }) {
return generateAnalysis({ ctx, input }); return generateAnalysis({ ctx, input });
}, },
}); });

@ -320,7 +320,6 @@ export const offersCommentsRouter = createRouter()
id: input.profileId, id: input.profileId,
}, },
}); });
} else { } else {
throw new trpc.TRPCError({ throw new trpc.TRPCError({
code: 'UNAUTHORIZED', code: 'UNAUTHORIZED',

@ -138,4 +138,4 @@ export const offersUserProfileRouter = createProtectedRouter()
}, },
}); });
}, },
}); });

@ -41,12 +41,13 @@ export const questionsQuestionEncounterUserRouter = createProtectedRouter()
}); });
} }
await tx.questionsQuestion.update({ await tx.questionsQuestion.update({
data: { data: {
lastSeenAt: (questionToUpdate.lastSeenAt === null || lastSeenAt:
questionToUpdate.lastSeenAt < input.seenAt) questionToUpdate.lastSeenAt === null ||
? input.seenAt : undefined, questionToUpdate.lastSeenAt < input.seenAt
? input.seenAt
: undefined,
numEncounters: { numEncounters: {
increment: 1, increment: 1,
}, },
@ -179,16 +180,16 @@ export const questionsQuestionEncounterUserRouter = createProtectedRouter()
} }
await tx.questionsQuestion.update({ await tx.questionsQuestion.update({
data: { data: {
lastSeenAt: lastSeenVal, lastSeenAt: lastSeenVal,
numEncounters: { numEncounters: {
increment: -1, increment: -1,
},
},
where: {
id: questionToUpdate!.id,
}, },
}); },
where: {
id: questionToUpdate!.id,
},
});
return questionEncounterDeleted; return questionEncounterDeleted;
}); });

@ -1,8 +1,13 @@
import type { Config } from 'unique-names-generator'; import type { Config } from 'unique-names-generator';
import { adjectives, animals,colors, uniqueNamesGenerator } from 'unique-names-generator'; import {
adjectives,
animals,
colors,
uniqueNamesGenerator,
} from 'unique-names-generator';
import { PrismaClient } from '@prisma/client'; import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient() const prisma = new PrismaClient();
const customConfig: Config = { const customConfig: Config = {
dictionaries: [adjectives, colors, animals], dictionaries: [adjectives, colors, animals],
@ -10,24 +15,23 @@ const customConfig: Config = {
separator: '-', separator: '-',
}; };
export default async function generateRandomName(): Promise<string> { export default async function generateRandomName(): Promise<string> {
let uniqueName: string = uniqueNamesGenerator(customConfig); let uniqueName: string = uniqueNamesGenerator(customConfig);
let sameNameProfiles = await prisma.offersProfile.findMany({ let sameNameProfiles = await prisma.offersProfile.findMany({
where: { where: {
profileName: uniqueName profileName: uniqueName,
} },
}) });
while (sameNameProfiles.length !== 0) { while (sameNameProfiles.length !== 0) {
uniqueName = uniqueNamesGenerator(customConfig); uniqueName = uniqueNamesGenerator(customConfig);
sameNameProfiles = await prisma.offersProfile.findMany({ sameNameProfiles = await prisma.offersProfile.findMany({
where: { where: {
profileName: uniqueName profileName: uniqueName,
} },
}) });
} }
return uniqueName return uniqueName;
} }

@ -71,7 +71,7 @@ While you're unlikely to be asked to implement a sorting algorithm from scratch
## Things to look out for during interviews ## Things to look out for during interviews
Make sure you know the time and space complexity of the language's default sorting algorithm! The time complexity is almost definitely O(nlog(n))). Bonus points if you can name the sort. In Python, it's [Timsort](https://en.wikipedia.org/wiki/Timsort). In Java, [an implementation of Timsort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/TimSort.java) is used for sorting objects, and [Dual-Pivot Quicksort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/DualPivotQuicksort.java) is used for sorting primitives. Make sure you know the time and space complexity of the language's default sorting algorithm! The time complexity is almost definitely O(n log n). Bonus points if you can name the sort. In Python 3.11+, it's [Powersort](https://www.wild-inter.net/posts/powersort-in-python-3.11), which replaced Timsort as the default sorting algorithm. In Java, [an implementation of Timsort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/TimSort.java) is used for sorting objects, and [Dual-Pivot Quicksort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/DualPivotQuicksort.java) is used for sorting primitives.
## Corner cases ## Corner cases

Loading…
Cancel
Save