fix import with name "viplight"
This commit is contained in:
@@ -4,7 +4,6 @@ import PartDetail from "./pages/PartDetail";
|
||||
import AddPartPage from "./pages/AddPartPage";
|
||||
import ProfilePage from "./pages/ProfilePage";
|
||||
import AuthForm from "./components/AuthForm";
|
||||
import RegisterForm from "./components/RegisterForm";
|
||||
|
||||
const PrivateRoute = ({ children }) => {
|
||||
const token = localStorage.getItem("token");
|
||||
|
||||
@@ -24,7 +24,7 @@ const AuthForm = () => {
|
||||
}
|
||||
} catch (err) {
|
||||
setMessage({
|
||||
text: err.response?.data?.error || "Неверный логин или пароль",
|
||||
text: err.response?.data?.error || err.message || "Неверный логин или пароль",
|
||||
isError: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,27 +21,11 @@ export default function Header({ onRefresh, onOpenScanner }) {
|
||||
<div className="max-w-[1440px] mx-auto px-4 md:px-8 h-16 md:h-20 flex justify-between items-center">
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-lg md:text-xl font-black text-white tracking-tighter">
|
||||
VIPLIGHT <span className="text-blue-500">MRP</span>
|
||||
<span className="text-blue-500">MRP</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="hidden md:block">
|
||||
<CsvImporter onImported={onRefresh} />
|
||||
</div>
|
||||
<button
|
||||
onClick={() => navigate("/add")}
|
||||
className="hidden md:flex h-10 px-6 bg-emerald-600 hover:bg-emerald-500 text-white rounded-xl font-bold text-xs items-center gap-2"
|
||||
>
|
||||
<span>+</span> НОВАЯ ПАНЕЛЬ
|
||||
</button>
|
||||
<button
|
||||
onClick={onOpenScanner}
|
||||
className="h-9 px-4 md:h-10 md:px-6 bg-blue-600 hover:bg-blue-500 text-white rounded-lg md:rounded-xl font-bold text-xs flex items-center gap-2"
|
||||
>
|
||||
<span>📷</span> СКАНЕР
|
||||
</button>
|
||||
|
||||
{/* Блок пользователя */}
|
||||
<div
|
||||
onClick={() => navigate("/profile")}
|
||||
@@ -49,11 +33,8 @@ export default function Header({ onRefresh, onOpenScanner }) {
|
||||
>
|
||||
<div className="text-right hidden sm:block">
|
||||
<p className="text-sm font-bold text-white leading-tight">
|
||||
{user.first_name} {user.last_name}
|
||||
</p>
|
||||
<p className="text-[10px] text-slate-400 font-medium uppercase tracking-widest mt-0.5">
|
||||
{user.department} <span className="text-slate-600 mx-1">|</span>{" "}
|
||||
{user.role}
|
||||
{"Привет, "}
|
||||
{user.first_name}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import { registerUser } from "../api"; // Используем твой метод из index.js
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function RegisterForm() {
|
||||
const navigate = useNavigate();
|
||||
const [formData, setFormData] = useState({
|
||||
username: "",
|
||||
password: "",
|
||||
first_name: "",
|
||||
last_name: "",
|
||||
phone: "",
|
||||
department: "",
|
||||
role: "Рабочий",
|
||||
});
|
||||
const [message, setMessage] = useState({ text: "", isError: false });
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setMessage({ text: "", isError: false });
|
||||
|
||||
try {
|
||||
await registerUser(formData);
|
||||
setMessage({ text: "Сотрудник успешно создан!", isError: false });
|
||||
// Небольшая задержка перед переходом, чтобы админ увидел успех
|
||||
setTimeout(() => navigate("/"), 1500);
|
||||
} catch (err) {
|
||||
setMessage({
|
||||
text: err.response?.data?.error || "Ошибка регистрации",
|
||||
isError: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-slate-950 px-4 py-10">
|
||||
<div className="w-full max-w-lg space-y-8 bg-slate-900 p-10 rounded-2xl border border-slate-800 shadow-2xl">
|
||||
<div className="text-center">
|
||||
<h2 className="text-3xl font-black text-white tracking-tighter">
|
||||
VIPLIGHT <span className="text-blue-500">MRP</span>
|
||||
</h2>
|
||||
<p className="mt-2 text-sm text-slate-400 uppercase tracking-widest">
|
||||
Регистрация сотрудника
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form className="mt-8 space-y-4" onSubmit={handleSubmit}>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Имя"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, first_name: e.target.value })
|
||||
}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Фамилия"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, last_name: e.target.value })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="email"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Email (Логин)"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, username: e.target.value })
|
||||
}
|
||||
/>
|
||||
|
||||
<input
|
||||
type="password"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Пароль (мин. 8 символов)"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, password: e.target.value })
|
||||
}
|
||||
/>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Телефон"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, phone: e.target.value })
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white placeholder-slate-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
|
||||
placeholder="Отдел"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, department: e.target.value })
|
||||
}
|
||||
/>
|
||||
<select
|
||||
className="appearance-none block w-full px-3 py-3 border border-slate-800 bg-slate-800 text-white rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm cursor-pointer"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, role: e.target.value })
|
||||
}
|
||||
value={formData.role}
|
||||
>
|
||||
<option value="Рабочий">Рабочий</option>
|
||||
<option value="Менеджер">Менеджер</option>
|
||||
<option value="Админ">Админ</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{message.text && (
|
||||
<p
|
||||
className={`text-center text-xs font-bold uppercase tracking-tighter ${message.isError ? "text-red-500" : "text-emerald-500"}`}
|
||||
>
|
||||
{message.text}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="flex gap-4 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/")}
|
||||
className="w-1/3 py-3 px-4 border border-slate-800 text-sm font-bold rounded-xl text-slate-400 hover:bg-slate-800 transition-all"
|
||||
>
|
||||
ОТМЕНА
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-2/3 py-3 px-4 border border-transparent text-sm font-bold rounded-xl text-white bg-blue-600 hover:bg-blue-500 transition-all active:scale-95 shadow-lg shadow-blue-900/20"
|
||||
>
|
||||
ЗАРЕГИСТРИРОВАТЬ
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user