Estou trabalhando neste desafio do Frontend Mentor e já dominei a maioria das funcionalidades. Consigo filtrar os dados por suas isActive
propriedades para exibir os itens corretos, independentemente de estarem ativos ou não. O que não consigo descobrir é como atualizar isActive
o status de um item individual e fazer com que ele renderize o aplicativo novamente ao alternar para mover o item para o filtro correto.
Aqui está o código para App.jsx
:
function App() {
const [data, setData] = useState([]);
const [filteredData, setFilteredData] = useState(data);
const [activeFilter, setActiveFilter] = useState("All");
// Fetch and set the data.
useEffect(() => {
fetch("../data.json")
.then((response) => response.json())
.then((data) => setData(data))
.catch((error) => console.error("error", error));
}, []);
// Filter the data
useEffect(() => {
if (activeFilter === "All") {
setFilteredData(data);
} else if (activeFilter === "Active") {
setFilteredData(data.filter((item) => item.isActive === true));
} else {
setFilteredData(data.filter((item) => item.isActive === false));
}
}, [activeFilter, data]);
return (
<div className="w-full h-full bg-linear-to-b from-[#040918] to-[#091540] py-6 px-3 flex flex-col text-white">
{/* Header */}
<Header />
{/* Options */}
<Options activeFilter={activeFilter} setActiveFilter={setActiveFilter} />
{/* Cards */}
{filteredData &&
filteredData.map((item) => (
<Card
logo={item.logo}
name={item.name}
description={item.description}
isActive={item.isActive}
key={item.name}
setFilteredData={setFilteredData}
filteredData={filteredData}
/>
))}
</div>
);
}
e aqui está Card.jsx
com a chave seletora:
const Card = ({
logo,
name,
description,
isActive,
filteredData,
setFilteredData,
}) => {
const [activeState, setActiveState] = useState(isActive);
function handleClick() {
setActiveState(!activeState);
}
return (
<div className="bg-neutral-700 p-4 rounded-xl border border-neutral-600 mt-4">
<div className="flex items-start gap-4">
{/* Logo */}
<img src={logo} alt="Extension Image" />
{/* Name and Description */}
<div className="flex flex-col gap-2 mb-8">
<h2 className="font-semibold text-xl">{name}</h2>
<p className="text-sm font-light">{description}</p>
</div>
</div>
{/* Remove Button */}
<div className="flex justify-between items-center">
<div className="border border-neutral-600 rounded-full px-3 py-1 flex items-center justify-center">
<button>Remove</button>
</div>
{/* Is Active Toggle */}
<div className="flex items-center justify-center">
<label
htmlFor={`${name}Toggle`}
className="flex items-center cursor-pointer "
>
<div className="relative">
<input
id={`${name}Toggle`}
type="checkbox"
className="sr-only"
onClick={handleClick}
/>
<div
className={`flex items-center ${
activeState ? "bg-red-400 " : "bg-gray-600 "
} w-11 h-6 rounded-full transition-all px-[2px]`}
>
<div
className={`bg-white w-5 h-5 rounded-full ${
activeState ? "translate-x-5" : "translate-x-0"
} transition-all`}
></div>
</div>
</div>
</label>
</div>
</div>
</div>
);
};
Eu estava tentando descobrir uma maneira dentro da handleclick
função do Card que correspondesse ao nome do card específico com o nome do item filteredData
e... inverter o status dele isActive
? Não consegui descobrir como fazer isso funcionar e nem tenho certeza se essa é a melhor maneira de fazer.