railbird-gql/graphql/client.tsx

82 lines
1.7 KiB
TypeScript

import {
ApolloClient,
ApolloLink,
ApolloProvider,
HttpLink,
InMemoryCache,
from,
} from "@apollo/client";
import React, {
ReactNode,
createContext,
useContext,
useMemo,
useState,
} from "react";
import { API_URI } from '../config'
type Props = {
children: ReactNode;
};
export const AuthHeaderContext = createContext<
| {
authHeader: { key: string; value: string };
setAuthHeader: React.Dispatch<
React.SetStateAction<{ key: string; value: string }>
>;
}
| undefined
>(undefined);
// Hook to use the auth header context
export const useAuthHeader = () => {
const context = useContext(AuthHeaderContext);
if (!context) {
throw new Error("useAuthHeader must be used within a ClientProvider");
}
return context;
};
export const ClientProvider: React.FC<Props> = ({ children }) => {
const [authHeader, setAuthHeader] = useState({ key: "", value: "" });
console.log(`The api uri is ${API_URI}`);
const httpLink = new HttpLink({
uri: API_URI,
});
const cache = new InMemoryCache({});
const authMiddleware = new ApolloLink((operation, forward) => {
const { key, value } = authHeader;
console.log("Auth Key", key, "Value", value);
if (key && value) {
operation.setContext({
headers: {
[key]: value,
},
});
}
return forward(operation);
});
// We use useMemo to avoid recreating the client on every render
const client = useMemo(
() =>
new ApolloClient({
// Chain the middleware with the httpLink
link: from([authMiddleware, httpLink]),
cache: new InMemoryCache(),
}),
[authHeader],
);
return (
<AuthHeaderContext.Provider value={{ authHeader, setAuthHeader }}>
<ApolloProvider client={client}>{children}</ApolloProvider>
</AuthHeaderContext.Provider>
);
};