Spotify OAuth with React not working properly

I am new to React in general and am trying to build a simple application. I want to build an application where users can sign in using their Spotify Account. I have the following files:

App.js:

import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import './App.css';
import OAuthSignInPage from './components/oauth';
import Callback from './components/callback';
import Welcome from './components/Welcome';
import Options from './components/Options';
import Header from './components/Header';
import { AuthProvider, useAuth } from './hooks/useAuth';

const ProtectedRoute = ({ children }) => {
  const { user } = useAuth();
  if (!user) {
    return <Navigate to="/" />;
  }
  return children;
};

function App() {
  return (
    <Router>
      <AuthProvider>
        <div className="App">
          <Header />
          <div className="content">
            <Routes>
              <Route path="/" element={<OAuthSignInPage />} />
              <Route path="/callback" element={<Callback />} />
              <Route path="/welcome" element={
                <ProtectedRoute>
                  <Welcome />
                </ProtectedRoute>
              } />
              <Route path="/options" element={
                <ProtectedRoute>
                  <Options />
                </ProtectedRoute>
              } />
            </Routes>
          </div>
        </div>
      </AuthProvider>
    </Router>
  );
}

export default App;

oauth.js

import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
import { useAuth } from "../hooks/useAuth";
import { useNavigate } from 'react-router-dom';

const providers = [
  { id: 'spotify', name: 'Spotify' }
];

const signIn = async (provider) => {
  
  if (provider.id === 'spotify') {
    // Redirect to Spotify login
    const clientId = process.env.REACT_APP_SPOTIFY_CLIENT_ID;
    const redirectUri = encodeURIComponent(`${window.location.origin}/callback`);
    const scope = 'user-read-private user-read-email user-top-read';
    const spotifyAuthUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&scope=${scope}`;
    
    window.location.href = spotifyAuthUrl;
    return new Promise(() => {}); // Promise won't resolve due to redirect
  }
  
  return { error: 'Invalid provider' };
};

export default function OAuthSignInPage() {
  const { user } = useAuth();
  const navigate = useNavigate();

  React.useEffect(() => {
    if (user) {
      navigate('/options');
    }
  }, [user, navigate]);

  const theme = useTheme();
  return (
    <AppProvider theme={theme}>
      <SignInPage signIn={signIn} providers={providers} />
    </AppProvider>
  );
}

protectedRoute.js:

import { Navigate } from "react-router-dom";
import { useAuth } from "../hooks/useAuth";

export const ProtectedRoute = ({ children }) => {
  const { user } = useAuth();
  if (!user) {
    // user is not authenticated
    return <Navigate to="/" />;
  }
  return children;
};

Callback.js

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';

function Callback() {
  const { login } = useAuth();
  const location = useLocation();

  useEffect(() => {
    const code = new URLSearchParams(location.search).get('code');
    if (code) {
      login({ code });
    }
  }, [location, login]);

  // No need for loading state since login handles navigation
  return null;
}

export default Callback;

useAuth.jsx

import { createContext, useContext, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { useLocalStorage } from "./useLocalStorage";
const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useLocalStorage("code", null);
  const navigate = useNavigate();

  // call this function when you want to authenticate the user
  const login = async (data) => {
    setUser(data);
  };

  // call this function to sign out logged in user
  const logout = () => {
    setUser(null);
    navigate("/", { replace: true });
  };

  const value = useMemo(
    () => ({
      user,
      login,
      logout,
    }),
    [user]
  );
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

export const useAuth = () => {
  return useContext(AuthContext);
};

Now the issue is, the OAuth part is working fine. I can login and Spotify is calling my /callback endpoint with the code. But the redirection is not working properly. After login it’s going to the /options route but it is a blank component. The error is:

Cannot update a component (`AuthProvider`) while rendering a different component (`Callback`). To locate the bad setState() call inside `Callback`, follow the stack trace as described in https://react.dev/link/setstate-in-render

And this error is being called in an infinite loop.

I just can’t figure out how to solve this. One more thing is when I manually type in the URL /welcome after login, it works. Help would be really appreciated.