import { useState, useCallback } from "react";
import { useTranslation } from 'react-i18next';
import MagnifierLogo from "./MagnifierLogo";
import { useAuth } from "../hooks/useAuth";
import { useRegister } from "../hooks/useRegister";
import {FLOAT_ICONS} from "../config/authConstants";
import "../styles/global.css";
import "../styles/auth.css";
import likeSmile from '../assets/success.png';
import { useCheckLogin } from "../hooks/useRegister";
// ─── helpers ──────────────────────────────────────────────────────────────────
function getStrength(val, t) {
if (!val) return { level: 0, label: "", color: "transparent", cls: "" };
let s = 0;
if (val.length >= 6) s++;
if (val.length >= 10) s++;
if (/[A-Z]/.test(val) || /[0-9]/.test(val)) s++;
if (/[^A-Za-z0-9]/.test(val)) s++;
const labels = ["", t('auth.strengthWeak'), t('auth.strengthMedium'), t('auth.strengthGood'), t('auth.strengthExcellent')];
const colors = ["", "#ff6b6b", "#ffd166", "#2de0c8", "#2de0c8"];
const cls = ["", "sw", "sm", "ss", "ss"];
return { level: s, label: labels[s], color: colors[s], cls: cls[s] };
}
// ─── Shared eye button ────────────────────────────────────────────────────────
function EyeBtn({ show, onToggle}) {
return (
);
}
// ─── Step dots ────────────────────────────────────────────────────────────────
function StepDots({ current, total }) {
return (
{Array.from({ length: total }).map((_, i) => (
))}
);
}
// ═══════════════════════════════════════════════════════════════════════════════
// LOGIN FORM
// ═══════════════════════════════════════════════════════════════════════════════
function LoginForm({ onSwitchToRegister }) {
const { t } = useTranslation();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPass, setShowPass] = useState(false);
const { login, loading, error } = useAuth();
return (
{t('auth.welcomeBack')}
{t('auth.noAccount')}{" "}
);
}
// ─── step 0+1: name + login + passwords ───────────────────────────────────────
function RegStep01({ data, onChange, onNext }) {
const { t } = useTranslation();
const [show1, setShow1] = useState(false);
const [show2, setShow2] = useState(false);
const [errors, setErrors] = useState({});
const strength = getStrength(data.password, t);
const matched = data.password && data.password === data.password2;
const { checking: checkingLogin, exists: loginExists } = useCheckLogin(data.login);
const validate = () => {
const e = {};
if (!data.name.trim()) e.name = t('auth.validateNameRequired');
if (!data.login.trim()) e.login = t('auth.validateLoginRequired');
else if (data.login.length < 3) e.login = t('auth.loginMinChars');
if (data.password.length < 6) e.password = t('auth.validatePasswordMin');
else if (data.password !== data.password2) e.password2 = t('auth.validatePasswordMatch');
setErrors(e);
return !Object.keys(e).length;
};
return (
<>
{
onChange("name", e.target.value);
setErrors(p => ({...p, name: ""}));
}}
autoComplete="off"
/>
{errors.name &&
{errors.name}
}
{
onChange("login", e.target.value);
setErrors(p => ({...p, login: ""}));
}}
autoComplete="off"
/>
{checkingLogin &&
{t('auth.checking')}
}
{!checkingLogin && data.login.length >= 3 && (
{loginExists ? t('auth.loginTaken') : t('auth.loginFree')}
)}
{errors.login &&
{errors.login}
}
{
onChange("password", e.target.value);
setErrors(p => ({...p, password: ""}));
}}
autoComplete="new-password"
/>
setShow1(v => !v)}/>
{data.password && (
<>
{[0, 1, 2, 3].map(i => (
))}
{strength.label}
>
)}
{errors.password &&
{errors.password}
}
{
onChange("password2", e.target.value);
setErrors(p => ({...p, password2: ""}));
}}
autoComplete="new-password"
/>
setShow2(v => !v)}/>
{data.password2 && (
{matched ? t('auth.passwordsMatch') : t('auth.passwordsNoMatch')}
)}
{errors.password2 &&
{errors.password2}
}
>
);
}
// ─── step 2: confirm ──────────────────────────────────────────────────────────
function RegStep2({data, onSubmit, onBack, loading, error}) {
const { t } = useTranslation();
return (
<>
{t('auth.nameLabel')}
{data.name}
{t('auth.loginLabel')}
@{data.login}
{error && {error}
}
>
);
}
// ─── success ──────────────────────────────────────────────────────────────────
function RegSuccess({name, onLogin}) {
const { t } = useTranslation();
return (
{t('auth.welcome', { name })}
{t('auth.accountCreated')}
);
}
function RegisterForm({onSwitchToLogin}) {
const { t } = useTranslation();
const [step, setStep] = useState(0);
const [form, setForm] = useState(
{name: "", login: "", password: "", password2: ""});
const {register, loading, error, success} = useRegister();
const setField = useCallback((key, val) => setForm(p => ({ ...p, [key]: val })), []);
if (success) {
return (
);
}
return (
{t('auth.createAccount')}
{step === 0 && (
setStep(1)} />
)}
{step === 1 && (
register({ name: form.name, login: form.login, password: form.password })}
onBack={() => setStep(0)}
loading={loading}
error={error}
/>
)}
{step === 0 && (
{t('auth.hasAccount')}{" "}
)}
);
}
// ═══════════════════════════════════════════════════════════════════════════════
// AUTH PAGE — единственная страница, переключает login ↔ register
// ═══════════════════════════════════════════════════════════════════════════════
export default function Authentication() {
const { t } = useTranslation();
const [mode, setMode] = useState("login"); // "login" | "register"
const [animating, setAnimating] = useState(false);
const switchTo = (next) => {
if (animating) return;
setAnimating(true);
// Небольшая задержка — карточка уходит, потом приходит новая
setTimeout(() => {
setMode(next);
setAnimating(false);
}, 320);
};
return (
{FLOAT_ICONS.map(({ icon, delay, size, ...pos }, i) => (

))}
{t('app.name')}
{mode === "login"
?
switchTo("register")} />
: switchTo("login")} />
}
);
}