Browse Source

Simplify tokenomics module to allow easier implementation of new tokenomics groups, fix typo in GenericWorkingGroupProposalForm

Edvin 3 years ago
parent
commit
84e8dcf2bd

+ 1 - 1
pioneer/packages/joy-proposals/src/forms/GenericWorkingGroupProposalForm.tsx

@@ -46,7 +46,7 @@ export type FormInnerProps = ProposalFormInnerProps<FormContainerProps, FormValu
 const availableGroupsOptions = Object.keys(WorkingGroupDef)
   .filter((wgKey) => wgKey !== 'Gateway') // Gateway group not yet supported!
   .map((wgKey) => {
-    let text = wgKey + 'Working Group';
+    let text = `${wgKey} Working Group`;
 
     if (wgKey.toLowerCase().includes('operations')) {
       const workingGroupType = wgKey.slice('operations'.length);

+ 62 - 162
pioneer/packages/joy-tokenomics/src/Overview/SpendingAndStakeDistributionTable.tsx

@@ -5,7 +5,7 @@ import { useWindowDimensions } from '../../../joy-utils/src/react/hooks';
 
 import { TokenomicsData, StatusServerData } from '@polkadot/joy-utils/src/types/tokenomics';
 
-import { COLORS } from './index';
+import { NON_WORKING_GROUPS, WORKING_GROUPS } from '../tokenomicsGroupsData';
 
 const round = (num: number): number => Math.round((num + Number.EPSILON) * 100) / 100;
 
@@ -121,34 +121,25 @@ const SpendingAndStakeTableRow: React.FC<{
   );
 };
 
-const WORKING_GROUPS = ['storageProviders', 'contentCurators', 'operationsAlpha', 'operationsBeta', 'operationsGamma'] as const;
-
-type TokenomicsGroup =
-  'validators' |
-  'council' |
-  typeof WORKING_GROUPS[number]
+type TokenomicsGroup = typeof WORKING_GROUPS[number]['groupType'] | typeof NON_WORKING_GROUPS[number]['groupType'];
 
 const SpendingAndStakeDistributionTable: React.FC<{data?: TokenomicsData; statusData?: StatusServerData | null}> = ({ data, statusData }) => {
   const { width } = useWindowDimensions();
 
   const displayStatusData = (group: TokenomicsGroup, dataType: 'rewardsPerWeek' | 'totalStake', lead = false): string | undefined => {
-    if ((WORKING_GROUPS.includes(group as any)) && lead) {
+    if (WORKING_GROUPS.map(({ groupType }) => groupType).includes(group as any) && lead) {
       return statusData === null
         ? 'Data currently unavailable...'
-        : (data && statusData) && `${(data[group as typeof WORKING_GROUPS[number]].lead[dataType] * Number(statusData.price)).toFixed(2)}`;
+        : data &&
+            statusData &&
+            `${(
+              data[group as typeof WORKING_GROUPS[number]['groupType']].lead[dataType] * Number(statusData.price)
+            ).toFixed(2)}`;
     } else {
       return statusData === null
         ? 'Data currently unavailable...'
-        : (data && statusData) && `${(data[group][dataType] * Number(statusData.price)).toFixed(2)}`;
-    }
-  };
-
-  const renderOperationsHelpText = (groupName: string, isLead?: boolean) => {
-    if (isLead) {
-      return `Current ${groupName} Lead, and their projected reward and stake.`;
+        : data && statusData && `${(data[group][dataType] * Number(statusData.price)).toFixed(2)}`;
     }
-
-    return `The current ${groupName} members, and the sum of their projected rewards and stakes.`;
   };
 
   return (
@@ -168,150 +159,59 @@ const SpendingAndStakeDistributionTable: React.FC<{data?: TokenomicsData; status
       </Table.Header>
 
       <Table.Body>
-        <SpendingAndStakeTableRow
-          role={width <= 1050 ? 'Validators' : 'Validators (Nominators)'}
-          helpContent='The current set of active Validators (and Nominators), and the sum of the sets projected rewards and total stakes (including Nominators).'
-          numberOfActors={data && `${data.validators.number} (${data.validators.nominators.number})`}
-          groupEarning={data && `${Math.round(data.validators.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('validators', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.validators.rewardsShare * 100)}`}
-          groupStake={data && `${data.validators.totalStake}`}
-          groupStakeDollar={displayStatusData('validators', 'totalStake')}
-          stakeShare={data && `${round(data.validators.stakeShare * 100)}`}
-          color={COLORS.VALIDATOR}
-        />
-        <SpendingAndStakeTableRow
-          role={width <= 1015 ? 'Council' : 'Council Members'}
-          helpContent='The current Council Members, and the sum of their projected rewards and total stakes (including voters/backers).'
-          numberOfActors={data && `${data.council.number}`}
-          groupEarning={data && `${Math.round(data.council.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('council', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.council.rewardsShare * 100)}`}
-          groupStake={data && `${data.council.totalStake}`}
-          groupStakeDollar={displayStatusData('council', 'totalStake')}
-          stakeShare={data && `${round(data.council.stakeShare * 100)}`}
-          color={COLORS.COUNCIL_MEMBER}
-        />
-        <SpendingAndStakeTableRow
-          role={width <= 1015 ? 'Storage' : 'Storage Providers'}
-          helpContent='The current Storage Providers, and the sum of their projected rewards and stakes.'
-          numberOfActors={data && `${data.storageProviders.number}`}
-          groupEarning={data && `${Math.round(data.storageProviders.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('storageProviders', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.storageProviders.rewardsShare * 100)}`}
-          groupStake={data && `${data.storageProviders.totalStake}`}
-          groupStakeDollar={displayStatusData('storageProviders', 'totalStake')}
-          stakeShare={data && `${round(data.storageProviders.stakeShare * 100)}`}
-          color={COLORS.STORAGE_PROVIDER}
-        />
-        <SpendingAndStakeTableRow
-          role={width <= 1015 ? 'S. Lead' : width <= 1050 ? 'Storage Lead' : 'Storage Provider Lead'}
-          helpContent='Current Storage Provider Lead, and their projected reward and stake.'
-          numberOfActors={data && `${data.storageProviders.lead.number}`}
-          groupEarning={data && `${Math.round(data.storageProviders.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('storageProviders', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.storageProviders.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.storageProviders.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('storageProviders', 'totalStake', true)}
-          stakeShare={data && `${round(data.storageProviders.lead.stakeShare * 100)}`}
-          color={COLORS.STORAGE_LEAD}
-        />
-        <SpendingAndStakeTableRow
-          role={width <= 1015 ? 'Curators' : 'Content Curators'}
-          helpContent='The current Content Curators, and the sum of their projected rewards and stakes.'
-          numberOfActors={data && `${data.contentCurators.number}`}
-          groupEarning={data && `${Math.round(data.contentCurators.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('contentCurators', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.contentCurators.rewardsShare * 100)}`}
-          groupStake={data && `${data.contentCurators.totalStake}`}
-          groupStakeDollar={displayStatusData('contentCurators', 'totalStake')}
-          stakeShare={data && `${round(data.contentCurators.stakeShare * 100)}`}
-          color={COLORS.CONTENT_CURATOR}
-        />
-        <SpendingAndStakeTableRow
-          role={width <= 1015 ? 'C. Lead' : 'Curators Lead'}
-          helpContent='Current Content Curators Lead, and their projected reward and stake.'
-          numberOfActors={data && `${data.contentCurators.lead.number}`}
-          groupEarning={data && `${Math.round(data.contentCurators.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('contentCurators', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.contentCurators.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.contentCurators.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('contentCurators', 'totalStake', true)}
-          stakeShare={data && `${round(data.contentCurators.lead.stakeShare * 100)}`}
-          color={COLORS.CURATOR_LEAD}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Alpha'
-          helpContent={renderOperationsHelpText('Operations Group Alpha')}
-          numberOfActors={data && `${data.operationsAlpha.number}`}
-          groupEarning={data && `${Math.round(data.operationsAlpha.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsAlpha', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.operationsAlpha.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsAlpha.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsAlpha', 'totalStake')}
-          stakeShare={data && `${round(data.operationsAlpha.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_ALPHA}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Alpha Lead'
-          helpContent={renderOperationsHelpText('Operations Group Alpha', true)}
-          numberOfActors={data && `${data.operationsAlpha.lead.number}`}
-          groupEarning={data && `${Math.round(data.operationsAlpha.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsAlpha', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.operationsAlpha.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsAlpha.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsAlpha', 'totalStake', true)}
-          stakeShare={data && `${round(data.operationsAlpha.lead.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_ALPHA_LEAD}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Beta'
-          helpContent={renderOperationsHelpText('Operations Group Beta')}
-          numberOfActors={data && `${data.operationsBeta.number}`}
-          groupEarning={data && `${Math.round(data.operationsBeta.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsBeta', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.operationsBeta.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsBeta.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsBeta', 'totalStake')}
-          stakeShare={data && `${round(data.operationsBeta.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_BETA}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Beta Lead'
-          helpContent={renderOperationsHelpText('Operations Group Beta', true)}
-          numberOfActors={data && `${data.operationsBeta.lead.number}`}
-          groupEarning={data && `${Math.round(data.operationsBeta.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsBeta', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.operationsBeta.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsBeta.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsBeta', 'totalStake', true)}
-          stakeShare={data && `${round(data.operationsBeta.lead.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_BETA_LEAD}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Gamma'
-          helpContent={renderOperationsHelpText('Operations Group Gamma')}
-          numberOfActors={data && `${data.operationsGamma.number}`}
-          groupEarning={data && `${Math.round(data.operationsGamma.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsGamma', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.operationsGamma.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsGamma.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsGamma', 'totalStake')}
-          stakeShare={data && `${round(data.operationsGamma.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_GAMMA}
-        />
-        <SpendingAndStakeTableRow
-          role='Operations Gamma Lead'
-          helpContent={renderOperationsHelpText('Operations Group Gamma', true)}
-          numberOfActors={data && `${data.operationsGamma.lead.number}`}
-          groupEarning={data && `${Math.round(data.operationsGamma.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operationsGamma', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.operationsGamma.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.operationsGamma.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('operationsGamma', 'totalStake', true)}
-          stakeShare={data && `${round(data.operationsGamma.lead.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_GAMMA_LEAD}
-        />
+        {NON_WORKING_GROUPS.map(({ groupType, titleCutoff, shortTitle, title, helpText, color }) => {
+          let numberOfActors = data && `${data[groupType].number}`;
+
+          if (groupType === 'validators' && data) {
+            numberOfActors = `${data.validators.number} (${data.validators.nominators.number})`;
+          }
+
+          return (
+            <SpendingAndStakeTableRow
+              key={groupType}
+              role={width <= titleCutoff ? shortTitle : title}
+              helpContent={helpText}
+              numberOfActors={numberOfActors}
+              groupEarning={data && `${Math.round(data[groupType].rewardsPerWeek)}`}
+              groupEarningDollar={displayStatusData(groupType, 'rewardsPerWeek')}
+              earningShare={data && `${round(data[groupType].rewardsShare * 100)}`}
+              groupStake={data && `${data[groupType].totalStake}`}
+              groupStakeDollar={displayStatusData(groupType, 'totalStake')}
+              stakeShare={data && `${round(data[groupType].stakeShare * 100)}`}
+              color={color}
+            />
+          );
+        })}
+        {WORKING_GROUPS.map(({ groupType, titleCutoff, shortTitle, title, helpText, color, lead }) => {
+          return (
+            <React.Fragment key={groupType}>
+              <SpendingAndStakeTableRow
+                role={width <= titleCutoff ? shortTitle : title}
+                helpContent={helpText}
+                numberOfActors={data && `${data[groupType].number}`}
+                groupEarning={data && `${Math.round(data[groupType].rewardsPerWeek)}`}
+                groupEarningDollar={displayStatusData(groupType, 'rewardsPerWeek')}
+                earningShare={data && `${round(data[groupType].rewardsShare * 100)}`}
+                groupStake={data && `${data[groupType].totalStake}`}
+                groupStakeDollar={displayStatusData(groupType, 'totalStake')}
+                stakeShare={data && `${round(data[groupType].stakeShare * 100)}`}
+                color={color}
+              />
+              <SpendingAndStakeTableRow
+                role={width <= lead.titleCutoff ? lead.shortTitle : lead.title}
+                helpContent={helpText}
+                numberOfActors={data && `${data[groupType].lead.number}`}
+                groupEarning={data && `${Math.round(data[groupType].lead.rewardsPerWeek)}`}
+                groupEarningDollar={displayStatusData(groupType, 'rewardsPerWeek', true)}
+                earningShare={data && `${round(data[groupType].lead.rewardsShare * 100)}`}
+                groupStake={data && `${data[groupType].lead.totalStake}`}
+                groupStakeDollar={displayStatusData(groupType, 'totalStake', true)}
+                stakeShare={data && `${round(data[groupType].lead.stakeShare * 100)}`}
+                color={lead.color}
+              />
+            </React.Fragment>
+          );
+        })}
         <SpendingAndStakeTableRow
           role='TOTAL'
           active={true}

+ 58 - 115
pioneer/packages/joy-tokenomics/src/Overview/TokenomicsCharts.tsx

@@ -4,7 +4,8 @@ import PieChart from '../../../react-components/src/Chart/PieChart';
 import styled from 'styled-components';
 
 import { TokenomicsData } from '@polkadot/joy-utils/src/types/tokenomics';
-import { COLORS } from './index';
+
+import { WORKING_GROUPS, NON_WORKING_GROUPS } from '../tokenomicsGroupsData';
 
 const StyledPieChart = styled(PieChart)`
   width:15rem;
@@ -29,120 +30,62 @@ const ChartContainer = styled('div')`
 const TokenomicsCharts: React.FC<{data?: TokenomicsData; className?: string}> = ({ data, className }) => {
   return (
     <div className={className}>
-      {data ? <ChartContainer>
-        <StyledPieChart
-          values={[{
-            colors: [COLORS.VALIDATOR],
-            label: 'Validators',
-            value: data.validators.rewardsShare * 100
-          }, {
-            colors: [COLORS.COUNCIL_MEMBER],
-            label: 'Council',
-            value: data.council.rewardsShare * 100
-          }, {
-            colors: [COLORS.STORAGE_PROVIDER],
-            label: 'Storage Providers',
-            value: data.storageProviders.rewardsShare * 100
-          }, {
-            colors: [COLORS.STORAGE_LEAD],
-            label: 'Storage Lead',
-            value: data.storageProviders.lead.rewardsShare * 100
-          }, {
-            colors: [COLORS.CONTENT_CURATOR],
-            label: 'Content Curators',
-            value: data.contentCurators.rewardsShare * 100
-          }, {
-            colors: [COLORS.CURATOR_LEAD],
-            label: 'Content Curators Lead',
-            value: data.contentCurators.lead.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_ALPHA],
-            label: 'Operations Alpha',
-            value: data.operationsAlpha.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_ALPHA_LEAD],
-            label: 'Operations Alpha Lead',
-            value: data.operationsAlpha.lead.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_BETA],
-            label: 'Operations Beta',
-            value: data.operationsBeta.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_BETA_LEAD],
-            label: 'Operations Beta Lead',
-            value: data.operationsBeta.lead.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_GAMMA],
-            label: 'Operations Gamma',
-            value: data.operationsGamma.rewardsShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_GAMMA_LEAD],
-            label: 'Operations Gamma Lead',
-            value: data.operationsGamma.lead.rewardsShare * 100
-          }
-          ]} />
-        <Label as='div'>
-          <Icon name='money' />
-          <span style={{ fontWeight: 600 }}>Spending</span>
-        </Label>
-      </ChartContainer> : <Icon name='circle notched' loading/>}
-      {data ? <ChartContainer>
-        <StyledPieChart
-          values={[{
-            colors: [COLORS.VALIDATOR],
-            label: 'Validators',
-            value: data.validators.stakeShare * 100
-          }, {
-            colors: [COLORS.COUNCIL_MEMBER],
-            label: 'Council',
-            value: data.council.stakeShare * 100
-          }, {
-            colors: [COLORS.STORAGE_PROVIDER],
-            label: 'Storage Providers',
-            value: data.storageProviders.stakeShare * 100
-          }, {
-            colors: [COLORS.STORAGE_LEAD],
-            label: 'Storage Lead',
-            value: data.storageProviders.lead.stakeShare * 100
-          }, {
-            colors: [COLORS.CONTENT_CURATOR],
-            label: 'Content Curators',
-            value: data.contentCurators.stakeShare * 100
-          }, {
-            colors: [COLORS.CURATOR_LEAD],
-            label: 'Content Curators Lead',
-            value: data.contentCurators.lead.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_ALPHA],
-            label: 'Operations Alpha',
-            value: data.operationsAlpha.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_ALPHA_LEAD],
-            label: 'Operations Alpha Lead',
-            value: data.operationsAlpha.lead.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_BETA],
-            label: 'Operations Beta',
-            value: data.operationsBeta.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_BETA_LEAD],
-            label: 'Operations Beta Lead',
-            value: data.operationsBeta.lead.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_GAMMA],
-            label: 'Operations Gamma',
-            value: data.operationsGamma.stakeShare * 100
-          }, {
-            colors: [COLORS.OPERATIONS_GAMMA_LEAD],
-            label: 'Operations Gamma Lead',
-            value: data.operationsGamma.lead.stakeShare * 100
-          }
-          ]} />
-        <Label as='div'>
-          <Icon name='block layout' />
-          <span style={{ fontWeight: 600 }}>Stake</span>
-        </Label>
-      </ChartContainer> : <Icon name='circle notched' loading/>}
+      {data ? (
+        <ChartContainer>
+          <StyledPieChart
+            values={[
+              ...WORKING_GROUPS.map(({ color, title, groupType, lead }) => [{
+                colors: [color],
+                label: title,
+                value: data[groupType].rewardsShare * 100
+              }, {
+                colors: [lead.color],
+                label: lead.title,
+                value: data[groupType].lead.rewardsShare * 100
+              }]).flat(),
+              ...NON_WORKING_GROUPS.map(({ color, shortTitle, groupType }) => ({
+                colors: [color],
+                label: shortTitle,
+                value: data[groupType].rewardsShare * 100
+              }))
+            ]}
+          />
+          <Label as='div'>
+            <Icon name='money' />
+            <span style={{ fontWeight: 600 }}>Spending</span>
+          </Label>
+        </ChartContainer>
+      ) : (
+        <Icon name='circle notched' loading />
+      )}
+      {data ? (
+        <ChartContainer>
+          <StyledPieChart
+            values={[
+              ...WORKING_GROUPS.map(({ color, title, groupType, lead }) => [{
+                colors: [color],
+                label: title,
+                value: data[groupType].stakeShare * 100
+              }, {
+                colors: [lead.color],
+                label: lead.title,
+                value: data[groupType].lead.stakeShare * 100
+              }]).flat(),
+              ...NON_WORKING_GROUPS.map(({ color, shortTitle, groupType }) => ({
+                colors: [color],
+                label: shortTitle,
+                value: data[groupType].stakeShare * 100
+              }))
+            ]}
+          />
+          <Label as='div'>
+            <Icon name='block layout' />
+            <span style={{ fontWeight: 600 }}>Stake</span>
+          </Label>
+        </ChartContainer>
+      ) : (
+        <Icon name='circle notched' loading />
+      )}
     </div>
   );
 };

+ 0 - 16
pioneer/packages/joy-tokenomics/src/Overview/index.tsx

@@ -38,21 +38,6 @@ const StyledTokenomicsCharts = styled(TokenomicsCharts)`
   }
 `;
 
-const COLORS = {
-  VALIDATOR: '#ff9800',
-  COUNCIL_MEMBER: '#ffc107',
-  STORAGE_PROVIDER: '#ffeb3b',
-  STORAGE_LEAD: '#cddc39',
-  CONTENT_CURATOR: '#8bc34a',
-  CURATOR_LEAD: '#4caf50',
-  OPERATIONS_ALPHA: '#009688',
-  OPERATIONS_ALPHA_LEAD: '#00bcd4',
-  OPERATIONS_BETA: '#03a9f4',
-  OPERATIONS_BETA_LEAD: '#2196f3',
-  OPERATIONS_GAMMA: '#3f51b5',
-  OPERATIONS_GAMMA_LEAD: '#673ab7'
-};
-
 const Overview: React.FC = () => {
   const transport = useTransport();
   const [statusDataValue, statusDataError] = usePromise<StatusServerData | undefined>(() => fetch('https://status.joystream.org/status').then((res) => res.json().then((data) => data as StatusServerData)), undefined, []);
@@ -72,4 +57,3 @@ const Overview: React.FC = () => {
 };
 
 export default Overview;
-export { COLORS };

+ 98 - 0
pioneer/packages/joy-tokenomics/src/tokenomicsGroupsData.ts

@@ -0,0 +1,98 @@
+export const NON_WORKING_GROUPS = [
+  {
+    groupType: 'validators' as const,
+    titleCutoff: 1050,
+    shortTitle: 'Validators',
+    title: 'Validators (Nominators)',
+    helpText:
+      'The current set of active Validators (and Nominators), and the sum of the sets projected rewards and total stakes (including Nominators).',
+    color: '#ff9800'
+  },
+  {
+    groupType: 'council' as const,
+    titleCutoff: 1015,
+    shortTitle: 'Council',
+    title: 'Council Members',
+    helpText:
+      'The current Council Members, and the sum of their projected rewards and total stakes (including voters/backers).',
+    color: '#ffc107'
+  }
+];
+
+export const WORKING_GROUPS = [
+  {
+    groupType: 'storageProviders' as const,
+    titleCutoff: 1015,
+    shortTitle: 'Storage',
+    title: 'Storage Providers',
+    helpText: 'The current Storage Providers, and the sum of their projected rewards and stakes.',
+    color: '#ffeb3b',
+    lead: {
+      titleCutoff: 1015,
+      shortTitle: 'S. Lead',
+      title: 'Storage Lead',
+      helpText: 'Current Storage Provider Lead, and their projected reward and stake.',
+      color: '#cddc39'
+    }
+  },
+  {
+    groupType: 'contentCurators' as const,
+    titleCutoff: 1015,
+    shortTitle: 'Curators',
+    title: 'Content Curators',
+    helpText: 'The current Content Curators, and the sum of their projected rewards and stakes.',
+    color: '#8bc34a',
+    lead: {
+      titleCutoff: 1015,
+      shortTitle: 'C. Lead',
+      title: 'Curators Lead',
+      helpText: 'Current Content Curators Lead, and their projected reward and stake.',
+      color: '#4caf50'
+    }
+  },
+  {
+    groupType: 'operationsAlpha' as const,
+    titleCutoff: 1050,
+    shortTitle: 'Operations A.',
+    title: 'Operations Alpha',
+    helpText: 'The current Operations Group Alpha members, and the sum of their projected rewards and stakes.',
+    color: '#009688',
+    lead: {
+      titleCutoff: 1015,
+      shortTitle: 'Operations A. Lead',
+      title: 'Operations Alpha Lead',
+      helpText: 'Current Operations Group Alpha Lead, and their projected reward and stake.',
+      color: '#00bcd4'
+    }
+  },
+  {
+    groupType: 'operationsBeta' as const,
+    titleCutoff: 1050,
+    shortTitle: 'Operations B.',
+    title: 'Operations Beta',
+    helpText: 'The current Operations Group Beta members, and the sum of their projected rewards and stakes.',
+    color: '#03a9f4',
+    lead: {
+      titleCutoff: 1015,
+      shortTitle: 'Operations B. Lead',
+      title: 'Operations Beta Lead',
+      helpText: 'Current Operations Group Beta Lead, and their projected reward and stake.',
+      color: '#2196f3'
+    }
+  },
+  {
+    groupType: 'operationsGamma' as const,
+    titleCutoff: 1050,
+    shortTitle: 'Operations G.',
+    title: 'Operations Gamma',
+    helpText: 'The current Operations Group Gamma members, and the sum of their projected rewards and stakes.',
+    color: '#3f51b5',
+    lead: {
+      titleCutoff: 1015,
+      shortTitle: 'Operations G. Lead',
+      title: 'Operations Gamma Lead',
+      helpText: 'Current Operations Group Gamma Lead, and their projected reward and stake.',
+      color: '#673ab7'
+    }
+  }
+];