+
{
+ onClick={(_ev) => {
dismissedAction && dismissedAction();
resetDialog();
}}
@@ -86,7 +86,7 @@ export function ConfirmationDialog() {
{
+ onClick={(_ev) => {
confirmedAction();
resetDialog();
}}
@@ -99,7 +99,7 @@ export function ConfirmationDialog() {
{
+ onClick={(_ev) => {
dismissedAction && dismissedAction();
resetDialog();
}}
diff --git a/app/client/src/components/errorBoundary.tsx b/app/client/src/components/errorBoundary.tsx
index 19bcb4ea..74c6a378 100644
--- a/app/client/src/components/errorBoundary.tsx
+++ b/app/client/src/components/errorBoundary.tsx
@@ -1,7 +1,7 @@
import { Component, ErrorInfo, ReactNode } from "react";
// ---
-import { messages } from "../config";
-import { Message } from "components/message";
+import { messages } from "@/config";
+import { Message } from "@/components/message";
type Props = {
children: ReactNode;
@@ -16,7 +16,7 @@ export class ErrorBoundary extends Component {
hasError: false,
};
- public static getDerivedStateFromError(error: Error): State {
+ public static getDerivedStateFromError(_error: Error): State {
return { hasError: true };
}
diff --git a/app/client/src/components/loading.tsx b/app/client/src/components/loading.tsx
index 644eb251..952f9691 100644
--- a/app/client/src/components/loading.tsx
+++ b/app/client/src/components/loading.tsx
@@ -1,7 +1,7 @@
// NOTE: React JSX doesn't support namespaces, so `uswds/img/loader.svg` copied
// into app's `images/loader.svg` with namespace tags removed
-import loader from "images/loader.svg";
-import loaderWhite from "images/loader-white.svg";
+import loader from "@/images/loader.svg";
+import loaderWhite from "@/images/loader-white.svg";
export function Loading() {
return (
diff --git a/app/client/src/components/notifications.tsx b/app/client/src/components/notifications.tsx
index 4897f4e9..c37a304c 100644
--- a/app/client/src/components/notifications.tsx
+++ b/app/client/src/components/notifications.tsx
@@ -9,7 +9,7 @@ import { XMarkIcon } from "@heroicons/react/20/solid";
import {
useNotificationsState,
useNotificationsActions,
-} from "contexts/notifications";
+} from "@/contexts/notifications";
export function Notifications() {
const { displayed, type, body } = useNotificationsState();
diff --git a/app/client/src/components/providers.tsx b/app/client/src/components/providers.tsx
index 14b40f36..495e4cc6 100644
--- a/app/client/src/components/providers.tsx
+++ b/app/client/src/components/providers.tsx
@@ -2,9 +2,9 @@ import type { ReactNode } from "react";
import { Suspense, lazy, useState, useEffect } from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
// ---
-import { DialogProvider } from "contexts/dialog";
-import { NotificationsProvider } from "contexts/notifications";
-import { RebateYearProvider } from "contexts/rebateYear";
+import { DialogProvider } from "@/contexts/dialog";
+import { NotificationsProvider } from "@/contexts/notifications";
+import { RebateYearProvider } from "@/contexts/rebateYear";
declare global {
interface Window {
diff --git a/app/client/src/components/userDashboard.tsx b/app/client/src/components/userDashboard.tsx
index d69280c2..7b8132e8 100644
--- a/app/client/src/components/userDashboard.tsx
+++ b/app/client/src/components/userDashboard.tsx
@@ -1,14 +1,14 @@
import { Link, Outlet, useLocation, useNavigate } from "react-router-dom";
import { Formio } from "@formio/react";
-import premium from "@formio/premium";
+import premium from "@formio/premium/lib/index.js";
import uswds from "@formio/uswds";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrlForHrefs, formioBaseUrl, formioProjectUrl } from "../config";
-import { useConfigQuery, useBapSamQuery, useBapSamData } from "../utilities";
-import { useHelpdeskAccess } from "components/app";
-import { Loading } from "components/loading";
-import { useDialogActions } from "contexts/dialog";
+import { serverUrl, formioBaseUrl, formioProjectUrl } from "@/config";
+import { useConfigQuery, useBapSamQuery, useBapSamData } from "@/utilities";
+import { useHelpdeskAccess } from "@/components/app";
+import { Loading } from "@/components/loading";
+import { useDialogActions } from "@/contexts/dialog";
Formio.setBaseUrl(formioBaseUrl);
Formio.setProjectUrl(formioProjectUrl);
@@ -170,7 +170,7 @@ export function UserDashboard(props: { email: string }) {
diff --git a/app/client/src/config.tsx b/app/client/src/config.tsx
index 90f9a152..d439f5d8 100644
--- a/app/client/src/config.tsx
+++ b/app/client/src/config.tsx
@@ -1,50 +1,33 @@
const {
- NODE_ENV,
- REACT_APP_SERVER_BASE_PATH,
- REACT_APP_CLOUD_SPACE,
- REACT_APP_FORMIO_BASE_URL,
- REACT_APP_FORMIO_PROJECT_NAME,
-} = process.env;
+ MODE,
+ VITE_SERVER_BASE_PATH,
+ VITE_CLOUD_SPACE,
+ VITE_FORMIO_BASE_URL,
+ VITE_FORMIO_PROJECT_NAME,
+} = import.meta.env;
-if (!REACT_APP_FORMIO_BASE_URL) {
- const message = `Required REACT_APP_FORMIO_BASE_URL environment variable not found.`;
+if (!VITE_FORMIO_BASE_URL) {
+ const message = `Required VITE_FORMIO_BASE_URL environment variable not found.`;
throw new Error(message);
}
-if (!REACT_APP_FORMIO_PROJECT_NAME) {
- const message = `Required REACT_APP_FORMIO_PROJECT_NAME environment variable not found.`;
+if (!VITE_FORMIO_PROJECT_NAME) {
+ const message = `Required VITE_FORMIO_PROJECT_NAME environment variable not found.`;
throw new Error(message);
}
// allows the app to be accessed from a sub directory of a server (e.g. /csb)
export const serverBasePath =
- NODE_ENV === "development" ? "" : REACT_APP_SERVER_BASE_PATH || "";
+ MODE === "development" ? "" : VITE_SERVER_BASE_PATH || "";
-// NOTE: This app is configured to use [Create React App's proxy setup]
-// (https://create-react-app.dev/docs/proxying-api-requests-in-development/)
-//
-// For local development, the React app development server runs on port 3000,
-// and the Express app server runs on port 3001, so we've added a proxy field to
-// the client app's package.json file to proxy unknown requests from the React
-// app to the Express app (for local dev only – only works with `npm start`).
-//
-// When deployed to Cloud.gov, the React app is built and served as static files
-// from the Express app, so it's one app running from a single port so no proxy
-// is needed for production.
export const serverUrl = window.location.origin + serverBasePath;
-// NOTE: Create React App's local development proxy setup doesn't proxy requests
-// that set an "Accept" request header to "text/html", so in those cases we need
-// to explicitly use the server app's URL/port (localhost:3001)
-export const serverUrlForHrefs =
- NODE_ENV === "development" ? "http://localhost:3001" : serverUrl;
-
export const cloudSpace =
- NODE_ENV === "development" ? "dev" : REACT_APP_CLOUD_SPACE || "";
+ MODE === "development" ? "dev" : VITE_CLOUD_SPACE || "";
-export const formioBaseUrl = REACT_APP_FORMIO_BASE_URL;
+export const formioBaseUrl = VITE_FORMIO_BASE_URL;
-const formioProjectName = REACT_APP_FORMIO_PROJECT_NAME;
+const formioProjectName = VITE_FORMIO_PROJECT_NAME;
export const formioProjectUrl = `${formioBaseUrl}/${formioProjectName}`;
diff --git a/app/client/src/contexts/dialog.tsx b/app/client/src/contexts/dialog.tsx
index 369476cd..20a59ad6 100644
--- a/app/client/src/contexts/dialog.tsx
+++ b/app/client/src/contexts/dialog.tsx
@@ -1,10 +1,5 @@
-import {
- Dispatch,
- ReactNode,
- createContext,
- useContext,
- useReducer,
-} from "react";
+import type { Dispatch, ReactNode } from "react";
+import { createContext, useContext, useReducer } from "react";
type Props = {
children: ReactNode;
diff --git a/app/client/src/contexts/notifications.tsx b/app/client/src/contexts/notifications.tsx
index edbb74ee..e1853627 100644
--- a/app/client/src/contexts/notifications.tsx
+++ b/app/client/src/contexts/notifications.tsx
@@ -1,10 +1,5 @@
-import {
- Dispatch,
- ReactNode,
- createContext,
- useContext,
- useReducer,
-} from "react";
+import type { Dispatch, ReactNode } from "react";
+import { createContext, useContext, useReducer } from "react";
type Props = {
children: ReactNode;
diff --git a/app/client/src/contexts/rebateYear.tsx b/app/client/src/contexts/rebateYear.tsx
index 9d535b20..d006e014 100644
--- a/app/client/src/contexts/rebateYear.tsx
+++ b/app/client/src/contexts/rebateYear.tsx
@@ -1,10 +1,5 @@
-import {
- Dispatch,
- ReactNode,
- createContext,
- useContext,
- useReducer,
-} from "react";
+import type { Dispatch, ReactNode } from "react";
+import { createContext, useContext, useReducer } from "react";
type Props = {
children: ReactNode;
diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx
index 17ebb5cc..f6636159 100644
--- a/app/client/src/index.tsx
+++ b/app/client/src/index.tsx
@@ -1,18 +1,20 @@
import { StrictMode } from "react";
import { render } from "react-dom";
-import reportWebVitals from "./reportWebVitals";
+/*
+ NOTE: regenerator-runtime is imported to avoid a bug with a GitHub Action
+ workflow including regenerator-runtime in the build as an external dependency.
+ For reference, the GitHub Action workflow's log message stated:
+ "regenerator-runtime/runtime.js" is imported by
+ "regenerator-runtime/runtime.js?commonjs-external", but could not be
+ resolved – treating it as an external dependency.
+*/
+import "regenerator-runtime";
// ---
-import { ErrorBoundary } from "components/errorBoundary";
-import { Providers } from "components/providers";
-import { App } from "components/app";
-import "./tailwind-preflight.css";
-import "./styles.css";
-
-declare global {
- interface Window {
- csb: any;
- }
-}
+import { ErrorBoundary } from "@/components/errorBoundary";
+import { Providers } from "@/components/providers";
+import { App } from "@/components/app";
+import "@/tailwind-preflight.css";
+import "@/styles.css";
const container = document.getElementById("root") as HTMLElement;
@@ -29,8 +31,3 @@ function Index() {
}
render(
, container);
-
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
diff --git a/app/client/src/reportWebVitals.ts b/app/client/src/reportWebVitals.ts
deleted file mode 100644
index 5fa3583b..00000000
--- a/app/client/src/reportWebVitals.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { ReportHandler } from "web-vitals";
-
-const reportWebVitals = (onPerfEntry?: ReportHandler) => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry);
- getFID(onPerfEntry);
- getFCP(onPerfEntry);
- getLCP(onPerfEntry);
- getTTFB(onPerfEntry);
- });
- }
-};
-
-export default reportWebVitals;
diff --git a/app/client/src/routes/crf2022.tsx b/app/client/src/routes/crf2022.tsx
index 472c4efc..63da1ca5 100644
--- a/app/client/src/routes/crf2022.tsx
+++ b/app/client/src/routes/crf2022.tsx
@@ -7,7 +7,7 @@ import s3 from "formiojs/providers/storage/s3";
import { cloneDeep, isEqual } from "lodash";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
FormioCRF2022Submission,
getData,
@@ -19,12 +19,12 @@ import {
useSubmissions,
submissionNeedsEdits,
getUserInfo,
-} from "../utilities";
-import { Loading } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { useNotificationsActions } from "contexts/notifications";
-import { useRebateYearState } from "contexts/rebateYear";
+} from "@/utilities";
+import { Loading } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { useNotificationsActions } from "@/contexts/notifications";
+import { useRebateYearState } from "@/contexts/rebateYear";
type ServerResponse =
| {
@@ -93,7 +93,7 @@ function useFormioSubmissionQueryAndMutation(rebateId: string | undefined) {
return prevData?.submission
? { ...prevData, submission: res }
: prevData;
- }
+ },
);
},
});
@@ -242,7 +242,7 @@ function CloseOutRequestForm(props: { email: string }) {
-
{}}>
+ {}}>
@@ -299,7 +299,7 @@ function CloseOutRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -333,7 +333,7 @@ function CloseOutRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
}
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -347,7 +347,7 @@ function CloseOutRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
formIsBeingSubmitted.current = false;
},
@@ -390,7 +390,7 @@ function CloseOutRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -408,7 +408,7 @@ function CloseOutRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -418,7 +418,7 @@ function CloseOutRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
},
});
diff --git a/app/client/src/routes/frf2022.tsx b/app/client/src/routes/frf2022.tsx
index 8e41dcad..9053a539 100644
--- a/app/client/src/routes/frf2022.tsx
+++ b/app/client/src/routes/frf2022.tsx
@@ -7,7 +7,7 @@ import s3 from "formiojs/providers/storage/s3";
import { cloneDeep, isEqual } from "lodash";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
FormioFRF2022Submission,
getData,
@@ -19,13 +19,13 @@ import {
useSubmissions,
submissionNeedsEdits,
getUserInfo,
-} from "../utilities";
-import { Loading } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { useDialogActions } from "contexts/dialog";
-import { useNotificationsActions } from "contexts/notifications";
-import { useRebateYearState } from "contexts/rebateYear";
+} from "@/utilities";
+import { Loading } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { useDialogActions } from "@/contexts/dialog";
+import { useNotificationsActions } from "@/contexts/notifications";
+import { useRebateYearState } from "@/contexts/rebateYear";
type ServerResponse =
| {
@@ -98,7 +98,7 @@ function useFormioSubmissionQueryAndMutation(mongoId: string | undefined) {
return prevData?.submission
? { ...prevData, submission: res }
: prevData;
- }
+ },
);
},
});
@@ -288,10 +288,10 @@ function FundingRequestForm(props: { email: string }) {
rebateId: prf.data.hidden_bap_rebate_id,
comboKey: prf.data.bap_hidden_entity_combo_key,
})
- .then((res) => {
+ .then((_res) => {
window.location.reload();
})
- .catch((err) => {
+ .catch((_err) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -378,7 +378,7 @@ function FundingRequestForm(props: { email: string }) {
)}
-
{}}>
+ {}}>
@@ -436,7 +436,7 @@ function FundingRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -470,7 +470,7 @@ function FundingRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
}
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -484,7 +484,7 @@ function FundingRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
formIsBeingSubmitted.current = false;
},
@@ -528,7 +528,7 @@ function FundingRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -546,7 +546,7 @@ function FundingRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -556,7 +556,7 @@ function FundingRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
},
});
diff --git a/app/client/src/routes/frf2023.tsx b/app/client/src/routes/frf2023.tsx
index ef426de0..fa13aca5 100644
--- a/app/client/src/routes/frf2023.tsx
+++ b/app/client/src/routes/frf2023.tsx
@@ -7,7 +7,7 @@ import s3 from "formiojs/providers/storage/s3";
import { cloneDeep, isEqual } from "lodash";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
FormioFRF2023Submission,
getData,
@@ -19,12 +19,12 @@ import {
// useSubmissions,
// submissionNeedsEdits,
getUserInfo,
-} from "../utilities";
-import { Loading } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { useNotificationsActions } from "contexts/notifications";
-import { useRebateYearState } from "contexts/rebateYear";
+} from "@/utilities";
+import { Loading } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { useNotificationsActions } from "@/contexts/notifications";
+import { useRebateYearState } from "@/contexts/rebateYear";
type ServerResponse =
| {
@@ -89,7 +89,7 @@ function useFormioSubmissionQueryAndMutation(mongoId: string | undefined) {
return prevData?.submission
? { ...prevData, submission: res }
: prevData;
- }
+ },
);
},
});
@@ -240,7 +240,7 @@ function FundingRequestForm(props: { email: string }) {
-
{}}>
+ {}}>
@@ -293,7 +293,7 @@ function FundingRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -327,7 +327,7 @@ function FundingRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
}
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -341,7 +341,7 @@ function FundingRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
formIsBeingSubmitted.current = false;
},
@@ -381,7 +381,7 @@ function FundingRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -399,7 +399,7 @@ function FundingRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -409,7 +409,7 @@ function FundingRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
},
});
diff --git a/app/client/src/routes/frfNew.tsx b/app/client/src/routes/frfNew.tsx
index 1d46993a..3747bff3 100644
--- a/app/client/src/routes/frfNew.tsx
+++ b/app/client/src/routes/frfNew.tsx
@@ -4,7 +4,7 @@ import { Dialog, Transition } from "@headlessui/react";
import { XMarkIcon } from "@heroicons/react/24/outline";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
BapSamEntity,
FormioFRF2022Submission,
@@ -14,12 +14,12 @@ import {
useConfigData,
useBapSamData,
getUserInfo,
-} from "../utilities";
-import { Loading, LoadingButtonIcon } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { TextWithTooltip } from "components/tooltip";
-import { useRebateYearState } from "contexts/rebateYear";
+} from "@/utilities";
+import { Loading, LoadingButtonIcon } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { TextWithTooltip } from "@/components/tooltip";
+import { useRebateYearState } from "@/contexts/rebateYear";
/**
* Creates the initial FRF submission data for a given rebate year
@@ -126,7 +126,7 @@ export function FRFNew() {
navigate("/")}
+ onClose={(_value) => navigate("/")}
>
navigate("/")}
+ onClick={(_ev) => navigate("/")}
>
Close
{
+ onClick={(_ev) => {
setErrorMessage({
displayed: false,
text: "",
@@ -267,13 +267,13 @@ export function FRFNew() {
| FormioFRF2023Submission
>(
`${serverUrl}/api/formio/${rebateYear}/frf-submission/`,
- { data, state: "draft" }
+ { data, state: "draft" },
)
.then((res) => {
const url = `/frf/${rebateYear}/${res._id}`;
navigate(url);
})
- .catch((err) => {
+ .catch((_err) => {
setErrorMessage({
displayed: true,
text: "Error creating new rebate form application.",
diff --git a/app/client/src/routes/helpdesk.tsx b/app/client/src/routes/helpdesk.tsx
index ebef6e0a..1cc1cd20 100644
--- a/app/client/src/routes/helpdesk.tsx
+++ b/app/client/src/routes/helpdesk.tsx
@@ -12,7 +12,7 @@ import {
bapFRFStatusMap,
bapPRFStatusMap,
bapCRFStatusMap,
-} from "../config";
+} from "@/config";
import {
FormioFRF2022Submission,
FormioPRF2022Submission,
@@ -23,17 +23,17 @@ import {
postData,
useContentData,
submissionNeedsEdits,
-} from "../utilities";
-import { useHelpdeskAccess } from "components/app";
-import { Loading } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { TextWithTooltip } from "components/tooltip";
+} from "@/utilities";
+import { useHelpdeskAccess } from "@/components/app";
+import { Loading } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { TextWithTooltip } from "@/components/tooltip";
import {
RebateYear,
useRebateYearState,
useRebateYearActions,
-} from "contexts/rebateYear";
+} from "@/contexts/rebateYear";
type FormType = "frf" | "prf" | "crf";
@@ -161,7 +161,7 @@ export function Helpdesk() {
const query = useQuery({
queryKey: ["helpdesk"],
queryFn: () => getData(url),
- onSuccess: (res) => setResultDisplayed(true),
+ onSuccess: (_res) => setResultDisplayed(true),
enabled: false,
});
diff --git a/app/client/src/routes/prf2022.tsx b/app/client/src/routes/prf2022.tsx
index 8644cf0c..c597142b 100644
--- a/app/client/src/routes/prf2022.tsx
+++ b/app/client/src/routes/prf2022.tsx
@@ -7,7 +7,7 @@ import s3 from "formiojs/providers/storage/s3";
import { cloneDeep, isEqual } from "lodash";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
FormioPRF2022Submission,
getData,
@@ -19,12 +19,12 @@ import {
useSubmissions,
submissionNeedsEdits,
getUserInfo,
-} from "../utilities";
-import { Loading } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { useNotificationsActions } from "contexts/notifications";
-import { useRebateYearState } from "contexts/rebateYear";
+} from "@/utilities";
+import { Loading } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { useNotificationsActions } from "@/contexts/notifications";
+import { useRebateYearState } from "@/contexts/rebateYear";
type ServerResponse =
| {
@@ -93,7 +93,7 @@ function useFormioSubmissionQueryAndMutation(rebateId: string | undefined) {
return prevData?.submission
? { ...prevData, submission: res }
: prevData;
- }
+ },
);
},
});
@@ -263,7 +263,7 @@ function PaymentRequestForm(props: { email: string }) {
- {}}>
+ {}}>
@@ -326,7 +326,7 @@ function PaymentRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -361,7 +361,7 @@ function PaymentRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
}
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -375,7 +375,7 @@ function PaymentRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
formIsBeingSubmitted.current = false;
},
@@ -441,7 +441,7 @@ function PaymentRequestForm(props: { email: string }) {
pendingSubmissionData.current = data;
mutation.mutate(updatedSubmission, {
- onSuccess: (res, payload, context) => {
+ onSuccess: (res, _payload, _context) => {
pendingSubmissionData.current = {};
lastSuccesfullySubmittedData.current = cloneDeep(res.data);
@@ -459,7 +459,7 @@ function PaymentRequestForm(props: { email: string }) {
setTimeout(() => dismissNotification({ id }), 5000);
},
- onError: (error, payload, context) => {
+ onError: (_error, _payload, _context) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -469,7 +469,7 @@ function PaymentRequestForm(props: { email: string }) {
),
});
},
- onSettled: (data, error, payload, context) => {
+ onSettled: (_data, _error, _payload, _context) => {
dataIsPosting.current = false;
},
});
diff --git a/app/client/src/routes/submissions.tsx b/app/client/src/routes/submissions.tsx
index 97e20e50..b1eadba2 100644
--- a/app/client/src/routes/submissions.tsx
+++ b/app/client/src/routes/submissions.tsx
@@ -3,7 +3,7 @@ import type { LinkProps } from "react-router-dom";
import { Link, useNavigate, useOutletContext } from "react-router-dom";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrl, messages } from "../config";
+import { serverUrl, messages } from "@/config";
import {
Rebate,
postData,
@@ -14,17 +14,17 @@ import {
useSubmissions,
submissionNeedsEdits,
getUserInfo,
-} from "../utilities";
-import { Loading, LoadingButtonIcon } from "components/loading";
-import { Message } from "components/message";
-import { MarkdownContent } from "components/markdownContent";
-import { TextWithTooltip } from "components/tooltip";
-import { useNotificationsActions } from "contexts/notifications";
+} from "@/utilities";
+import { Loading, LoadingButtonIcon } from "@/components/loading";
+import { Message } from "@/components/message";
+import { MarkdownContent } from "@/components/markdownContent";
+import { TextWithTooltip } from "@/components/tooltip";
+import { useNotificationsActions } from "@/contexts/notifications";
import {
RebateYear,
useRebateYearState,
useRebateYearActions,
-} from "contexts/rebateYear";
+} from "@/contexts/rebateYear";
const defaultTableRowClassNames = "bg-gray-5";
const highlightedTableRowClassNames = "bg-primary-lighter";
@@ -419,7 +419,7 @@ function PRF2022Submission(props: {
{
+ onClick={(_ev) => {
if (!prfSubmissionPeriodOpen) return;
if (!frf.bap || !entity) return;
@@ -440,10 +440,10 @@ function PRF2022Submission(props: {
frfReviewItemId: frf.bap.reviewItemId, // CSB Rebate ID with form/version ID (9 digits)
frfFormModified: frf.bap.modified,
})
- .then((res) => {
+ .then((_res) => {
navigate(`/prf/2022/${frf.bap?.rebateId}`);
})
- .catch((err) => {
+ .catch((_err) => {
displayErrorNotification({
id: Date.now(),
body: (
@@ -654,7 +654,7 @@ function CRF2022Submission(props: {
{
+ onClick={(_ev) => {
if (!crfSubmissionPeriodOpen) return;
if (!frf.bap || !prf.bap || !entity) return;
@@ -676,10 +676,10 @@ function CRF2022Submission(props: {
prfReviewItemId: prf.bap.reviewItemId, // CSB Rebate ID with form/version ID (9 digits)
prfModified: prf.bap.modified,
})
- .then((res) => {
+ .then((_res) => {
navigate(`/crf/2022/${prf.bap?.rebateId}`);
})
- .catch((err) => {
+ .catch((_err) => {
displayErrorNotification({
id: Date.now(),
body: (
diff --git a/app/client/src/routes/welcome.tsx b/app/client/src/routes/welcome.tsx
index 67369e20..9f4f506b 100644
--- a/app/client/src/routes/welcome.tsx
+++ b/app/client/src/routes/welcome.tsx
@@ -2,8 +2,8 @@ import { useState, useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import icons from "uswds/img/sprite.svg";
// ---
-import { serverUrlForHrefs, messages } from "../config";
-import { Message } from "components/message";
+import { serverUrl, messages } from "@/config";
+import { Message } from "@/components/message";
export function Welcome() {
const [searchParams, setSearchParams] = useSearchParams();
@@ -84,7 +84,7 @@ export function Welcome() {
Sign in
diff --git a/app/client/src/setupTests.ts b/app/client/src/setupTests.ts
deleted file mode 100644
index 1dd407a6..00000000
--- a/app/client/src/setupTests.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import "@testing-library/jest-dom";
diff --git a/app/client/src/tailwind-preflight.css b/app/client/src/tailwind-preflight.css
index 95991b9e..00d6f144 100644
--- a/app/client/src/tailwind-preflight.css
+++ b/app/client/src/tailwind-preflight.css
@@ -3,17 +3,17 @@
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/
-.twpf *,
-.twpf ::before,
-.twpf ::after {
+:where(.twpf) *,
+:where(.twpf) ::before,
+:where(.twpf) ::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: currentColor; /* 2 */
}
-.twpf ::before,
-.twpf ::after {
+:where(.twpf) ::before,
+:where(.twpf) ::after {
--tw-content: "";
}
@@ -25,14 +25,26 @@
5. Use the user's configured `sans` font-feature-settings by default.
*/
-html .twpf {
+html :where(.twpf) {
line-height: 1.5; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-moz-tab-size: 4; /* 3 */
tab-size: 4; /* 3 */
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
- "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
- "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
+ font-family:
+ ui-sans-serif,
+ system-ui,
+ -apple-system,
+ BlinkMacSystemFont,
+ "Segoe UI",
+ Roboto,
+ "Helvetica Neue",
+ Arial,
+ "Noto Sans",
+ sans-serif,
+ "Apple Color Emoji",
+ "Segoe UI Emoji",
+ "Segoe UI Symbol",
+ "Noto Color Emoji"; /* 4 */
font-feature-settings: normal; /* 5 */
}
@@ -41,7 +53,7 @@ html .twpf {
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/
-body .twpf {
+body :where(.twpf) {
margin: 0; /* 1 */
line-height: inherit; /* 2 */
}
@@ -52,7 +64,7 @@ body .twpf {
3. Ensure horizontal rules are visible by default.
*/
-.twpf hr {
+:where(.twpf) hr {
height: 0; /* 1 */
color: inherit; /* 2 */
border-top-width: 1px; /* 3 */
@@ -62,7 +74,7 @@ body .twpf {
Add the correct text decoration in Chrome, Edge, and Safari.
*/
-.twpf abbr:where([title]) {
+:where(.twpf) abbr:where([title]) {
text-decoration: underline dotted;
}
@@ -70,12 +82,12 @@ Add the correct text decoration in Chrome, Edge, and Safari.
Remove the default font size and weight for headings.
*/
-.twpf h1,
-.twpf h2,
-.twpf h3,
-.twpf h4,
-.twpf h5,
-.twpf h6 {
+:where(.twpf) h1,
+:where(.twpf) h2,
+:where(.twpf) h3,
+:where(.twpf) h4,
+:where(.twpf) h5,
+:where(.twpf) h6 {
font-size: inherit;
font-weight: inherit;
}
@@ -84,7 +96,7 @@ Remove the default font size and weight for headings.
Reset links to optimize for opt-in styling instead of opt-out.
*/
-.twpf a {
+:where(.twpf) a {
color: inherit;
text-decoration: inherit;
}
@@ -93,8 +105,8 @@ Reset links to optimize for opt-in styling instead of opt-out.
Add the correct font weight in Edge and Safari.
*/
-.twpf b,
-.twpf strong {
+:where(.twpf) b,
+:where(.twpf) strong {
font-weight: bolder;
}
@@ -103,10 +115,10 @@ Add the correct font weight in Edge and Safari.
2. Correct the odd `em` font sizing in all browsers.
*/
-.twpf code,
-.twpf kbd,
-.twpf samp,
-.twpf pre {
+:where(.twpf) code,
+:where(.twpf) kbd,
+:where(.twpf) samp,
+:where(.twpf) pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace; /* 1 */
font-size: 1em; /* 2 */
@@ -116,7 +128,7 @@ Add the correct font weight in Edge and Safari.
Add the correct font size in all browsers.
*/
-.twpf small {
+:where(.twpf) small {
font-size: 80%;
}
@@ -124,19 +136,19 @@ Add the correct font size in all browsers.
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/
-.twpf sub,
-.twpf sup {
+:where(.twpf) sub,
+:where(.twpf) sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
-.twpf sub {
+:where(.twpf) sub {
bottom: -0.25em;
}
-.twpf sup {
+:where(.twpf) sup {
top: -0.5em;
}
@@ -146,7 +158,7 @@ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
3. Remove gaps between table borders by default.
*/
-.twpf table {
+:where(.twpf) table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
border-collapse: collapse; /* 3 */
@@ -158,11 +170,11 @@ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
3. Remove default padding in all browsers.
*/
-.twpf button,
-.twpf input,
-.twpf optgroup,
-.twpf select,
-.twpf textarea {
+:where(.twpf) button,
+:where(.twpf) input,
+:where(.twpf) optgroup,
+:where(.twpf) select,
+:where(.twpf) textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
font-weight: inherit; /* 1 */
@@ -175,8 +187,8 @@ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
Remove the inheritance of text transform in Edge and Firefox.
*/
-.twpf button,
-.twpf select {
+:where(.twpf) button,
+:where(.twpf) select {
text-transform: none;
}
@@ -185,10 +197,10 @@ Remove the inheritance of text transform in Edge and Firefox.
2. Remove default button styles.
*/
-.twpf button,
-.twpf [type="button"],
-.twpf [type="reset"],
-.twpf [type="submit"] {
+:where(.twpf) button,
+:where(.twpf) [type="button"],
+:where(.twpf) [type="reset"],
+:where(.twpf) [type="submit"] {
-webkit-appearance: button; /* 1 */
background-color: transparent; /* 2 */
background-image: none; /* 2 */
@@ -198,7 +210,7 @@ Remove the inheritance of text transform in Edge and Firefox.
Use the modern Firefox focus style for all focusable elements.
*/
-.twpf :-moz-focusring {
+:where(.twpf) :-moz-focusring {
outline: auto;
}
@@ -206,7 +218,7 @@ Use the modern Firefox focus style for all focusable elements.
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/
-.twpf :-moz-ui-invalid {
+:where(.twpf) :-moz-ui-invalid {
box-shadow: none;
}
@@ -214,7 +226,7 @@ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/
Add the correct vertical alignment in Chrome and Firefox.
*/
-.twpf progress {
+:where(.twpf) progress {
vertical-align: baseline;
}
@@ -222,8 +234,8 @@ Add the correct vertical alignment in Chrome and Firefox.
Correct the cursor style of increment and decrement buttons in Safari.
*/
-.twpf ::-webkit-inner-spin-button,
-.twpf ::-webkit-outer-spin-button {
+:where(.twpf) ::-webkit-inner-spin-button,
+:where(.twpf) ::-webkit-outer-spin-button {
height: auto;
}
@@ -232,7 +244,7 @@ Correct the cursor style of increment and decrement buttons in Safari.
2. Correct the outline style in Safari.
*/
-.twpf [type="search"] {
+:where(.twpf) [type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
@@ -241,7 +253,7 @@ Correct the cursor style of increment and decrement buttons in Safari.
Remove the inner padding in Chrome and Safari on macOS.
*/
-.twpf ::-webkit-search-decoration {
+:where(.twpf) ::-webkit-search-decoration {
-webkit-appearance: none;
}
@@ -250,7 +262,7 @@ Remove the inner padding in Chrome and Safari on macOS.
2. Change font properties to `inherit` in Safari.
*/
-.twpf ::-webkit-file-upload-button {
+:where(.twpf) ::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
@@ -259,7 +271,7 @@ Remove the inner padding in Chrome and Safari on macOS.
Add the correct display in Chrome and Safari.
*/
-.twpf summary {
+:where(.twpf) summary {
display: list-item;
}
@@ -267,34 +279,34 @@ Add the correct display in Chrome and Safari.
Removes the default spacing and border for appropriate elements.
*/
-.twpf blockquote,
-.twpf dl,
-.twpf dd,
-.twpf h1,
-.twpf h2,
-.twpf h3,
-.twpf h4,
-.twpf h5,
-.twpf h6,
-.twpf hr,
-.twpf figure,
-.twpf p,
-.twpf pre {
+:where(.twpf) blockquote,
+:where(.twpf) dl,
+:where(.twpf) dd,
+:where(.twpf) h1,
+:where(.twpf) h2,
+:where(.twpf) h3,
+:where(.twpf) h4,
+:where(.twpf) h5,
+:where(.twpf) h6,
+:where(.twpf) hr,
+:where(.twpf) figure,
+:where(.twpf) p,
+:where(.twpf) pre {
margin: 0;
}
-.twpf fieldset {
+:where(.twpf) fieldset {
margin: 0;
padding: 0;
}
-.twpf legend {
+:where(.twpf) legend {
padding: 0;
}
-.twpf ol,
-.twpf ul,
-.twpf menu {
+:where(.twpf) ol,
+:where(.twpf) ul,
+:where(.twpf) menu {
list-style: none;
margin: 0;
padding: 0;
@@ -304,7 +316,7 @@ Removes the default spacing and border for appropriate elements.
Prevent resizing textareas horizontally by default.
*/
-.twpf textarea {
+:where(.twpf) textarea {
resize: vertical;
}
@@ -313,8 +325,8 @@ Prevent resizing textareas horizontally by default.
2. Set the default placeholder color to the user's configured gray 400 color.
*/
-.twpf input::placeholder,
-.twpf textarea::placeholder {
+:where(.twpf) input::placeholder,
+:where(.twpf) textarea::placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
@@ -323,15 +335,15 @@ Prevent resizing textareas horizontally by default.
Set the default cursor for buttons.
*/
-.twpf button,
-.twpf [role="button"] {
+:where(.twpf) button,
+:where(.twpf) [role="button"] {
cursor: pointer;
}
/*
Make sure disabled buttons don't get the pointer cursor.
*/
-.twpf :disabled {
+:where(.twpf) :disabled {
cursor: default;
}
@@ -341,14 +353,14 @@ Make sure disabled buttons don't get the pointer cursor.
This can trigger a poorly considered lint error in some tools but is included by design.
*/
-.twpf img,
-.twpf svg,
-.twpf video,
-.twpf canvas,
-.twpf audio,
-.twpf iframe,
-.twpf embed,
-.twpf object {
+:where(.twpf) img,
+:where(.twpf) svg,
+:where(.twpf) video,
+:where(.twpf) canvas,
+:where(.twpf) audio,
+:where(.twpf) iframe,
+:where(.twpf) embed,
+:where(.twpf) object {
display: block; /* 1 */
vertical-align: middle; /* 2 */
}
@@ -357,13 +369,13 @@ Make sure disabled buttons don't get the pointer cursor.
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/
-.twpf img,
-.twpf video {
+:where(.twpf) img,
+:where(.twpf) video {
max-width: 100%;
height: auto;
}
/* Make elements with the HTML hidden attribute stay hidden by default */
-.twpf [hidden] {
+:where(.twpf) [hidden] {
display: none;
}
diff --git a/app/client/src/utilities.ts b/app/client/src/utilities.ts
index e4b5aa83..966c4aef 100644
--- a/app/client/src/utilities.ts
+++ b/app/client/src/utilities.ts
@@ -2,7 +2,7 @@ import { useEffect } from "react";
import { useQueryClient, useQuery, useQueries } from "@tanstack/react-query";
import { useSearchParams } from "react-router-dom";
// ---
-import { serverUrl, serverUrlForHrefs } from "./config";
+import { serverUrl } from "@/config";
type RebateYear = "2022" | "2023";
@@ -326,11 +326,11 @@ export function useBapSamQuery() {
queryFn: () => getData(`${serverUrl}/api/bap/sam`),
onSuccess: (res) => {
if (!res.results) {
- window.location.href = `${serverUrlForHrefs}/logout?RelayState=/welcome?info=bap-sam-results`;
+ window.location.href = `${serverUrl}/logout?RelayState=/welcome?info=bap-sam-results`;
}
},
- onError: (err) => {
- window.location.href = `${serverUrlForHrefs}/logout?RelayState=/welcome?error=bap-sam-fetch`;
+ onError: (_err) => {
+ window.location.href = `${serverUrl}/logout?RelayState=/welcome?error=bap-sam-fetch`;
},
refetchOnWindowFocus: false,
});
@@ -368,7 +368,7 @@ export function useSubmissionsQueries(rebateYear: RebateYear) {
frfs: [] as BapFormSubmission[],
prfs: [] as BapFormSubmission[],
crfs: [] as BapFormSubmission[],
- }
+ },
);
return Promise.resolve(submissions);
diff --git a/app/client/src/react-app-env.d.ts b/app/client/src/vite-env.d.ts
similarity index 66%
rename from app/client/src/react-app-env.d.ts
rename to app/client/src/vite-env.d.ts
index 3281ec0a..61098606 100644
--- a/app/client/src/react-app-env.d.ts
+++ b/app/client/src/vite-env.d.ts
@@ -1,4 +1,4 @@
-///
+///
declare module "formiojs/providers/storage/s3";
declare module "@formio/react";
diff --git a/app/client/tsconfig.json b/app/client/tsconfig.json
index 5452a6dc..439469d5 100644
--- a/app/client/tsconfig.json
+++ b/app/client/tsconfig.json
@@ -1,21 +1,29 @@
{
"compilerOptions": {
- "target": "es5",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
"skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noFallthroughCasesInSwitch": true,
- "module": "esnext",
- "moduleResolution": "node",
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
- "baseUrl": "src"
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+
+ "paths": {
+ "@/*": ["./src/*"]
+ }
},
- "include": ["src"]
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/app/client/tsconfig.node.json b/app/client/tsconfig.node.json
new file mode 100644
index 00000000..42872c59
--- /dev/null
+++ b/app/client/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/app/client/vite.config.ts b/app/client/vite.config.ts
new file mode 100644
index 00000000..690110a3
--- /dev/null
+++ b/app/client/vite.config.ts
@@ -0,0 +1,57 @@
+import path from "node:path";
+import { defineConfig, loadEnv } from "vite";
+import react from "@vitejs/plugin-react-swc";
+
+// https://vitejs.dev/config/
+export default ({ mode }) => {
+ process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
+
+ const { VITE_SERVER_BASE_PATH } = process.env;
+
+ // allows the app to be accessed from a sub directory of a server (e.g. /csb)
+ const serverBasePath =
+ mode === "development" ? "" : VITE_SERVER_BASE_PATH || "";
+
+ return defineConfig({
+ base: serverBasePath,
+ build: {
+ outDir: "build",
+ sourcemap: true,
+ rollupOptions: {
+ output: {
+ entryFileNames: "static/js/[name]-[hash].js",
+ chunkFileNames: "static/js/[name]-[hash].js",
+ assetFileNames: (chunkInfo) => {
+ const extension = [...chunkInfo.name.split(".")].pop();
+ const directory = /\.(css)$/.test(chunkInfo.name)
+ ? "static/css"
+ : /\.(woff|woff2|eot|ttf|otf)$/.test(chunkInfo.name)
+ ? "static/fonts"
+ : /\.(png|jpe?g|gif|svg|webp|webm|mp3)$/.test(chunkInfo.name)
+ ? "static/media"
+ : "static";
+ return `${directory}/[name]-[hash].${extension}`;
+ },
+ },
+ },
+ },
+ define: {
+ "process.env": {},
+ },
+ plugins: [react()],
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ },
+ },
+ server: {
+ open: true,
+ port: 3000,
+ proxy: {
+ "/api": "http://localhost:3001",
+ "/login": "http://localhost:3001",
+ "/logout": "http://localhost:3001",
+ },
+ },
+ });
+};
diff --git a/app/package.json b/app/package.json
index faafd125..710b5587 100644
--- a/app/package.json
+++ b/app/package.json
@@ -17,7 +17,7 @@
"prettier-plugin-tailwindcss": "0.5.4"
},
"scripts": {
- "client": "cd client && npm run start",
+ "client": "cd client && npm run dev",
"server": "cd server && npm start",
"start": "concurrently -kc \"blue.dim,green.dim\" \"npm:server\" \"npm:client\""
},