311 lines
8.9 KiB
TypeScript
311 lines
8.9 KiB
TypeScript
import React, { useState } from "react";
|
||
import { FaTimes, FaPlus } from "react-icons/fa";
|
||
import { useAdminStore } from "../store/useAdminStore";
|
||
|
||
interface CreateUserModalProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
}
|
||
|
||
export const CreateUserModal: React.FC<CreateUserModalProps> = ({
|
||
isOpen,
|
||
onClose,
|
||
}) => {
|
||
const createUser = useAdminStore((s) => s.createUser);
|
||
|
||
const [form, setForm] = useState({
|
||
login: "",
|
||
name: "",
|
||
last_name: "",
|
||
password: "",
|
||
is_active: true,
|
||
permission_admin: false,
|
||
permission_manage_agent: false,
|
||
permission_view: true,
|
||
});
|
||
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
if (!isOpen) return null;
|
||
|
||
const handleSubmit = async () => {
|
||
if (!form.login || !form.password) return;
|
||
setLoading(true);
|
||
await createUser(form);
|
||
setLoading(false);
|
||
setForm({
|
||
login: "",
|
||
name: "",
|
||
last_name: "",
|
||
password: "",
|
||
is_active: true,
|
||
permission_admin: false,
|
||
permission_manage_agent: false,
|
||
permission_view: true,
|
||
});
|
||
onClose();
|
||
};
|
||
|
||
return (
|
||
<div
|
||
style={{
|
||
position: "fixed",
|
||
top: 0,
|
||
left: 0,
|
||
right: 0,
|
||
bottom: 0,
|
||
backgroundColor: "rgba(0,0,0,0.6)",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
zIndex: 2000,
|
||
}}
|
||
onClick={onClose}
|
||
>
|
||
<div
|
||
style={{
|
||
backgroundColor: "var(--card-bg)",
|
||
borderRadius: "8px",
|
||
padding: "24px",
|
||
minWidth: "380px",
|
||
border: "1px solid var(--border)",
|
||
boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
|
||
}}
|
||
onClick={(e) => e.stopPropagation()}
|
||
>
|
||
<div
|
||
style={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "space-between",
|
||
marginBottom: "20px",
|
||
}}
|
||
>
|
||
<h3
|
||
style={{
|
||
margin: 0,
|
||
fontSize: "16px",
|
||
fontWeight: 600,
|
||
color: "var(--text-primary)",
|
||
}}
|
||
>
|
||
Создать пользователя
|
||
</h3>
|
||
<button
|
||
onClick={onClose}
|
||
style={{
|
||
background: "transparent",
|
||
border: "none",
|
||
color: "var(--text-secondary)",
|
||
cursor: "pointer",
|
||
padding: "4px",
|
||
}}
|
||
>
|
||
<FaTimes size={14} />
|
||
</button>
|
||
</div>
|
||
|
||
<div style={{ display: "flex", flexDirection: "column", gap: "12px" }}>
|
||
{/* Login */}
|
||
<div>
|
||
<label
|
||
style={{
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
marginBottom: "4px",
|
||
display: "block",
|
||
}}
|
||
>
|
||
Логин
|
||
</label>
|
||
<input
|
||
type="text"
|
||
value={form.login}
|
||
onChange={(e) => setForm({ ...form, login: e.target.value })}
|
||
style={{
|
||
width: "100%",
|
||
padding: "8px",
|
||
backgroundColor: "var(--input-bg)",
|
||
border: "1px solid var(--border)",
|
||
borderRadius: "6px",
|
||
color: "var(--text-primary)",
|
||
fontSize: "13px",
|
||
outline: "none",
|
||
}}
|
||
/>
|
||
</div>
|
||
|
||
{/* Password */}
|
||
<div>
|
||
<label
|
||
style={{
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
marginBottom: "4px",
|
||
display: "block",
|
||
}}
|
||
>
|
||
Пароль
|
||
</label>
|
||
<input
|
||
type="password"
|
||
value={form.password}
|
||
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
||
style={{
|
||
width: "100%",
|
||
padding: "8px",
|
||
backgroundColor: "var(--input-bg)",
|
||
border: "1px solid var(--border)",
|
||
borderRadius: "6px",
|
||
color: "var(--text-primary)",
|
||
fontSize: "13px",
|
||
outline: "none",
|
||
}}
|
||
/>
|
||
</div>
|
||
|
||
{/* Name + Last name */}
|
||
<div style={{ display: "flex", gap: "8px" }}>
|
||
<div style={{ flex: 1 }}>
|
||
<label
|
||
style={{
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
marginBottom: "4px",
|
||
display: "block",
|
||
}}
|
||
>
|
||
Имя
|
||
</label>
|
||
<input
|
||
type="text"
|
||
value={form.name}
|
||
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||
style={{
|
||
width: "100%",
|
||
padding: "8px",
|
||
backgroundColor: "var(--input-bg)",
|
||
border: "1px solid var(--border)",
|
||
borderRadius: "6px",
|
||
color: "var(--text-primary)",
|
||
fontSize: "13px",
|
||
outline: "none",
|
||
}}
|
||
/>
|
||
</div>
|
||
<div style={{ flex: 1 }}>
|
||
<label
|
||
style={{
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
marginBottom: "4px",
|
||
display: "block",
|
||
}}
|
||
>
|
||
Фамилия
|
||
</label>
|
||
<input
|
||
type="text"
|
||
value={form.last_name}
|
||
onChange={(e) =>
|
||
setForm({ ...form, last_name: e.target.value })
|
||
}
|
||
style={{
|
||
width: "100%",
|
||
padding: "8px",
|
||
backgroundColor: "var(--input-bg)",
|
||
border: "1px solid var(--border)",
|
||
borderRadius: "6px",
|
||
color: "var(--text-primary)",
|
||
fontSize: "13px",
|
||
outline: "none",
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Permissions */}
|
||
<div style={{ paddingTop: "8px" }}>
|
||
<label
|
||
style={{
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
marginBottom: "8px",
|
||
display: "block",
|
||
}}
|
||
>
|
||
Разрешения
|
||
</label>
|
||
<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
|
||
{[
|
||
{ key: "is_active", label: "Active" },
|
||
{ key: "permission_view", label: "View" },
|
||
{ key: "permission_manage_agent", label: "Manage Agent" },
|
||
{ key: "permission_admin", label: "Admin" },
|
||
].map(({ key, label }) => (
|
||
<label
|
||
key={key}
|
||
style={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
gap: "6px",
|
||
cursor: "pointer",
|
||
fontSize: "12px",
|
||
color: "var(--text-secondary)",
|
||
userSelect: "none",
|
||
}}
|
||
>
|
||
<input
|
||
type="checkbox"
|
||
checked={
|
||
form[key as keyof typeof form] as boolean
|
||
}
|
||
onChange={(e) =>
|
||
setForm({ ...form, [key]: e.target.checked })
|
||
}
|
||
style={{ accentColor: "var(--accent)" }}
|
||
/>
|
||
{label}
|
||
</label>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Submit */}
|
||
<button
|
||
onClick={handleSubmit}
|
||
disabled={loading || !form.login || !form.password}
|
||
style={{
|
||
marginTop: "8px",
|
||
padding: "10px",
|
||
backgroundColor:
|
||
loading || !form.login || !form.password
|
||
? "var(--bg-secondary)"
|
||
: "var(--accent)",
|
||
color:
|
||
loading || !form.login || !form.password
|
||
? "var(--text-muted)"
|
||
: "var(--accent-text)",
|
||
border: "none",
|
||
borderRadius: "6px",
|
||
cursor:
|
||
loading || !form.login || !form.password
|
||
? "default"
|
||
: "pointer",
|
||
fontSize: "13px",
|
||
fontWeight: 500,
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
gap: "6px",
|
||
}}
|
||
>
|
||
<FaPlus size={12} />
|
||
{loading ? "Создание..." : "Создать"}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|