135 lines
4.4 KiB
TypeScript
135 lines
4.4 KiB
TypeScript
"use client";
|
||
|
||
// ============================================================================
|
||
// Login Page
|
||
// ============================================================================
|
||
|
||
import React, { useState } from "react";
|
||
import { useAuth } from "@/components/auth/auth-provider";
|
||
import { USE_MOCKS, BOT_USERNAME } from "@/lib/utils/constants";
|
||
import {
|
||
Card,
|
||
CardContent,
|
||
CardDescription,
|
||
CardHeader,
|
||
CardTitle,
|
||
} from "@/components/ui/card";
|
||
import { Button } from "@/components/ui/button";
|
||
import { AlertCircle, LogIn, Loader2 } from "lucide-react";
|
||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||
import Image from "next/image";
|
||
|
||
export default function LoginPage() {
|
||
const { loginMock, error: authError } = useAuth();
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
const handleTelegramLogin = () => {
|
||
const telegramUrl = `https://t.me/${BOT_USERNAME}?start=login`;
|
||
window.open(telegramUrl, "_blank");
|
||
};
|
||
|
||
const handleMockLogin = async () => {
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
await loginMock();
|
||
} catch (err: any) {
|
||
setError(err?.error?.message || "Ошибка входа");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
const displayError = error || authError;
|
||
|
||
return (
|
||
<div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-[#2B1D49] via-[#5F31F4] to-[#2B1D49] p-4">
|
||
<Card className="w-full max-w-md">
|
||
<CardHeader className="text-center space-y-2">
|
||
<div className="mx-auto w-12 h-12 flex items-center justify-center mb-2">
|
||
<Image
|
||
src="/logo.webp"
|
||
width={64}
|
||
height={64}
|
||
alt="Smartpost"
|
||
className="rounded-xl"
|
||
/>
|
||
</div>
|
||
<CardTitle className="text-2xl">Smartpost</CardTitle>
|
||
<CardDescription>
|
||
Система управления рекламными закупками в Telegram
|
||
</CardDescription>
|
||
</CardHeader>
|
||
|
||
<CardContent className="space-y-4">
|
||
{displayError && (
|
||
<Alert variant="destructive">
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertDescription>{displayError}</AlertDescription>
|
||
</Alert>
|
||
)}
|
||
|
||
{USE_MOCKS && (
|
||
<div className="space-y-3">
|
||
<Button
|
||
onClick={handleMockLogin}
|
||
disabled={loading}
|
||
className="w-full"
|
||
size="lg"
|
||
>
|
||
{loading ? (
|
||
<>
|
||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||
Вход...
|
||
</>
|
||
) : (
|
||
<>
|
||
<LogIn className="mr-2 h-4 w-4" />
|
||
Войти как тестовый пользователь
|
||
</>
|
||
)}
|
||
</Button>
|
||
|
||
<div className="relative">
|
||
<div className="absolute inset-0 flex items-center">
|
||
<span className="w-full border-t" />
|
||
</div>
|
||
<div className="relative flex justify-center text-xs uppercase">
|
||
<span className="bg-background px-2 text-muted-foreground">
|
||
или
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<Button
|
||
onClick={handleTelegramLogin}
|
||
variant={USE_MOCKS ? "outline" : "default"}
|
||
className="w-full"
|
||
size="lg"
|
||
>
|
||
<Image width={30} height={30} alt="telegram" src="/icons/telegram.svg" className="mr-2 h-5 w-5"/>
|
||
Войти через Telegram
|
||
</Button>
|
||
|
||
{USE_MOCKS && (
|
||
<Alert>
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertDescription className="text-xs">
|
||
<strong>Режим разработки:</strong> Используются моки данных.
|
||
Бекенд не требуется.
|
||
</AlertDescription>
|
||
</Alert>
|
||
)}
|
||
|
||
<p className="text-xs text-center text-muted-foreground mt-4">
|
||
Войдя в систему, вы соглашаетесь с условиями использования
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
);
|
||
}
|