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

pull/314/head
Keane Chan 2 years ago committed by GitHub
parent 7c40353f6b
commit 9f61ecf9c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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,

@ -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)

@ -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">

@ -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;

@ -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,
},
});
},
},
);
Loading…
Cancel
Save