feat: Telegram Login Widget on /login page

This commit is contained in:
2026-05-20 12:39:24 +03:00
parent f3c80de219
commit bbc423d9c7
+43 -4
View File
@@ -1,4 +1,4 @@
import { useState } from "react"; import { useState, useEffect, useRef } from "react";
import { useNavigate, Link } from "react-router-dom"; import { useNavigate, Link } from "react-router-dom";
import { Shield } from "lucide-react"; import { Shield } from "lucide-react";
import { api } from "../api/client"; import { api } from "../api/client";
@@ -7,6 +7,12 @@ import { Button } from "../components/ui/Button";
import { Input } from "../components/ui/Input"; import { Input } from "../components/ui/Input";
import { GlassCard } from "../components/ui/GlassCard"; import { GlassCard } from "../components/ui/GlassCard";
declare global {
interface Window {
onTelegramAuth: (user: Record<string, any>) => void;
}
}
export default function Login() { export default function Login() {
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
@@ -14,6 +20,31 @@ export default function Login() {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { setAuth } = useAuthStore(); const { setAuth } = useAuthStore();
const navigate = useNavigate(); const navigate = useNavigate();
const tgRef = useRef<HTMLDivElement>(null);
useEffect(() => {
window.onTelegramAuth = async (tgUser) => {
setError("");
setLoading(true);
const res = await api.tgAuth(tgUser);
setLoading(false);
if (!res.ok) { setError(res.error || "Ошибка входа через Telegram"); return; }
setAuth(res.access_token, res.refresh_token, res.user);
navigate("/dashboard");
};
if (!tgRef.current) return;
const script = document.createElement("script");
script.src = "https://telegram.org/js/telegram-widget.js?22";
script.setAttribute("data-telegram-login", "cricket_vpn_bot");
script.setAttribute("data-size", "large");
script.setAttribute("data-onauth", "onTelegramAuth(user)");
script.setAttribute("data-request-access", "write");
script.async = true;
tgRef.current.appendChild(script);
return () => { delete (window as any).onTelegramAuth; };
}, []);
async function handleLogin(e: React.FormEvent) { async function handleLogin(e: React.FormEvent) {
e.preventDefault(); e.preventDefault();
@@ -40,15 +71,23 @@ export default function Login() {
<p className="text-sm text-white/40 mt-1">Доступ к личному кабинету</p> <p className="text-sm text-white/40 mt-1">Доступ к личному кабинету</p>
</div> </div>
<div className="flex items-center gap-3 mb-6"> {/* Telegram Login Widget */}
<div className="flex justify-center mb-5">
<div ref={tgRef} />
</div>
{loading && <p className="text-center text-sm text-white/40 mb-4">Вход...</p>}
{error && <p className="text-center text-sm text-red-400 mb-4">{error}</p>}
<div className="flex items-center gap-3 mb-5">
<div className="flex-1 h-px bg-white/10" /> <div className="flex-1 h-px bg-white/10" />
<span className="text-xs text-white/30">email</span> <span className="text-xs text-white/30">или email</span>
<div className="flex-1 h-px bg-white/10" /> <div className="flex-1 h-px bg-white/10" />
</div> </div>
<form onSubmit={handleLogin} className="space-y-4"> <form onSubmit={handleLogin} className="space-y-4">
<Input label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" required /> <Input label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" required />
<Input label="Пароль" type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••" required error={error} /> <Input label="Пароль" type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••" required />
<Button type="submit" loading={loading} className="w-full text-base py-3">Войти</Button> <Button type="submit" loading={loading} className="w-full text-base py-3">Войти</Button>
</form> </form>