A
Anonymous

Sidebar - Copy this React, Tailwind Component to your project

adapta el codigo que me diste a este import { useEffect, useState, useRef } from "react"; import { getNotifications } from "@services/apiNotificaciones"; import { SvgIcon, LogoNotificacion, LogoEmptyIcon, LogoCamapanaAnimada, } from "@helpers/svgIcons.jsx"; import { useSelector } from "react-redux"; import notificationIcon from "@assets/notificationIcon.svg"; import emptyAlert from "@assets/emptyIcon.svg"; const AlertaBarraLateral = () => { const [isClicked, setIsClicked] = useState(false); const [detalleAlertas, setDetalleAlertas] = useState([]); // Obtener usuario y cliente desde Redux const usuario = useSelector((state) => state.user); const usuarioId = usuario?.id; const clienteId = usuario?.cliente; const handleClick = () => { setIsClicked(!isClicked); }; useEffect(() => { const obtenerAlertas = async () => { const response = await getNotifications(usuarioId, clienteId); const { codError, msgError, alertas } = response; // console.log("馃殌 ~ obtenerAlertas ~ alertas:", alertas) setDetalleAlertas(alertas); }; obtenerAlertas(); }, [clienteId, usuarioId]); useEffect(() => { // Cuando se clickea escape con la barra lateral abierta, la cierra const handleKeyDown = (event) => { if (event.key === "Escape") { setIsClicked(false); } }; window.addEventListener("keydown", handleKeyDown); return () => { window.removeEventListener("keydown", handleKeyDown); }; }, []); const handleClickOutside = (event) => { if (accordionRef.current && !accordionRef.current.contains(event.target)) { setIsClicked(false); } }; // Escuchar el evento de clic fuera del componente useEffect(() => { document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); // const [isShaking, setIsShaking] = useState(false); // useEffect(() => { // // Funci贸n de escucha del evento // const handleCustomEvent = (event) => { // // Realizar alguna acci贸n cuando se reciba el evento // // Cambiar el estado a true // setIsShaking(true); // // Despu茅s de 500ms, cambiar el estado a false // setTimeout(() => { // setIsShaking(false); // }, 500); // }; // // Agregar el event listener al montar el componente // window.addEventListener("shake", handleCustomEvent); // // Limpiar el event listener al desmontar el componente // return () => { // window.removeEventListener("shake", handleCustomEvent); // }; // }, []); const accordionRef = useRef(null); return ( <> <div className="z-40 mt-[-5px]" ref={accordionRef}> <div className={`absolute mt-[10px] z-40 right-0 ${ isClicked === true ? "mr-[170px] sm:mr-[295px] max-[316px]:mr-[150px] pl-2" : "mr-[20px]" } transition-all duration-500 ease-in-out`} > <SvgIcon onClick={handleClick} className={`w-10 h-10 bi bi-arrow-right-short ${ isClicked !== true && "-scale-x-100" } transition-all duration-500 ease-in-out cursor-pointer transform`} alt="carrito" draggable="false" icon={LogoCamapanaAnimada} fill="currentColor" /> </div> <div className={`absolute min-h-screen h-screen shadow-lg ${ isClicked === true ? "w-[210px] sm:w-[337px]" : "w-[0px]" } border-black-400 right-0 dark:bg-[#282C34] bg-[#f9fafc] transition-all duration-500 ease-in-out max-[316px]:mr-[-20px]`} style={{ touchAction: "pan-y" }} > <div className={`sidebar min-h-screen h-screen w-full`}> <div className="flex flex-col w-full h-full"> <div className={`flex rounded-t-md transition-all duration-1000 ease-in-out w-full h-[50px] min-h-[60px] dark:bg-[#282C34] bg-[#f9fafc] items-center justify-center ${isClicked ? "opacity-100" : "w-0 opacity-0 overflow-hidden"}`} > <p className="text-lg font-medium transition-all duration-1000 ease-in-out"> Alertas </p> </div> <div className={`${ isClicked ? "flex" : "hidden w-0" } transition-all duration-1000 easy-in-out h-[20px] dark:bg-[#596273] bg-[#b1b4ba] py-3 items-center border-b border-[#b1b4ba]`} > <p className="text-left text-xs ml-2 text-ellipsis text-nowrap"> Ordenar por: </p> <select className="bg-transparent ml-1 text-xs"> <option style={{ background: "transparent", color: "black" }} value="someOption" > Fecha de creaci贸n </option> <option style={{ background: "transparent", color: "black" }} value="otherOption" > Estado </option> </select> </div> {/* Contenedor de alertas con scroll */} <div className="flex-1 h-full overflow-y-scroll no-scrollbar dark:bg-[#282C34] bg-[#f9fafc] pb-16 sm:pb-12 min-[380px]:mb-1 md:mb-0 rounded-b-md"> <div className="w-full space-y-2 mx-2 pr-4 py-2"> {typeof detalleAlertas === "undefined" || detalleAlertas?.length === 0 || detalleAlertas === "" ? ( <div className="flex flex-col justify-center items-center opacity-15 select-none h-full w-full"> <SvgIcon className="w-12 sm:w-20 mb-2" alt="Sin alertas" draggable="false" fill="currentColor" stroke="auto" icon={LogoEmptyIcon} /> <p>No se han encontrado alertas</p> </div> ) : ( detalleAlertas?.map((alert, index) => ( <div key={index} className={`flex flex-col text-nowrap sm:flex-row p-1 transition-all duration-300 ease-in dark:odd:bg-[#383C45] dark:even:bg-[#404349] odd:bg-[#dedede] even:bg-[#cdcccc] dark:text-white text-black shadow-bottom-only rounded-lg`} > <div className="rounded-md p-2 md:mb-0 lg:text-left"> {alert.estacionNombre} <p>{alert.moduloNombre}</p> </div> <div className="rounded-md p-2 md:mb-0 lg:text-right"> <p>{alert.hora}</p> <p>{alert.fecha}</p> </div> <div className="rounded-md p-2 text-center lg:text-right"> Gravedad <p>{alert.gravedadNombre}</p> </div> </div> )) )} </div> </div> </div> </div> </div> </div> </> ); }; export default AlertaBarraLateral;

Prompt

About

Sidebar - A responsive, customizable sidebar with smooth animations, perfect for navigation. Built with React and Tailwind. Copy template now!

Share

Last updated 1 month ago