forked from Ajeet1606/roast-github
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
326 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ node_modules | |
dist | ||
dist-ssr | ||
*.local | ||
.env | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* Dark Mode Styles */ | ||
body { | ||
background-color: #121212; /* Dark gray background */ | ||
color: #e0e0e0; /* Light gray text */ | ||
} | ||
|
||
a { | ||
color: #bb86fc; /* Optional: Add accent color for links (e.g., a soft purple) */ | ||
} | ||
|
||
button { | ||
background-color: #333333; /* Slightly lighter dark gray for buttons */ | ||
color: #e0e0e0; /* Light gray text on buttons */ | ||
} | ||
|
||
/* Additional styling for readability */ | ||
input, | ||
textarea { | ||
background-color: #1e1e1e; /* Slightly lighter dark gray for input fields */ | ||
color: #e0e0e0; /* Light gray text in input fields */ | ||
border: 1px solid #333333; /* Border color matching button */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,18 @@ | ||
import './App.css' | ||
import "./App.css"; | ||
import Footer from "./components/Footer"; | ||
import Main from "./components/Main"; | ||
import Navbar from "./components/Navbar"; | ||
|
||
function App() { | ||
return <> | ||
<h1 className='text-3xl font-bold'>Vite + React</h1> | ||
return ( | ||
<> | ||
<div className="h-[100vh] w-full font-montserrat flex flex-col justify-between"> | ||
<Navbar /> | ||
<Main /> | ||
<Footer /> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default App | ||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const Footer = () => { | ||
return ( | ||
<div className="h-1/6 flex flex-col"> | ||
<h1 className="text-center text-sm p-5 mt-auto"> | ||
Made with ❤️ by{" "} | ||
<span className="font-bold"> | ||
<a href="https://twitter.com/iampatelajeet">Ajeet Patel</a> | ||
</span> | ||
</h1> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Footer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { useState } from "react"; | ||
import { ProfileSchema, getProfileDetails } from "../utils/utils"; | ||
import { GoogleGenerativeAI } from "@google/generative-ai"; | ||
|
||
const Main = () => { | ||
const [inputUserName, setInputUserName] = useState(""); | ||
const [roastMessage, setRoastMessage] = useState(""); | ||
const [errorMessage, setErrorMessage] = useState(""); | ||
|
||
async function getRoastMessage(e: any) { | ||
e.preventDefault(); | ||
if (inputUserName === "") { | ||
setErrorMessage("Please enter a username."); | ||
setRoastMessage(""); | ||
return; | ||
} | ||
const userDetails: ProfileSchema = await getProfileDetails(inputUserName); | ||
|
||
if (!userDetails) { | ||
setErrorMessage(`Github Profile not found.`); | ||
setRoastMessage(""); | ||
return; | ||
} | ||
|
||
const prompt = `Here's a GitHub profile for you to roast: | ||
- Name: ${userDetails.name} | ||
- Bio: ${userDetails.bio} | ||
- Avatar URL: ${userDetails.avatarUrl} | ||
- Repositories: ${userDetails.repositories.totalCount} | ||
- Followers: ${userDetails.followers.totalCount} | ||
- Following: ${userDetails.following.totalCount} | ||
- Starred Repositories: ${userDetails.starredRepositories.totalCount} | ||
- Total Commits: ${userDetails.contributionsCollection.totalCommitContributions} in this year. | ||
Go ahead and give a satire roast of this GitHub user! Keep it in around 100 words.`; | ||
return await getRoastResponse(prompt); | ||
} | ||
|
||
async function getRoastResponse(prompt: string) { | ||
try { | ||
setRoastMessage("Loading..."); | ||
setErrorMessage(""); | ||
const GEMINI_API_KEY = import.meta.env.VITE_GEMINI_API_KEY!; | ||
const GEMINI_MODEL = import.meta.env.VITE_GEMINI_MODEL!; | ||
const genAI = new GoogleGenerativeAI(GEMINI_API_KEY); | ||
const model = genAI.getGenerativeModel({ | ||
model: GEMINI_MODEL, | ||
systemInstruction: "Act as a satire and sarcastic person.", | ||
}); | ||
|
||
const result = await model.generateContentStream(prompt); | ||
setRoastMessage(""); | ||
for await (const chunk of result.stream) { | ||
const chunkText = chunk.text(); | ||
console.log(chunkText); | ||
setRoastMessage((prevData) => prevData + chunkText); | ||
} | ||
} catch (error) { | ||
// console.error("Error calling Gemini API:", error); | ||
setErrorMessage("An error occurred. Please try again later."); | ||
return error; | ||
} | ||
} | ||
|
||
function handleInputChange(e: React.ChangeEvent<HTMLInputElement>) { | ||
e.preventDefault(); | ||
setInputUserName(e.target.value); | ||
} | ||
|
||
return ( | ||
<div className="w-10/12 md:w-1/2 flex flex-col justify-center mx-auto"> | ||
<form action="" className="w-full" onSubmit={getRoastMessage}> | ||
<div className="w-full flex flex-col"> | ||
<input | ||
type="text" | ||
placeholder="Enter Your GitHub username" | ||
className="w-full rounded-md p-2 mb-4 border-white outline-none" | ||
onChange={handleInputChange} | ||
/> | ||
<button | ||
className="w-full rounded-md p-2 border border-white" | ||
type="submit" | ||
> | ||
Get Roasted | ||
</button> | ||
</div> | ||
</form> | ||
|
||
<div className="w-full mt-4"> | ||
<p className="text-center">{roastMessage}</p> | ||
{ | ||
errorMessage && <p className="text-center text-red-500">{errorMessage}</p> | ||
} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Main; |
Oops, something went wrong.