diff --git a/app/auth/callback/page.tsx b/app/auth/callback/page.tsx index 6e78300..f988ffd 100644 --- a/app/auth/callback/page.tsx +++ b/app/auth/callback/page.tsx @@ -14,9 +14,14 @@ function AuthCallbackContent() { "loading", ); const [message, setMessage] = useState(""); + const [isProcessing, setIsProcessing] = useState(false); useEffect(() => { const handleCallback = async () => { + // Prevent multiple simultaneous executions + if (isProcessing) return; + setIsProcessing(true); + try { // Check if this is an OAuth callback const success = searchParams.get("success"); @@ -67,11 +72,14 @@ function AuthCallbackContent() { "An error occurred during authentication. Please try again.", ); setTimeout(() => router.push("/"), 3000); + } finally { + setIsProcessing(false); } }; handleCallback(); - }, [router, searchParams, refreshUser]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchParams]); if (status === "loading") { return ( diff --git a/components/AuthModal.tsx b/components/AuthModal.tsx index 7f54bf8..b38a371 100644 --- a/components/AuthModal.tsx +++ b/components/AuthModal.tsx @@ -143,23 +143,14 @@ export const AuthModal: React.FC = ({ const handleAppleSignIn = async () => { setIsLoading(true); - setMessage("Redirecting to Apple..."); // User feedback try { // Save last used method const method = { type: "apple", value: "Apple" }; setLastUsedMethod(method); localStorage.setItem("lastUsedAuthMethod", JSON.stringify(method)); - - const result = await signInWithApple(); - - if (!result.success && result.error) { - setMessage(result.error); - setIsLoading(false); - } - // Note: For Apple OAuth, loading state will be reset when the modal auto-closes - // or when the page redirects. Don't reset here for successful redirects. + await signInWithApple(); } catch (error) { - setMessage("Failed to sign in with Apple. Please try again."); + setMessage("Failed to sign in with Apple"); setIsLoading(false); } }; diff --git a/components/Header.tsx b/components/Header.tsx index b011f70..9ec69ad 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,7 +1,6 @@ "use client"; import React, { useEffect, useState } from "react"; -import HomeButton from "./HomeButton"; import Image from "next/image"; import { usePathname, useRouter } from "next/navigation"; import { useAuth } from "../contexts/AuthContext"; @@ -60,30 +59,12 @@ const Header = () => {
- {/* Left section - Home button or logo */} + {/* Left section - Logo */}
- {pathname !== "/" ? ( - { - router.push("/"); - }} - /> - ) : ( -
- Ditectrev Logo -
- )} -
- - {/* Center section - Logo on non-home pages */} - {pathname !== "/" && ( -
+
- )} + +
{/* Right section - Navigation and Auth */}
diff --git a/components/HomeButton.tsx b/components/HomeButton.tsx deleted file mode 100644 index ff67ed2..0000000 --- a/components/HomeButton.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; - -type Props = { - handleReturnToMainPage: () => void; -}; - -const HomeButton: React.FC = ({ - handleReturnToMainPage -}) => { - return ( - - ); -}; - -export default HomeButton; \ No newline at end of file diff --git a/components/QuizForm.tsx b/components/QuizForm.tsx index 3367519..82eaedf 100644 --- a/components/QuizForm.tsx +++ b/components/QuizForm.tsx @@ -325,33 +325,46 @@ const QuizForm: FC = ({ {isThinking ? "Thinking..." : "Explain"} )} - + {currentQuestionIndex < totalQuestions ? ( + + ) : ( + + )}
); diff --git a/package-lock.json b/package-lock.json index a6064b1..c3435c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "practice-exams-platform", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "practice-exams-platform", - "version": "1.4.3", + "version": "1.4.4", "dependencies": { "@apollo/client": "^3.7.9", "@apollo/server": "^4.11.0", diff --git a/package.json b/package.json index 2acc863..22c7789 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "practice-exams-platform", - "version": "1.4.3", + "version": "1.4.4", "private": true, "engines": { "node": "20.x" diff --git a/styles/globals.css b/styles/globals.css index 19bc73a..b3e1e41 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -30,41 +30,39 @@ a[target="_blank"]:hover .external-link-icon { } .loading-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - z-index: 9999; - } + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; +} - .spinner { - border: 8px solid rgba(255, 255, 255, 0.3); - border-top: 8px solid #1E293B; - border-radius: 50%; - width: 60px; - height: 60px; - -webkit-animation: spin 1s linear infinite; - animation: spin 1s linear infinite; +.spinner { + border: 8px solid rgba(255, 255, 255, 0.3); + border-top: 8px solid #1E293B; + border-radius: 50%; + width: 60px; + height: 60px; + -webkit-animation: spin 1s linear infinite; + animation: spin 1s linear infinite; +} +@-webkit-keyframes spin { + 0% { + transform: rotate(0deg); } - - @-webkit-keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } + 100% { + transform: rotate(360deg); } - - @keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } +} +@keyframes spin { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); + } +}