mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 12:43:12 +08:00
[resumes][refactor] Package routers into folders (#341)
* [resumes][refactor] package routers into folders * [resumes][fix] use US as value
This commit is contained in:
@ -54,7 +54,7 @@ export const EXPERIENCE = [
|
||||
|
||||
export const LOCATION = [
|
||||
{ checked: false, label: 'Singapore', value: 'Singapore' },
|
||||
{ checked: false, label: 'United States', value: 'Usa' },
|
||||
{ checked: false, label: 'United States', value: 'US' },
|
||||
{ checked: false, label: 'India', value: 'India' },
|
||||
];
|
||||
|
||||
|
@ -20,7 +20,6 @@ export default function CommentsList({
|
||||
const [tab, setTab] = useState(COMMENTS_SECTIONS[0].value);
|
||||
const { data: session } = useSession();
|
||||
|
||||
// Fetch the most updated comments to render
|
||||
const commentsQuery = trpc.useQuery(['resumes.reviews.list', { resumeId }]);
|
||||
|
||||
// TODO: Add loading prompt
|
||||
|
@ -27,17 +27,17 @@ export default function ResumeReviewPage() {
|
||||
const { data: session } = useSession();
|
||||
const router = useRouter();
|
||||
const { resumeId } = router.query;
|
||||
const utils = trpc.useContext();
|
||||
const trpcContext = trpc.useContext();
|
||||
// Safe to assert resumeId type as string because query is only sent if so
|
||||
const detailsQuery = trpc.useQuery(
|
||||
['resumes.details.find', { resumeId: resumeId as string }],
|
||||
['resumes.resume.findOne', { resumeId: resumeId as string }],
|
||||
{
|
||||
enabled: typeof resumeId === 'string' && session?.user?.id !== undefined,
|
||||
enabled: typeof resumeId === 'string',
|
||||
},
|
||||
);
|
||||
const starMutation = trpc.useMutation('resumes.details.update_star', {
|
||||
const starMutation = trpc.useMutation('resumes.star.user.create_or_delete', {
|
||||
onSuccess() {
|
||||
utils.invalidateQueries();
|
||||
trpcContext.invalidateQueries(['resumes.resume.findOne']);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -53,24 +53,30 @@ export default function ResumeHomePage() {
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [resumes, setResumes] = useState<Array<Resume>>([]);
|
||||
|
||||
const allResumesQuery = trpc.useQuery(['resumes.resume.all'], {
|
||||
const allResumesQuery = trpc.useQuery(['resumes.resume.findAll'], {
|
||||
enabled: tabsValue === BROWSE_TABS_VALUES.ALL,
|
||||
onSuccess: (data) => {
|
||||
setResumes(data);
|
||||
},
|
||||
});
|
||||
const starredResumesQuery = trpc.useQuery(['resumes.resume.browse.stars'], {
|
||||
enabled: tabsValue === BROWSE_TABS_VALUES.STARRED,
|
||||
onSuccess: (data) => {
|
||||
setResumes(data);
|
||||
const starredResumesQuery = trpc.useQuery(
|
||||
['resumes.resume.user.findUserStarred'],
|
||||
{
|
||||
enabled: tabsValue === BROWSE_TABS_VALUES.STARRED,
|
||||
onSuccess: (data) => {
|
||||
setResumes(data);
|
||||
},
|
||||
},
|
||||
});
|
||||
const myResumesQuery = trpc.useQuery(['resumes.resume.browse.my'], {
|
||||
enabled: tabsValue === BROWSE_TABS_VALUES.MY,
|
||||
onSuccess: (data) => {
|
||||
setResumes(data);
|
||||
);
|
||||
const myResumesQuery = trpc.useQuery(
|
||||
['resumes.resume.user.findUserCreated'],
|
||||
{
|
||||
enabled: tabsValue === BROWSE_TABS_VALUES.MY,
|
||||
onSuccess: (data) => {
|
||||
setResumes(data);
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
const onClickNew = () => {
|
||||
if (sessionData?.user?.id) {
|
||||
|
@ -2,13 +2,12 @@ import superjson from 'superjson';
|
||||
|
||||
import { createRouter } from './context';
|
||||
import { protectedExampleRouter } from './protected-example-router';
|
||||
import { questionsQuestionRouter} from './questions-question-router';
|
||||
import { resumesRouter } from './resumes';
|
||||
import { resumesDetailsRouter } from './resumes-details-router';
|
||||
import { resumesResumeProtectedTabsRouter } from './resumes-resume-protected-tabs-router';
|
||||
import { resumesResumeUserRouter } from './resumes-resume-user-router';
|
||||
import { resumeReviewsRouter } from './resumes-reviews-router';
|
||||
import { resumesReviewsUserRouter } from './resumes-reviews-user-router';
|
||||
import { questionsQuestionRouter } from './questions-question-router';
|
||||
import { resumesRouter } from './resumes/resumes-resume-router';
|
||||
import { resumesResumeUserRouter } from './resumes/resumes-resume-user-router';
|
||||
import { resumeReviewsRouter } from './resumes/resumes-reviews-router';
|
||||
import { resumesReviewsUserRouter } from './resumes/resumes-reviews-user-router';
|
||||
import { resumesStarUserRouter } from './resumes/resumes-star-user-router';
|
||||
import { todosRouter } from './todos';
|
||||
import { todosUserRouter } from './todos-user-router';
|
||||
|
||||
@ -21,9 +20,8 @@ export const appRouter = createRouter()
|
||||
.merge('todos.', todosRouter)
|
||||
.merge('todos.user.', todosUserRouter)
|
||||
.merge('resumes.resume.', resumesRouter)
|
||||
.merge('resumes.details.', resumesDetailsRouter)
|
||||
.merge('resumes.resume.user.', resumesResumeUserRouter)
|
||||
.merge('resumes.resume.browse.', resumesResumeProtectedTabsRouter)
|
||||
.merge('resumes.star.user.', resumesStarUserRouter)
|
||||
.merge('resumes.reviews.', resumeReviewsRouter)
|
||||
.merge('resumes.reviews.user.', resumesReviewsUserRouter)
|
||||
.merge('questions.questions.', questionsQuestionRouter);
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createProtectedRouter } from './context';
|
||||
|
||||
export const resumesResumeUserRouter = createProtectedRouter().mutation(
|
||||
'create',
|
||||
{
|
||||
// TODO: Use enums for experience, location, role
|
||||
input: z.object({
|
||||
additionalInfo: z.string().optional(),
|
||||
experience: z.string(),
|
||||
location: z.string(),
|
||||
role: z.string(),
|
||||
title: z.string(),
|
||||
url: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
const userId = ctx.session?.user.id;
|
||||
return await ctx.prisma.resumesResume.create({
|
||||
data: {
|
||||
...input,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
@ -1,42 +0,0 @@
|
||||
import { createRouter } from './context';
|
||||
|
||||
import type { Resume } from '~/types/resume';
|
||||
|
||||
export const resumesRouter = createRouter().query('all', {
|
||||
async resolve({ ctx }) {
|
||||
const resumesData = await ctx.prisma.resumesResume.findMany({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
comments: true,
|
||||
stars: true,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
return resumesData.map((r) => {
|
||||
const resume: Resume = {
|
||||
additionalInfo: r.additionalInfo,
|
||||
createdAt: r.createdAt,
|
||||
experience: r.experience,
|
||||
id: r.id,
|
||||
location: r.location,
|
||||
numComments: r._count.comments,
|
||||
numStars: r._count.stars,
|
||||
role: r.role,
|
||||
title: r.title,
|
||||
url: r.url,
|
||||
user: r.user.name!,
|
||||
};
|
||||
return resume;
|
||||
});
|
||||
},
|
||||
});
|
@ -0,0 +1,79 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createRouter } from '../context';
|
||||
|
||||
import type { Resume } from '~/types/resume';
|
||||
|
||||
export const resumesRouter = createRouter()
|
||||
.query('findAll', {
|
||||
async resolve({ ctx }) {
|
||||
const resumesData = await ctx.prisma.resumesResume.findMany({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
comments: true,
|
||||
stars: true,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
return resumesData.map((r) => {
|
||||
const resume: Resume = {
|
||||
additionalInfo: r.additionalInfo,
|
||||
createdAt: r.createdAt,
|
||||
experience: r.experience,
|
||||
id: r.id,
|
||||
location: r.location,
|
||||
numComments: r._count.comments,
|
||||
numStars: r._count.stars,
|
||||
role: r.role,
|
||||
title: r.title,
|
||||
url: r.url,
|
||||
user: r.user.name!,
|
||||
};
|
||||
return resume;
|
||||
});
|
||||
},
|
||||
})
|
||||
.query('findOne', {
|
||||
input: z.object({
|
||||
resumeId: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
const { resumeId } = input;
|
||||
const userId = ctx.session?.user?.id;
|
||||
|
||||
// Use the resumeId to query all related information of a single resume
|
||||
// from Resumesresume:
|
||||
return await ctx.prisma.resumesResume.findUnique({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
stars: true,
|
||||
},
|
||||
},
|
||||
stars: {
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
id: resumeId,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
@ -1,9 +1,31 @@
|
||||
import { createProtectedRouter } from './context';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createProtectedRouter } from '../context';
|
||||
|
||||
import type { Resume } from '~/types/resume';
|
||||
|
||||
export const resumesResumeProtectedTabsRouter = createProtectedRouter()
|
||||
.query('stars', {
|
||||
export const resumesResumeUserRouter = createProtectedRouter()
|
||||
.mutation('create', {
|
||||
// TODO: Use enums for experience, location, role
|
||||
input: z.object({
|
||||
additionalInfo: z.string().optional(),
|
||||
experience: z.string(),
|
||||
location: z.string(),
|
||||
role: z.string(),
|
||||
title: z.string(),
|
||||
url: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
const userId = ctx.session?.user.id;
|
||||
return await ctx.prisma.resumesResume.create({
|
||||
data: {
|
||||
...input,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
},
|
||||
})
|
||||
.query('findUserStarred', {
|
||||
async resolve({ ctx }) {
|
||||
const userId = ctx.session?.user?.id;
|
||||
const resumeStarsData = await ctx.prisma.resumesStar.findMany({
|
||||
@ -49,7 +71,7 @@ export const resumesResumeProtectedTabsRouter = createProtectedRouter()
|
||||
});
|
||||
},
|
||||
})
|
||||
.query('my', {
|
||||
.query('findUserCreated', {
|
||||
async resolve({ ctx }) {
|
||||
const userId = ctx.session?.user?.id;
|
||||
const resumesData = await ctx.prisma.resumesResume.findMany({
|
@ -1,6 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createRouter } from './context';
|
||||
import { createRouter } from '../context';
|
||||
|
||||
import type { ResumeComment } from '~/types/resume-comments';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import { ResumesSection } from '@prisma/client';
|
||||
|
||||
import { createProtectedRouter } from './context';
|
||||
import { createProtectedRouter } from '../context';
|
||||
|
||||
type IResumeCommentInput = Readonly<{
|
||||
description: string;
|
@ -1,43 +1,10 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createRouter } from './context';
|
||||
import { createProtectedRouter } from '../context';
|
||||
|
||||
export const resumesDetailsRouter = createRouter()
|
||||
.query('find', {
|
||||
input: z.object({
|
||||
resumeId: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
const { resumeId } = input;
|
||||
const userId = ctx.session?.user?.id;
|
||||
|
||||
// Use the resumeId to query all related information of a single resume
|
||||
// from Resumesresume:
|
||||
return await ctx.prisma.resumesResume.findUnique({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
stars: true,
|
||||
},
|
||||
},
|
||||
stars: {
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
id: resumeId,
|
||||
},
|
||||
});
|
||||
},
|
||||
})
|
||||
.mutation('update_star', {
|
||||
export const resumesStarUserRouter = createProtectedRouter().mutation(
|
||||
'create_or_delete',
|
||||
{
|
||||
input: z.object({
|
||||
resumeId: z.string(),
|
||||
}),
|
||||
@ -76,4 +43,5 @@ export const resumesDetailsRouter = createRouter()
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
Reference in New Issue
Block a user