0

I have created my react app with a Header/navigation bar, it contains a dictionary search bar and login/register links, I want when clicking on either one Login/Register even though it takes me to the Login form I should still see the Header Like the below image Header it shouldn't be hidden when clicking on either one Login/Register

enter image description here

However, currently, When I click on The Login It takes me the login page but the header disappears as image below Login Form.

enter image description here

How can I get this fixed?

I have spent over an hour but couldn't figure it out.

see below my Header.js and App.js

Header.js

import { useContext, useEffect, useState } from 'react';
import { InputContext } from '../Context/Input.context';
import { getWordSuggestions } from '../api/getWordSuggestions';
import WordItem from './WordItem';
import { Link, Outlet } from 'react-router-dom';
import './Header.css';
import { UserContext } from '../Context/User.context';
import { signOut } from 'firebase/auth';
import { auth } from '../pages/firebase';

const Header = () => {
  const [value, setValue] = useState('');
  const [isDropdownOpen, setIsDropdownOpen] = useState(true);
  const [searchSuggestions, setSearchSuggestions] = useState({
    suggestions: [],
    suggestionsState: [],
  });
  const { inputValue, setInputValue } = useContext(InputContext);
  const { currentUser, setCurrentUser } = useContext(UserContext);

  const handleSubmit = (word) => {
    const index = searchSuggestions.suggestionsState.indexOf('active');
    setInputValue(searchSuggestions.suggestions[index]);
    setValue('');
    setSearchSuggestions({
      suggestions: [],
      suggestionsState: [],
    });
    setIsDropdownOpen(true);
  };

  // On change of search field
  const handleInputChange = async (e) => {
    console.log(e);
    if (!e.target.value) {
      setIsDropdownOpen(false);
    } else if (e.target.value) {
      setIsDropdownOpen(true);
    }
    setValue(e.target.value);
  };

  // To submit the form
  const handleShowResult = (e) => {
    e.preventDefault();
    // if (!value) return;

    handleSubmit(value);
  };

  const handleSuggestions = async (value) => {
    const suggestions = await getWordSuggestions(value);
    const suggestionsState = Array(suggestions.length).fill('inActive', 1);
    suggestionsState[0] = 'active';
    setSearchSuggestions({
      suggestions: suggestions,
      suggestionsState: suggestionsState,
    });
    console.log(suggestions);
    console.log(suggestionsState);
    let onArrowPress = 0;
    document.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowDown') {
        if (typeof suggestionsState[onArrowPress + 1] !== 'undefined') {
          suggestionsState[onArrowPress + 1] = 'active';
          if (onArrowPress >= 0) {
            suggestionsState[onArrowPress] = 'inActive';
          }
          onArrowPress++;
        }
      }
      if (e.key === 'ArrowUp') {
        if (typeof suggestionsState[onArrowPress - 1] !== 'undefined') {
          suggestionsState[onArrowPress - 1] = 'active';
          if (onArrowPress - 1 >= 0) {
            suggestionsState[onArrowPress] = 'inActive';
          }
          onArrowPress--;
        }
      }
      setSearchSuggestions({
        suggestions: suggestions,
        suggestionsState: suggestionsState,
      });
    });
  };

  useEffect(() => {
    if (value) handleSuggestions(value);
  }, [value]);


  // setCurrentUser(true)

  return (
    <div className="bg-gray-700">
      <div className="nav">
        {!currentUser?.emailVerified ? (
          <>
            <Link to="/login" className="nav-Link">
              Login
            </Link>
            <Link to={'/register'} className="nav-Link">
              Signup
            </Link>
          </>
        ) : (
          <span className="cursor-pointer" onClick={() => signOut(auth)}>
            Sign Out
          </span>
          
        )}
        <Outlet />
      </div>

      <div className="container mx auto py-8">
        {/* <h1 className="text-3xl font-bold text-center text-white">
          My Free Dictionary
        </h1> */}

        <p className="text-center mt-1 mb-10 text-white text-lg">Find Definitions for word</p>

        <div className="flex itmes-center justify-center mt-5">
          <form
            className="LOOK relative flex border-2 border-gray-200 rounded"
            onSubmit={handleShowResult}
            onFocus={() => setInputValue(false)}
            onBlur={() => setIsDropdownOpen(false)}>
            <input
              className="pw-96 px-4 py-2 md:w-80"
              type="text"
              placeholder="Search.."
              onChange={handleInputChange}
              value={value}
            />
            <button className="bg-blue-400 border-l px-4 py-2 text-white">Search</button>
            {isDropdownOpen === true && (
              <div className="word-suggestion-dropdown should-be-in-a-container absolute top-full bg-gray-50 w-full z-10">
                {searchSuggestions.suggestions.map((word, onArrowPress) => {
                  return (
                    <WordItem
                      key={word}
                      word={word}
                      addedClassname={searchSuggestions.suggestionsState[onArrowPress]}
                      handleClick={handleSubmit}
                    />
                  );
                })}
              </div>
            )}
          </form>
        </div>
        {inputValue && (
          <h3 className="text-gray-50 text-center mt-4">
            Results for: <span className="text-white font-bold">{inputValue}</span>
          </h3>
        )}
      </div>
    </div>
  );
};

export default Header;

App.js

import { Routes, Route, Navigate, Outlet } from 'react-router-dom';
import Home from './pages/Home';
import Login from './pages/login/Login';
import Profile from './pages/Profile';
import Register from './pages/Register/Register';
import PrivateRoute from './pages/PrivateRoute';
import VerifyEmail from './pages/verifyEmail';
import { useContext, useState } from 'react';

import { AuthProvider } from './pages/AuthContext';
import Reset from './pages/Reset';
import { UserContext } from './Context/User.context';

function App() {
  const { currentUser } = useContext(UserContext);
  const [timeActive, setTimeActive] = useState(false);

  return (
    <AuthProvider value={{ timeActive, setTimeActive }}>
      <Routes>
        <Route path="/" element={<Outlet />}>
          <Route exact path="/" element={<Home />} />
          <Route path="/profile" element={<Profile />} />
          <Route path="/login" element={!currentUser?.emailVerified ? <Login /> : <Navigate to="/" replace />} />
          <Route path="/register" element={!currentUser?.emailVerified ? <Register /> : <Navigate to="/" replace />} />
          <Route path="/verify-email" element={<VerifyEmail />} />
          <Route exact path="/reset" element={<Reset />} />
        </Route>
      </Routes>
    </AuthProvider>
  );
}

export default App;
Motty
  • 3
  • 2
  • Please provide a running sample. The current code is not able to find how you use header.js. If you add a header in the inner pages. Then login page not added a header. If you using a template then use the template on the login/register page. – Dhaval Gajjar Nov 10 '22 at 02:37
  • this is my app page https://free-dictionary-git-master-moshe844.vercel.app/ i tried adding the to my Header so it always stays the same place even though i click on the login form, but couldn't get it to work – Motty Nov 10 '22 at 02:43
  • or if you want to take a look at my git repo https://github.com/Moshe844/free-dictionary.git – Motty Nov 10 '22 at 02:46
  • You are adding `
    ` in the Home component. So you need to add that to Login/Register. Or in App.js add `
    ` before ``. That will apply the header to all pages.
    – Dhaval Gajjar Nov 10 '22 at 02:52
  • Just render the `Header` component instead of the `Outlet` on the layout route, i.e. `}>...`. The duplicate explains this in a bit more detail. – Drew Reese Nov 10 '22 at 02:57

0 Answers0