feat: add first version of TougliGui with same features as on google sheet
This commit is contained in:
94
src/components/Sidebar.tsx
Normal file
94
src/components/Sidebar.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
import { useState } from "react";
|
||||
import { useStore } from "../store";
|
||||
|
||||
export default function Sidebar() {
|
||||
const { guides, openGuide, activeGuideGid, view } = useStore();
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const filtered = guides.filter(g =>
|
||||
g.name.toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
|
||||
return (
|
||||
<aside style={{
|
||||
width: "220px", flexShrink: 0,
|
||||
background: "#161b22", borderRight: "1px solid #2d3748",
|
||||
display: "flex", flexDirection: "column", overflow: "hidden",
|
||||
}}>
|
||||
<div style={{ padding: "10px 12px", borderBottom: "1px solid #2d3748" }}>
|
||||
<input
|
||||
value={search}
|
||||
onChange={e => setSearch(e.target.value)}
|
||||
placeholder="Rechercher un Dofus…"
|
||||
style={{
|
||||
width: "100%", background: "#0d1117", border: "1px solid #2d3748",
|
||||
borderRadius: "6px", padding: "6px 10px", color: "#e2e8f0",
|
||||
fontSize: "12px", outline: "none",
|
||||
}}
|
||||
onFocus={e => (e.target.style.borderColor = "#f0c040")}
|
||||
onBlur={e => (e.target.style.borderColor = "#2d3748")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, overflowY: "auto", padding: "8px 0" }}>
|
||||
{filtered.length === 0 ? (
|
||||
<div style={{ padding: "16px 12px", color: "#4a5568", fontSize: "12px", textAlign: "center" }}>
|
||||
Aucun guide synchronisé
|
||||
</div>
|
||||
) : (
|
||||
filtered.map(guide => {
|
||||
const pct = guide.total_quests > 0
|
||||
? Math.round((guide.completed_quests / guide.total_quests) * 100)
|
||||
: 0;
|
||||
const isActive = guide.gid === activeGuideGid && view === "guide";
|
||||
|
||||
return (
|
||||
<button
|
||||
key={guide.gid}
|
||||
onClick={() => openGuide(guide.gid)}
|
||||
style={{
|
||||
width: "100%", textAlign: "left", background: isActive ? "rgba(240,192,64,0.08)" : "transparent",
|
||||
border: "none", borderLeft: isActive ? "2px solid #f0c040" : "2px solid transparent",
|
||||
padding: "8px 12px", cursor: "pointer", transition: "all 0.12s",
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
if (!isActive) (e.currentTarget as HTMLElement).style.background = "rgba(255,255,255,0.03)";
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
if (!isActive) (e.currentTarget as HTMLElement).style.background = "transparent";
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
||||
<span style={{
|
||||
fontSize: "12px", fontWeight: isActive ? 600 : 400,
|
||||
color: isActive ? "#f0c040" : "#e2e8f0",
|
||||
whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
|
||||
maxWidth: "140px",
|
||||
}}>
|
||||
{guide.name}
|
||||
</span>
|
||||
<span style={{
|
||||
fontSize: "10px", color: pct === 100 ? "#4ade80" : "#94a3b8",
|
||||
fontWeight: 600, flexShrink: 0,
|
||||
}}>
|
||||
{pct}%
|
||||
</span>
|
||||
</div>
|
||||
<div style={{
|
||||
marginTop: "4px", height: "2px", background: "#2d3748",
|
||||
borderRadius: "1px", overflow: "hidden",
|
||||
}}>
|
||||
<div style={{
|
||||
height: "100%", width: `${pct}%`,
|
||||
background: pct === 100 ? "#4ade80" : pct > 50 ? "#f0c040" : "#4a9eff",
|
||||
transition: "width 0.3s ease",
|
||||
}} />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user