import axios, { AxiosRequestConfig, AxiosResponse } from "axios"; import moment from "moment"; import { createContext, PropsWithChildren, useContext } from "react"; import PondProvider from "./pond/pond"; import { useAuth0 } from "@auth0/auth0-react"; import SnackbarProvider from "./Snackbar"; interface IHTTPContext { get: (url: string, spreadOptions?: AxiosRequestConfig) => Promise>; put: ( url: string, data?: any, spreadOptions?: AxiosRequestConfig ) => Promise>; post: ( url: string, data?: any, spreadOptions?: AxiosRequestConfig ) => Promise>; del: (url: string, spreadOptions?: AxiosRequestConfig) => Promise>; options: (demo?: boolean) => AxiosRequestConfig; token: string; } interface Props extends PropsWithChildren{ token: string; } export const HTTPContext = createContext({} as IHTTPContext); export default function HTTPProvider(props: Props) { const { children, token } = props; const { isAuthenticated, loginWithRedirect } = useAuth0(); const defaultOptions = (demo: boolean = false) => { if (demo || !isAuthenticated || !token) { return { headers: { "Content-Type": "application/json" } }; } const config = { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }, }; return config; }; function isTokenExpired(token: string): boolean { try { // Split the token and decode the payload (second part) const payloadBase64 = token.split('.')[1]; const decodedPayload = atob(payloadBase64); // Decode base64 const payload = JSON.parse(decodedPayload); // Get expiration time (in seconds) const exp = payload.exp; if (!exp) return true; // No exp field? Treat as expired // Current time in seconds const now = Math.floor(Date.now() / 1000); // Compare return now >= exp; } catch (error) { console.error("Invalid token format:", error); return true; // Err on the side of caution if decoding fails } } function get(url: string, spreadOptions?: AxiosRequestConfig): Promise> { if (isTokenExpired(token)) loginWithRedirect() return axios.get(url, {...defaultOptions(), ...spreadOptions}); } function put( url: string, data?: any, spreadOptions?: AxiosRequestConfig ): Promise> { return axios.put(url, data, { ...defaultOptions(), ...spreadOptions }); } function post( url: string, data?: any, spreadOptions?: AxiosRequestConfig ): Promise> { return axios.post(url, data, { ...defaultOptions(), ...spreadOptions }); } function del(url: string, spreadOptions?: AxiosRequestConfig): Promise> { return axios.delete(url, { ...defaultOptions(), ...spreadOptions }); } return ( {/* */} {children} {/* */} {/* {children} */} {/* */} {/* */} ); } export const useHTTP = () => useContext(HTTPContext); //returns a string depending on the given start and end to be used in a url query export function dateRange(start: any, end: any): string { start = moment(start).toISOString(); end = moment(end).toISOString(); var queryRange = ""; if ( typeof start !== "undefined" && start !== null && typeof end !== "undefined" && end !== null ) { queryRange = "?start=" + start + "&end=" + end; } else if (typeof start !== "undefined" && start !== null) { queryRange = "?start=" + start; } else if (typeof end !== "undefined" && end !== null) { queryRange += "?end=" + end; } return queryRange; }