mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2026-04-27 12:03:41 +08:00
contents: update default Python sort to Powersort (#721)
Signed-off-by: SoulSniper1212 <warush23@gmail.com>
This commit is contained in:
@@ -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 }}>
|
||||||
|
|||||||
@@ -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) {
|
|
||||||
input.sortBy = '-' + sortingKeysMap.monthYearReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
const order = getOrder(input.sortBy.charAt(0));
|
|
||||||
const sortingKey = input.sortBy.substring(1);
|
|
||||||
|
|
||||||
const data = !yoeRange
|
|
||||||
? await ctx.prisma.offersOffer.findMany({
|
|
||||||
// Internship
|
|
||||||
include: {
|
|
||||||
company: true,
|
|
||||||
location: {
|
|
||||||
include: {
|
|
||||||
state: {
|
|
||||||
include: {
|
|
||||||
country: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
profile: {
|
|
||||||
include: {
|
|
||||||
background: true,
|
|
||||||
offers: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderBy:
|
|
||||||
sortingKey === sortingKeysMap.monthYearReceived
|
|
||||||
? {
|
|
||||||
monthYearReceived: order,
|
|
||||||
}
|
|
||||||
: sortingKey === sortingKeysMap.totalCompensation
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
offersIntern: {
|
|
||||||
monthlySalary: {
|
|
||||||
baseValue: order,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
monthYearReceived: 'desc',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: sortingKey === sortingKeysMap.totalYoe
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: order,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
monthYearReceived: 'desc',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: sortingKey === sortingKeysMap.companyName
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
company: {
|
|
||||||
name: 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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersIntern: {
|
|
||||||
isNot: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersIntern: {
|
|
||||||
title:
|
|
||||||
input.title != null && input.title.length !== 0
|
|
||||||
? input.title
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersIntern: {
|
|
||||||
monthlySalary: {
|
|
||||||
baseValue: {
|
|
||||||
gte: input.salaryMin ?? undefined,
|
|
||||||
lte: input.salaryMax ?? undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersFullTime: {
|
|
||||||
is: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
companyId:
|
|
||||||
input.companyId && input.companyId.length !== 0
|
|
||||||
? input.companyId
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: {
|
|
||||||
gte: yoeMin,
|
|
||||||
lte: yoeMax,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
monthYearReceived: {
|
|
||||||
gte: input.dateStart ?? undefined,
|
|
||||||
lte: input.dateEnd ?? undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
: await ctx.prisma.offersOffer.findMany({
|
|
||||||
// Junior, Mid, Senior
|
|
||||||
include: {
|
|
||||||
company: true,
|
|
||||||
location: {
|
|
||||||
include: {
|
|
||||||
state: {
|
|
||||||
include: {
|
|
||||||
country: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offersFullTime: {
|
|
||||||
include: {
|
|
||||||
baseSalary: true,
|
|
||||||
bonus: true,
|
|
||||||
stocks: true,
|
|
||||||
totalCompensation: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
offersIntern: {
|
|
||||||
include: {
|
|
||||||
monthlySalary: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
profile: {
|
|
||||||
include: {
|
|
||||||
background: true,
|
|
||||||
offers: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderBy:
|
|
||||||
sortingKey === sortingKeysMap.monthYearReceived
|
|
||||||
? {
|
|
||||||
monthYearReceived: order,
|
|
||||||
}
|
|
||||||
: sortingKey === sortingKeysMap.totalCompensation
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
offersFullTime: {
|
|
||||||
totalCompensation: {
|
|
||||||
baseValue: order,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
monthYearReceived: 'desc',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: sortingKey === sortingKeysMap.totalYoe
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
background: {
|
|
||||||
totalYoe: order,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
monthYearReceived: 'desc',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: sortingKey === sortingKeysMap.companyName
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
company: {
|
|
||||||
name: 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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersIntern: {
|
|
||||||
is: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersFullTime: {
|
|
||||||
isNot: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersFullTime: {
|
|
||||||
title:
|
|
||||||
input.title != null && input.title.length !== 0
|
|
||||||
? input.title
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offersFullTime: {
|
|
||||||
totalCompensation: {
|
|
||||||
baseValue: {
|
|
||||||
gte: input.salaryMin ?? undefined,
|
|
||||||
lte: input.salaryMax ?? undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
companyId:
|
|
||||||
input.companyId && input.companyId.length !== 0
|
|
||||||
? 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 endRecordIndex: number =
|
|
||||||
startRecordIndex + input.limit <= data.length
|
|
||||||
? startRecordIndex + input.limit
|
|
||||||
: data.length;
|
|
||||||
let paginatedData = data.slice(startRecordIndex, endRecordIndex);
|
|
||||||
|
|
||||||
// CONVERTING
|
|
||||||
const currency = input.currency?.toUpperCase();
|
|
||||||
if (currency != null && currency in Currency) {
|
|
||||||
paginatedData = await Promise.all(
|
|
||||||
paginatedData.map(async (offer) => {
|
|
||||||
if (offer.offersFullTime?.totalCompensation != null) {
|
|
||||||
offer.offersFullTime.totalCompensation.value =
|
|
||||||
await convertWithDate(
|
|
||||||
offer.offersFullTime.totalCompensation.value,
|
|
||||||
offer.offersFullTime.totalCompensation.currency,
|
|
||||||
currency,
|
|
||||||
offer.offersFullTime.totalCompensation.updatedAt,
|
|
||||||
);
|
|
||||||
offer.offersFullTime.totalCompensation.currency = currency;
|
|
||||||
|
|
||||||
if (offer.offersFullTime?.baseSalary != null) {
|
|
||||||
offer.offersFullTime.baseSalary.value = await convertWithDate(
|
|
||||||
offer.offersFullTime.baseSalary.value,
|
|
||||||
offer.offersFullTime.baseSalary.currency,
|
|
||||||
currency,
|
|
||||||
offer.offersFullTime.baseSalary.updatedAt,
|
|
||||||
);
|
|
||||||
offer.offersFullTime.baseSalary.currency = currency;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offer.offersFullTime?.stocks != null) {
|
|
||||||
offer.offersFullTime.stocks.value = await convertWithDate(
|
|
||||||
offer.offersFullTime.stocks.value,
|
|
||||||
offer.offersFullTime.stocks.currency,
|
|
||||||
currency,
|
|
||||||
offer.offersFullTime.stocks.updatedAt,
|
|
||||||
);
|
|
||||||
offer.offersFullTime.stocks.currency = currency;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offer.offersFullTime?.bonus != null) {
|
|
||||||
offer.offersFullTime.bonus.value = await convertWithDate(
|
|
||||||
offer.offersFullTime.bonus.value,
|
|
||||||
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,
|
|
||||||
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(
|
|
||||||
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
|
const yoeRange = getYoeRange(input.yoeCategory);
|
||||||
}
|
const yoeMin = input.yoeMin != null ? input.yoeMin : yoeRange?.minYoe;
|
||||||
});
|
const yoeMax = input.yoeMax != null ? input.yoeMax : yoeRange?.maxYoe;
|
||||||
|
|
||||||
|
if (!input.sortBy) {
|
||||||
|
input.sortBy = '-' + sortingKeysMap.monthYearReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
const order = getOrder(input.sortBy.charAt(0));
|
||||||
|
const sortingKey = input.sortBy.substring(1);
|
||||||
|
|
||||||
|
const data = !yoeRange
|
||||||
|
? await ctx.prisma.offersOffer.findMany({
|
||||||
|
// Internship
|
||||||
|
include: {
|
||||||
|
company: true,
|
||||||
|
location: {
|
||||||
|
include: {
|
||||||
|
state: {
|
||||||
|
include: {
|
||||||
|
country: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
offersFullTime: {
|
||||||
|
include: {
|
||||||
|
baseSalary: true,
|
||||||
|
bonus: true,
|
||||||
|
stocks: true,
|
||||||
|
totalCompensation: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
offersIntern: {
|
||||||
|
include: {
|
||||||
|
monthlySalary: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
profile: {
|
||||||
|
include: {
|
||||||
|
background: true,
|
||||||
|
offers: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy:
|
||||||
|
sortingKey === sortingKeysMap.monthYearReceived
|
||||||
|
? {
|
||||||
|
monthYearReceived: order,
|
||||||
|
}
|
||||||
|
: sortingKey === sortingKeysMap.totalCompensation
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
offersIntern: {
|
||||||
|
monthlySalary: {
|
||||||
|
baseValue: order,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monthYearReceived: 'desc',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: sortingKey === sortingKeysMap.totalYoe
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
profile: {
|
||||||
|
background: {
|
||||||
|
totalYoe: order,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monthYearReceived: 'desc',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: sortingKey === sortingKeysMap.companyName
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
company: {
|
||||||
|
name: 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersIntern: {
|
||||||
|
isNot: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersIntern: {
|
||||||
|
title:
|
||||||
|
input.title != null && input.title.length !== 0
|
||||||
|
? input.title
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersIntern: {
|
||||||
|
monthlySalary: {
|
||||||
|
baseValue: {
|
||||||
|
gte: input.salaryMin ?? undefined,
|
||||||
|
lte: input.salaryMax ?? undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersFullTime: {
|
||||||
|
is: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
companyId:
|
||||||
|
input.companyId && input.companyId.length !== 0
|
||||||
|
? input.companyId
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
profile: {
|
||||||
|
background: {
|
||||||
|
totalYoe: {
|
||||||
|
gte: yoeMin,
|
||||||
|
lte: yoeMax,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monthYearReceived: {
|
||||||
|
gte: input.dateStart ?? undefined,
|
||||||
|
lte: input.dateEnd ?? undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: await ctx.prisma.offersOffer.findMany({
|
||||||
|
// Junior, Mid, Senior
|
||||||
|
include: {
|
||||||
|
company: true,
|
||||||
|
location: {
|
||||||
|
include: {
|
||||||
|
state: {
|
||||||
|
include: {
|
||||||
|
country: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
offersFullTime: {
|
||||||
|
include: {
|
||||||
|
baseSalary: true,
|
||||||
|
bonus: true,
|
||||||
|
stocks: true,
|
||||||
|
totalCompensation: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
offersIntern: {
|
||||||
|
include: {
|
||||||
|
monthlySalary: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
profile: {
|
||||||
|
include: {
|
||||||
|
background: true,
|
||||||
|
offers: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy:
|
||||||
|
sortingKey === sortingKeysMap.monthYearReceived
|
||||||
|
? {
|
||||||
|
monthYearReceived: order,
|
||||||
|
}
|
||||||
|
: sortingKey === sortingKeysMap.totalCompensation
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
offersFullTime: {
|
||||||
|
totalCompensation: {
|
||||||
|
baseValue: order,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monthYearReceived: 'desc',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: sortingKey === sortingKeysMap.totalYoe
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
profile: {
|
||||||
|
background: {
|
||||||
|
totalYoe: order,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monthYearReceived: 'desc',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: sortingKey === sortingKeysMap.companyName
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
company: {
|
||||||
|
name: 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersIntern: {
|
||||||
|
is: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersFullTime: {
|
||||||
|
isNot: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersFullTime: {
|
||||||
|
title:
|
||||||
|
input.title != null && input.title.length !== 0
|
||||||
|
? input.title
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offersFullTime: {
|
||||||
|
totalCompensation: {
|
||||||
|
baseValue: {
|
||||||
|
gte: input.salaryMin ?? undefined,
|
||||||
|
lte: input.salaryMax ?? undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
companyId:
|
||||||
|
input.companyId && input.companyId.length !== 0
|
||||||
|
? 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 endRecordIndex: number =
|
||||||
|
startRecordIndex + input.limit <= data.length
|
||||||
|
? startRecordIndex + input.limit
|
||||||
|
: data.length;
|
||||||
|
let paginatedData = data.slice(startRecordIndex, endRecordIndex);
|
||||||
|
|
||||||
|
// CONVERTING
|
||||||
|
const currency = input.currency?.toUpperCase();
|
||||||
|
if (currency != null && currency in Currency) {
|
||||||
|
paginatedData = await Promise.all(
|
||||||
|
paginatedData.map(async (offer) => {
|
||||||
|
if (offer.offersFullTime?.totalCompensation != null) {
|
||||||
|
offer.offersFullTime.totalCompensation.value =
|
||||||
|
await convertWithDate(
|
||||||
|
offer.offersFullTime.totalCompensation.value,
|
||||||
|
offer.offersFullTime.totalCompensation.currency,
|
||||||
|
currency,
|
||||||
|
offer.offersFullTime.totalCompensation.updatedAt,
|
||||||
|
);
|
||||||
|
offer.offersFullTime.totalCompensation.currency = currency;
|
||||||
|
|
||||||
|
if (offer.offersFullTime?.baseSalary != null) {
|
||||||
|
offer.offersFullTime.baseSalary.value = await convertWithDate(
|
||||||
|
offer.offersFullTime.baseSalary.value,
|
||||||
|
offer.offersFullTime.baseSalary.currency,
|
||||||
|
currency,
|
||||||
|
offer.offersFullTime.baseSalary.updatedAt,
|
||||||
|
);
|
||||||
|
offer.offersFullTime.baseSalary.currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offer.offersFullTime?.stocks != null) {
|
||||||
|
offer.offersFullTime.stocks.value = await convertWithDate(
|
||||||
|
offer.offersFullTime.stocks.value,
|
||||||
|
offer.offersFullTime.stocks.currency,
|
||||||
|
currency,
|
||||||
|
offer.offersFullTime.stocks.updatedAt,
|
||||||
|
);
|
||||||
|
offer.offersFullTime.stocks.currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offer.offersFullTime?.bonus != null) {
|
||||||
|
offer.offersFullTime.bonus.value = await convertWithDate(
|
||||||
|
offer.offersFullTime.bonus.value,
|
||||||
|
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,
|
||||||
|
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(
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user