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 { 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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user