The stock hover effect expands downward with properly sized text.
"Will go 50 points up/down" text is adjusted for mobile compatibility.
The index section is included.
The profile section remains functional.
A search bar with a voice search icon is added. import React, { useState, useEffect,
useRef } from "react";
import { motion } from "framer-motion";
import { FiSearch, FiMic } from "react-icons/fi";
import { AiOutlineClose } from "react-icons/ai";
const HomePage = () => {
const [isProfileOpen, setIsProfileOpen] = useState(false);
const [hoveredStock, setHoveredStock] = useState(null);
const [profilePic, setProfilePic] = useState("/user-avatar.png");
const profileRef = useRef(null);
const toggleProfile = () => {
setIsProfileOpen(!isProfileOpen);
};
const handleProfilePicChange = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = () => setProfilePic(reader.result);
reader.readAsDataURL(file);
}
};
useEffect(() => {
const handleClickOutside = (event) => {
if (profileRef.current && !profileRef.current.contains(event.target)) {
setIsProfileOpen(false);
}
};
if (isProfileOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => document.removeEventListener("mousedown", handleClickOutside);
}, [isProfileOpen]);
const indices = [
{ name: "Nifty 50", price: 22000, change: 50, percent: 0.23, up: true },
{ name: "Sensex", price: 73000, change: -120, percent: -0.16, up: false },
{ name: "NASDAQ", price: 15600, change: 80, percent: 0.51, up: true }
];
const stocks = [
{ name: "Reliance", price: 2500, change: 20, percent: 0.8, recommendation: "Buy now",
success: 75, prediction: "Will go 50 points up" },
{ name: "TCS", price: 3700, change: -15, percent: -0.4, recommendation: "Hold till
tomorrow", success: 45, prediction: "Will go 50 points down" }
];
return (
<div className="relative min-h-screen p-4 bg-white text-gray-900">
{/* Header Section */}
<div className="flex justify-between items-center bg-gray-100 p-3 shadow-md
rounded-lg">
<div className="flex items-center gap-3 cursor-pointer" onClick={toggleProfile}>
<img src={profilePic} alt="User" className="w-10 h-10 rounded-full border-2
border-gray-400" />
<span className="font-semibold">User Name</span>
</div>
<div className="flex items-center bg-white p-2 rounded-lg shadow-md border border-
gray-300">
<FiSearch className="text-gray-500 mr-2" />
<input type="text" placeholder="Search stocks..." className="outline-none bg-
transparent text-gray-900" />
<FiMic className="text-gray-500 ml-2 cursor-pointer" />
</div>
</div>
{/* Profile Panel */}
{isProfileOpen && (
<motion.div
ref={profileRef}
initial={{ x: -300 }}
animate={{ x: 0 }}
exit={{ x: -300 }}
className="fixed top-0 left-0 h-full w-64 bg-gray-200 shadow-lg p-4 z-50 text-gray-
900"
>
<AiOutlineClose className="absolute top-4 right-4 cursor-pointer"
onClick={toggleProfile} />
<h2 className="text-lg font-semibold mb-4">Profile</h2>
<div className="flex flex-col items-center mb-4">
<img src={profilePic} alt="User" className="w-20 h-20 rounded-full border-2
border-gray-400" />
<label className="mt-2 text-blue-500 cursor-pointer">
Edit Photo
<input type="file" className="hidden" onChange={handleProfilePicChange} />
</label>
</div>
<ul className="space-y-3">
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Settings</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Privacy Policy</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded text-red-
500">Logout</li>
</ul>
</motion.div>
)}
{/* Market Indices Section */}
<div className="mt-6 bg-gray-100 p-4 rounded-lg shadow">
<h2 className="text-lg font-semibold mb-3 text-gray-900">Market Indices</h2>
<div className="grid grid-cols-3 gap-4">
{indices.map((index, idx) => (
<div key={idx} className={`p-3 rounded-lg shadow text-center text-lg font-bold $
{index.up ? 'bg-green-300' : 'bg-red-300'}`}>
<span>{index.name}</span>
<div>{index.price}</div>
<div>{index.change} ({index.percent}%) {index.up ? '📈' : '📉'}</div>
</div>
))}
</div>
</div>
{/* Stock List with Hover Effect */}
<div className="mt-6 grid grid-cols-2 gap-4">
{stocks.map((stock, idx) => (
<div
key={idx}
className="relative bg-gray-100 p-4 rounded-lg shadow-md cursor-pointer
overflow-hidden"
onMouseEnter={() => setHoveredStock(idx)}
onMouseLeave={() => setHoveredStock(null)}
>
<div className="text-lg font-bold">{stock.name}</div>
<div>₹{stock.price}</div>
<motion.div
initial={{ height: 0 }}
animate={{ height: hoveredStock === idx ? "auto" : 0 }}
className="mt-2 overflow-hidden"
>
<div className="text-gray-900 font-medium text-lg">{stock.prediction}</div>
<div className={`mt-2 p-2 w-16 h-16 flex items-center justify-center rounded-full
text-white text-lg font-bold ${stock.success > 50 ? 'bg-green-500' : 'bg-red-500'}`}>
{stock.success}%
</div>
</motion.div>
</div>
))}
</div>
</div>
);
};
export default HomePage; import React, { useState, useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { FiSearch, FiMic } from "react-icons/fi";
import { AiOutlineClose } from "react-icons/ai";
const HomePage = () => {
const [isProfileOpen, setIsProfileOpen] = useState(false);
const [hoveredStock, setHoveredStock] = useState(null);
const [profilePic, setProfilePic] = useState("/user-avatar.png");
const profileRef = useRef(null);
const toggleProfile = () => {
setIsProfileOpen(!isProfileOpen);
};
const handleProfilePicChange = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = () => setProfilePic(reader.result);
reader.readAsDataURL(file);
}
};
useEffect(() => {
const handleClickOutside = (event) => {
if (profileRef.current && !profileRef.current.contains(event.target)) {
setIsProfileOpen(false);
}
};
if (isProfileOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => document.removeEventListener("mousedown", handleClickOutside);
}, [isProfileOpen]);
const indices = [
{ name: "Nifty 50", price: 22000, change: 50, percent: 0.23, up: true },
{ name: "Sensex", price: 73000, change: -120, percent: -0.16, up: false },
{ name: "NASDAQ", price: 15600, change: 80, percent: 0.51, up: true }
];
const stocks = [
{ name: "Reliance", price: 2500, change: 20, percent: 0.8, recommendation: "Buy now",
success: 75, prediction: "Will go 50 points up" },
{ name: "TCS", price: 3700, change: -15, percent: -0.4, recommendation: "Hold till
tomorrow", success: 45, prediction: "Will go 50 points down" }
];
return (
<div className="relative min-h-screen p-4 bg-white text-gray-900">
{/* Header Section */}
<div className="flex justify-between items-center bg-gray-100 p-3 shadow-md
rounded-lg">
<div className="flex items-center gap-3 cursor-pointer" onClick={toggleProfile}>
<img src={profilePic} alt="User" className="w-10 h-10 rounded-full border-2
border-gray-400" />
<span className="font-semibold">User Name</span>
</div>
<div className="flex items-center bg-white p-2 rounded-lg shadow-md border border-
gray-300">
<FiSearch className="text-gray-500 mr-2" />
<input type="text" placeholder="Search stocks..." className="outline-none bg-
transparent text-gray-900" />
<FiMic className="text-gray-500 ml-2 cursor-pointer" />
</div>
</div>
{/* Profile Panel */}
{isProfileOpen && (
<motion.div
ref={profileRef}
initial={{ x: -300 }}
animate={{ x: 0 }}
exit={{ x: -300 }}
className="fixed top-0 left-0 h-full w-64 bg-gray-200 shadow-lg p-4 z-50 text-gray-
900"
>
<AiOutlineClose className="absolute top-4 right-4 cursor-pointer"
onClick={toggleProfile} />
<h2 className="text-lg font-semibold mb-4">Profile</h2>
<div className="flex flex-col items-center mb-4">
<img src={profilePic} alt="User" className="w-20 h-20 rounded-full border-2
border-gray-400" />
<label className="mt-2 text-blue-500 cursor-pointer">
Edit Photo
<input type="file" className="hidden" onChange={handleProfilePicChange} />
</label>
</div>
<ul className="space-y-3">
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Settings</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Privacy Policy</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded text-red-
500">Logout</li>
</ul>
</motion.div>
)}
{/* Market Indices Section */}
<div className="mt-6 bg-gray-100 p-4 rounded-lg shadow">
<h2 className="text-lg font-semibold mb-3 text-gray-900">Market Indices</h2>
<div className="grid grid-cols-3 gap-4">
{indices.map((index, idx) => (
<div key={idx} className={`p-3 rounded-lg shadow text-center text-lg font-bold $
{index.up ? 'bg-green-300' : 'bg-red-300'}`}>
<span>{index.name}</span>
<div>{index.price}</div>
<div>{index.change} ({index.percent}%) {index.up ? '📈' : '📉'}</div>
</div>
))}
<button className="col-span-3 bg-blue-500 text-white py-2 rounded-lg mt-2">Add
More</button>
</div>
</div>
{/* Stock List with Hover Effect */}
<div className="mt-6 grid grid-cols-2 gap-4">
{stocks.map((stock, idx) => (
<div
key={idx}
className="relative bg-gray-100 p-4 rounded-lg shadow-md cursor-pointer
overflow-hidden"
onMouseEnter={() => setHoveredStock(idx)}
onMouseLeave={() => setHoveredStock(null)}
>
<div className="text-lg font-bold">{stock.name}</div>
<div>₹{stock.price}</div>
<motion.div
initial={{ height: 0 }}
animate={{ height: hoveredStock === idx ? "auto" : 0 }}
className="mt-2 overflow-hidden"
>
<div className="text-gray-900 font-medium text-lg">{stock.prediction}</div>
<div className={`mt-2 p-2 w-16 h-16 flex items-center justify-center rounded-full
text-white text-lg font-bold ${stock.success > 50 ? 'bg-green-500' : 'bg-red-
500'}`}>{stock.success}%</div>
</motion.div>
</div>
))}
</div>
</div>
);
};
export default HomePage;
----------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------- import React, { useState,
useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { FiSearch, FiMic } from "react-icons/fi";
import { AiOutlineClose } from "react-icons/ai";
const HomePage = () => {
const [isProfileOpen, setIsProfileOpen] = useState(false);
const [hoveredStock, setHoveredStock] = useState(null);
const [profilePic, setProfilePic] = useState("/user-avatar.png");
const profileRef = useRef(null);
const toggleProfile = () => {
setIsProfileOpen(!isProfileOpen);
};
const handleProfilePicChange = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = () => setProfilePic(reader.result);
reader.readAsDataURL(file);
}
};
useEffect(() => {
const handleClickOutside = (event) => {
if (profileRef.current && !profileRef.current.contains(event.target)) {
setIsProfileOpen(false);
}
};
if (isProfileOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => document.removeEventListener("mousedown", handleClickOutside);
}, [isProfileOpen]);
const indices = [
{ name: "Nifty 50", price: 22000, change: 50, percent: 0.23, up: true },
{ name: "Sensex", price: 73000, change: -120, percent: -0.16, up: false },
{ name: "NASDAQ", price: 15600, change: 80, percent: 0.51, up: true }
];
const stocks = [
{ name: "Reliance", price: 2500, change: 20, percent: 0.8, recommendation: "Buy now",
success: 75, prediction: "Will go 50 points up" },
{ name: "TCS", price: 3700, change: -15, percent: -0.4, recommendation: "Hold till
tomorrow", success: 45, prediction: "Will go 50 points down" }
];
return (
<div className="relative min-h-screen p-4 bg-white text-gray-900">
{/* Header Section */}
<div className="flex justify-between items-center bg-gray-100 p-3 shadow-md
rounded-lg">
<div className="flex items-center gap-3 cursor-pointer" onClick={toggleProfile}>
<img src={profilePic} alt="User" className="w-10 h-10 rounded-full border-2
border-gray-400" />
<span className="font-semibold">User Name</span>
</div>
<div className="flex items-center bg-white p-2 rounded-lg shadow-md border border-
gray-300">
<FiSearch className="text-gray-500 mr-2" />
<input type="text" placeholder="Search stocks..." className="outline-none bg-
transparent text-gray-900" />
<FiMic className="text-gray-500 ml-2 cursor-pointer" />
</div>
</div>
{/* Profile Panel */}
{isProfileOpen && (
<motion.div
ref={profileRef}
initial={{ x: -300 }}
animate={{ x: 0 }}
exit={{ x: -300 }}
className="fixed top-0 left-0 h-full w-64 bg-gray-200 shadow-lg p-4 z-50 text-gray-
900"
>
<AiOutlineClose className="absolute top-4 right-4 cursor-pointer"
onClick={toggleProfile} />
<h2 className="text-lg font-semibold mb-4">Profile</h2>
<div className="flex flex-col items-center mb-4">
<img src={profilePic} alt="User" className="w-20 h-20 rounded-full border-2
border-gray-400" />
<label className="mt-2 text-blue-500 cursor-pointer">
Edit Photo
<input type="file" className="hidden" onChange={handleProfilePicChange} />
</label>
</div>
<ul className="space-y-3">
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Settings</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded">Privacy Policy</li>
<li className="cursor-pointer hover:bg-gray-300 p-2 rounded text-red-
500">Logout</li>
</ul>
</motion.div>
)}
{/* Market Indices Section */}
<div className="mt-6 bg-gray-100 p-4 rounded-lg shadow">
<h2 className="text-lg font-semibold mb-3 text-gray-900">Market Indices</h2>
<div className="grid grid-cols-3 gap-4">
{indices.map((index, idx) => (
<div key={idx} className={`p-3 rounded-lg shadow text-center text-lg font-bold $
{index.up ? 'bg-green-300' : 'bg-red-300'}`}>
<span>{index.name}</span>
<div>{index.price}</div>
<div>{index.change} ({index.percent}%) {index.up ? '📈' : '📉'}</div>
</div>
))}
<button className="col-span-3 bg-blue-500 text-white py-2 rounded-lg mt-2">Add
More</button>
</div>
</div>
<h2 className="text-xl font-bold mt-6 mb-2">Here is some stocks for you!</h2>
{/* Stock List with Hover Effect */}
<div className="grid grid-cols-2 gap-4">
{stocks.map((stock, idx) => (
<div
key={idx}
className="relative bg-gray-100 p-4 rounded-lg shadow-md cursor-pointer
overflow-hidden"
onMouseEnter={() => setHoveredStock(idx)}
onMouseLeave={() => setHoveredStock(null)}
>
<div className="text-lg font-bold">{stock.name}</div>
<div>₹{stock.price} <span className={stock.change > 0 ? 'text-green-500' : 'text-
red-500'}>({stock.change}%)</span></div>
<motion.div
initial={{ height: 0 }}
animate={{ height: hoveredStock === idx ? "auto" : 0 }}
className="mt-2 overflow-hidden"
>
<div className="text-gray-900 font-medium text-lg">{stock.prediction}</div>
<div className={`mt-2 p-2 w-16 h-16 flex items-center justify-center rounded-full
text-white text-lg font-bold ${stock.success > 50 ? 'bg-green-500' : 'bg-red-
500'}`}>{stock.success}%</div>
</motion.div>
</div>
))}
</div>
</div>
);
};
export default HomePage;