104 lines
3.4 KiB
JavaScript
104 lines
3.4 KiB
JavaScript
import React from "react";
|
||
import { Navigate } from "react-router-dom";
|
||
import { ROLE_LABELS } from "../constants/roles";
|
||
import { useAuth } from "../context/AuthContext";
|
||
import { demoUsers } from "../data/mockAppData";
|
||
import { Button } from "../components/UI/Button";
|
||
import { OtpLoginForm } from "../components/auth/OtpLoginForm";
|
||
|
||
const DEMO_ROLE_ORDER = ["logistician", "driver", "manager", "admin"];
|
||
|
||
export const LoginPage = () => {
|
||
const { user, isOtpSent, isLoading, authError, isDemoMode, requestOtp, verifyOtp, loginAsDemoUser } = useAuth();
|
||
const [email, setEmail] = React.useState("");
|
||
const [otp, setOtp] = React.useState("");
|
||
const [error, setError] = React.useState("");
|
||
|
||
const displayError = error || authError;
|
||
|
||
const handleRequestOtp = async () => {
|
||
const response = await requestOtp({ email });
|
||
if (!response.success) {
|
||
setError(response.error?.message || "Не удалось отправить код");
|
||
return;
|
||
}
|
||
setError("");
|
||
};
|
||
|
||
const handleVerifyOtp = async () => {
|
||
const response = await verifyOtp({ email, otp });
|
||
if (!response.success) {
|
||
setError(response.error?.message || "Не удалось подтвердить код");
|
||
return;
|
||
}
|
||
setError("");
|
||
};
|
||
|
||
const handleDemoLogin = (role) => {
|
||
const demoUser = demoUsers.find((u) => u.role === role);
|
||
if (!demoUser) {
|
||
return;
|
||
}
|
||
|
||
if (isDemoMode) {
|
||
setEmail(demoUser.email);
|
||
requestOtp({ email: demoUser.email, roleHint: role }).then((requestResponse) => {
|
||
if (!requestResponse.success) {
|
||
setError(requestResponse.error?.message || "Ошибка демо-входа");
|
||
return;
|
||
}
|
||
|
||
verifyOtp({ email: demoUser.email, otp: "000000" }).then((verifyResponse) => {
|
||
if (!verifyResponse.success) {
|
||
setError(verifyResponse.error?.message || "Ошибка демо-входа");
|
||
}
|
||
});
|
||
});
|
||
} else {
|
||
loginAsDemoUser(demoUser);
|
||
}
|
||
};
|
||
|
||
if (user) {
|
||
return <Navigate to="/dashboard" replace />;
|
||
}
|
||
|
||
return (
|
||
<div className="flex min-h-screen flex-col items-center justify-center gap-6 px-3 py-6 sm:px-4 sm:py-10">
|
||
<OtpLoginForm
|
||
email={email}
|
||
setEmail={setEmail}
|
||
otp={otp}
|
||
setOtp={setOtp}
|
||
isOtpSent={isOtpSent}
|
||
isLoading={isLoading}
|
||
onRequestOtp={handleRequestOtp}
|
||
onVerifyOtp={handleVerifyOtp}
|
||
error={displayError}
|
||
/>
|
||
|
||
{(isDemoMode || import.meta.env.DEV === true && import.meta.env.VITE_ENABLE_DEMO === 'true') ? (
|
||
<div className="w-full max-w-md space-y-3">
|
||
<p className="text-center text-sm text-[var(--color-text-muted)]">
|
||
{isDemoMode ? "Демо-режим — войдите под любой ролью" : "Быстрый вход (только для разработки)"}
|
||
</p>
|
||
<div className="flex flex-wrap justify-center gap-2">
|
||
{DEMO_ROLE_ORDER.map((role) => {
|
||
const demoUser = demoUsers.find((u) => u.role === role);
|
||
return (
|
||
<Button
|
||
key={role}
|
||
variant="secondary"
|
||
onClick={() => handleDemoLogin(role)}
|
||
disabled={isLoading}
|
||
>
|
||
{ROLE_LABELS[role]}
|
||
</Button>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
) : null}
|
||
</div>
|
||
);
|
||
}; |