diff --git a/src/app/_components/StatusBar/index.tsx b/src/app/_components/StatusBar/index.tsx
index 225ae7616..ae113cef2 100644
--- a/src/app/_components/StatusBar/index.tsx
+++ b/src/app/_components/StatusBar/index.tsx
@@ -2,6 +2,8 @@ import { QueryErrorResetBoundary } from '@tanstack/react-query';
import dynamic from 'next/dynamic';
import { ErrorBoundary } from 'react-error-boundary';
+import { FlexProps } from '../../../ui/Flex';
+
const renderLoadingComponent = () => null;
const renderErrorComponent = () => null;
@@ -13,7 +15,7 @@ const IncidentsStatusBar = dynamic(
}
);
-export const IncidentsStatusBarWithErrorBoundary = () => (
+export const IncidentsStatusBarWithErrorBoundary = (props: FlexProps) => (
{({ reset }) => (
(
}}
onReset={reset}
>
-
+
)}
diff --git a/src/app/_components/StatusBar/status-bar-slice.ts b/src/app/_components/StatusBar/status-bar-slice.ts
deleted file mode 100644
index 08e816967..000000000
--- a/src/app/_components/StatusBar/status-bar-slice.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { PayloadAction, createSelector, createSlice } from '@reduxjs/toolkit';
-
-import { RootState } from '../../../common/state/store';
-
-export interface StatusBarState {
- isStatusBarActive: boolean;
- statusBarHeight: number;
-}
-
-export const initialState: StatusBarState = {
- isStatusBarActive: false,
- statusBarHeight: 0,
-};
-
-export const statusBarSlice = createSlice({
- name: 'statusbar',
- initialState,
- reducers: {
- setStatusBar: (state, action: PayloadAction
) => {
- state.isStatusBarActive = action.payload;
- },
- setStatusBarHeight: (state, action: PayloadAction) => {
- state.statusBarHeight = action.payload;
- },
- },
-});
-
-export const { setStatusBar, setStatusBarHeight } = statusBarSlice.actions;
-
-const selectStatusBar = (state: RootState) => state.statusBar;
-
-export const selectIsStatusBarActive = createSelector(
- [selectStatusBar],
- statusBar => statusBar.isStatusBarActive
-);
-export const selectStatusBarHeight = createSelector(
- [selectStatusBar],
- statusBar => statusBar.statusBarHeight
-);
diff --git a/src/app/_components/StatusBar/utils.ts b/src/app/_components/StatusBar/utils.ts
index 304f5ac84..cf4b52a4d 100644
--- a/src/app/_components/StatusBar/utils.ts
+++ b/src/app/_components/StatusBar/utils.ts
@@ -1,14 +1,14 @@
import { IncidentImpact } from 'statuspage.io';
-export const getColor = (incidentImpact: IncidentImpact) => {
+export const getColor = (incidentImpact: IncidentImpact, colorMode: string) => {
switch (incidentImpact) {
case IncidentImpact.Critical:
- return 'red.600';
+ return 'red.500';
case IncidentImpact.Major:
- return 'orange.600';
+ return 'red.500';
case IncidentImpact.Minor:
- return 'green.600';
+ return colorMode === 'light' ? 'orange.600' : 'orange.500';
+ default:
+ return colorMode === 'light' ? 'purple.600' : 'purple.400';
}
-
- return 'slate.850';
};
diff --git a/src/app/getStatusBarContent.ts b/src/app/getStatusBarContent.ts
new file mode 100644
index 000000000..a062d780b
--- /dev/null
+++ b/src/app/getStatusBarContent.ts
@@ -0,0 +1,8 @@
+import { CMS_URL } from '../common/constants/env';
+import { IncidentContent } from '../common/types/incidents';
+
+export async function getStatusBarContent(): Promise {
+ return fetch(CMS_URL, {
+ next: { revalidate: 60 }, // Revalidate every 1 minute
+ }).then(res => res.json());
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index a869d30e4..144fa0cef 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -13,6 +13,7 @@ import {
import { AppContextProvider } from '../common/context/GlobalContext';
import { PageWrapper } from './_components/PageWrapper';
import { Providers } from './_components/Providers';
+import { getStatusBarContent } from './getStatusBarContent';
import { getTokenPrice } from './getTokenPriceInfo';
import './global.css';
@@ -23,6 +24,7 @@ export async function generateMetadata(): Promise {
export default async function RootLayout({ children }: { children: ReactNode }) {
const headersList = headers();
const tokenPrice = await getTokenPrice();
+ const statusBarContent = await getStatusBarContent();
return (
@@ -34,7 +36,9 @@ export default async function RootLayout({ children }: { children: ReactNode })
btcAddressBaseUrls={NetworkModeBtcAddressBaseUrlMap} // TODO: why does this need to be in context? remove. make a function that returns these. network should be in redux not context
>
- {children}
+
+ {children}
+
diff --git a/src/common/constants/env.ts b/src/common/constants/env.ts
index e352c4dfd..833486f18 100644
--- a/src/common/constants/env.ts
+++ b/src/common/constants/env.ts
@@ -25,7 +25,7 @@ export const RELEASE_TAG_NAME =
export const REDIS_URL = process.env.REDIS_URL || '';
export const LUNAR_CRUSH_API_KEY = process.env.LUNAR_CRUSH_API_KEY || '';
export const NODE_ENV = process.env.NODE_ENV || '';
-
+export const CMS_URL = process.env.CMS_URL ?? process.env.CMS_URL ?? '';
export const HIRO_HEADERS: HeadersInit = {
'x-api-key': X_API_KEY,
'x-hiro-product': 'explorer',
diff --git a/src/common/state/store.ts b/src/common/state/store.ts
index 5fdf489a9..99c1fc5ba 100644
--- a/src/common/state/store.ts
+++ b/src/common/state/store.ts
@@ -2,7 +2,6 @@
import { combineReducers, configureStore } from '@reduxjs/toolkit';
-import { StatusBarState, statusBarSlice } from '../../app/_components/StatusBar/status-bar-slice';
import { ConnectState, sandboxSlice } from '../../app/sandbox/sandbox-slice';
import { SearchState, searchSlice } from '../../features/search/search-slice';
import {
@@ -21,7 +20,6 @@ const rootReducer = combineReducers({
connect: sandboxSlice.reducer,
...filterAndSortReducers,
activeTransactionValueFilter: activeTransactionValueFilterSlice.reducer,
- statusBar: statusBarSlice.reducer,
});
export const makeStore = () =>
@@ -44,7 +42,6 @@ export interface RootState extends TxFilters {
search: SearchState;
connect: ConnectState;
activeTransactionValueFilter: TransactionValueFilterState;
- statusBar: StatusBarState;
}
export type AppDispatch = ReturnType['dispatch'];
diff --git a/src/common/types/incidents.ts b/src/common/types/incidents.ts
new file mode 100644
index 000000000..261957b67
--- /dev/null
+++ b/src/common/types/incidents.ts
@@ -0,0 +1,16 @@
+import { Document } from '@contentful/rich-text-types';
+import { ContentfulCollection } from 'contentful';
+import { ContentTypeSys } from 'contentful/dist/types/types/content-type';
+import { IncidentImpact } from 'statuspage.io';
+
+interface ContentType {
+ sys: ContentTypeSys;
+ fields: {
+ content: Document;
+ impact: IncidentImpact;
+ showOnMainnet: boolean;
+ showOnTestnet: boolean;
+ };
+}
+
+export type IncidentContent = ContentfulCollection;
diff --git a/src/common/utils/getRichTextRenderOptions.tsx b/src/common/utils/getRichTextRenderOptions.tsx
new file mode 100644
index 000000000..a95fe35d2
--- /dev/null
+++ b/src/common/utils/getRichTextRenderOptions.tsx
@@ -0,0 +1,43 @@
+import { Options } from '@contentful/rich-text-react-renderer';
+import { BLOCKS, Block, INLINES, Inline, MARKS } from '@contentful/rich-text-types';
+import { ReactNode } from 'react';
+
+import { ListItem } from '../../ui/ListItem';
+import { Text } from '../../ui/Text';
+import { TextLink } from '../../ui/TextLink';
+import { UnorderedList } from '../../ui/UnorderedList';
+
+export const getRichTextRenderOptions = (origin: string): Options => ({
+ renderMark: {
+ [MARKS.BOLD]: text => (
+
+ {text}
+
+ ),
+ },
+ renderNode: {
+ [BLOCKS.PARAGRAPH]: (node: Block | Inline, children: ReactNode) => (
+ {children}
+ ),
+ [BLOCKS.UL_LIST]: (node: Block | Inline, children: ReactNode) => (
+
+ {children}
+
+ ),
+ [BLOCKS.LIST_ITEM]: (node: Block | Inline, children: ReactNode) => (
+ {children}
+ ),
+ [INLINES.HYPERLINK]: ({ data }: Block | Inline, children: ReactNode) => (
+
+ {children}
+
+ ),
+ },
+});
diff --git a/src/common/utils/test-utils/renderWithReduxProvider.tsx b/src/common/utils/test-utils/renderWithReduxProvider.tsx
index f3c8fc2c6..b826c1a68 100644
--- a/src/common/utils/test-utils/renderWithReduxProvider.tsx
+++ b/src/common/utils/test-utils/renderWithReduxProvider.tsx
@@ -5,10 +5,6 @@ import { render } from '@testing-library/react';
import React, { PropsWithChildren } from 'react';
import { Provider } from 'react-redux';
-import {
- statusBarSlice,
- initialState as statusBarSliceInitialState,
-} from '../../../app/_components/StatusBar/status-bar-slice';
import {
sandboxSlice,
initialState as sandboxSliceInitialState,
@@ -50,7 +46,6 @@ export function renderWithReduxProviders(
(acc, filterType) => ({ ...acc, [filterType]: filterSliceInitialState }),
{} as TxFilters
),
- statusBar: statusBarSliceInitialState,
},
store = configureStore({
reducer: {
@@ -58,7 +53,6 @@ export function renderWithReduxProviders(
search: searchSlice.reducer,
connect: sandboxSlice.reducer,
activeTransactionValueFilter: activeTransactionValueFilterSlice.reducer,
- statusBar: statusBarSlice.reducer,
...filterAndSortReducers,
},
preloadedState,