improvement for the backend api
This commit is contained in:
115
app/(auth)/auth/complete/page.tsx
Normal file
115
app/(auth)/auth/complete/page.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
"use client";
|
||||
|
||||
// ============================================================================
|
||||
// Auth Complete Page
|
||||
// ============================================================================
|
||||
|
||||
import React, { useEffect, useState, Suspense } from "react";
|
||||
import { useSearchParams, useRouter } from "next/navigation";
|
||||
import { useAuth } from "@/components/auth/auth-provider";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { AlertCircle, CheckCircle, Loader2 } from "lucide-react";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
function AuthCompleteContent() {
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
const { login } = useAuth();
|
||||
const [status, setStatus] = useState<"loading" | "success" | "error">(
|
||||
"loading"
|
||||
);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const token = searchParams.get("token");
|
||||
|
||||
if (!token) {
|
||||
setStatus("error");
|
||||
setError("Токен авторизации не найден");
|
||||
return;
|
||||
}
|
||||
|
||||
const completeAuth = async () => {
|
||||
try {
|
||||
await login(token);
|
||||
setStatus("success");
|
||||
|
||||
// Redirect after short delay
|
||||
setTimeout(() => {
|
||||
router.push("/");
|
||||
}, 1500);
|
||||
} catch (err: any) {
|
||||
setStatus("error");
|
||||
setError(err?.detail || err?.error?.message || "Ошибка авторизации");
|
||||
}
|
||||
};
|
||||
|
||||
completeAuth();
|
||||
}, [searchParams, login, router]);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-950 dark:to-slate-900 p-4">
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader className="text-center">
|
||||
<div className="mx-auto mb-4">
|
||||
{status === "loading" && (
|
||||
<Loader2 className="h-12 w-12 animate-spin text-primary" />
|
||||
)}
|
||||
{status === "success" && (
|
||||
<CheckCircle className="h-12 w-12 text-green-500" />
|
||||
)}
|
||||
{status === "error" && (
|
||||
<AlertCircle className="h-12 w-12 text-destructive" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<CardTitle>
|
||||
{status === "loading" && "Авторизация..."}
|
||||
{status === "success" && "Успешно!"}
|
||||
{status === "error" && "Ошибка"}
|
||||
</CardTitle>
|
||||
|
||||
<CardDescription>
|
||||
{status === "loading" && "Пожалуйста, подождите"}
|
||||
{status === "success" && "Перенаправляем в приложение..."}
|
||||
{status === "error" && error}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
{status === "error" && (
|
||||
<CardContent>
|
||||
<Alert variant="destructive" className="mb-4">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertDescription>{error}</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<Button onClick={() => router.push("/login")} className="w-full">
|
||||
Вернуться к входу
|
||||
</Button>
|
||||
</CardContent>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AuthCompletePage() {
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
<Loader2 className="h-12 w-12 animate-spin text-primary" />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<AuthCompleteContent />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user