UI: секретный вход в админку — удержание кнопки меню 10с; убраны видимые кнопки входа админа
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
import { Menu, Plus, Users } from "lucide-react";
|
||||
import { useRef } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { useToast } from "../context/ToastContext";
|
||||
import { useMe } from "../hooks/auth";
|
||||
|
||||
const ADMIN_HOLD_MS = 10000; // секретный вход в админку — удержание кнопки меню 10с
|
||||
|
||||
export function BottomBar({ onMenu }: { onMenu: () => void }) {
|
||||
const { data: me } = useMe();
|
||||
const navigate = useNavigate();
|
||||
@@ -11,6 +14,28 @@ export function BottomBar({ onMenu }: { onMenu: () => void }) {
|
||||
const hasGroup = me?.active_group_id != null;
|
||||
const activeGroup = me?.groups.find((g) => g.id === me?.active_group_id);
|
||||
|
||||
// Долгое удержание кнопки меню → /admin/login; короткий тап → открыть боковое меню.
|
||||
const holdTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const holdFired = useRef(false);
|
||||
|
||||
const startHold = () => {
|
||||
holdFired.current = false;
|
||||
holdTimer.current = setTimeout(() => {
|
||||
holdFired.current = true;
|
||||
navigate("/admin/login");
|
||||
}, ADMIN_HOLD_MS);
|
||||
};
|
||||
const clearHold = () => {
|
||||
if (holdTimer.current) {
|
||||
clearTimeout(holdTimer.current);
|
||||
holdTimer.current = null;
|
||||
}
|
||||
};
|
||||
const endHold = () => {
|
||||
clearHold();
|
||||
if (!holdFired.current) onMenu(); // обычный тап
|
||||
};
|
||||
|
||||
const onCreate = () => {
|
||||
if (!hasGroup) {
|
||||
toast.show("Вы не состоите в группе. Создайте или вступите в группу.");
|
||||
@@ -29,7 +54,14 @@ export function BottomBar({ onMenu }: { onMenu: () => void }) {
|
||||
|
||||
<div className="spacer" />
|
||||
|
||||
<button className="slot" onClick={onMenu} aria-label="Меню">
|
||||
<button
|
||||
className="slot"
|
||||
aria-label="Меню"
|
||||
onPointerDown={startHold}
|
||||
onPointerUp={endHold}
|
||||
onPointerLeave={clearHold}
|
||||
onPointerCancel={clearHold}
|
||||
>
|
||||
<Menu size={20} />
|
||||
<span>Меню</span>
|
||||
</button>
|
||||
|
||||
@@ -158,12 +158,6 @@ export function AccountPage() {
|
||||
<button className="btn btn-danger" style={{ width: "100%" }} onClick={doLogout}>
|
||||
Выйти
|
||||
</button>
|
||||
|
||||
<p className="center" style={{ marginTop: 24 }}>
|
||||
<button className="btn btn-ghost small muted" onClick={() => navigate("/admin/login")}>
|
||||
Вход для администратора
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,16 +93,6 @@ export function LoginPage() {
|
||||
{showStub && !pendingTg && <DevLogin onError={setError} />}
|
||||
|
||||
{error && <p className="error-text center">{error}</p>}
|
||||
|
||||
<p className="center" style={{ marginTop: 40 }}>
|
||||
<button
|
||||
className="btn btn-ghost small"
|
||||
onClick={() => navigate("/admin/login")}
|
||||
style={{ opacity: 0.4 }}
|
||||
>
|
||||
·
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user