<file_sep>import { useState } from "react";

const useFetch = (url) => {
  const [isLoading, setIsLoading] = useState(false);
  const [hasError, setHasError] = useState(false);
  const [searchResult, setSearchResult] = useState(null);

  const fetchFunction = async () => {
    try {
      setIsLoading(true);

      const response = await fetch(url);
      const result = await response.json();
      setSearchResult(result);
      console.log(result);
    } catch {
      setHasError(true);
    } finally {
      setIsLoading(false);
    }
  };

  return [fetchFunction, searchResult, isLoading, hasError];
};
export default useFetch;
<file_sep>import { useEffect } from "react";
import { withRouter } from "react-router-dom";
import OneCountry from "../components/OneCountry";
import useFetch from "../hooks/useFetch";

const Details = (props) => {
  const {
    params: { alpha3Code },
  } = props.match;

  const url = `https://restcountries.eu/rest/v2/name/${alpha3Code}`;
  const [fetchCountry, country, isLoading, hasError] = useFetch(url);

  useEffect(() => {
    if (alpha3Code) fetchCountry();
  }, [alpha3Code]);

  return (
    <div>
      {isLoading && <div>loading</div>}
      {hasError && <div>Error</div>}
      {!isLoading && !hasError && country && (
        <div>
          <OneCountry country={country[0]} />
        </div>
      )}
    </div>
  );
};
export default withRouter(Details);
<file_sep># React-Project-class-31<file_sep>import { Link } from "react-router-dom";

export default function Card({ country }) {
  const { name, flag } = country;
  return (
    <div className="card">
      <Link to={`/${name}`}>
        <img className="countriesListImg" src={flag} alt={""} />
        <h3> {name} </h3>
      </Link>
    </div>
  );
}
<file_sep>import { useEffect, useRef, useContext } from "react";
import { CountryContext } from "../contexts/CountryContext";

const Search = () => {
  const { searchTerm, setSearchTerm, isLoading, hasError } =
    useContext(CountryContext);

  const refContainer = useRef(null);
  useEffect(() => {
    refContainer.current.focus();
  });

  const handleChange = (event) => {
    setSearchTerm(event.target.value);
  };

  return (
    <div className="search">
      <input
        className="input"
        type="text"
        name="cityName"
        placeholder="Enter Country Name..."
        value={searchTerm}
        ref={refContainer}
        onChange={handleChange}
      />

      {isLoading && <p className="loading">Loading....</p>}
      {hasError && <p className="error">Something Went Wrong!</p>}
    </div>
  );
};

export default Search;
<file_sep>import { useContext } from "react";
import Card from "../components/Card";
import { CountryContext } from "../contexts/CountryContext";
import Search from "../components/Search";

export default function Home() {
  const { countries, isLoading, hasError } = useContext(CountryContext);
  return (
    <div>
      {isLoading && <div>loading</div>}
      {hasError && <div>Error</div>}
      {!isLoading && !hasError && (
        <>
          <Search />
          <div className="countryContainer">
            {countries.map((country) => {
              return <Card country={country} key={country.name} />;
            })}
          </div>
        </>
      )}
    </div>
  );
}
<file_sep>import { createContext, useEffect, useState } from "react";
import useFetch from "../hooks/useFetch";

export const CountryContext = createContext();

export default function CountryContextProvider(props) {
  const url = "https://restcountries.eu/rest/v2/all";
  const [searchTerm, setSearchTerm] = useState("");

  const [fetchAllCountries, countries, isLoading, hasError] = useFetch(url);

  useEffect(() => {
    fetchAllCountries();
  }, []);

  let filteredCountries = countries || [];
  if (searchTerm) {
    filteredCountries = filteredCountries.filter((country) => {
      return country.name.toLowerCase().includes(searchTerm.toLowerCase());
    });
  }

  return (
    <CountryContext.Provider
      value={{
        isLoading,
        hasError,
        searchTerm,
        setSearchTerm,
        countries: filteredCountries,
        fetchAllCountries,
      }}
    >
      {props.children}
    </CountryContext.Provider>
  );
}
