Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions client/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# React + Vite

Steps
git clone url of foked project
cd InfantCareCompass
cd client
npm i
npm install @google/generative-ai

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:
Expand Down
401 changes: 213 additions & 188 deletions client/package-lock.json

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@
"preview": "vite preview"
},
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@reduxjs/toolkit": "^2.5.0",
"@zegocloud/zego-uikit-prebuilt": "^2.15.1",
"axios": "^1.7.9",
"chart.js": "^4.4.0",
"client": "^0.0.1",
"date-fns": "^4.1.0",
"dotenv": "^17.2.2",
"framer-motion": "^11.15.0",
"lucide-react": "^0.525.0",
"motion": "^12.23.6",
"openai": "^5.20.2",
"path": "^0.12.7",
"react": "^18.3.1",
"react-chartjs-2": "^5.2.0",
"react-dom": "^18.3.1",
"react-hook-form": "^7.54.2",
"react-hot-toast": "^2.6.0",
Expand All @@ -31,24 +36,23 @@
"redux-persist": "^6.0.0",
"simple-peer": "^9.11.1",
"swiper": "^11.2.10",
"toaster-js": "^2.2.3",
"chart.js": "^4.4.0",
"react-chartjs-2": "^5.2.0"
"toaster-js": "^2.2.3"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@types/node": "^22.10.2",
"@types/react": "^18.3.17",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react": "^5.0.2",
"autoprefixer": "^10.4.20",
"eslint": "^9.17.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.13.0",
"postcss": "^8.4.49",
"react-refresh": "^0.17.0",
"tailwindcss": "^3.4.17",
"vite": "^6.0.3"
"vite": "^7.1.5"
}
}
4 changes: 0 additions & 4 deletions client/src/.env

This file was deleted.

1 change: 1 addition & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ScrollRestoration from "./components/ScrollRestoration";
import { Toaster } from 'react-hot-toast';
import { ThemeProvider } from "./contexts/ThemeContext";
import MagicCursorTrail from "./components/magiccursortrail.jsx";
import InfantCareChatbot from "./pages/Chatbot.jsx";

function App() {
const matches = useMatches();
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { motion } from "framer-motion";
import navlogo from "/logo.png";
import ThemeToggle from "./ThemeToggle";
import InfantCareChatbot from "../pages/Chatbot.jsx";

export default function Header() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
Expand Down Expand Up @@ -58,6 +59,7 @@ export default function Header() {
{ to: "/blog", label: "Blog", icon: <BookOpen className="w-4 h-4" /> },
{ to: "/contactus", label: "Contact", icon: <Mail className="w-4 h-4" /> },
{ to: "/news", label: "News", icon: <Newspaper className="w-4 h-4" /> },
{to:"/chatbot",label:"",icon:"AI chat"},
{
to: "/consultation",
label: "Consultation",
Expand Down
109 changes: 109 additions & 0 deletions client/src/pages/Chatbot.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useState } from "react";
import { GoogleGenerativeAI } from "@google/generative-ai";

// Load API Key from .env
const genAI = new GoogleGenerativeAI(import.meta.env.VITE_GEMINI_API_KEY);

const InfantCareChatbot = () => {
const [messages, setMessages] = useState([
{
sender: "bot",
text: "👶 Hello! I’m your Infant Care Assistant. Ask me anything about infant care.",
},
]);
const [input, setInput] = useState("");
const [loading, setLoading] = useState(false);

const handleSend = async () => {
if (!input.trim()) return;

const newMessages = [...messages, { sender: "user", text: input }];
setMessages(newMessages);
setInput("");
setLoading(true);

try {
// Create model
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

// Convert messages to prompt
const history = newMessages
.map(
(msg) =>
`${msg.sender === "user" ? "User" : "Assistant"}: ${msg.text}`
)
.join("\n");

const prompt = `
You are an Infant Care Assistant. Always give safe, supportive, and responsible answers about infant health, feeding, sleep, and parenting.
Conversation so far:
${history}
Assistant:
`;

// Call Gemini
const result = await model.generateContent(prompt);
const botReply = result.response.text();

setMessages([...newMessages, { sender: "bot", text: botReply }]);
} catch (err) {
console.error(err);
setMessages([
...newMessages,
{
sender: "bot",
text: "⚠️ Sorry, I couldn’t process that. Try again!",
},
]);
} finally {
setLoading(false);
}
};

return (
<div className="flex justify-center items-center h-screen bg-gradient-to-br from-blue-100 to-pink-100">
<div className="w-full max-w-md bg-white shadow-lg rounded-2xl p-4 flex flex-col">
<h2 className="text-xl font-bold text-center text-pink-600 mb-2">
Infant Care Chatbot 🤱
</h2>

{/* Chat Window */}
<div className="flex-1 overflow-y-auto p-2 space-y-2 border rounded-lg bg-gray-50">
{messages.map((msg, idx) => (
<div
key={idx}
className={`p-2 rounded-lg max-w-[80%] ${
msg.sender === "user"
? "bg-blue-500 text-white self-end ml-auto"
: "bg-pink-200 text-gray-800 self-start"
}`}
>
{msg.text}
</div>
))}
{loading && <p className="text-sm text-gray-500">🤖 Typing...</p>}
</div>

{/* Input */}
<div className="mt-3 flex">
<input
type="text"
className="flex-1 border rounded-l-lg px-3 py-2 outline-none"
placeholder="Ask me about infant care..."
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSend()}
/>
<button
onClick={handleSend}
className="bg-pink-500 hover:bg-pink-600 text-white px-4 rounded-r-lg"
>
Send
</button>
</div>
</div>
</div>
);
};

export default InfantCareChatbot;
4 changes: 3 additions & 1 deletion client/src/routes/routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import LearningHub from "../pages/LearningHub";
import Services from "../pages/Services";

import ConsultationPage from "../pages/consult";

import InfantCareChatbot from "../pages/Chatbot.jsx";

// Components
import BabyFeeder from "../components/BabyFeeder";
Expand All @@ -46,6 +46,8 @@ const router = createBrowserRouter([
{ path: "babyfeeder", element: <BabyFeeder /> },
{ path: "sleeper", element: <Sleeper /> },
{ path: "care-co-pilot", element: <CareCoPilot /> },
{ path: "chatbot", element: <InfantCareChatbot /> },

{
path: "consultation",
element: <ConsultationPage />,
Expand Down