diff --git a/src/components/pages/__tests__/__snapshots__/developer-home.tsx.snap b/src/components/pages/__tests__/__snapshots__/developer-home.tsx.snap
index 315d230d36..b1f19c350f 100644
--- a/src/components/pages/__tests__/__snapshots__/developer-home.tsx.snap
+++ b/src/components/pages/__tests__/__snapshots__/developer-home.tsx.snap
@@ -65,6 +65,9 @@ exports[`DeveloperHome should match a snapshot 1`] = `
}
title="My Apps"
/>
+
@@ -139,6 +142,9 @@ exports[`DeveloperHome should match a snapshot 3`] = `
}
title="My Apps"
/>
+
diff --git a/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap b/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap
index 34a89ad4cd..4df85ced6f 100644
--- a/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap
+++ b/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap
@@ -15,6 +15,9 @@ exports[`Swagger should match a snapshot 1`] = `
url="undefined/prod/swaggerdocs"
/>
+
`;
diff --git a/src/components/pages/developer-home.tsx b/src/components/pages/developer-home.tsx
index 721964cf87..0efa47de4e 100644
--- a/src/components/pages/developer-home.tsx
+++ b/src/components/pages/developer-home.tsx
@@ -13,6 +13,7 @@ import DeveloperAppModal from '../ui/developer-app-modal'
import { setDeveloperAppModalStateViewDetail, developerAppShowModal } from '@/actions/developer-app-modal'
import { appDeleteSetInitFormState } from '@/actions/app-delete'
import { AppSummaryModel } from '@reapit/foundations-ts-definitions'
+import { SandboxPopUp } from '../ui/sandbox-pop-up'
export interface DeveloperMappedActions {
fetchAppDetail: (id: string) => void
@@ -96,6 +97,7 @@ export const DeveloperHome: React.FunctionComponent = ({
onChange: handleOnChange(history)
}}
/>
+
{
return {
@@ -33,6 +34,7 @@ export const SwaggerPage: React.SFC = () => {
requestInterceptor={fetchInterceptor}
/>
+
)
diff --git a/src/components/ui/__tests__/__snapshots__/sandbox-pop-up.tsx.snap b/src/components/ui/__tests__/__snapshots__/sandbox-pop-up.tsx.snap
new file mode 100644
index 0000000000..29d91df25f
--- /dev/null
+++ b/src/components/ui/__tests__/__snapshots__/sandbox-pop-up.tsx.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SandboxPopUp should match snapshot with default 1`] = `
+
+
+
+`;
+
+exports[`SandboxPopUp should match snapshot with passed props 1`] = `
+
+
+
+`;
diff --git a/src/components/ui/__tests__/sandbox-pop-up.tsx b/src/components/ui/__tests__/sandbox-pop-up.tsx
new file mode 100644
index 0000000000..c45563487f
--- /dev/null
+++ b/src/components/ui/__tests__/sandbox-pop-up.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react'
+import { shallow } from 'enzyme'
+import { popUp, SandboxPopUp, HALF_SECOND } from '../sandbox-pop-up'
+
+const setOpen = jest.fn()
+jest.useFakeTimers()
+describe('popUp', () => {
+ afterEach(() => {
+ jest.clearAllMocks()
+ jest.clearAllTimers()
+ })
+ it('should call setTimeout if loading = false', () => {
+ const fn = popUp(setOpen, false)
+ fn()
+ expect(setTimeout).toHaveBeenCalledTimes(1)
+ expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), HALF_SECOND)
+ })
+ it('should not call setTimeout if loading = true', () => {
+ const fn = popUp(setOpen, true)
+ fn()
+ expect(setTimeout).not.toHaveBeenCalled()
+ })
+})
+
+describe('SandboxPopUp', () => {
+ it('should match snapshot with default', () => {
+ expect(shallow()).toMatchSnapshot()
+ })
+ it('should match snapshot with passed props', () => {
+ expect(shallow()).toMatchSnapshot()
+ })
+})
diff --git a/src/components/ui/sandbox-pop-up.tsx b/src/components/ui/sandbox-pop-up.tsx
new file mode 100644
index 0000000000..c615189d36
--- /dev/null
+++ b/src/components/ui/sandbox-pop-up.tsx
@@ -0,0 +1,26 @@
+import * as React from 'react'
+import { ToastMessage } from '@reapit/elements'
+import styles from '@/styles/blocks/sandbox-pop-up.scss?mod'
+
+export const HALF_SECOND = 500
+
+export const popUp = (setOpen, loading) => () => {
+ if (!loading) setTimeout(setOpen, HALF_SECOND)
+}
+
+export const SandboxPopUp = ({
+ loading = false,
+ message = 'Data in the dev portal APIs is sandbox and is regularly refreshed. You should not use these feeds for production apps, they are for development purposes only.'
+}) => {
+ const [isOpen, setIsOpen] = React.useState(false)
+ const setOpen = React.useCallback(setIsOpen.bind(null, true), [setIsOpen])
+ const setClose = React.useCallback(setIsOpen.bind(null, false), [setIsOpen])
+
+ React.useEffect(popUp(setOpen, loading), [loading])
+
+ return (
+
+
+
+ )
+}
diff --git a/src/styles/blocks/sandbox-pop-up.scss b/src/styles/blocks/sandbox-pop-up.scss
new file mode 100644
index 0000000000..69adabc23e
--- /dev/null
+++ b/src/styles/blocks/sandbox-pop-up.scss
@@ -0,0 +1,6 @@
+.wrap-pop-up {
+ transform: translateX(-2rem);
+ width: 100vw;
+ position: fixed;
+ bottom: 0;
+}