Skip to content

Commit

Permalink
add search and update breadcrumb
Browse files Browse the repository at this point in the history
  • Loading branch information
JackySun9 committed Dec 18, 2024
1 parent 77e6b6f commit 95c2fe7
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 11 deletions.
32 changes: 25 additions & 7 deletions src/components/Breadcrumb.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom";

const Breadcrumb = ({ items, isDarkMode }) => {
const Breadcrumb = ({ items, isDarkMode, activeMenu }) => {
const navigate = useNavigate();

const handleMenuClick = () => {
navigate("/"); // Call the parent handler with current menu
};
return (
<div className="text-sm breadcrumbs p-4">
<ul className={`${isDarkMode ? 'text-white' : 'text-black'}`}>
<ul className={`${isDarkMode ? "text-white" : "text-black"}`}>
<li>
<Link to="/">Home</Link>
</li>
{activeMenu && (
<li>
<button
onClick={handleMenuClick}
className="hover:text-primary transition-colors"
>
{activeMenu}
</button>
</li>
)}
{items.map((item, index) => (
<li key={index}>
{item.link ? (
Expand All @@ -26,10 +42,12 @@ Breadcrumb.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string.isRequired,
link: PropTypes.string
link: PropTypes.string,
})
).isRequired,
isDarkMode: PropTypes.bool.isRequired
isDarkMode: PropTypes.bool.isRequired,
activeMenu: PropTypes.string,
onMenuClick: PropTypes.func,
};

export default Breadcrumb;
export default Breadcrumb;
106 changes: 105 additions & 1 deletion src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ const menuData = {
DA: ['da-homepage', 'da-dc', 'da-cc', 'da-bacom', 'da-bacom-blog', 'da-feds']
};

const searchData = Object.values(menuData).flat().map(item => ({
title: item,
url: `/imagediff/${item}`,
type: 'page'
}));

const Header = ({ isDarkMode, handleThemeToggle, activeMenu, setActiveMenu }) => {
const navigate = useNavigate();
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [hoveredMenu, setHoveredMenu] = useState(null);
const menuRef = useRef(null);
const [searchQuery, setSearchQuery] = useState('');
const [searchResults, setSearchResults] = useState([]);
const [isSearching, setIsSearching] = useState(false);
const searchRef = useRef(null);

useEffect(() => {
const handleClickOutside = (event) => {
Expand Down Expand Up @@ -80,7 +90,7 @@ const Header = ({ isDarkMode, handleThemeToggle, activeMenu, setActiveMenu }) =>
<Link
key={item}
to={`/imagediff/${item}`}
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 group flex items-center gap-2"
className="px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 group flex items-center gap-2"
onClick={(e) => {
e.stopPropagation();
setHoveredMenu(null);
Expand All @@ -95,13 +105,103 @@ const Header = ({ isDarkMode, handleThemeToggle, activeMenu, setActiveMenu }) =>
);
};

const handleSearch = (query) => {
setSearchQuery(query);
if (query.trim() === '') {
setSearchResults([]);
return;
}

const filtered = searchData.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase())
);
setSearchResults(filtered);
};

useEffect(() => {
const handleClickOutside = (event) => {
if (searchRef.current && !searchRef.current.contains(event.target)) {
setIsSearching(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

const searchBar = (
<div ref={searchRef} className="relative flex-1 max-w-xl mx-4">
<div className="relative">
<input
type="text"
placeholder="Search..."
value={searchQuery}
onChange={(e) => handleSearch(e.target.value)}
onFocus={() => setIsSearching(true)}
className={`w-full px-4 py-2 rounded-lg border ${
isDarkMode
? 'bg-gray-800 border-gray-700 text-white'
: 'bg-white border-gray-200 text-gray-900'
} focus:outline-none focus:ring-2 focus:ring-primary`}
/>
<svg
className={`absolute right-3 top-2.5 w-5 h-5 ${
isDarkMode ? 'text-gray-400' : 'text-gray-500'
}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>

{isSearching && searchResults.length > 0 && (
<div className={`absolute mt-2 w-full rounded-lg shadow-lg ${
isDarkMode ? 'bg-gray-800' : 'bg-white'
} ring-1 ring-black ring-opacity-5 z-50`}>
<div className="py-1">
{searchResults.map((result) => (
<Link
key={result.title}
to={result.url}
onClick={() => {
setIsSearching(false);
setSearchQuery('');
}}
className={`block px-4 py-2 text-sm ${
isDarkMode
? 'text-gray-200 hover:bg-gray-700'
: 'text-gray-700 hover:bg-gray-50'
} transition-colors duration-150`}
>
{result.title}
</Link>
))}
</div>
</div>
)}
</div>
);

return (
<nav className={`${isDarkMode ? 'bg-gray-900' : 'bg-gray-100'} p-4 sticky top-0 z-50 shadow-md`}>
<div className="container mx-auto flex justify-between items-center">
<Link to="/" className={`text-xl font-bold ${isDarkMode ? 'text-white' : 'text-black'}`}>
Auto Tests Dashboard
</Link>

<div className="hidden md:block flex-1 max-w-xl mx-4">
{searchBar}
</div>

<div className="md:hidden">
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
Expand Down Expand Up @@ -157,6 +257,10 @@ const Header = ({ isDarkMode, handleThemeToggle, activeMenu, setActiveMenu }) =>
</li>
</ul>
</div>

<div className="md:hidden block w-full mt-4">
{isMenuOpen && searchBar}
</div>
</div>
</nav>
);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const HomePage = () => {
activeMenu={activeMenu}
setActiveMenu={setActiveMenu}
/>
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} />
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} activeMenu={activeMenu}/>

<div className='container mx-auto pb-5 pt-4'>
{/* Cards */}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/ImageDiffPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const ImageDiffPage = () => {
activeMenu={activeMenu}
setActiveMenu={setActiveMenu}
/>
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} />
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} activeMenu={activeMenu}/>
<div className="container mx-auto p-4">
<ImageDiff data={data} timestamp={timestamp} isDarkMode={isDarkMode} />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/JsonViewerPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const JsonViewerPage = () => {
activeMenu={activeMenu}
setActiveMenu={setActiveMenu}
/>
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} />
<Breadcrumb items={breadcrumbItems} isDarkMode={isDarkMode} activeMenu={activeMenu}/>

<div className="container mx-auto p-4">
{isLoading && (
Expand Down

0 comments on commit 95c2fe7

Please sign in to comment.