Select Git revision
SearchComponent.js
SearchComponent.js 6.42 KiB
import { styled, alpha } from "@mui/material/styles";
import SearchIcon from "@mui/icons-material/Search";
import KeyboardVoiceIcon from "@mui/icons-material/KeyboardVoice";
import KeyboardIcon from "@mui/icons-material/Keyboard";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState, useRef, useCallback } from "react";
let suggestions = [
{ name: "Recursos", class: "LearningObject", ref: "busca?page=LearningObject" },
{ name: "Coleções", class: "Collection", ref: "busca?page=Collection" },
{ name: "Usuários", class: "User", ref: "busca?page=User" },
];
/**
*
* @param {Object} props
* @param {Function} props.setQuery
* @param {Boolean} props.sizeWindow
* @returns searchComponent na header
*/
export default function SearchComponent({ setFilterState, filterState, sizeWindow }) {
const router = useRouter();
const pathname = usePathname();
const [input, setInput] = useState("");
const [drop, setDrop] = useState(false);
const [width, setWidth] = useState(0);
const [selectedIndex, setSelectedIndex] = useState(0);
const dropdownRef = useRef(null);
const searchRef = useRef(null);
const searchParams = useSearchParams()
const [isFocused, setIsFocused] = useState(false);
const handleFocus = () => {
setIsFocused(true);
};
const handleBlur = () => {
setIsFocused(false);
};
const handleSubmit = (e) => {
e.preventDefault();
const search = input === "" ? "*" : input;
let defaultType = "/busca?page=Collection";
if (
pathname === "/busca?page=Collection" ||
pathname === "/busca?page=LearningObject" ||
pathname === "/busca?page=User"
) {
defaultType = pathname;
}
if (!drop) {
router.push(`${defaultType}&filter=${search}`);
} else {
router.push(`/${suggestions[selectedIndex].ref}&filter=${search}`);
}
};
const handleClickOutside = (e) => {
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
setDrop(false);
}
};
const handleKeyDown = useCallback(
(e) => {
if (!drop) return;
if (e.key === "ArrowDown") {
e.preventDefault();
setSelectedIndex((prevIndex) =>
prevIndex < suggestions.length - 1 ? prevIndex + 1 : 0
);
} else if (e.key === "ArrowUp") {
e.preventDefault();
setSelectedIndex((prevIndex) =>
prevIndex > 0 ? prevIndex - 1 : suggestions.length - 1
);
} else if (e.key === "Enter" && selectedIndex >= 0) {
router.push(`/${suggestions[selectedIndex].ref}&filter=${input}`);
setDrop(false)
}
},
[drop, input, router, selectedIndex]
);
useEffect(() => {
if (drop) {
document.addEventListener("keydown", handleKeyDown);
} else {
document.removeEventListener("keydown", handleKeyDown);
}
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, [drop, handleKeyDown]);
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
useEffect(() => {
if (searchRef.current) {
setWidth(searchRef.current.offsetWidth);
}
}, [input, drop]);
useEffect(() => {
const handleResize = () => {
if (searchRef.current) {
setWidth(searchRef.current.offsetWidth);
}
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
useEffect(() => {
const index = suggestions.map(s => s.class).indexOf(searchParams.get('page'));
if (index !== -1) { // Estamos em uma página válida
setSelectedIndex(index);
}
}, [searchParams]);
return (
<form
onKeyDown={(e) => {
if (e.key === "Enter") e.preventDefault();
if (drop) e.stopPropagation();
}}
className="w-full max-sm:w-[90%] max-md:mx-2 h-[50px] z-30 items-center"
onSubmit={handleSubmit}
>
<div className="flex gap-1 items-center h-full">
<div
ref={searchRef}
className={`flex grow align-middle bg-white-HC-dark rounded-md text-xl items-center h-full ${
isFocused ? 'outline outline-2 outline-turquoise-HC-white' : ''
}`}
>
<input
id="buscar"
type="text"
placeholder="Digite aqui o que você deseja pesquisar"
className="p-2 px-5 rounded-lg outline outline-1 font-light text-2xl
text-darkGray-HC-dark
placeholder:text-darkGray-HC-dark
outline-ice-HC-white align-middle h-full w-full"
onFocus={handleFocus}
onBlur={handleBlur}
onChange={(e) => {
setInput(e.target.value);
setDrop(e.target.value !== "");
}}
onClick={(e) =>
setDrop(e.target.value !== "")
}
onKeyDown={handleKeyDown}
/>
</div>
<button
type="submit"
alt="Buscar"
title="Buscar"
className=" bg-turquoise-HC-dark hover:bg-darkGray-HC-white w-[50px] h-[50px] max-sm:w-10 max-sm:h-10 rounded-lg outline outline-1 outline-ice-HC-white text-ice-HC-white hover:text-white-HC-dark-underline flex-shrink-0 transition "
>
<SearchIcon className="h-full text-4xl max-sm:text-3xl" />
</button>
</div>
{drop && (
<div
ref={dropdownRef}
className={`fixed z-50 bg-white-HC-dark rounded-lg shadow-md `}
style={{ width: `${width}px` }}
tabIndex={0}
>
<ul className=" z-10">
{suggestions.map((suggestion, index) => (
<li
key={index}
onClick={() => {
router.push(`/${suggestion.ref}&filter=${input}`);
setDrop(false)
}}
className={`p-2 text-darkGray-HC-white hover:bg-ice-HC-dark cursor-pointer flex ${
index === selectedIndex ? "bg-ice-HC-dark " : ""
}`}
>
<div className="truncate">{input}</div>{" "}
<div className=" flex-shrink-0 indent-1">
{" "}
em {suggestion.name}
</div>
</li>
))}
</ul>
</div>
)}
</form>
);
}