@campxdev/campx-web-utils 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env ADDED
@@ -0,0 +1,2 @@
1
+ REACT_APP_API_HOST=https://api.campx.dev
2
+ PORT=3082
@@ -0,0 +1,25 @@
1
+ const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
2
+
3
+ const path = require("path");
4
+ const deps = require("./package.json").dependencies;
5
+ const { getLoader, loaderByName } = require("@craco/craco");
6
+ const packages = [];
7
+ packages.push(path.dirname(require.resolve("@campxdev/react-blueprint")));
8
+ module.exports = {
9
+ webpack: {
10
+ configure: (webpackConfig) => {
11
+ const { isFound, match } = getLoader(
12
+ webpackConfig,
13
+ loaderByName("babel-loader")
14
+ );
15
+ if (isFound) {
16
+ const include = Array.isArray(match.loader.include)
17
+ ? match.loader.include
18
+ : [match.loader.include];
19
+ match.loader.include = include.concat(packages);
20
+ }
21
+
22
+ return webpackConfig;
23
+ },
24
+ },
25
+ };
package/exports.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./src/config/axios";
2
+ export * from "./src/ErrorBoundary/export";
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@campxdev/campx-web-utils",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "main": "./exports.ts",
5
5
  "private": false,
6
6
  "dependencies": {
7
- "@campxdev/react-blueprint": "^0.1.41",
7
+ "@campxdev/react-blueprint": "^1.0.6",
8
+ "@mui/x-date-pickers": "^7.11.0",
8
9
  "@testing-library/jest-dom": "^5.14.1",
9
10
  "@testing-library/react": "^13.0.0",
10
11
  "@testing-library/user-event": "^13.2.1",
11
- "react-toastify": "^9.0.1",
12
12
  "@types/jest": "^27.0.1",
13
13
  "@types/node": "^16.7.13",
14
14
  "@types/react": "^18.0.0",
@@ -18,17 +18,32 @@
18
18
  "pullstate": "^1.25.0",
19
19
  "react": "^18.3.1",
20
20
  "react-dom": "^18.3.1",
21
+ "react-query": "^3.39.3",
21
22
  "react-scripts": "5.0.1",
23
+ "react-toastify": "^9.0.1",
22
24
  "typescript": "^4.4.2",
23
25
  "web-vitals": "^2.1.0"
24
26
  },
25
27
  "devDependencies": {
26
- "@types/js-cookie": "^3.0.2"
28
+ "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
29
+ "@craco/craco": "^7.1.0",
30
+ "@types/babel__core": "^7.20.5",
31
+ "@types/babel__generator": "^7.6.8",
32
+ "@types/babel__template": "^7.4.4",
33
+ "@types/babel__traverse": "^7.20.6",
34
+ "@types/bonjour": "^3.5.13",
35
+ "@types/js-cookie": "^3.0.2",
36
+ "@types/lodash": "^4.17.5",
37
+ "@types/prettier": "^3.0.0",
38
+ "@types/react": "^18.3.3",
39
+ "@types/react-dom": "^18.3.0",
40
+ "@types/react-query": "^1.2.9",
41
+ "@types/react-router-dom": "^5.3.3"
27
42
  },
28
43
  "scripts": {
29
- "start": "react-scripts start",
30
- "build": "react-scripts build",
31
- "test": "react-scripts test",
44
+ "start": "craco start",
45
+ "build": "craco build",
46
+ "test": "craco test",
32
47
  "eject": "react-scripts eject"
33
48
  },
34
49
  "eslintConfig": {
package/src/App.tsx CHANGED
@@ -1,26 +1,15 @@
1
- import React from 'react';
2
- import logo from './logo.svg';
3
- import './App.css';
1
+ import { useRoutes } from "react-router-dom";
2
+ import Providers from "./context/Providers";
3
+ import { mainRoutes } from "./Pages/main";
4
4
 
5
- function App() {
5
+ export default function App() {
6
6
  return (
7
- <div className="App">
8
- <header className="App-header">
9
- <img src={logo} className="App-logo" alt="logo" />
10
- <p>
11
- Edit <code>src/App.tsx</code> and save to reload.
12
- </p>
13
- <a
14
- className="App-link"
15
- href="https://reactjs.org"
16
- target="_blank"
17
- rel="noopener noreferrer"
18
- >
19
- Learn React
20
- </a>
21
- </header>
22
- </div>
7
+ <Providers>
8
+ <AppRouter />
9
+ </Providers>
23
10
  );
24
11
  }
25
-
26
- export default App;
12
+ const AppRouter = () => {
13
+ const app = useRoutes(mainRoutes);
14
+ return app;
15
+ };
@@ -0,0 +1,29 @@
1
+ import { useQuery } from "react-query";
2
+ import { axios } from "./config/axios";
3
+
4
+ const fetchClubRequests = () => {
5
+ return axios.get(`/square/clubs`).then((res) => res.data);
6
+ };
7
+
8
+ function AppContent() {
9
+ const {
10
+ data: requests,
11
+ isLoading,
12
+ error,
13
+ refetch,
14
+ } = useQuery("club-requests", () => fetchClubRequests());
15
+
16
+ if (isLoading) {
17
+ return <div>Loading...</div>;
18
+ }
19
+
20
+ // if (error) {
21
+ // // No need to handle the error locally, it will be caught by ErrorBoundary
22
+ // console.error("Error fetching club requests:", error);
23
+ // throw error; // Re-throw the error to be caught by the ErrorBoundary
24
+ // }
25
+
26
+ return <></>;
27
+ }
28
+
29
+ export default AppContent;
@@ -0,0 +1,104 @@
1
+ import { PageNotFound } from "@campxdev/react-blueprint";
2
+ import { InternalServerError } from "@campxdev/react-blueprint/src/components/Assets/ErrorPages/InternalServerError";
3
+ import { NoInterneConnection } from "@campxdev/react-blueprint/src/components/Assets/ErrorPages/NoInternetConnection";
4
+ import { UnAuthorized } from "@campxdev/react-blueprint/src/components/Assets/ErrorPages/UnAuthorized";
5
+ import { Typography } from "@campxdev/react-blueprint/src/components/DataDisplay/Typography/Typography";
6
+ import { Button } from "@campxdev/react-blueprint/src/components/Input/Button/Button";
7
+ import Cookies from "js-cookie";
8
+ import { ReactNode } from "react";
9
+ import { ErrorBoundary as ReactErrorBoundary } from "react-error-boundary";
10
+ import { QueryErrorResetBoundary } from "react-query";
11
+ import { useLocation, useNavigate } from "react-router-dom";
12
+ import { axios } from "../config/axios";
13
+
14
+ export type ErrorBoundaryProps = {
15
+ children: ReactNode;
16
+ resetKey?: string;
17
+ };
18
+
19
+ export const ErrorBoundary = (props: ErrorBoundaryProps) => {
20
+ const location = useLocation();
21
+ console.log(location?.pathname, "kkk");
22
+ return (
23
+ <QueryErrorResetBoundary>
24
+ {({ reset }) => (
25
+ <ReactErrorBoundary
26
+ key={location?.pathname}
27
+ onReset={reset}
28
+ FallbackComponent={ErrorFallback}
29
+ >
30
+ {props.children}
31
+ </ReactErrorBoundary>
32
+ )}
33
+ </QueryErrorResetBoundary>
34
+ );
35
+ };
36
+
37
+ export const ErrorFallback = ({ error, resetErrorBoundary }: any) => {
38
+ if (error?.response?.status) {
39
+ console.log(error?.response?.status);
40
+ switch (error?.response?.status) {
41
+ case 401:
42
+ return <UnAuth resetErrorBoundary={resetErrorBoundary} />;
43
+
44
+ case 500:
45
+ return <InternalServerError resetBoundary={resetErrorBoundary} />;
46
+
47
+ case 404:
48
+ return <PageNotFound resetErrorBoundary={resetErrorBoundary} />;
49
+
50
+ default:
51
+ return <InternalServerError resetBoundary={resetErrorBoundary} />;
52
+ }
53
+ }
54
+
55
+ if (error?.message === "Network Error") {
56
+ return <NoInterneConnection resetBoundary={resetErrorBoundary} />;
57
+ }
58
+
59
+ return (
60
+ <>
61
+ <Typography>
62
+ {error?.response?.data?.message ?? error?.message}
63
+ </Typography>
64
+ </>
65
+ );
66
+ };
67
+
68
+ const UnAuth = ({ resetBoundary }: any) => {
69
+ const navigate = useNavigate();
70
+
71
+ const sessionCookie = Cookies.get("campx_session_key");
72
+
73
+ const appinit = async () => {
74
+ await axios.get("/auth/my-permissions").catch((e: any) => {
75
+ navigate("/auth/login");
76
+ });
77
+ };
78
+
79
+ const handleLoginClick = () => {
80
+ if (!sessionCookie) {
81
+ navigate("/auth/login");
82
+ } else {
83
+ appinit();
84
+ }
85
+ };
86
+
87
+ return (
88
+ <UnAuthorized
89
+ component={
90
+ <>
91
+ <Button
92
+ sx={{
93
+ marginTop: "20px",
94
+ }}
95
+ variant="contained"
96
+ onClick={handleLoginClick}
97
+ >
98
+ Click Here To Login
99
+ </Button>
100
+ </>
101
+ }
102
+ />
103
+ );
104
+ };
@@ -0,0 +1,13 @@
1
+ import { LinearProgress } from "@mui/material";
2
+ import { Store } from "pullstate";
3
+
4
+ export const NetworkStore = new Store({
5
+ loading: false,
6
+ });
7
+
8
+ export default function GlobalNetworkLoadingIndicator() {
9
+ const { loading } = NetworkStore.useState();
10
+
11
+ if (loading) return <LinearProgress />;
12
+ if (loading) return null;
13
+ }
@@ -0,0 +1 @@
1
+ export * from "./ErrorBoundary";
@@ -0,0 +1,14 @@
1
+ import { Outlet } from "react-router-dom";
2
+ import { ErrorBoundary } from "../ErrorBoundary/export";
3
+
4
+ const AppLayout = () => {
5
+ return (
6
+ <>
7
+ <ErrorBoundary>
8
+ <Outlet />
9
+ </ErrorBoundary>
10
+ </>
11
+ );
12
+ };
13
+
14
+ export default AppLayout;
@@ -0,0 +1,20 @@
1
+ import { Navigate } from "react-router-dom";
2
+ import AppContent from "../AppContent";
3
+ import AppLayout from "../Layout/AppLayout";
4
+
5
+ export const mainRoutes = [
6
+ {
7
+ path: "/",
8
+ element: <AppLayout />,
9
+ children: [
10
+ {
11
+ index: true,
12
+ element: <Navigate to={"app-content"} />,
13
+ },
14
+ {
15
+ path: "app-content",
16
+ element: <AppContent />,
17
+ },
18
+ ],
19
+ },
20
+ ];
@@ -1,18 +1,13 @@
1
1
  import Axios, { InternalAxiosRequestConfig } from "axios";
2
2
  import Cookies from "js-cookie";
3
- import { toast } from "react-toastify";
4
- // import { NetworkStore } from "../components/ErrorBoundary/GlobalNetworkLoadingIndicator";
5
3
 
6
4
  const isDevelopment = process.env.NODE_ENV == "development";
7
5
 
8
- const sessionKey = Cookies.get("campx_session_key");
9
6
  const tenantCode = isDevelopment
10
7
  ? Cookies.get("campx_tenant")
11
8
  : window.location.hostname.split(".")[0];
12
9
  const institutionCode = window.location.pathname.split("/")[1];
13
10
 
14
- const openPaymentsKey = Cookies.get("campx_open_payments_key");
15
-
16
11
  export const formatParams = (params: any) => {
17
12
  return Object.fromEntries(
18
13
  Object.entries(params ?? {})?.map((i) => [
@@ -22,58 +17,45 @@ export const formatParams = (params: any) => {
22
17
  );
23
18
  };
24
19
 
25
- let axios = Axios.create({
20
+ export const axios = Axios.create({
26
21
  baseURL: process.env.REACT_APP_API_HOST,
27
22
  withCredentials: true,
28
23
  headers: {
29
24
  "x-tenant-id": tenantCode,
30
25
  "x-institution-code": institutionCode,
31
- campx_session_key: sessionKey,
32
- ...(openPaymentsKey && {
33
- campx_open_payments_key: openPaymentsKey,
34
- }),
35
26
  },
36
27
  });
37
28
 
38
29
  axios.interceptors.request.use(
39
30
  function (config: InternalAxiosRequestConfig) {
40
31
  const params = formatParams(config?.params);
41
- // NetworkStore.update((s) => {
42
- // s.loading = true;
43
- // });
44
- return { ...config, params };
32
+
33
+ const sessionKey = Cookies.get("campx_session_key");
34
+ const openPaymentsKey = Cookies.get("campx_open_payments_key");
35
+
36
+ if (isDevelopment && sessionKey) {
37
+ config.headers.set("campx_session_key", sessionKey);
38
+ }
39
+
40
+ if (openPaymentsKey) {
41
+ config.headers.set("campx_open_payments_key", openPaymentsKey);
42
+ }
43
+
44
+ return {
45
+ ...config,
46
+ params,
47
+ };
45
48
  },
46
49
  function (error) {
47
- // NetworkStore.update((s) => {
48
- // s.loading = false;
49
- // });
50
50
  return Promise.reject(error);
51
51
  }
52
52
  );
53
53
 
54
54
  axios.interceptors.response.use(
55
55
  function (response) {
56
- // NetworkStore.update((s) => {
57
- // s.loading = false;
58
- // });
59
56
  return response;
60
57
  },
61
58
  function (err) {
62
- // NetworkStore.update((s) => {
63
- // s.loading = false;
64
- // });
65
59
  return Promise.reject(err);
66
60
  }
67
61
  );
68
-
69
- export default axios;
70
-
71
- export const axiosErrorToast = (error: any, fallback?: string) => {
72
- const fallbackMessage = fallback ?? "Something went wrong.";
73
- const errorMessage =
74
- typeof error?.response?.data?.message !== "string"
75
- ? error?.response?.data?.message?.join("\n") ?? fallbackMessage
76
- : error?.response?.data?.message;
77
-
78
- return toast.error(errorMessage);
79
- };
@@ -0,0 +1,26 @@
1
+ import { MuiThemeProvider } from "@campxdev/react-blueprint";
2
+ import { ReactNode } from "react";
3
+ import { QueryClient, QueryClientProvider } from "react-query";
4
+ import { BrowserRouter } from "react-router-dom";
5
+
6
+ export const queryClient = new QueryClient({
7
+ defaultOptions: {
8
+ queries: {
9
+ refetchOnWindowFocus: false,
10
+ retry: false,
11
+ useErrorBoundary: true,
12
+ },
13
+ },
14
+ });
15
+
16
+ export default function Providers({ children }: { children: ReactNode }) {
17
+ var baseName = "/";
18
+
19
+ return (
20
+ <BrowserRouter basename={baseName}>
21
+ <QueryClientProvider client={queryClient}>
22
+ <MuiThemeProvider>{children}</MuiThemeProvider>
23
+ </QueryClientProvider>
24
+ </BrowserRouter>
25
+ );
26
+ }
package/tsconfig.json CHANGED
@@ -21,6 +21,10 @@
21
21
  "jsx": "react-jsx"
22
22
  },
23
23
  "include": [
24
- "src"
24
+ "src",
25
+ "./types"
26
+ ],
27
+ "exclude": [
28
+ "node_modules"
25
29
  ]
26
30
  }
@@ -0,0 +1,58 @@
1
+ import "@mui/material/styles";
2
+
3
+ declare module "@mui/material/styles" {
4
+ interface Theme {
5
+ palette: {
6
+ [x: string]: any;
7
+ primary: {
8
+ dark: string;
9
+ main: string;
10
+ light: string;
11
+ };
12
+ secondary: {
13
+ main: string;
14
+ light: string;
15
+ dark: string;
16
+ };
17
+ tertiary: {
18
+ main: string;
19
+ };
20
+ text: {
21
+ primary: string;
22
+ secondary: string;
23
+ tertiary: string;
24
+ };
25
+ surface: {
26
+ defaultBackground: string;
27
+ paperBackground: string;
28
+ grey: string;
29
+ };
30
+ border: {
31
+ primary: string;
32
+ };
33
+ highlight: {
34
+ highlightGreen: string;
35
+ highlightOrange: string;
36
+ highlightBlue: string;
37
+ highlightRed: string;
38
+ highlightPink: string;
39
+ highlightYellow: string;
40
+ greenBackground: string;
41
+ orangeBackground: string;
42
+ blueBackground: string;
43
+ redBackground: string;
44
+ pinkBackground: string;
45
+ yellowBackground: string;
46
+ };
47
+ };
48
+ }
49
+ export function createTheme(options?: CustomThemeOptions): CustomTheme;
50
+ }
51
+
52
+ declare module "@mui/material/Typography" {
53
+ interface TypographyPropsVariantOverrides {
54
+ label1: true;
55
+ label2: true;
56
+ subtitle3: true;
57
+ }
58
+ }
package/src/App.test.tsx DELETED
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import App from './App';
4
-
5
- test('renders learn react link', () => {
6
- render(<App />);
7
- const linkElement = screen.getByText(/learn react/i);
8
- expect(linkElement).toBeInTheDocument();
9
- });