115 lines
3.8 KiB
JavaScript
115 lines
3.8 KiB
JavaScript
import React, { useState } from "react";
|
||
import axios from "axios";
|
||
import "./Chatbot.css";
|
||
|
||
const Chatbot = ({ context }) => {
|
||
|
||
const [messages, setMessages] = useState([
|
||
{
|
||
role: "assistant",
|
||
content:
|
||
"Hi! I’m here to help you with career suggestions, ROI analysis, and any questions you have about your career. How can I assist you today?",
|
||
},
|
||
]);
|
||
const [input, setInput] = useState("");
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
const sendMessage = async (content) => {
|
||
const userMessage = { role: "user", content };
|
||
|
||
// Ensure career data is injected into every API call
|
||
const contextSummary = `
|
||
You are an advanced AI career advisor for AptivaAI.
|
||
Your role is to not only provide career suggestions but to analyze them based on salary potential, job stability, education costs, and market trends.
|
||
|
||
Use the following user-specific data:
|
||
- Career Suggestions: ${context.careerSuggestions?.map((c) => c.title).join(", ") || "No suggestions available."}
|
||
- Selected Career: ${context.selectedCareer?.title || "None"}
|
||
- Schools: ${context.schools?.map((s) => s["INSTNM"]).join(", ") || "No schools available."}
|
||
- Median Salary: ${
|
||
context.salaryData?.find((s) => s.percentile === "Median")?.value || "Unavailable"
|
||
}
|
||
- ROI (Return on Investment): If available, use education costs vs. salary potential to guide users.
|
||
|
||
**Your response should ALWAYS provide analysis, not just list careers.**
|
||
Example responses:
|
||
- "If you're looking for a high salary right away, X might be a great option, but it has slow growth."
|
||
- "If you prefer job stability, Y is projected to grow in demand over the next 10 years."
|
||
- "If work-life balance is a priority, avoid Z as it has high stress and irregular hours."
|
||
|
||
If the user asks about "the best career," do not assume a single best choice. Instead, explain trade-offs like:
|
||
- "If you want high pay now, X is great, but it has limited upward growth."
|
||
- "If you prefer stability, Y is a better long-term bet."
|
||
`;
|
||
|
||
const messagesToSend = [
|
||
{ role: "system", content: contextSummary }, // Inject AptivaAI data on every request
|
||
...messages,
|
||
userMessage,
|
||
];
|
||
|
||
try {
|
||
setLoading(true);
|
||
const response = await axios.post(
|
||
"https://api.openai.com/v1/chat/completions",
|
||
{
|
||
model: "gpt-3.5-turbo",
|
||
messages: messagesToSend,
|
||
temperature: 0.7,
|
||
},
|
||
{
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
Authorization: `Bearer ${process.env.REACT_APP_OPENAI_API_KEY}`,
|
||
},
|
||
}
|
||
);
|
||
|
||
const botMessage = response.data.choices[0].message;
|
||
setMessages([...messages, userMessage, botMessage]);
|
||
} catch (error) {
|
||
console.error("Chatbot Error:", error);
|
||
setMessages([
|
||
...messages,
|
||
userMessage,
|
||
{ role: "assistant", content: "Error: Unable to fetch response. Please try again." },
|
||
]);
|
||
} finally {
|
||
setLoading(false);
|
||
setInput("");
|
||
}
|
||
};
|
||
|
||
const handleSubmit = (e) => {
|
||
e.preventDefault();
|
||
if (input.trim()) {
|
||
sendMessage(input.trim());
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="chatbot-container">
|
||
<div className="chat-messages">
|
||
{messages.map((msg, index) => (
|
||
<div key={index} className={`message ${msg.role}`}>
|
||
{msg.content}
|
||
</div>
|
||
))}
|
||
{loading && <div className="message assistant">Typing...</div>}
|
||
</div>
|
||
<form onSubmit={handleSubmit} className="chat-input-form">
|
||
<input
|
||
type="text"
|
||
placeholder="Ask a question..."
|
||
value={input}
|
||
onChange={(e) => setInput(e.target.value)}
|
||
/>
|
||
<button type="submit" disabled={loading}>
|
||
Send
|
||
</button>
|
||
</form>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Chatbot; |