= {
+ title: 'Components/StashReceiver/StashReceiver',
+ component: StashReceiver,
+ tags: ['autodocs'],
+};
+
+export default meta;
+
+const StashDisplay = () => {
+ const { data, loading, error } = useStashContext();
+ if (loading) return Loading stash data...
;
+ if (error) return Error: {error}
;
+ return {JSON.stringify(data, null, 2)};
+};
+
+export const _StashReceiver: StoryObj = {
+ render: (args) => (
+
+
+
+ ),
+ args: {
+ sessionId: 'example-session-id',
+ },
+};
diff --git a/packages/stash-receiver/src/lib/StashReceiver.test.tsx b/packages/stash-receiver/src/lib/StashReceiver.test.tsx
new file mode 100644
index 000000000..14733cc9b
--- /dev/null
+++ b/packages/stash-receiver/src/lib/StashReceiver.test.tsx
@@ -0,0 +1,53 @@
+import '@testing-library/jest-dom';
+import { render, waitFor } from '@testing-library/react';
+import { http, HttpResponse } from 'msw';
+import { StashReceiver, useStashContext } from './StashReceiver';
+
+// eslint-disable-next-line @nx/enforce-module-boundaries
+import { server } from '../../../mock/src/lib/server';
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+const Consumer = () => {
+ const { data, loading, error } = useStashContext();
+ if (loading) return loading;
+ if (error) return error: {error};
+ return memberId: {String(data?.memberId)};
+};
+
+describe('StashReceiver', () => {
+ it('shows loading state initially', () => {
+ const { getByText } = render(
+
+
+
+ );
+ expect(getByText('loading')).toBeInTheDocument();
+ });
+
+ it('provides stash data to children after fetch', async () => {
+ const { getByText } = render(
+
+
+
+ );
+ await waitFor(() => expect(getByText('memberId: member-123')).toBeInTheDocument());
+ });
+
+ it('provides error state when fetch fails', async () => {
+ server.use(
+ http.get('/cloud/web/appl/stash/v1/session/data/:sessionId', () =>
+ HttpResponse.json({ message: 'Server Error' }, { status: 500 })
+ )
+ );
+
+ const { getByText } = render(
+
+
+
+ );
+ await waitFor(() => expect(getByText('error: Error fetching stash data.')).toBeInTheDocument());
+ });
+});
diff --git a/packages/stash-receiver/src/lib/StashReceiver.tsx b/packages/stash-receiver/src/lib/StashReceiver.tsx
new file mode 100644
index 000000000..e6ec2c7a7
--- /dev/null
+++ b/packages/stash-receiver/src/lib/StashReceiver.tsx
@@ -0,0 +1,56 @@
+import { createContext, useContext, useEffect, useState } from 'react';
+import axios from 'axios';
+
+export type StashData = Record;
+
+export type StashContextType = {
+ /** The data returned from the Stash API. */
+ data: StashData | undefined;
+ /** Whether the Stash API call is in progress. */
+ loading: boolean;
+ /** Error message if the Stash API call failed. */
+ error: string | undefined;
+};
+
+export type StashReceiverProps = {
+ /** The session ID used to fetch data from the Stash API. */
+ sessionId: string;
+ /** Children rendered inside the provider. */
+ children?: React.ReactNode;
+};
+
+export const STASH_API_URL = '/cloud/web/appl/stash/v1/session/data';
+
+export const INITIAL_STATE: StashContextType = {
+ data: undefined,
+ loading: true,
+ error: undefined,
+};
+
+export const StashContext = createContext(INITIAL_STATE);
+
+export const useStashContext = () => useContext(StashContext);
+
+export const StashReceiver = ({ sessionId, children }: StashReceiverProps): React.JSX.Element => {
+ const [data, setData] = useState(undefined);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(undefined);
+
+ useEffect(() => {
+ setLoading(true);
+ setError(undefined);
+ axios
+ .get(`${STASH_API_URL}/${sessionId}`)
+ .then((res) => {
+ setData(res.data);
+ })
+ .catch(() => {
+ setError('Error fetching stash data.');
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, [sessionId]);
+
+ return {children};
+};
diff --git a/packages/stash-receiver/tsconfig.json b/packages/stash-receiver/tsconfig.json
new file mode 100644
index 000000000..fcaa54641
--- /dev/null
+++ b/packages/stash-receiver/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "include": ["."],
+ "exclude": ["dist", "build", "node_modules"]
+}
diff --git a/packages/stash-receiver/tsconfig.spec.json b/packages/stash-receiver/tsconfig.spec.json
new file mode 100644
index 000000000..e4d456740
--- /dev/null
+++ b/packages/stash-receiver/tsconfig.spec.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "module": "commonjs",
+ "types": ["jest", "node", "@testing-library/jest-dom"],
+ "allowJs": true
+ },
+ "include": ["**/*.test.js", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"]
+}
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 2316500ac..9adb05c5d 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -63,6 +63,7 @@
"@availity/mui-progress": ["packages/progress/src/index.ts"],
"@availity/mui-snackbar": ["packages/snackbar/src/index.ts"],
"@availity/mui-spaces": ["packages/spaces/src/index.ts"],
+ "@availity/mui-stash-receiver": ["packages/stash-receiver/src/index.ts"],
"@availity/mui-stepper": ["packages/stepper/src/index.ts"],
"@availity/mui-table": ["packages/table/src/index.ts"],
"@availity/mui-tabs": ["packages/tabs/src/index.ts"],
diff --git a/yarn.lock b/yarn.lock
index 0bae905e7..5eeff6a4e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -128,6 +128,7 @@ __metadata:
"@availity/mui-progress": "workspace:*"
"@availity/mui-snackbar": "workspace:*"
"@availity/mui-spaces": "workspace:*"
+ "@availity/mui-stash-receiver": "workspace:*"
"@availity/mui-stepper": "workspace:*"
"@availity/mui-table": "workspace:*"
"@availity/mui-tabs": "workspace:*"
@@ -991,6 +992,23 @@ __metadata:
languageName: unknown
linkType: soft
+"@availity/mui-stash-receiver@workspace:*, @availity/mui-stash-receiver@workspace:packages/stash-receiver":
+ version: 0.0.0-use.local
+ resolution: "@availity/mui-stash-receiver@workspace:packages/stash-receiver"
+ dependencies:
+ "@mui/material": "npm:^7.3.4"
+ axios: "npm:^1.16.1"
+ react: "npm:19.2.0"
+ react-dom: "npm:19.2.0"
+ tsup: "npm:^8.4.0"
+ typescript: "npm:^5.4.5"
+ peerDependencies:
+ "@mui/material": ^7.0.0
+ axios: ">=1.0.0"
+ react: ">=17.0.0"
+ languageName: unknown
+ linkType: soft
+
"@availity/mui-stepper@workspace:*, @availity/mui-stepper@workspace:packages/stepper":
version: 0.0.0-use.local
resolution: "@availity/mui-stepper@workspace:packages/stepper"
@@ -7800,6 +7818,15 @@ __metadata:
languageName: node
linkType: hard
+"agent-base@npm:6":
+ version: 6.0.2
+ resolution: "agent-base@npm:6.0.2"
+ dependencies:
+ debug: "npm:4"
+ checksum: 10/21fb903e0917e5cb16591b4d0ef6a028a54b83ac30cd1fca58dece3d4e0990512a8723f9f83130d88a41e2af8b1f7be1386fda3ea2d181bb1a62155e75e95e23
+ languageName: node
+ linkType: hard
+
"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2":
version: 7.1.4
resolution: "agent-base@npm:7.1.4"
@@ -8304,6 +8331,18 @@ __metadata:
languageName: node
linkType: hard
+"axios@npm:^1.16.1":
+ version: 1.16.1
+ resolution: "axios@npm:1.16.1"
+ dependencies:
+ follow-redirects: "npm:^1.16.0"
+ form-data: "npm:^4.0.5"
+ https-proxy-agent: "npm:^5.0.1"
+ proxy-from-env: "npm:^2.1.0"
+ checksum: 10/9b6218cf96321cfbbf8f160658d695367114bcf4fb62492bdc1ccd647f184b5c71ae400e5ecaaf41079bc561de2ecbaf1fec63f398b3ec53389beff7694df64c
+ languageName: node
+ linkType: hard
+
"axobject-query@npm:^4.1.0":
version: 4.1.0
resolution: "axobject-query@npm:4.1.0"
@@ -11652,6 +11691,16 @@ __metadata:
languageName: node
linkType: hard
+"follow-redirects@npm:^1.16.0":
+ version: 1.16.0
+ resolution: "follow-redirects@npm:1.16.0"
+ peerDependenciesMeta:
+ debug:
+ optional: true
+ checksum: 10/3fbe3d80b3b544c22705d837aa5d4a0d07a740d913534a2620b0a004c610af4148e3b58723536dd099aaa1c9d3a155964bde9665d6e5cb331460809a1fc572fd
+ languageName: node
+ linkType: hard
+
"for-each@npm:^0.3.3, for-each@npm:^0.3.5":
version: 0.3.5
resolution: "for-each@npm:0.3.5"
@@ -11671,7 +11720,7 @@ __metadata:
languageName: node
linkType: hard
-"form-data@npm:^4.0.4":
+"form-data@npm:^4.0.4, form-data@npm:^4.0.5":
version: 4.0.5
resolution: "form-data@npm:4.0.5"
dependencies:
@@ -12485,6 +12534,16 @@ __metadata:
languageName: node
linkType: hard
+"https-proxy-agent@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "https-proxy-agent@npm:5.0.1"
+ dependencies:
+ agent-base: "npm:6"
+ debug: "npm:4"
+ checksum: 10/f0dce7bdcac5e8eaa0be3c7368bb8836ed010fb5b6349ffb412b172a203efe8f807d9a6681319105ea1b6901e1972c7b5ea899672a7b9aad58309f766dcbe0df
+ languageName: node
+ linkType: hard
+
"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6":
version: 7.0.6
resolution: "https-proxy-agent@npm:7.0.6"
@@ -17390,6 +17449,13 @@ __metadata:
languageName: node
linkType: hard
+"proxy-from-env@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "proxy-from-env@npm:2.1.0"
+ checksum: 10/fbbaf4dab2a6231dc9e394903a5f66f20475e36b734335790b46feb9da07c37d6b32e2c02e3e2ea4d4b23774c53d8562e5b7cc73282cb43f4a597b7eacaee2ee
+ languageName: node
+ linkType: hard
+
"psl@npm:^1.1.33":
version: 1.15.0
resolution: "psl@npm:1.15.0"