import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { ApolloLink } from "apollo-link";
import { BatchHttpLink } from "apollo-link-batch-http";
import { setContext } from "apollo-link-context";
import { ErrorResponse, onError } from "apollo-link-error";
import { createUploadLink } from "apollo-upload-client";
import React from "react";
import { ApolloProvider } from "react-apollo";
import { render } from "react-dom";
import { useIntl } from "react-intl";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import AttributeSection from "./attributes";
import { attributeSection } from "./attributes/urls";
import { getAuthToken, removeAuthToken } from "./auth";
import AuthProvider from "./auth/AuthProvider";
import LoginLoading from "./auth/components/LoginLoading/LoginLoading";
import SectionRoute from "./auth/components/SectionRoute";
import { hasPermission } from "./auth/misc";
import Login from "./auth/views/Login";
import CategorySection from "./categories";
import CollectionSection from "./collections";
import { AppProgressProvider } from "./components/AppProgress";
import { DateProvider } from "./components/Date";
import { LocaleProvider } from "./components/Locale";
import { MessageManager } from "./components/messages";
import { ShopProvider } from "./components/Shop";
import ThemeProvider from "./components/Theme";
import { WindowTitle } from "./components/WindowTitle";
import { API_URI, APP_MOUNT_URI } from "./config";
import ConfigurationSection, { createConfigurationMenu } from "./configuration";
import { CustomerSection } from "./customers";
import DiscountSection from "./discounts";
import HomePage from "./home";
import { commonMessages } from "./intl";
import NavigationSection from "./navigation";
import { navigationSection } from "./navigation/urls";
import { NotFound } from "./NotFound";
import OrdersSection from "./orders";
import PageSection from "./pages";
import ProductSection from "./products";
import ProductTypesSection from "./productTypes";
import ShippingSection from "./shipping";
import SiteSettingsSection from "./siteSettings";
import StaffSection from "./staff";
import TaxesSection from "./taxes";
import TranslationsSection from "./translations";
import { PermissionEnum } from "./types/globalTypes";
interface ResponseError extends ErrorResponse {
networkError?: Error & {
statusCode?: number;
bodyText?: string;
};
}
const invalidTokenLink = onError((error: ResponseError) => {
if (error.networkError && error.networkError.statusCode === 401) {
removeAuthToken();
}
});
const authLink = setContext((_, context) => {
const authToken = getAuthToken();
return {
...context,
headers: {
...context.headers,
Authorization: authToken ? `JWT ${authToken}` : null
}
};
});
// DON'T TOUCH THIS
// These are separate clients and do not share configs between themselves
// so we need to explicitly set them
const linkOptions = {
credentials: "same-origin",
uri: API_URI
};
const uploadLink = createUploadLink(linkOptions);
const batchLink = new BatchHttpLink({
batchInterval: 100,
...linkOptions
});
const link = ApolloLink.split(
operation => operation.getContext().useBatching,
batchLink,
uploadLink
);
const apolloClient = new ApolloClient({
cache: new InMemoryCache({
dataIdFromObject: (obj: any) => {
// We need to set manually shop's ID, since it is singleton and
// API does not return its ID
if (obj.__typename === "Shop") {
return "shop";
}
return defaultDataIdFromObject(obj);
}
}),
link: invalidTokenLink.concat(authLink.concat(link))
});
const App: React.FC = () => {
const isDark = localStorage.getItem("theme") === "true";
return (
);
};
const Routes: React.FC = () => {
const intl = useIntl();
return (
<>
{({
hasToken,
isAuthenticated,
tokenAuthLoading,
tokenVerifyLoading,
user
}) =>
isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading ? (
{createConfigurationMenu(intl).filter(menuItem =>
hasPermission(menuItem.permission, user)
).length > 0 && (
)}
) : hasToken && tokenVerifyLoading ? (
) : (
)
}
>
);
};
render(, document.querySelector("#dashboard-app"));