feat: add first version of TougliGui with same features as on google sheet
This commit is contained in:
118
src/components/ProfileModal.tsx
Normal file
118
src/components/ProfileModal.tsx
Normal file
@ -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 (
|
||||
<div style={{
|
||||
position: "fixed", inset: 0, background: "rgba(0,0,0,0.7)",
|
||||
display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50,
|
||||
}} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
|
||||
<div style={{
|
||||
background: "#161b22", border: "1px solid #2d3748", borderRadius: "12px",
|
||||
padding: "24px", width: "360px", maxHeight: "500px",
|
||||
display: "flex", flexDirection: "column", gap: "16px",
|
||||
}}>
|
||||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
||||
<h2 style={{ fontSize: "16px", fontWeight: 700, color: "#f0c040" }}>Profils</h2>
|
||||
<button onClick={onClose} style={{ background: "none", border: "none", color: "#94a3b8", cursor: "pointer", fontSize: "16px" }}>✕</button>
|
||||
</div>
|
||||
|
||||
{/* Profile list */}
|
||||
<div style={{ flex: 1, overflowY: "auto", display: "flex", flexDirection: "column", gap: "6px" }}>
|
||||
{profiles.map(profile => (
|
||||
<div key={profile.id} style={{
|
||||
display: "flex", alignItems: "center", gap: "8px",
|
||||
background: profile.id === activeProfileId ? "rgba(240,192,64,0.08)" : "#1a2233",
|
||||
border: `1px solid ${profile.id === activeProfileId ? "rgba(240,192,64,0.4)" : "#2d3748"}`,
|
||||
borderRadius: "8px", padding: "10px 12px",
|
||||
}}>
|
||||
<button
|
||||
onClick={() => { setActiveProfile(profile.id); onClose(); }}
|
||||
style={{
|
||||
flex: 1, background: "none", border: "none", textAlign: "left",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: "13px", fontWeight: 600, color: profile.id === activeProfileId ? "#f0c040" : "#e2e8f0" }}>
|
||||
{profile.id === activeProfileId && "✓ "}{profile.name}
|
||||
</div>
|
||||
<div style={{ fontSize: "10px", color: "#4a5568", marginTop: "2px" }}>
|
||||
Créé le {new Date(profile.created_at).toLocaleDateString("fr-FR")}
|
||||
</div>
|
||||
</button>
|
||||
{profiles.length > 1 && (
|
||||
<button
|
||||
onClick={() => handleDelete(profile.id)}
|
||||
style={{
|
||||
background: "none", border: "none", color: "#f87171",
|
||||
cursor: "pointer", padding: "4px", borderRadius: "4px", fontSize: "12px",
|
||||
}}
|
||||
title="Supprimer ce profil"
|
||||
>
|
||||
🗑
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Create new profile */}
|
||||
<div style={{ borderTop: "1px solid #2d3748", paddingTop: "12px" }}>
|
||||
<p style={{ fontSize: "11px", color: "#4a5568", marginBottom: "8px" }}>Nouveau profil</p>
|
||||
<div style={{ display: "flex", gap: "8px" }}>
|
||||
<input
|
||||
value={newName}
|
||||
onChange={e => { 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")}
|
||||
/>
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
disabled={!newName.trim()}
|
||||
style={{
|
||||
background: "#f0c040", color: "#0d1117", border: "none",
|
||||
borderRadius: "6px", padding: "7px 14px", fontWeight: 700,
|
||||
fontSize: "12px", cursor: newName.trim() ? "pointer" : "default",
|
||||
opacity: newName.trim() ? 1 : 0.4,
|
||||
}}
|
||||
>
|
||||
Créer
|
||||
</button>
|
||||
</div>
|
||||
{error && <p style={{ fontSize: "11px", color: "#f87171", marginTop: "6px" }}>{error}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user