Skip to content

Commit

Permalink
Feat/377 (#388)
Browse files Browse the repository at this point in the history
* feat: Multi-Step Form

* feat: changes ui

* feat: Gemini Integaretion
  • Loading branch information
Sid-80 authored Jul 19, 2024
1 parent e1c7990 commit 4fe74ef
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ NEXT_PUBLIC_URL=https://git-re.vercel.app/
NEXT_PUBLIC_UPSTASH_REDIS_URL=
NEXT_PUBLIC_UPSTASH_REDIS_TOKEN=

NEXT_PUBLIC_GEMINI_API_KEY=your-gemini-api-key

# Generate the token from https://github.com/settings/tokens?type=beta
# Repository Access to public repositories (read-only)
NEXT_PUBLIC_GITHUB_TOKEN=
29 changes: 25 additions & 4 deletions components/CoverLetterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { Textarea } from "./ui/textarea";
import { ArrowRightIcon } from "@radix-ui/react-icons";
import { SetStateAction } from "react";
import { getCoverLetter } from "@/utils/Gemini";

const formSchema = z.object({
jobDescription: z
Expand All @@ -34,7 +35,10 @@ type Props = {
isSubmit: boolean;
setIsJobDescription: React.Dispatch<SetStateAction<boolean>>;
setIsResumeDetails: React.Dispatch<SetStateAction<boolean>>;
setIsResponseGenerated: React.Dispatch<SetStateAction<boolean>>;
setIsError: React.Dispatch<SetStateAction<boolean>>;
setIsSubmit: React.Dispatch<SetStateAction<boolean>>;
setResponse: React.Dispatch<SetStateAction<string>>;
};

export default function CoverLetterForm({
Expand All @@ -44,6 +48,9 @@ export default function CoverLetterForm({
setIsJobDescription,
setIsSubmit,
setIsResumeDetails,
setIsResponseGenerated,
setIsError,
setResponse,
}: Props) {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
Expand Down Expand Up @@ -75,11 +82,25 @@ export default function CoverLetterForm({
}
}

function onSubmit(values: z.infer<typeof formSchema>) {
const onSubmit = async (values: z.infer<typeof formSchema>) => {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
}
const { jobDescription, project, skills, experience } = values;

try {
const res = await getCoverLetter({
jobDescription,
project,
skills,
experience,
});

console.log(res);
} catch (err) {
setIsError(true);
}
};

return (
<Form {...form}>
<form
Expand Down Expand Up @@ -122,7 +143,7 @@ export default function CoverLetterForm({
name="skills"
render={({ field }) => (
<FormItem>
<FormLabel>Projects</FormLabel>
<FormLabel>Skills</FormLabel>
<FormControl>
<Textarea
className="h-[100px]"
Expand Down
7 changes: 7 additions & 0 deletions components/cover-letter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export default function CoverLetter({ user }: Props) {
const [isResume, setIsResume] = useState(false);
const [isSubmit, setIsSubmit] = useState(false);

const [isResponseGenerated, setIsResponseGenerated] = useState(false);
const [isError, setIsError] = useState(false);
const [response, setResponse] = useState("");

if (user === null) {
router.push("/");
}
Expand Down Expand Up @@ -61,11 +65,14 @@ export default function CoverLetter({ user }: Props) {

<div className="flex flex-1 items-center justify-center">
<CoverLetterForm
setIsError={setIsError}
setIsResponseGenerated={setIsResponseGenerated}
isJobDescription={isJobDescription}
isResumeDetails={isResume}
isSubmit={isSubmit}
setIsResumeDetails={setIsResume}
setIsJobDescription={setIsJobDescription}
setResponse={setResponse}
setIsSubmit={setIsSubmit}
/>
</div>
Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@google/generative-ai": "^0.15.0",
"@hookform/resolvers": "^3.8.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.0",
Expand Down
54 changes: 54 additions & 0 deletions utils/Gemini.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { GoogleGenerativeAI } from "@google/generative-ai";

const MODEL_NAME = "gemini-1.5-pro";
const API_KEY1 = process.env.NEXT_PUBLIC_GEMINI_API_KEY as string;

const chatHistory = [
{
role: "user",
parts: [
{
text: `You are an expert in generating cover letter. Your task is to generate cover letter for given job description and resume details. If you are unable to generate then provide output as Information is insufficient!!`,
},
],
},
{
role: "model",
parts: [{ text: "How can I help you ?" }],
},
];

type Props = {
jobDescription: string;
project: string;
skills: string;
experience: string;
};

export async function getCoverLetter({
jobDescription,
project,
skills,
experience,
}: Props) {
if (!API_KEY1) throw new Error("Invalid Api Key!");

const genAI = new GoogleGenerativeAI(API_KEY1);
const model = genAI.getGenerativeModel({ model: MODEL_NAME });

model.generationConfig = {
temperature: 0.9,
topK: 1,
topP: 1,
};

const chat = model.startChat({
history: chatHistory,
});

const result = await chat.sendMessage(
`Job Description : \n${jobDescription}.\n Projects : \n${project} \nSkills: \n${skills} \nExperience: \n${experience}`
);
const response = result.response;
return response.text();
}

0 comments on commit 4fe74ef

Please sign in to comment.