+
60 ? "#f0c040" : "#4a9eff",
+ borderRadius: "2px",
+ }} />
+
+
+
+ {guide.completed_quests}/{guide.total_quests} quĂȘtes
+
+
+ {pct}%
+
+
+
+ );
+}
diff --git a/src/components/ProfileModal.tsx b/src/components/ProfileModal.tsx
new file mode 100644
index 0000000..38ee6ed
--- /dev/null
+++ b/src/components/ProfileModal.tsx
@@ -0,0 +1,118 @@
+import { useState } from "react";
+import { useStore } from "../store";
+
+export default function ProfileModal({ onClose }: { onClose: () => void }) {
+ const { profiles, activeProfileId, setActiveProfile, createProfile, deleteProfile } = useStore();
+ const [newName, setNewName] = useState("");
+ const [error, setError] = useState("");
+
+ async function handleCreate() {
+ const name = newName.trim();
+ if (!name) return;
+ if (profiles.find(p => p.name === name)) {
+ setError("Un profil avec ce nom existe déjà .");
+ return;
+ }
+ await createProfile(name);
+ setNewName("");
+ setError("");
+ }
+
+ async function handleDelete(id: string) {
+ if (profiles.length <= 1) {
+ setError("Vous ne pouvez pas supprimer le dernier profil.");
+ return;
+ }
+ await deleteProfile(id);
+ }
+
+ return (
+
{ if (e.target === e.currentTarget) onClose(); }}>
+
+
+
Profils
+
+
+
+ {/* Profile list */}
+
+ {profiles.map(profile => (
+
+
+ {profiles.length > 1 && (
+
+ )}
+
+ ))}
+
+
+ {/* Create new profile */}
+
+
Nouveau profil
+
+ { setNewName(e.target.value); setError(""); }}
+ onKeyDown={e => e.key === "Enter" && handleCreate()}
+ placeholder="Nom du profilâŠ"
+ style={{
+ flex: 1, background: "#0d1117", border: "1px solid #2d3748",
+ borderRadius: "6px", padding: "7px 10px", color: "#e2e8f0",
+ fontSize: "12px", outline: "none",
+ }}
+ onFocus={e => (e.target.style.borderColor = "#f0c040")}
+ onBlur={e => (e.target.style.borderColor = "#2d3748")}
+ />
+
+
+ {error &&
{error}
}
+
+
+
+ );
+}
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
new file mode 100644
index 0000000..257fff2
--- /dev/null
+++ b/src/components/Sidebar.tsx
@@ -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 (
+