[resumes][feat] Add top 10 shortcut (#518)

pull/520/head
Su Yin 2 years ago committed by GitHub
parent ec97ee992a
commit c2288ba69c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -187,6 +187,7 @@ export default function ResumeHomePage() {
'resumes.resume.findAll', 'resumes.resume.findAll',
{ {
experienceFilters: userFilters.experience.map(({ value }) => value), experienceFilters: userFilters.experience.map(({ value }) => value),
isTop10: userFilters.isTop10,
isUnreviewed: userFilters.isUnreviewed, isUnreviewed: userFilters.isUnreviewed,
locationFilters: userFilters.location.map(({ value }) => value), locationFilters: userFilters.location.map(({ value }) => value),
roleFilters: userFilters.role.map(({ value }) => value), roleFilters: userFilters.role.map(({ value }) => value),
@ -206,6 +207,7 @@ export default function ResumeHomePage() {
'resumes.resume.user.findUserStarred', 'resumes.resume.user.findUserStarred',
{ {
experienceFilters: userFilters.experience.map(({ value }) => value), experienceFilters: userFilters.experience.map(({ value }) => value),
isTop10: userFilters.isTop10,
isUnreviewed: userFilters.isUnreviewed, isUnreviewed: userFilters.isUnreviewed,
locationFilters: userFilters.location.map(({ value }) => value), locationFilters: userFilters.location.map(({ value }) => value),
roleFilters: userFilters.role.map(({ value }) => value), roleFilters: userFilters.role.map(({ value }) => value),
@ -226,6 +228,7 @@ export default function ResumeHomePage() {
'resumes.resume.user.findUserCreated', 'resumes.resume.user.findUserCreated',
{ {
experienceFilters: userFilters.experience.map(({ value }) => value), experienceFilters: userFilters.experience.map(({ value }) => value),
isTop10: userFilters.isTop10,
isUnreviewed: userFilters.isUnreviewed, isUnreviewed: userFilters.isUnreviewed,
locationFilters: userFilters.location.map(({ value }) => value), locationFilters: userFilters.location.map(({ value }) => value),
roleFilters: userFilters.role.map(({ value }) => value), roleFilters: userFilters.role.map(({ value }) => value),

@ -1,6 +1,9 @@
import { z } from 'zod'; import { z } from 'zod';
import { Vote } from '@prisma/client'; import { Vote } from '@prisma/client';
import type { FilterCounts } from '~/utils/resumes/resumeFilters';
import { resumeGetFilterCounts } from '~/utils/resumes/resumeGetFilterCounts';
import { createRouter } from '../context'; import { createRouter } from '../context';
import type { Resume } from '~/types/resume'; import type { Resume } from '~/types/resume';
@ -9,6 +12,7 @@ export const resumesRouter = createRouter()
.query('findAll', { .query('findAll', {
input: z.object({ input: z.object({
experienceFilters: z.string().array(), experienceFilters: z.string().array(),
isTop10: z.boolean(),
isUnreviewed: z.boolean(), isUnreviewed: z.boolean(),
locationFilters: z.string().array(), locationFilters: z.string().array(),
roleFilters: z.string().array(), roleFilters: z.string().array(),
@ -25,19 +29,14 @@ export const resumesRouter = createRouter()
sortOrder, sortOrder,
isUnreviewed, isUnreviewed,
skip, skip,
isTop10,
searchValue, searchValue,
take, take,
} = input; } = input;
const userId = ctx.session?.user?.id; const userId = ctx.session?.user?.id;
const totalRecords = await ctx.prisma.resumesResume.count({ let totalRecords = 10;
where: { let filterCounts = {} as FilterCounts;
experience: { in: experienceFilters },
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
},
});
const resumesData = await ctx.prisma.resumesResume.findMany({ const resumesData = await ctx.prisma.resumesResume.findMany({
include: { include: {
_count: { _count: {
@ -77,7 +76,7 @@ export const resumesRouter = createRouter()
}, },
} }
: { comments: { _count: 'desc' } }, : { comments: { _count: 'desc' } },
skip, skip: isTop10 ? 0 : skip,
take, take,
where: { where: {
experience: { in: experienceFilters }, experience: { in: experienceFilters },
@ -107,6 +106,19 @@ export const resumesRouter = createRouter()
return resume; return resume;
}); });
if (isTop10) {
filterCounts = resumeGetFilterCounts(mappedResumeData);
} else {
totalRecords = await ctx.prisma.resumesResume.count({
where: {
experience: { in: experienceFilters },
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
},
});
// Group by role and count, taking into account all role/experience/locationId/isUnreviewed filters and search value // Group by role and count, taking into account all role/experience/locationId/isUnreviewed filters and search value
const roleCounts = await ctx.prisma.resumesResume.groupBy({ const roleCounts = await ctx.prisma.resumesResume.groupBy({
_count: { _count: {
@ -158,11 +170,12 @@ export const resumesRouter = createRouter()
locationCounts.map((lc) => [lc.locationId, lc._count._all]), locationCounts.map((lc) => [lc.locationId, lc._count._all]),
); );
const filterCounts = { filterCounts = {
experience: mappedExperienceCounts, experience: mappedExperienceCounts,
location: mappedLocationCounts, location: mappedLocationCounts,
role: mappedRoleCounts, role: mappedRoleCounts,
}; };
}
return { return {
filterCounts, filterCounts,

@ -1,5 +1,8 @@
import { z } from 'zod'; import { z } from 'zod';
import type { FilterCounts } from '~/utils/resumes/resumeFilters';
import { resumeGetFilterCounts } from '~/utils/resumes/resumeGetFilterCounts';
import { createProtectedRouter } from '../context'; import { createProtectedRouter } from '../context';
import type { Resume } from '~/types/resume'; import type { Resume } from '~/types/resume';
@ -63,6 +66,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
.query('findUserStarred', { .query('findUserStarred', {
input: z.object({ input: z.object({
experienceFilters: z.string().array(), experienceFilters: z.string().array(),
isTop10: z.boolean(),
isUnreviewed: z.boolean(), isUnreviewed: z.boolean(),
locationFilters: z.string().array(), locationFilters: z.string().array(),
roleFilters: z.string().array(), roleFilters: z.string().array(),
@ -78,23 +82,16 @@ export const resumesResumeUserRouter = createProtectedRouter()
locationFilters, locationFilters,
experienceFilters, experienceFilters,
searchValue, searchValue,
isTop10,
sortOrder, sortOrder,
isUnreviewed, isUnreviewed,
skip, skip,
take, take,
} = input; } = input;
const totalRecords = await ctx.prisma.resumesStar.count({
where: { let totalRecords = 10;
resume: { let filterCounts = {} as FilterCounts;
experience: { in: experienceFilters },
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
},
userId,
},
});
const resumeStarsData = await ctx.prisma.resumesStar.findMany({ const resumeStarsData = await ctx.prisma.resumesStar.findMany({
include: { include: {
resume: { resume: {
@ -140,7 +137,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
}, },
}, },
}, },
skip, skip: isTop10 ? 0 : skip,
take, take,
where: { where: {
resume: { resume: {
@ -174,6 +171,22 @@ export const resumesResumeUserRouter = createProtectedRouter()
return resume; return resume;
}); });
if (isTop10) {
filterCounts = resumeGetFilterCounts(mappedResumeData);
} else {
totalRecords = await ctx.prisma.resumesStar.count({
where: {
resume: {
experience: { in: experienceFilters },
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
},
userId,
},
});
const roleCounts = await ctx.prisma.resumesResume.groupBy({ const roleCounts = await ctx.prisma.resumesResume.groupBy({
_count: { _count: {
_all: true, _all: true,
@ -237,11 +250,12 @@ export const resumesResumeUserRouter = createProtectedRouter()
locationCounts.map((lc) => [lc.locationId, lc._count._all]), locationCounts.map((lc) => [lc.locationId, lc._count._all]),
); );
const filterCounts = { filterCounts = {
experience: mappedExperienceCounts, experience: mappedExperienceCounts,
location: mappedLocationCounts, location: mappedLocationCounts,
role: mappedRoleCounts, role: mappedRoleCounts,
}; };
}
return { filterCounts, mappedResumeData, totalRecords }; return { filterCounts, mappedResumeData, totalRecords };
}, },
@ -249,6 +263,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
.query('findUserCreated', { .query('findUserCreated', {
input: z.object({ input: z.object({
experienceFilters: z.string().array(), experienceFilters: z.string().array(),
isTop10: z.boolean(),
isUnreviewed: z.boolean(), isUnreviewed: z.boolean(),
locationFilters: z.string().array(), locationFilters: z.string().array(),
roleFilters: z.string().array(), roleFilters: z.string().array(),
@ -265,20 +280,15 @@ export const resumesResumeUserRouter = createProtectedRouter()
experienceFilters, experienceFilters,
sortOrder, sortOrder,
searchValue, searchValue,
isTop10,
isUnreviewed, isUnreviewed,
take, take,
skip, skip,
} = input; } = input;
const totalRecords = await ctx.prisma.resumesResume.count({
where: { let totalRecords = 10;
experience: { in: experienceFilters }, let filterCounts = {} as FilterCounts;
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
userId,
},
});
const resumesData = await ctx.prisma.resumesResume.findMany({ const resumesData = await ctx.prisma.resumesResume.findMany({
include: { include: {
_count: { _count: {
@ -315,7 +325,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
}, },
} }
: { comments: { _count: 'desc' } }, : { comments: { _count: 'desc' } },
skip, skip: isTop10 ? 0 : skip,
take, take,
where: { where: {
experience: { in: experienceFilters }, experience: { in: experienceFilters },
@ -346,6 +356,20 @@ export const resumesResumeUserRouter = createProtectedRouter()
return resume; return resume;
}); });
if (isTop10) {
filterCounts = resumeGetFilterCounts(mappedResumeData);
} else {
totalRecords = await ctx.prisma.resumesResume.count({
where: {
experience: { in: experienceFilters },
isResolved: isUnreviewed ? false : {},
locationId: { in: locationFilters },
role: { in: roleFilters },
title: { contains: searchValue, mode: 'insensitive' },
userId,
},
});
const roleCounts = await ctx.prisma.resumesResume.groupBy({ const roleCounts = await ctx.prisma.resumesResume.groupBy({
_count: { _count: {
_all: true, _all: true,
@ -397,11 +421,12 @@ export const resumesResumeUserRouter = createProtectedRouter()
locationCounts.map((lc) => [lc.locationId, lc._count._all]), locationCounts.map((lc) => [lc.locationId, lc._count._all]),
); );
const filterCounts = { filterCounts = {
experience: mappedExperienceCounts, experience: mappedExperienceCounts,
location: mappedLocationCounts, location: mappedLocationCounts,
role: mappedRoleCounts, role: mappedRoleCounts,
}; };
}
return { filterCounts, mappedResumeData, totalRecords }; return { filterCounts, mappedResumeData, totalRecords };
}, },

@ -5,8 +5,10 @@ import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
import { JobTitleLabels } from '~/components/shared/JobTitles'; import { JobTitleLabels } from '~/components/shared/JobTitles';
export type FilterId = 'experience' | 'location' | 'role'; export type FilterId = 'experience' | 'location' | 'role';
export type FilterCounts = Record<FilterId, Record<string, number>>;
export type CustomFilter = { export type CustomFilter = {
isTop10: boolean;
isUnreviewed: boolean; isUnreviewed: boolean;
}; };
@ -145,6 +147,7 @@ export const INITIAL_LOCATIONS: Array<TypeaheadOption> = [
export const INITIAL_FILTER_STATE: FilterState = { export const INITIAL_FILTER_STATE: FilterState = {
experience: EXPERIENCES, experience: EXPERIENCES,
isTop10: false,
isUnreviewed: true, isUnreviewed: true,
location: INITIAL_LOCATIONS, location: INITIAL_LOCATIONS,
role: INITIAL_ROLES, role: INITIAL_ROLES,
@ -185,6 +188,7 @@ export const SHORTCUTS: Array<Shortcut> = [
{ {
filters: { filters: {
...INITIAL_FILTER_STATE, ...INITIAL_FILTER_STATE,
isTop10: true,
isUnreviewed: false, isUnreviewed: false,
}, },
name: 'Top 10', name: 'Top 10',

@ -0,0 +1,39 @@
import type { Resume } from '~/types/resume';
export function resumeGetFilterCounts(data: Array<Resume>) {
const roleCounts: Record<string, number> = {};
for (let i = 0; i < data.length; i++) {
const { role } = data[i];
if (!(role in roleCounts)) {
roleCounts[role] = 1;
} else {
roleCounts[role]++;
}
}
const experienceCounts: Record<string, number> = {};
for (let i = 0; i < data.length; i++) {
const { experience } = data[i];
if (!(experience in experienceCounts)) {
experienceCounts[experience] = 1;
} else {
experienceCounts[experience]++;
}
}
const locationCounts: Record<string, number> = {};
for (let i = 0; i < data.length; i++) {
const { locationId } = data[i];
if (!(locationId in locationCounts)) {
locationCounts[locationId] = 1;
} else {
locationCounts[locationId]++;
}
}
return {
experience: experienceCounts,
location: locationCounts,
role: roleCounts,
};
}
Loading…
Cancel
Save