diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 59d6eb294b3c..aa6b51940694 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -155,6 +155,7 @@ src/applications/static-pages/health-care-manage-benefits/view-test-and-lab-resu
src/applications/facility-locator @department-of-veterans-affairs/vfs-facilities-frontend @department-of-veterans-affairs/va-platform-cop-frontend
src/applications/static-pages/facilities @department-of-veterans-affairs/vfs-facilities-frontend @department-of-veterans-affairs/va-platform-cop-frontend
src/applications/static-pages/tests/facilities @department-of-veterans-affairs/vfs-facilities-frontend @department-of-veterans-affairs/va-platform-cop-frontend
+src/applications/static-pages/situation-updates-banner @department-of-veterans-affairs/vfs-facilities-frontend @department-of-veterans-affairs/va-platform-cop-frontend
# Caregiver
diff --git a/script/watch.js b/script/watch.js
index aee70cf27a21..d2a854d53787 100644
--- a/script/watch.js
+++ b/script/watch.js
@@ -2,7 +2,7 @@ const argv = require('minimist')(process.argv.slice(2));
const printBuildHelp = require('./build-help');
const { runCommand } = require('./utils');
-// Preset memory options 1gb -> 8gb
+// Preset memory options 1gb -> 12gb
const memoryOptions = [1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 12288];
// Caching the input memory arg
diff --git a/src/applications/static-pages/situation-updates-banner/createSituationUpdatesBanner.jsx b/src/applications/static-pages/situation-updates-banner/createSituationUpdatesBanner.jsx
new file mode 100644
index 000000000000..326c302b9e3c
--- /dev/null
+++ b/src/applications/static-pages/situation-updates-banner/createSituationUpdatesBanner.jsx
@@ -0,0 +1,54 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { Provider } from 'react-redux';
+import { useFeatureToggle } from '~/platform/utilities/feature-toggles';
+import SituationUpdateBanner from './situationUpdateBanner';
+
+export const BannerContainer = () => {
+ const {
+ TOGGLE_NAMES,
+ useToggleValue,
+ useToggleLoadingValue,
+ } = useFeatureToggle();
+
+ const alternativeBannersEnabled = useToggleValue(
+ TOGGLE_NAMES.bannerUseAlternativeBanners,
+ );
+ const isLoadingFeatureFlags = useToggleLoadingValue();
+
+ if (isLoadingFeatureFlags || !alternativeBannersEnabled) {
+ return null;
+ }
+
+ const defaultProps = {
+ id: '1',
+ bundle: 'situation-updates',
+ headline: 'Situation update',
+ alertType: 'warning',
+ content:
+ "We're having issues at this location. Please avoid this facility until further notice.",
+ context: 'global',
+ showClose: true,
+ operatingStatusCTA: false,
+ emailUpdatesButton: false,
+ findFacilitiesCTA: false,
+ limitSubpageInheritance: false,
+ };
+
+ return ;
+};
+
+export default async function createSituationUpdatesBanner(store, widgetType) {
+ const bannerWidget = document.querySelector(
+ `[data-widget-type="${widgetType}"]`,
+ );
+
+ if (bannerWidget) {
+ ReactDOM.render(
+
+
+ ,
+ bannerWidget,
+ );
+ }
+}
diff --git a/src/applications/static-pages/situation-updates-banner/situationUpdateBanner.jsx b/src/applications/static-pages/situation-updates-banner/situationUpdateBanner.jsx
new file mode 100644
index 000000000000..e1dd008d86d0
--- /dev/null
+++ b/src/applications/static-pages/situation-updates-banner/situationUpdateBanner.jsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default function SituationUpdateBanner({
+ id,
+ alertType,
+ headline,
+ showClose,
+ content,
+}) {
+ return (
+
+ {content}
+
+ );
+}
+
+SituationUpdateBanner.propTypes = {
+ alertType: PropTypes.string.isRequired,
+ content: PropTypes.node.isRequired,
+ headline: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
+ showClose: PropTypes.bool,
+};
diff --git a/src/applications/static-pages/situation-updates-banner/tests/createSituationUpdatesBanner.unit.spec.js b/src/applications/static-pages/situation-updates-banner/tests/createSituationUpdatesBanner.unit.spec.js
new file mode 100644
index 000000000000..7723cb5a2548
--- /dev/null
+++ b/src/applications/static-pages/situation-updates-banner/tests/createSituationUpdatesBanner.unit.spec.js
@@ -0,0 +1,75 @@
+import { expect } from 'chai';
+import sinon from 'sinon';
+import ReactDOM from 'react-dom';
+import { Provider } from 'react-redux';
+
+import createSituationUpdatesBanner, {
+ BannerContainer,
+} from '../createSituationUpdatesBanner';
+import widgetTypes from '../../widgetTypes';
+
+describe('createSituationUpdatesBanner', () => {
+ let sandbox;
+ let store;
+ let widgetContainer;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ store = {
+ getState: () => ({
+ featureToggles: {
+ loading: false,
+ bannerUseAlternativeBanners: true,
+ },
+ }),
+ subscribe: () => {},
+ dispatch: sinon.spy(),
+ };
+
+ widgetContainer = document.createElement('div');
+ widgetContainer.setAttribute(
+ 'data-widget-type',
+ widgetTypes.SITUATION_UPDATES_BANNER,
+ );
+ document.body.appendChild(widgetContainer);
+
+ sandbox.stub(ReactDOM, 'render');
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ if (widgetContainer && widgetContainer.parentNode) {
+ widgetContainer.parentNode.removeChild(widgetContainer);
+ }
+ });
+
+ it('should not render banner when widget container is not found', async () => {
+ document.body.removeChild(widgetContainer);
+ await createSituationUpdatesBanner(
+ store,
+ widgetTypes.SITUATION_UPDATES_BANNER,
+ );
+ expect(ReactDOM.render.called).to.be.false;
+ });
+
+ it('should render banner with default props when widget container exists', async () => {
+ await createSituationUpdatesBanner(
+ store,
+ widgetTypes.SITUATION_UPDATES_BANNER,
+ );
+
+ expect(ReactDOM.render.calledOnce).to.be.true;
+
+ const renderCall = ReactDOM.render.getCall(0);
+ const [element, container] = renderCall.args;
+
+ expect(container).to.equal(widgetContainer);
+
+ // Check if rendered element is wrapped in Provider
+ expect(element.type).to.equal(Provider);
+
+ // Check if SituationUpdateBanner is rendered with correct props
+ const situationBanner = element.props.children;
+ expect(situationBanner.type).to.equal(BannerContainer);
+ });
+});
diff --git a/src/applications/static-pages/static-pages-entry.js b/src/applications/static-pages/static-pages-entry.js
index 4b1c2ff24c75..244d4cd1c494 100644
--- a/src/applications/static-pages/static-pages-entry.js
+++ b/src/applications/static-pages/static-pages-entry.js
@@ -64,6 +64,7 @@ import createPost911GiBillStatusWidget, {
post911GIBillStatusReducer,
} from '../post-911-gib-status/createPost911GiBillStatusWidget';
import createResourcesAndSupportSearchWidget from './widget-creators/resources-and-support-search';
+import createSituationUpdatesBanner from './situation-updates-banner/createSituationUpdatesBanner';
import createThirdPartyApps, {
thirdPartyAppsReducer,
} from '../third-party-app-directory/createThirdPartyApps';
@@ -200,6 +201,7 @@ createScheduleViewVAAppointmentsPage(
widgetTypes.SCHEDULE_VIEW_VA_APPOINTMENTS_PAGE,
);
createSecureMessagingPage(store, widgetTypes.SECURE_MESSAGING_PAGE);
+createSituationUpdatesBanner(store, widgetTypes.SITUATION_UPDATES_BANNER);
createViewTestAndLabResultsPage(
store,
widgetTypes.VIEW_TEST_AND_LAB_RESULTS_PAGE,
diff --git a/src/applications/static-pages/widgetTypes.js b/src/applications/static-pages/widgetTypes.js
index 287c49be0c58..c128249c0661 100644
--- a/src/applications/static-pages/widgetTypes.js
+++ b/src/applications/static-pages/widgetTypes.js
@@ -74,6 +74,7 @@ export default {
SCO_EVENTS: 'sco-events',
SECURE_MESSAGING_PAGE: 'secure-messaging-page',
SIDE_NAV: 'side-nav',
+ SITUATION_UPDATES_BANNER: 'situation-updates-banner',
SUPPLEMENTAL_CLAIM: 'supplemental_claim',
THIRD_PARTY_APP_DIRECTORY: 'third-party-app-directory',
VET_CENTER_HOURS: 'vet-center-hours',
diff --git a/src/platform/utilities/feature-toggles/featureFlagNames.json b/src/platform/utilities/feature-toggles/featureFlagNames.json
index 1c039ec255b4..2599a906133c 100644
--- a/src/platform/utilities/feature-toggles/featureFlagNames.json
+++ b/src/platform/utilities/feature-toggles/featureFlagNames.json
@@ -7,6 +7,7 @@
"askVaIntroductionPageFeature": "ask_va_introduction_page_feature",
"authExpVbaDowntimeMessage": "auth_exp_vba_downtime_message",
"avsEnabled": "avs_enabled",
+ "bannerUseAlternativeBanners": "banner_use_alternative_banners",
"bcasLettersUseLighthouse": "bcas_letters_use_lighthouse",
"benefitsDocumentsUseLighthouse": "benefits_documents_use_lighthouse",
"burialFormEnabled": "burial_form_enabled",