From 2bd4f17b0b6eef2ed91d4bf4d50f931b910f0531 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Tue, 6 Oct 2020 23:01:15 -0700 Subject: [PATCH 1/3] Updated env variables + added axios base url. --- client/src/App/App.container.jsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index fc04f2a02..fd55de87d 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -22,6 +22,13 @@ import App from "./App"; moment.locale("en-US"); +//if (process.env.NODE_ENV === "prodution") +axios.defaults.baseURL = + process.env.REACT_APP_AXIOS_BASE_API_URL || "https://api.imex.online/"; +console.log( + " process.env.REACT_APP_AXIOS_BASE_API_URL ", + process.env.REACT_APP_AXIOS_BASE_API_URL +); export const axiosAuthInterceptorId = axios.interceptors.request.use( async (config) => { if (!config.headers.Authorization) { From b6f2ad3cf02be87034db9a371e90f9d2a25ef9fe Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Wed, 7 Oct 2020 10:04:22 -0700 Subject: [PATCH 2/3] Updated images in assets and removed some packages. --- .ebextensions/eb-redirect-https.config | 53 + admin/public/index.html | 2 +- client/madge-graph.svg | 439 + client/package.json | 8 +- client/public/favicon.png | Bin 0 -> 8881 bytes client/public/index.html | 4 +- client/public/manifest.json | 2 +- client/src/App/App.container.jsx | 8 +- client/src/App/App.styles.scss | 1 + client/src/assets/logo1024.png | Bin 18480 -> 87519 bytes client/src/assets/logo192.png | Bin 8581 -> 8881 bytes client/src/assets/logo240.png | Bin 2390 -> 0 bytes client/src/assets/logo512.png | Bin 0 -> 27744 bytes .../dashboard-grid.component.jsx | 340 +- .../schedule-calendar.styles.scss | 4 +- .../sign-in-form/sign-in-form.component.jsx | 30 +- .../user-request-reset-pw.component.jsx | 2 +- .../user-validate-pw-reset.component.jsx | 2 +- client/yarn.lock | 14645 ---------------- server/_test/test.js | 2 +- 20 files changed, 693 insertions(+), 14849 deletions(-) create mode 100644 .ebextensions/eb-redirect-https.config create mode 100644 client/madge-graph.svg create mode 100644 client/public/favicon.png delete mode 100644 client/src/assets/logo240.png create mode 100644 client/src/assets/logo512.png delete mode 100644 client/yarn.lock diff --git a/.ebextensions/eb-redirect-https.config b/.ebextensions/eb-redirect-https.config new file mode 100644 index 000000000..17aacb0da --- /dev/null +++ b/.ebextensions/eb-redirect-https.config @@ -0,0 +1,53 @@ +#################################################################################################### +#### Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +#### +#### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file +#### except in compliance with the License. A copy of the License is located at +#### +#### http://aws.amazon.com/apache2.0/ +#### +#### or in the "license" file accompanying this file. This file is distributed on an "AS IS" +#### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +#### License for the specific language governing permissions and limitations under the License. +#################################################################################################### + +#################################################################################################### +#### This configuration file adds a listener to the Application Load Balancer for port 443, this new listener +#### requires the ARN of a public website certificate create residing in the certificate manager service. +#### The configuration file also modifies the default port 80 listener attached to an Application Load Balancer +#### to automatically redirect incoming connections on HTTP to HTTPS. +#### This will not work with an environment using the load balancer type Classic or Network. +#### Do not use this configuration file if a listener has already been created for port 443 from the console. +#################################################################################################### + +Resources: + AWSEBV2LoadBalancerListener: + Type: 'AWS::ElasticLoadBalancingV2::Listener' + Properties: + DefaultActions: + - Type: redirect + RedirectConfig: + Protocol: HTTPS + Port: '443' + Host: '#{host}' + Path: '/#{path}' + Query: '#{query}' + StatusCode: HTTP_301 + LoadBalancerArn: + Ref: AWSEBV2LoadBalancer + Port: 80 + Protocol: HTTP + AWSEBV2LoadBalancerListenerHTTPS: + Type: 'AWS::ElasticLoadBalancingV2::Listener' + Properties: + Certificates: + - CertificateArn: arn:aws:acm:ca-central-1:714144183158:certificate/c6a0fcde-b959-4aee-afc6-934e27c4962b + DefaultActions: + - Type: forward + TargetGroupArn: + Ref: AWSEBV2LoadBalancerTargetGroup + LoadBalancerArn: + Ref: AWSEBV2LoadBalancer + Port: 443 + Protocol: HTTPS + \ No newline at end of file diff --git a/admin/public/index.html b/admin/public/index.html index 5ce0f5032..5b7dbccaf 100644 --- a/admin/public/index.html +++ b/admin/public/index.html @@ -2,7 +2,7 @@ - + + + + + + +G + + + +src/App/App.container.jsx + +src/App/App.container.jsx + + + +src/App/App.jsx + +src/App/App.jsx + + + +src/App/App.container.jsx->src/App/App.jsx + + + + + +src/firebase/firebase.utils.js + +src/firebase/firebase.utils.js + + + +src/App/App.container.jsx->src/firebase/firebase.utils.js + + + + + +src/components/error-boundary/error-boundary.component.jsx + +src/components/error-boundary/error-boundary.component.jsx + + + +src/App/App.jsx->src/components/error-boundary/error-boundary.component.jsx + + + + + +src/pages/manage/manage.page.container.jsx + +src/pages/manage/manage.page.container.jsx + + + +src/App/App.jsx->src/pages/manage/manage.page.container.jsx + + + + + +src/redux/store.js + +src/redux/store.js + + + +src/firebase/firebase.utils.js->src/redux/store.js + + + + + +src/components/error-boundary/error-boundary.component.jsx->src/firebase/firebase.utils.js + + + + + +src/pages/manage/manage.page.component.jsx + +src/pages/manage/manage.page.component.jsx + + + +src/pages/manage/manage.page.container.jsx->src/pages/manage/manage.page.component.jsx + + + + + +src/components/bill-detail-edit/bill-detail-edit.container.jsx + +src/components/bill-detail-edit/bill-detail-edit.container.jsx + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx + +src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx + + + +src/components/bill-detail-edit/bill-detail-edit.container.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx + + + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx + +src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx + + + + + +src/components/bill-enter-modal/bill-enter-modal.container.jsx + +src/components/bill-enter-modal/bill-enter-modal.container.jsx + + + +src/components/documents-upload/documents-upload.utility.js + +src/components/documents-upload/documents-upload.utility.js + + + +src/components/bill-enter-modal/bill-enter-modal.container.jsx->src/components/documents-upload/documents-upload.utility.js + + + + + +src/components/documents-upload/documents-upload.utility.js->src/App/App.container.jsx + + + + + +src/components/documents-upload/documents-upload.utility.js->src/firebase/firebase.utils.js + + + + + +src/components/email-overlay/email-overlay.container.jsx + +src/components/email-overlay/email-overlay.container.jsx + + + +src/components/email-overlay/email-overlay.container.jsx->src/firebase/firebase.utils.js + + + + + +src/utils/RenderTemplate.js + +src/utils/RenderTemplate.js + + + +src/components/email-overlay/email-overlay.container.jsx->src/utils/RenderTemplate.js + + + + + +src/utils/RenderTemplate.js->src/App/App.container.jsx + + + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx + +src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx + + + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx->src/App/App.container.jsx + + + + + +src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx->src/firebase/firebase.utils.js + + + + + +src/components/shop-template-add/shop-template-add.component.jsx + +src/components/shop-template-add/shop-template-add.component.jsx + + + +src/components/shop-template-add/shop-template-add.component.jsx->src/App/App.container.jsx + + + + + +src/components/shop-template-add/shop-template-add.component.jsx->src/firebase/firebase.utils.js + + + + + +src/components/shop-template-editor/shop-template-editor.component.jsx + +src/components/shop-template-editor/shop-template-editor.component.jsx + + + +src/components/shop-template-test-render/shop-template-test-render.component.jsx + +src/components/shop-template-test-render/shop-template-test-render.component.jsx + + + +src/components/shop-template-editor/shop-template-editor.component.jsx->src/components/shop-template-test-render/shop-template-test-render.component.jsx + + + + + +src/components/shop-template-test-render/shop-template-test-render.component.jsx->src/App/App.container.jsx + + + + + +src/components/shop-template-test-render/shop-template-test-render.component.jsx->src/utils/RenderTemplate.js + + + + + +src/components/shop-template-editor/shop-template-editor.container.jsx + +src/components/shop-template-editor/shop-template-editor.container.jsx + + + +src/components/shop-template-editor/shop-template-editor.container.jsx->src/components/shop-template-editor/shop-template-editor.component.jsx + + + + + +src/components/shop-templates-list/shop-templates-list.container.jsx + +src/components/shop-templates-list/shop-templates-list.container.jsx + + + +src/components/shop-templates-list/shop-templates-list.container.jsx->src/components/shop-template-add/shop-template-add.component.jsx + + + + + +src/redux/root.saga.js + +src/redux/root.saga.js + + + +src/redux/store.js->src/redux/root.saga.js + + + + + +src/pages/bills/bills.page.container.jsx + +src/pages/bills/bills.page.container.jsx + + + +src/pages/bills/bills.page.container.jsx->src/components/bill-detail-edit/bill-detail-edit.container.jsx + + + + + +src/pages/manage/manage.page.component.jsx->src/App/App.container.jsx + + + + + +src/pages/manage/manage.page.component.jsx->src/components/error-boundary/error-boundary.component.jsx + + + + + +src/pages/manage/manage.page.component.jsx->src/components/bill-enter-modal/bill-enter-modal.container.jsx + + + + + +src/pages/manage/manage.page.component.jsx->src/components/email-overlay/email-overlay.container.jsx + + + + + +src/pages/manage/manage.page.component.jsx->src/pages/bills/bills.page.container.jsx + + + + + +src/pages/shop-templates/shop-templates.container.js + +src/pages/shop-templates/shop-templates.container.js + + + +src/pages/manage/manage.page.component.jsx->src/pages/shop-templates/shop-templates.container.js + + + + + +src/pages/shop-templates/shop-templates.container.js->src/components/shop-template-editor/shop-template-editor.container.jsx + + + + + +src/pages/shop-templates/shop-templates.container.js->src/components/shop-templates-list/shop-templates-list.container.jsx + + + + + +src/redux/application/application.sagas.js + +src/redux/application/application.sagas.js + + + +src/redux/application/application.sagas.js->src/App/App.container.jsx + + + + + +src/redux/messaging/messaging.sagas.js + +src/redux/messaging/messaging.sagas.js + + + +src/redux/messaging/messaging.sagas.js->src/App/App.container.jsx + + + + + +src/redux/messaging/messaging.sagas.js->src/firebase/firebase.utils.js + + + + + +src/redux/root.saga.js->src/redux/application/application.sagas.js + + + + + +src/redux/root.saga.js->src/redux/messaging/messaging.sagas.js + + + + + +src/redux/tech/tech.sagas.js + +src/redux/tech/tech.sagas.js + + + +src/redux/root.saga.js->src/redux/tech/tech.sagas.js + + + + + +src/redux/user/user.sagas.js + +src/redux/user/user.sagas.js + + + +src/redux/root.saga.js->src/redux/user/user.sagas.js + + + + + +src/redux/tech/tech.sagas.js->src/firebase/firebase.utils.js + + + + + +src/redux/user/user.sagas.js->src/firebase/firebase.utils.js + + + + + diff --git a/client/package.json b/client/package.json index 6abf01fcd..cbf7c1f5e 100644 --- a/client/package.json +++ b/client/package.json @@ -11,11 +11,7 @@ "@tinymce/tinymce-react": "^3.7.0", "antd": "^4.6.6", "apollo-boost": "^0.4.9", - "apollo-link-context": "^1.0.20", - "apollo-link-error": "^1.1.13", "apollo-link-logger": "^2.0.0", - "apollo-link-retry": "^2.2.16", - "apollo-link-ws": "^1.0.20", "axios": "^0.20.0", "codemirror": "^5.58.1", "codemirror-graphql": "^0.12.2", @@ -45,7 +41,6 @@ "react-email-editor": "^1.1.1", "react-ga": "^3.1.2", "react-grid-gallery": "^0.5.5", - "react-grid-layout": "^1.1.1", "react-i18next": "^11.7.3", "react-icons": "^3.11.0", "react-moment": "^1.0.0", @@ -70,7 +65,8 @@ "start": "react-scripts start", "build": "REACT_APP_GIT_SHA=`git rev-parse --short HEAD` react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "madge": "madge --image ./madge-graph.svg --extensions js,jsx,ts,tsx --circular ." }, "eslintConfig": { "extends": "react-app" diff --git a/client/public/favicon.png b/client/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..d14882bea4c37d980bf9996b681c76d2ac0ce5c7 GIT binary patch literal 8881 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 HMMnM)Q(q^t literal 0 HcmV?d00001 diff --git a/client/public/index.html b/client/public/index.html index 8b3eb7a0d..f92ac3b35 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -2,7 +2,7 @@ - + - + - - + + G - - - -src/App/App.container.jsx - -src/App/App.container.jsx - - - -src/App/App.jsx - -src/App/App.jsx - - - -src/App/App.container.jsx->src/App/App.jsx - - - - - -src/firebase/firebase.utils.js - -src/firebase/firebase.utils.js - - - -src/App/App.container.jsx->src/firebase/firebase.utils.js - - - - - -src/components/error-boundary/error-boundary.component.jsx - -src/components/error-boundary/error-boundary.component.jsx - - - -src/App/App.jsx->src/components/error-boundary/error-boundary.component.jsx - - - - - -src/pages/manage/manage.page.container.jsx - -src/pages/manage/manage.page.container.jsx - - - -src/App/App.jsx->src/pages/manage/manage.page.container.jsx - - - - - -src/redux/store.js - -src/redux/store.js - - - -src/firebase/firebase.utils.js->src/redux/store.js - - - - - -src/components/error-boundary/error-boundary.component.jsx->src/firebase/firebase.utils.js - - - - - -src/pages/manage/manage.page.component.jsx - -src/pages/manage/manage.page.component.jsx - - - -src/pages/manage/manage.page.container.jsx->src/pages/manage/manage.page.component.jsx - - - - - -src/components/bill-detail-edit/bill-detail-edit.container.jsx - -src/components/bill-detail-edit/bill-detail-edit.container.jsx - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx - -src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx - - - -src/components/bill-detail-edit/bill-detail-edit.container.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx - - - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx - -src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx - - - - - -src/components/bill-enter-modal/bill-enter-modal.container.jsx - -src/components/bill-enter-modal/bill-enter-modal.container.jsx - - - -src/components/documents-upload/documents-upload.utility.js - -src/components/documents-upload/documents-upload.utility.js - - - -src/components/bill-enter-modal/bill-enter-modal.container.jsx->src/components/documents-upload/documents-upload.utility.js - - - - - -src/components/documents-upload/documents-upload.utility.js->src/App/App.container.jsx - - - - - -src/components/documents-upload/documents-upload.utility.js->src/firebase/firebase.utils.js - - - - - -src/components/email-overlay/email-overlay.container.jsx - -src/components/email-overlay/email-overlay.container.jsx - - - -src/components/email-overlay/email-overlay.container.jsx->src/firebase/firebase.utils.js - - - - - -src/utils/RenderTemplate.js - -src/utils/RenderTemplate.js - - - -src/components/email-overlay/email-overlay.container.jsx->src/utils/RenderTemplate.js - - - - - -src/utils/RenderTemplate.js->src/App/App.container.jsx - - - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx - -src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx->src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx - - - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx->src/App/App.container.jsx - - - - - -src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx->src/firebase/firebase.utils.js - - - - - -src/components/shop-template-add/shop-template-add.component.jsx - -src/components/shop-template-add/shop-template-add.component.jsx - - - -src/components/shop-template-add/shop-template-add.component.jsx->src/App/App.container.jsx - - - - - -src/components/shop-template-add/shop-template-add.component.jsx->src/firebase/firebase.utils.js - - - - - -src/components/shop-template-editor/shop-template-editor.component.jsx - -src/components/shop-template-editor/shop-template-editor.component.jsx - - - -src/components/shop-template-test-render/shop-template-test-render.component.jsx - -src/components/shop-template-test-render/shop-template-test-render.component.jsx - - - -src/components/shop-template-editor/shop-template-editor.component.jsx->src/components/shop-template-test-render/shop-template-test-render.component.jsx - - - - - -src/components/shop-template-test-render/shop-template-test-render.component.jsx->src/App/App.container.jsx - - - - - -src/components/shop-template-test-render/shop-template-test-render.component.jsx->src/utils/RenderTemplate.js - - - - - -src/components/shop-template-editor/shop-template-editor.container.jsx - -src/components/shop-template-editor/shop-template-editor.container.jsx - - - -src/components/shop-template-editor/shop-template-editor.container.jsx->src/components/shop-template-editor/shop-template-editor.component.jsx - - - - - -src/components/shop-templates-list/shop-templates-list.container.jsx - -src/components/shop-templates-list/shop-templates-list.container.jsx - - - -src/components/shop-templates-list/shop-templates-list.container.jsx->src/components/shop-template-add/shop-template-add.component.jsx - - - - - -src/redux/root.saga.js - -src/redux/root.saga.js - - - -src/redux/store.js->src/redux/root.saga.js - - - - - -src/pages/bills/bills.page.container.jsx - -src/pages/bills/bills.page.container.jsx - - - -src/pages/bills/bills.page.container.jsx->src/components/bill-detail-edit/bill-detail-edit.container.jsx - - - - - -src/pages/manage/manage.page.component.jsx->src/App/App.container.jsx - - - - - -src/pages/manage/manage.page.component.jsx->src/components/error-boundary/error-boundary.component.jsx - - - - - -src/pages/manage/manage.page.component.jsx->src/components/bill-enter-modal/bill-enter-modal.container.jsx - - - - - -src/pages/manage/manage.page.component.jsx->src/components/email-overlay/email-overlay.container.jsx - - - - - -src/pages/manage/manage.page.component.jsx->src/pages/bills/bills.page.container.jsx - - - - - -src/pages/shop-templates/shop-templates.container.js - -src/pages/shop-templates/shop-templates.container.js - - - -src/pages/manage/manage.page.component.jsx->src/pages/shop-templates/shop-templates.container.js - - - - - -src/pages/shop-templates/shop-templates.container.js->src/components/shop-template-editor/shop-template-editor.container.jsx - - - - - -src/pages/shop-templates/shop-templates.container.js->src/components/shop-templates-list/shop-templates-list.container.jsx - - - - - -src/redux/application/application.sagas.js - -src/redux/application/application.sagas.js - - - -src/redux/application/application.sagas.js->src/App/App.container.jsx - - - - - -src/redux/messaging/messaging.sagas.js - -src/redux/messaging/messaging.sagas.js - - - -src/redux/messaging/messaging.sagas.js->src/App/App.container.jsx - - - - - -src/redux/messaging/messaging.sagas.js->src/firebase/firebase.utils.js - - - - - -src/redux/root.saga.js->src/redux/application/application.sagas.js - - - - - -src/redux/root.saga.js->src/redux/messaging/messaging.sagas.js - - - - - -src/redux/tech/tech.sagas.js - -src/redux/tech/tech.sagas.js - - - -src/redux/root.saga.js->src/redux/tech/tech.sagas.js - - - - - -src/redux/user/user.sagas.js - -src/redux/user/user.sagas.js - - - -src/redux/root.saga.js->src/redux/user/user.sagas.js - - - - - -src/redux/tech/tech.sagas.js->src/firebase/firebase.utils.js - - - - - -src/redux/user/user.sagas.js->src/firebase/firebase.utils.js - - - + diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index 58199bc5a..afc980a1e 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -1,160 +1,16 @@ import { ApolloProvider } from "@apollo/react-common"; import { ConfigProvider } from "antd"; import enLocale from "antd/es/locale/en_US"; -import { ApolloLink } from "apollo-boost"; -import { InMemoryCache } from "apollo-cache-inmemory"; -import ApolloClient from "apollo-client"; -import { split } from "apollo-link"; -import { setContext } from "@apollo/client/link/context"; -import { HttpLink } from "@apollo/client/link/http"; //"apollo-link-http"; -import apolloLogger from "apollo-link-logger"; -import { RetryLink } from "@apollo/client/link/retry"; -import { WebSocketLink } from "@apollo/client/link/ws"; -import { getMainDefinition } from "apollo-utilities"; -import axios from "axios"; import LogRocket from "logrocket"; import moment from "moment"; import React from "react"; import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component"; -import { auth } from "../firebase/firebase.utils"; -import errorLink from "../graphql/apollo-error-handling"; +import client from "../utils/GraphQLClient"; import App from "./App"; - moment.locale("en-US"); -//if (process.env.NODE_ENV === "prodution") -axios.defaults.baseURL = - process.env.REACT_APP_AXIOS_BASE_API_URL || "https://api.imex.online/"; -console.log( - " process.env.REACT_APP_AXIOS_BASE_API_URL ", - process.env.REACT_APP_AXIOS_BASE_API_URL -); -export const axiosAuthInterceptorId = axios.interceptors.request.use( - async (config) => { - if (!config.headers.Authorization) { - const token = - auth.currentUser && (await auth.currentUser.getIdToken(true)); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - } - - return config; - }, - (error) => Promise.reject(error) -); - -export const cleanAxios = axios.create(); -cleanAxios.interceptors.request.eject(axiosAuthInterceptorId); - if (process.env.NODE_ENV === "production") LogRocket.init("gvfvfw/bodyshopapp"); -const httpLink = new HttpLink({ - uri: process.env.REACT_APP_GRAPHQL_ENDPOINT, -}); - -const wsLink = new WebSocketLink({ - uri: process.env.REACT_APP_GRAPHQL_ENDPOINT_WS, - options: { - lazy: true, - reconnect: true, - connectionParams: async () => { - const token = - auth.currentUser && (await auth.currentUser.getIdToken(true)); - if (token) { - return { - headers: { - authorization: token ? `Bearer ${token}` : "", - }, - }; - } - }, - }, -}); - -const subscriptionMiddleware = { - applyMiddleware: async (options, next) => { - options.authToken = - auth.currentUser && (await auth.currentUser.getIdToken(true)); - next(); - }, -}; -wsLink.subscriptionClient.use([subscriptionMiddleware]); - -const link = split( - // split based on operation type - ({ query }) => { - const definition = getMainDefinition(query); - // console.log( - // "##Intercepted GQL Transaction : " + - // definition.operation + - // "|" + - // definition.name.value + - // "##", - // query - // ); - return ( - definition.kind === "OperationDefinition" && - definition.operation === "subscription" - ); - }, - wsLink, - httpLink -); - -const authLink = setContext((_, { headers }) => { - return ( - auth.currentUser && - auth.currentUser.getIdToken().then((token) => { - if (token) { - return { - headers: { - ...headers, - authorization: token ? `Bearer ${token}` : "", - }, - }; - } else { - return { headers }; - } - }) - ); -}); - -const retryLink = new RetryLink({ - delay: { - initial: 500, - max: 5, - jitter: true, - }, - attempts: { - max: 5, - retryIf: (error, _operation) => !!error, - }, -}); - -const middlewares = []; -if (process.env.NODE_ENV === "development") { - middlewares.push(apolloLogger); -} - -middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); - -const cache = new InMemoryCache({}); - -export const client = new ApolloClient({ - link: ApolloLink.from(middlewares), - cache, - connectToDevTools: process.env.NODE_ENV !== "production", - defaultOptions: { - query: { - fetchPolicy: "network-only", - }, - watchQuery: { - fetchPolicy: "network-only", - }, - }, -}); - export default function AppContainer() { return ( diff --git a/client/src/components/documents-upload/documents-upload.utility.js b/client/src/components/documents-upload/documents-upload.utility.js index 025dfc4d1..5ae6f986f 100644 --- a/client/src/components/documents-upload/documents-upload.utility.js +++ b/client/src/components/documents-upload/documents-upload.utility.js @@ -1,7 +1,7 @@ import { notification } from "antd"; import axios from "axios"; import i18n from "i18next"; -import { axiosAuthInterceptorId, client } from "../../App/App.container"; +import client, { axiosAuthInterceptorId } from "../../utils/CleanAxios"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { INSERT_NEW_DOCUMENT } from "../../graphql/documents.queries"; //Context: currentUserEmail, bodyshop, jobid, invoiceid diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx index 62914c0e5..6fda5e113 100644 --- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx @@ -4,9 +4,9 @@ import { Button, notification, Popconfirm } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { cleanAxios } from "../../App/App.container"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { DELETE_DOCUMENT } from "../../graphql/documents.queries"; +import cleanAxios from "../../utils/CleanAxios"; //Context: currentUserEmail, bodyshop, jobid, invoiceid export default function JobsDocumentsDeleteButton({ diff --git a/client/src/components/shop-template-add/shop-template-add.component.jsx b/client/src/components/shop-template-add/shop-template-add.component.jsx index d8d021a00..47a071652 100644 --- a/client/src/components/shop-template-add/shop-template-add.component.jsx +++ b/client/src/components/shop-template-add/shop-template-add.component.jsx @@ -14,7 +14,7 @@ import { import { selectBodyshop } from "../../redux/user/user.selectors"; import { TemplateList } from "../../utils/TemplateConstants"; import { logImEXEvent } from "../../firebase/firebase.utils"; -import { client } from "../../App/App.container"; +import client from "../../utils/GraphQLClient"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser diff --git a/client/src/components/shop-template-test-render/shop-template-test-render.component.jsx b/client/src/components/shop-template-test-render/shop-template-test-render.component.jsx index 6b7ad63c4..438bc8912 100644 --- a/client/src/components/shop-template-test-render/shop-template-test-render.component.jsx +++ b/client/src/components/shop-template-test-render/shop-template-test-render.component.jsx @@ -8,7 +8,7 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import { client } from "../../App/App.container"; +import client from "../../utils/GraphQLClient"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { displayTemplateInWindowNoprint } from "../../utils/RenderTemplate"; diff --git a/client/src/firebase/firebase.utils.js b/client/src/firebase/firebase.utils.js index 6d7f4a3a4..9d4255c2e 100644 --- a/client/src/firebase/firebase.utils.js +++ b/client/src/firebase/firebase.utils.js @@ -1,10 +1,10 @@ +import "firebase/analytics"; import firebase from "firebase/app"; -import "firebase/firestore"; import "firebase/auth"; import "firebase/database"; -import "firebase/analytics"; +import "firebase/firestore"; import "firebase/messaging"; -import { store } from "../redux/store"; +//import { store } from "../redux/store"; const config = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG); firebase.initializeApp(config); @@ -48,14 +48,14 @@ try { export { messaging }; export const logImEXEvent = (eventName, additionalParams, stateProp = null) => { - const state = stateProp || store.getState(); + // const state = stateProp || store.getState(); const eventParams = { - shop: - (state.user && state.user.bodyshop && state.user.bodyshop.shopname) || - null, - user: - (state.user && state.user.currentUser && state.user.currentUser.email) || - null, + // shop: + // (state.user && state.user.bodyshop && state.user.bodyshop.shopname) || + // null, + // user: + // (state.user && state.user.currentUser && state.user.currentUser.email) || + // null, ...additionalParams, }; analytics.logEvent(eventName, eventParams); diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index 8239e793d..18ca730a1 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Route, Switch } from "react-router-dom"; import { createStructuredSelector } from "reselect"; -import { client } from "../../App/App.container"; +import client from "../../utils/GraphQLClient"; import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component"; import ChatAffixContainer from "../../components/chat-affix/chat-affix.container"; import ConflictComponent from "../../components/conflict/conflict.component"; diff --git a/client/src/redux/application/application.sagas.js b/client/src/redux/application/application.sagas.js index f90453ba9..69bd72263 100644 --- a/client/src/redux/application/application.sagas.js +++ b/client/src/redux/application/application.sagas.js @@ -1,6 +1,6 @@ import { all, takeLatest, call, put } from "redux-saga/effects"; import ApplicationActionTypes from "./application.types"; -import { client } from "../../App/App.container"; +import client from "../../utils/GraphQLClient"; import { QUERY_SCHEDULE_LOAD_DATA } from "../../graphql/appointments.queries"; import { scheduleLoadFailure, diff --git a/client/src/redux/messaging/messaging.sagas.js b/client/src/redux/messaging/messaging.sagas.js index 8d45112a6..c3db8d974 100644 --- a/client/src/redux/messaging/messaging.sagas.js +++ b/client/src/redux/messaging/messaging.sagas.js @@ -1,7 +1,7 @@ import axios from "axios"; import phone from "phone"; import { all, call, put, select, takeLatest } from "redux-saga/effects"; -import { client } from "../../App/App.container"; +import client from "../../utils/GraphQLClient"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { CONVERSATION_ID_BY_PHONE, diff --git a/client/src/utils/CleanAxios.js b/client/src/utils/CleanAxios.js new file mode 100644 index 000000000..1f7b6591a --- /dev/null +++ b/client/src/utils/CleanAxios.js @@ -0,0 +1,27 @@ +import axios from "axios"; +import { auth } from "../firebase/firebase.utils"; + +if (process.env.NODE_ENV === "prodution") { + axios.defaults.baseURL = + process.env.REACT_APP_AXIOS_BASE_API_URL || "https://api.imex.online/"; +} + +export const axiosAuthInterceptorId = axios.interceptors.request.use( + async (config) => { + if (!config.headers.Authorization) { + const token = + auth.currentUser && (await auth.currentUser.getIdToken(true)); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + } + + return config; + }, + (error) => Promise.reject(error) +); + +const cleanAxios = axios.create(); +cleanAxios.interceptors.request.eject(axiosAuthInterceptorId); + +export default cleanAxios; diff --git a/client/src/utils/GraphQLClient.js b/client/src/utils/GraphQLClient.js new file mode 100644 index 000000000..b827008ae --- /dev/null +++ b/client/src/utils/GraphQLClient.js @@ -0,0 +1,118 @@ +import { setContext } from "@apollo/client/link/context"; +import { HttpLink } from "@apollo/client/link/http"; //"apollo-link-http"; +import { RetryLink } from "@apollo/client/link/retry"; +import { WebSocketLink } from "@apollo/client/link/ws"; +import { ApolloLink } from "apollo-boost"; +import { InMemoryCache } from "apollo-cache-inmemory"; +import ApolloClient from "apollo-client"; +import { split } from "apollo-link"; +import apolloLogger from "apollo-link-logger"; +import { getMainDefinition } from "apollo-utilities"; +import { auth } from "../firebase/firebase.utils"; +import errorLink from "../graphql/apollo-error-handling"; + +const httpLink = new HttpLink({ + uri: process.env.REACT_APP_GRAPHQL_ENDPOINT, +}); + +const wsLink = new WebSocketLink({ + uri: process.env.REACT_APP_GRAPHQL_ENDPOINT_WS, + options: { + lazy: true, + reconnect: true, + connectionParams: async () => { + const token = + auth.currentUser && (await auth.currentUser.getIdToken(true)); + if (token) { + return { + headers: { + authorization: token ? `Bearer ${token}` : "", + }, + }; + } + }, + }, +}); + +const subscriptionMiddleware = { + applyMiddleware: async (options, next) => { + options.authToken = + auth.currentUser && (await auth.currentUser.getIdToken(true)); + next(); + }, +}; +wsLink.subscriptionClient.use([subscriptionMiddleware]); + +const link = split( + // split based on operation type + ({ query }) => { + const definition = getMainDefinition(query); + // console.log( + // "##Intercepted GQL Transaction : " + + // definition.operation + + // "|" + + // definition.name.value + + // "##", + // query + // ); + return ( + definition.kind === "OperationDefinition" && + definition.operation === "subscription" + ); + }, + wsLink, + httpLink +); + +const authLink = setContext((_, { headers }) => { + return ( + auth.currentUser && + auth.currentUser.getIdToken().then((token) => { + if (token) { + return { + headers: { + ...headers, + authorization: token ? `Bearer ${token}` : "", + }, + }; + } else { + return { headers }; + } + }) + ); +}); + +const retryLink = new RetryLink({ + delay: { + initial: 500, + max: 5, + jitter: true, + }, + attempts: { + max: 5, + retryIf: (error, _operation) => !!error, + }, +}); + +const middlewares = []; +if (process.env.NODE_ENV === "development") { + middlewares.push(apolloLogger); +} + +middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); + +const cache = new InMemoryCache({}); + +export default new ApolloClient({ + link: ApolloLink.from(middlewares), + cache, + connectToDevTools: process.env.NODE_ENV !== "production", + defaultOptions: { + query: { + fetchPolicy: "network-only", + }, + watchQuery: { + fetchPolicy: "network-only", + }, + }, +}); diff --git a/client/src/utils/RenderTemplate.js b/client/src/utils/RenderTemplate.js index fd64a8b0a..0f91bed13 100644 --- a/client/src/utils/RenderTemplate.js +++ b/client/src/utils/RenderTemplate.js @@ -1,7 +1,7 @@ +import axios from "axios"; import gql from "graphql-tag"; import { QUERY_TEMPLATES_BY_NAME } from "../graphql/templates.queries"; -import axios from "axios"; -import { client } from "../App/App.container"; +import client from "../utils/GraphQLClient"; export default async function RenderTemplate(templateObject, bodyshop) { const { data: templateRecords } = await client.query({ diff --git a/client/src/utils/dates.js b/client/src/utils/dates.js deleted file mode 100644 index 60d0c25ef..000000000 --- a/client/src/utils/dates.js +++ /dev/null @@ -1,170 +0,0 @@ -/* eslint no-fallthrough: off */ -import * as dates from "date-arithmetic"; - -export { - milliseconds, - seconds, - minutes, - hours, - month, - startOf, - endOf, - add, - eq, - gte, - gt, - lte, - lt, - inRange, - min, - max -} from "date-arithmetic"; - -const MILLI = { - seconds: 1000, - minutes: 1000 * 60, - hours: 1000 * 60 * 60, - day: 1000 * 60 * 60 * 24 -}; - -const MONTHS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; - -export function monthsInYear(year) { - let date = new Date(year, 0, 1); - - return MONTHS.map(i => dates.month(date, i)); -} - -export function firstVisibleDay(date, localizer) { - let firstOfMonth = dates.startOf(date, "month"); - - return dates.startOf(firstOfMonth, "week", localizer.startOfWeek()); -} - -export function lastVisibleDay(date, localizer) { - let endOfMonth = dates.endOf(date, "month"); - - return dates.endOf(endOfMonth, "week", localizer.startOfWeek()); -} - -export function visibleDays(date, localizer) { - let current = firstVisibleDay(date, localizer), - last = lastVisibleDay(date, localizer), - days = []; - - while (dates.lte(current, last, "day")) { - days.push(current); - current = dates.add(current, 1, "day"); - } - - return days; -} - -export function ceil(date, unit) { - let floor = dates.startOf(date, unit); - - return dates.eq(floor, date) ? floor : dates.add(floor, 1, unit); -} - -export function range(start, end, unit = "day") { - let current = start, - days = []; - - while (dates.lte(current, end, unit)) { - days.push(current); - current = dates.add(current, 1, unit); - } - - return days; -} - -export function merge(date, time) { - if (time == null && date == null) return null; - - if (time == null) time = new Date(); - if (date == null) date = new Date(); - - date = dates.startOf(date, "day"); - date = dates.hours(date, dates.hours(time)); - date = dates.minutes(date, dates.minutes(time)); - date = dates.seconds(date, dates.seconds(time)); - return dates.milliseconds(date, dates.milliseconds(time)); -} - -export function eqTime(dateA, dateB) { - return ( - dates.hours(dateA) === dates.hours(dateB) && - dates.minutes(dateA) === dates.minutes(dateB) && - dates.seconds(dateA) === dates.seconds(dateB) - ); -} - -export function isJustDate(date) { - return ( - dates.hours(date) === 0 && - dates.minutes(date) === 0 && - dates.seconds(date) === 0 && - dates.milliseconds(date) === 0 - ); -} - -export function duration(start, end, unit, firstOfWeek) { - if (unit === "day") unit = "date"; - return Math.abs( - dates[unit](start, undefined, firstOfWeek) - - dates[unit](end, undefined, firstOfWeek) - ); -} - -export function diff(dateA, dateB, unit) { - if (!unit || unit === "milliseconds") return Math.abs(+dateA - +dateB); - - // the .round() handles an edge case - // with DST where the total won't be exact - // since one day in the range may be shorter/longer by an hour - return Math.round( - Math.abs( - +dates.startOf(dateA, unit) / MILLI[unit] - - +dates.startOf(dateB, unit) / MILLI[unit] - ) - ); -} - -export function total(date, unit) { - let ms = date.getTime(), - div = 1; - - switch (unit) { - case "week": - div *= 7; - case "day": - div *= 24; - case "hours": - div *= 60; - case "minutes": - div *= 60; - case "seconds": - div *= 1000; - } - - return ms / div; -} - -export function week(date) { - var d = new Date(date); - d.setHours(0, 0, 0); - d.setDate(d.getDate() + 4 - (d.getDay() || 7)); - return Math.ceil(((d - new Date(d.getFullYear(), 0, 1)) / 8.64e7 + 1) / 7); -} - -export function today() { - return dates.startOf(new Date(), "day"); -} - -export function yesterday() { - return dates.add(dates.startOf(new Date(), "day"), -1, "day"); -} - -export function tomorrow() { - return dates.add(dates.startOf(new Date(), "day"), 1, "day"); -}