[resumes][feat] submit resume mutation (#310)

This commit is contained in:
Keane Chan
2022-10-06 17:40:11 +08:00
committed by GitHub
parent 7c40353f6b
commit 9f61ecf9c2
5 changed files with 56 additions and 11 deletions

View File

@ -6,8 +6,11 @@ CREATE TABLE "ResumesResume" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"additionalInfo" TEXT NOT NULL,
"role" TEXT NOT NULL,
"experience" TEXT NOT NULL,
"location" TEXT NOT NULL,
"url" TEXT NOT NULL,
"additionalInfo" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

View File

@ -94,9 +94,12 @@ model ResumesResume {
id String @id @default(cuid())
userId String
title String @db.Text
additionalInfo String @db.Text
// TODO: Add role, experience, location from Enums
// TODO: Update role, experience, location to use Enums
role String @db.Text
experience String @db.Text
location String @db.Text
url String
additionalInfo String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

View File

@ -1,10 +1,13 @@
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import { PaperClipIcon } from '@heroicons/react/24/outline';
import { Button, Select, TextInput } from '@tih/ui';
import { trpc } from '~/utils/trpc';
const TITLE_PLACEHOLDER =
'e.g. Applying for Company XYZ, please help me to review!';
const ADDITIONAL_INFO_PLACEHOLDER = `e.g. Im applying for company XYZ. I have been resume-rejected by N companies that I have applied for. Please help me to review so company XYZ gives me an interview!`;
@ -13,7 +16,7 @@ const FILE_UPLOAD_ERROR = 'Please upload a PDF file that is less than 10MB.';
const MAX_FILE_SIZE_LIMIT = 10485760;
type IFormInput = {
additionalInformation?: string;
additionalInfo?: string;
experience: string;
file: File;
location: string;
@ -68,6 +71,9 @@ export default function SubmitResumeForm() {
},
];
const resumeCreateMutation = trpc.useMutation('resumes.resume.user.create');
const router = useRouter();
const [resumeFile, setResumeFile] = useState<File | null>();
const [invalidFileUploadError, setInvalidFileUploadError] = useState<
string | null
@ -81,10 +87,11 @@ export default function SubmitResumeForm() {
formState: { errors },
} = useForm<IFormInput>();
// TODO: Add Create resume mutation
const onSubmit: SubmitHandler<IFormInput> = (data) => {
alert(JSON.stringify(data));
onClickReset();
const onSubmit: SubmitHandler<IFormInput> = async (data) => {
await resumeCreateMutation.mutate({
...data,
});
router.push('/resumes');
};
const onUploadFile = (event: React.ChangeEvent<HTMLInputElement>) => {
@ -196,10 +203,10 @@ export default function SubmitResumeForm() {
<div className="mb-4">
{/* TODO: Use TextInputArea instead */}
<TextInput
{...register('additionalInformation')}
{...register('additionalInfo')}
label="Additional Information"
placeholder={ADDITIONAL_INFO_PLACEHOLDER}
onChange={(val) => setValue('additionalInformation', val)}
onChange={(val) => setValue('additionalInfo', val)}
/>
</div>
<div className="mt-4 flex justify-end gap-4">

View File

@ -2,6 +2,7 @@ import superjson from 'superjson';
import { createRouter } from './context';
import { protectedExampleRouter } from './protected-example-router';
import { resumesResumeUserRouter } from './resumes-resume-user-router';
import { todosRouter } from './todos';
import { todosUserRouter } from './todos-user-router';
@ -12,7 +13,8 @@ export const appRouter = createRouter()
// Example routers. Learn more about tRPC routers: https://trpc.io/docs/v9/router
.merge('auth.', protectedExampleRouter)
.merge('todos.', todosRouter)
.merge('todos.user.', todosUserRouter);
.merge('todos.user.', todosUserRouter)
.merge('resumes.resume.user.', resumesResumeUserRouter);
// Export type definition of API
export type AppRouter = typeof appRouter;

View File

@ -0,0 +1,30 @@
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(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user.id;
// TODO: Store file in file storage and retrieve URL
return await ctx.prisma.resumesResume.create({
data: {
...input,
url: '',
userId,
},
});
},
},
);