feat: Telegram Login Widget on /login page
This commit is contained in:
+43
-4
@@ -1,4 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { useNavigate, Link } from "react-router-dom";
|
||||
import { Shield } from "lucide-react";
|
||||
import { api } from "../api/client";
|
||||
@@ -7,6 +7,12 @@ import { Button } from "../components/ui/Button";
|
||||
import { Input } from "../components/ui/Input";
|
||||
import { GlassCard } from "../components/ui/GlassCard";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
onTelegramAuth: (user: Record<string, any>) => void;
|
||||
}
|
||||
}
|
||||
|
||||
export default function Login() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
@@ -14,6 +20,31 @@ export default function Login() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { setAuth } = useAuthStore();
|
||||
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) {
|
||||
e.preventDefault();
|
||||
@@ -40,15 +71,23 @@ export default function Login() {
|
||||
<p className="text-sm text-white/40 mt-1">Доступ к личному кабинету</p>
|
||||
</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" />
|
||||
<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>
|
||||
|
||||
<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="Пароль" 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>
|
||||
</form>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user