Proyecto completo con configuracion de variables de entorno para EasyPanel
This commit is contained in:
76
frontend/src/components/Sidebar.jsx
Normal file
76
frontend/src/components/Sidebar.jsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { api } from "../lib/api";
|
||||
|
||||
const MENU = [
|
||||
{ id: "leads", ico: "🎯", label: "Leads" },
|
||||
{ id: "otros", ico: "📊", label: "Otros General" },
|
||||
];
|
||||
|
||||
export default function Sidebar({ active, onChange, onConfig }) {
|
||||
const [menuUser, setMenuUser] = useState(false);
|
||||
const [ultima, setUltima] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const cargar = () => api.ultimaActualizacion()
|
||||
.then((r) => setUltima(r.hora || "")).catch(() => {});
|
||||
cargar();
|
||||
const id = setInterval(cargar, 60 * 1000); // refresca la hora cada minuto
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<aside className="sidebar">
|
||||
<div className="sidebar-logo">Escuela <span>Refrigeración</span></div>
|
||||
<nav className="nav" style={{ flex: 1 }}>
|
||||
{MENU.map((m) => (
|
||||
<button
|
||||
key={m.id}
|
||||
className={`nav-item ${active === m.id ? "active" : ""}`}
|
||||
onClick={() => onChange(m.id)}
|
||||
>
|
||||
<span className="ico">{m.ico}</span> {m.label}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Bloque de usuario con menú desplegable */}
|
||||
{ultima && (
|
||||
<div style={{ padding: "0 16px 2px", fontSize: 10, color: "#64748b", textAlign: "left" }}>
|
||||
Actualizado: {ultima}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ position: "relative", borderTop: "1px solid rgba(255,255,255,0.08)", padding: 12 }}>
|
||||
{menuUser && (
|
||||
<div style={{ position: "absolute", bottom: 64, left: 12, right: 12, background: "#1e293b",
|
||||
border: "1px solid rgba(255,255,255,0.12)", borderRadius: 10, overflow: "hidden",
|
||||
boxShadow: "0 8px 24px rgba(0,0,0,0.4)" }}>
|
||||
<button onClick={() => { setMenuUser(false); onConfig && onConfig(); }}
|
||||
style={{ width: "100%", textAlign: "left", padding: "11px 14px", background: "transparent",
|
||||
border: "none", color: "#e2e8f0", cursor: "pointer", fontSize: 13,
|
||||
display: "flex", alignItems: "center", gap: 9 }}>
|
||||
⚙️ Configuración
|
||||
</button>
|
||||
<button onClick={() => setMenuUser(false)}
|
||||
style={{ width: "100%", textAlign: "left", padding: "11px 14px", background: "transparent",
|
||||
border: "none", borderTop: "1px solid rgba(255,255,255,0.08)", color: "#f87171",
|
||||
cursor: "pointer", fontSize: 13, display: "flex", alignItems: "center", gap: 9 }}>
|
||||
⎋ Cerrar sesión
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<button onClick={() => setMenuUser((v) => !v)}
|
||||
style={{ width: "100%", display: "flex", alignItems: "center", gap: 10, background: "transparent",
|
||||
border: "none", cursor: "pointer", padding: "6px 4px", color: "#e2e8f0" }}>
|
||||
<div style={{ width: 34, height: 34, borderRadius: "50%", background: "#2563eb", color: "#fff",
|
||||
display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 700,
|
||||
fontSize: 13, flexShrink: 0 }}>AS</div>
|
||||
<div style={{ flex: 1, textAlign: "left", lineHeight: 1.2 }}>
|
||||
<div style={{ fontSize: 13, fontWeight: 600 }}>Aron</div>
|
||||
<div style={{ fontSize: 11, color: "#94a3b8" }}>RP ERP</div>
|
||||
</div>
|
||||
<span style={{ fontSize: 11, color: "#94a3b8" }}>{menuUser ? "▲" : "▼"}</span>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user