- {isLoading &&
- Array.from({ length: OAUTH_PROVIDERS_COUNT }, (_v, i) => (
-
- ))}
+ {isLoading && Array.from({ length: 3 }, (_v, i) =>
)}
{data?.map((item) => {
- const providerConfig = OAUTH_PROVIDERS[item.value];
-
- return (
-
- );
+ return
;
})}
);
diff --git a/src/features/handle-query-params/index.ts b/src/features/handle-query-params/index.ts
new file mode 100644
index 0000000..162963b
--- /dev/null
+++ b/src/features/handle-query-params/index.ts
@@ -0,0 +1 @@
+export { QueryParamsHandler } from './ui/QueryParamsHandler';
diff --git a/src/features/handle-query-params/ui/QueryParamsHandler.tsx b/src/features/handle-query-params/ui/QueryParamsHandler.tsx
new file mode 100644
index 0000000..d132422
--- /dev/null
+++ b/src/features/handle-query-params/ui/QueryParamsHandler.tsx
@@ -0,0 +1,30 @@
+'use client';
+
+import { type Route } from 'next';
+import { useRouter, useSearchParams } from 'next/navigation';
+import { useEffect, useRef } from 'react';
+import { toast } from 'sonner';
+
+export function QueryParamsHandler() {
+ const params = useSearchParams();
+ const isShowToast = useRef(false);
+ const router = useRouter();
+
+ useEffect(() => {
+ const success = params?.get('success');
+ const message = params?.get('message');
+
+ if (isShowToast.current || !success) return;
+
+ if (success === 'true') {
+ toast.success(message || 'Операция выполнена успешно');
+ } else if (success === 'false') {
+ toast.error(message || 'Произошла ошибка. Пожалуйста, попробуйте позже');
+ }
+
+ isShowToast.current = true;
+ router.replace(location.pathname as Route);
+ }, [params, router]);
+
+ return null;
+}
diff --git a/src/pages/auth/oauth/ui/OAuthPage.tsx b/src/pages/auth/oauth/ui/OAuthPage.tsx
index 960533b..16613be 100644
--- a/src/pages/auth/oauth/ui/OAuthPage.tsx
+++ b/src/pages/auth/oauth/ui/OAuthPage.tsx
@@ -21,6 +21,8 @@ interface Props {
export async function OAuthPage({ searchParams }: Props) {
const { success, message, provider, startOAuth } = await searchParams;
+ // TODO: страница знает API
+
if (provider && startOAuth === 'true') {
redirect(`${env.NEXT_PUBLIC_API_BASE_URL}/auth/oauth/${provider}` as Route);
}
@@ -30,11 +32,13 @@ export async function OAuthPage({ searchParams }: Props) {
}
if (success === 'true') {
- redirect(routes.user.profile());
+ redirect(
+ `${routes.user.profile()}?success=true&message=${encodeURIComponent(message || 'Вход успешен')}`
+ );
}
const errorUrl = message
- ? `${routes.auth.signin()}?oauth_error=1&message=${encodeURIComponent(message)}`
+ ? `${routes.auth.signin()}?success=true&message=${encodeURIComponent(message)}`
: routes.auth.signin();
redirect(errorUrl as Route);
diff --git a/src/pages/auth/signin/model/useAuthRedirectMessage.ts b/src/pages/auth/signin/model/useAuthRedirectMessage.ts
deleted file mode 100644
index 8d64438..0000000
--- a/src/pages/auth/signin/model/useAuthRedirectMessage.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-'use client';
-import { useRouter, useSearchParams } from 'next/navigation';
-import { useEffect } from 'react';
-import { routes } from 'shared/config';
-import { toast } from 'sonner';
-
-export function useAuthRedirectMessage() {
- const params = useSearchParams();
- const router = useRouter();
-
- useEffect(() => {
- const error = params?.get('oauth_error');
- const message = params?.get('message');
-
- if (!error) return;
- toast.error(message ?? 'Authorization failed');
- router.replace(routes.auth.signin());
- }, [params, router]);
-}
diff --git a/src/pages/auth/signin/ui/AuthRedirectHandler.tsx b/src/pages/auth/signin/ui/AuthRedirectHandler.tsx
deleted file mode 100644
index 2b5a8ee..0000000
--- a/src/pages/auth/signin/ui/AuthRedirectHandler.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-'use client';
-import { useAuthRedirectMessage } from '../model/useAuthRedirectMessage';
-
-export function AuthRedirectHandler() {
- useAuthRedirectMessage();
- return null;
-}
diff --git a/src/pages/auth/signin/ui/SigninForm.tsx b/src/pages/auth/signin/ui/SigninForm.tsx
index 0fa94d5..6fa91e4 100644
--- a/src/pages/auth/signin/ui/SigninForm.tsx
+++ b/src/pages/auth/signin/ui/SigninForm.tsx
@@ -24,9 +24,10 @@ import { cn, setFormErrors } from 'shared/lib/utils';
import { routes } from 'shared/config';
import { extractValidationIssues } from 'shared/api';
import { TAuth } from 'entities/auth';
-import { ComponentProps } from 'react';
+import { ComponentProps, Suspense } from 'react';
import { useSignin, UseSigninOptions } from '../model/useSignin';
import { OAuthLoginButtons, OAuthSeparator } from 'features/auth/oauth-login';
+import { QueryParamsHandler } from 'features/handle-query-params';
interface SigninFormProps extends Omit