Archived
Добавлены frontend-экраны входа и регистрации
This commit is contained in:
+54
-6
@@ -1,21 +1,69 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
|
import { getMe, login, register } from "./api";
|
||||||
import "./styles.css";
|
import "./styles.css";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const [mode, setMode] = useState("login");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [user, setUser] = useState(null);
|
||||||
|
|
||||||
|
async function handleSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
setMessage("");
|
||||||
|
try {
|
||||||
|
if (mode === "register") {
|
||||||
|
await register(email, password);
|
||||||
|
setMessage("Регистрация завершена. Теперь войдите.");
|
||||||
|
setMode("login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tokenData = await login(email, password);
|
||||||
|
const currentUser = await getMe(tokenData.access_token);
|
||||||
|
setUser(currentUser);
|
||||||
|
setMessage(`Вы вошли как ${currentUser.role}.`);
|
||||||
|
} catch (error) {
|
||||||
|
setMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="page">
|
<main className="page">
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<h1>Proxmox VPS Panel</h1>
|
<h1>Proxmox VPS Panel</h1>
|
||||||
<p>Защищённая версия панели готова к подключению API.</p>
|
{user ? (
|
||||||
<p className="muted">Следующий этап — перенос экранов авторизации, шаблонов и инстансов.</p>
|
<>
|
||||||
|
<p>Добро пожаловать, {user.email}</p>
|
||||||
|
<p className="muted">Роль: {user.role}</p>
|
||||||
|
<button type="button" onClick={() => setUser(null)}>Выйти</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<h2>{mode === "login" ? "Вход" : "Регистрация"}</h2>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<label>
|
||||||
|
Email
|
||||||
|
<input type="email" value={email} onChange={(event) => setEmail(event.target.value)} required />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Пароль
|
||||||
|
<input type="password" minLength={12} value={password} onChange={(event) => setPassword(event.target.value)} required />
|
||||||
|
</label>
|
||||||
|
<button type="submit">{mode === "login" ? "Войти" : "Зарегистрироваться"}</button>
|
||||||
|
</form>
|
||||||
|
<button className="link" type="button" onClick={() => setMode(mode === "login" ? "register" : "login")}>
|
||||||
|
{mode === "login" ? "Создать аккаунт" : "У меня уже есть аккаунт"}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{message && <p className="message">{message}</p>}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createRoot(document.getElementById("root")).render(
|
createRoot(document.getElementById("root")).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode><App /></React.StrictMode>,
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user