diff --git a/src/i18n/en-motions.ts b/src/i18n/en-motions.ts index baa6be58a1..f3896f440b 100644 --- a/src/i18n/en-motions.ts +++ b/src/i18n/en-motions.ts @@ -24,6 +24,7 @@ const motionsMessageDescriptors = { other {pts} } reputation reward} ${ColonyMotions.UnlockTokenMotion} {Unlock native token {tokenSymbol}} + ${ColonyMotions.DAOIncorporationMotion} {Incorporate this DAO} other {Generic motion we don't have information about} }`, [`motion.${ColonyMotions.SetUserRolesMotion}.assign`]: `Assign the {roles} in {fromDomainName} to {recipient}`, @@ -41,6 +42,7 @@ const motionsMessageDescriptors = { ${ColonyMotions.EmitDomainReputationPenaltyMotion} {Smite} ${ColonyMotions.EmitDomainReputationRewardMotion} {Award} ${ColonyMotions.UnlockTokenMotion} {Unlock Token} + ${ColonyMotions.DAOIncorporationMotion} {DAO Incorporation} other {Generic} }`, }; diff --git a/src/img/icons.json b/src/img/icons.json index 45a498aae0..9498e34de7 100644 --- a/src/img/icons.json +++ b/src/img/icons.json @@ -73,6 +73,7 @@ "envelope", "file", "filled-circle-person", + "flag", "forbidden-signal", "four-square", "graph-line", diff --git a/src/img/icons/flag.svg b/src/img/icons/flag.svg new file mode 100644 index 0000000000..d9f4326a97 --- /dev/null +++ b/src/img/icons/flag.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/dashboard/components/ActionsPage/ActionsComponents/DefaultMotion.tsx b/src/modules/dashboard/components/ActionsPage/ActionsComponents/DefaultMotion.tsx index 88734f1808..ddc00ca253 100644 --- a/src/modules/dashboard/components/ActionsPage/ActionsComponents/DefaultMotion.tsx +++ b/src/modules/dashboard/components/ActionsPage/ActionsComponents/DefaultMotion.tsx @@ -49,6 +49,7 @@ import { useColonyHistoricRolesQuery, useNetworkContracts, } from '~data/index'; +import { useTitle } from '~utils/hooks/useTitle'; import DetailsWidget from '../DetailsWidget'; import StakingWidgetFlow from '../StakingWidget'; @@ -61,9 +62,9 @@ import FinalizeMotionAndClaimWidget, { import VoteResults from '../FinalizeMotionAndClaimWidget/VoteResults'; import CountDownTimer from '../CountDownTimer'; -import styles from './DefaultAction.css'; import motionSpecificStyles from './DefaultMotion.css'; -import { useTitle } from '~utils/hooks/useTitle'; +import { cost, source, incorporationName } from './constants'; +import styles from './DefaultAction.css'; const MSG = defineMessages({ or: { @@ -350,6 +351,12 @@ const DefaultMotion = ({ reputationChange: formattedReputationChange, reputationChangeNumeral: , isSmiteAction: new Decimal(reputationChange).isNegative(), + // Cost, source and incorporationName are mocks. Add backend data here when ready. + cost: , + source: domains.find( + ({ ethDomainId }) => ethDomainId === source, + ) as OneDomain, + incorporationName, }; const actionAndEventValuesForDocumentTitle = { diff --git a/src/modules/dashboard/components/ActionsPage/ActionsComponents/constants.ts b/src/modules/dashboard/components/ActionsPage/ActionsComponents/constants.ts new file mode 100644 index 0000000000..86871405bc --- /dev/null +++ b/src/modules/dashboard/components/ActionsPage/ActionsComponents/constants.ts @@ -0,0 +1,83 @@ +// Mock data. Replace with backend data (DAO Incorporation Motion details) when ready. +export const cost = 5300; +export const source = 1; +export const incorporationName = 'WallStreetBets'; + +export const mockColonyActionData = { + colonyAction: { + actionInitiator: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + actionType: 'DAOIncorporationMotion', + amount: '5300', + annotationHash: null, + blockNumber: 922, + colonyAvatarHash: '#123', + colonyDisplayName: 'test', + colonyTokens: [], + createdAt: 1678185528000, + domainColor: '', + domainName: '1', + domainPurpose: '', + events: [ + { + createdAt: 1678185528000, + emmitedBy: 'VotingReputationClient', + name: 'MotionCreated', + transactionHash: + '0xe459e77c2b10e8b391c71fe0c3a788e176301221d5b201dcdfa582d7754a80ac', + type: 'NetworkEvent', + values: '', + }, + ], + fromDomain: 1, + hash: '0xe459e77c2b10e8b391c71fe0c3a788e176301221d5b201dcdfa582d7754a80ac', + motionDomain: 1, + motionState: 'Staking', + newVersion: '0', + oldVersion: '0', + recipient: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + reputationChange: '0', + roles: [], + rootHash: + '0x113f47cccf1266a78e892a719efb64e82892999ed9a6c042af53e63827f6d42c', + status: 1, + toDomain: 1, + tokenAddress: '0x3Fe98e1e643c3f78aCF72B7FC4A68B5A737CD274', + cost: 5300, + source: 1, + incorporationName: 'WallStreetBets', + }, +}; + +export const initiatorProfileWithFallbackMock = { + id: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + profile: { + avatarHash: null, + bio: null, + displayName: null, + location: null, + username: 'john doe', + walletAddress: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + website: null, + }, +}; + +export const recipientProfileWithFallbackMock = { + id: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + profile: { + avatarHash: null, + bio: null, + displayName: null, + location: null, + username: 'john doe', + walletAddress: '0xb77D57F4959eAfA0339424b83FcFaf9c15407461', + website: null, + }, +}; + +export const tokenDataMock = { + address: '0x3Fe98e1e643c3f78aCF72B7FC4A68B5A737CD274', + decimals: 18, + iconHash: null, + name: 'xDai', + symbol: 'XDAI', +}; diff --git a/src/modules/dashboard/components/ActionsPage/ActionsPage.tsx b/src/modules/dashboard/components/ActionsPage/ActionsPage.tsx index 09aa50b03f..25249fc6ba 100644 --- a/src/modules/dashboard/components/ActionsPage/ActionsPage.tsx +++ b/src/modules/dashboard/components/ActionsPage/ActionsPage.tsx @@ -28,6 +28,12 @@ import { STATUS_MAP } from './staticMaps'; import NakedMoleImage from '../../../../img/naked-mole.svg'; import styles from './ActionsPage.css'; +import { + initiatorProfileWithFallbackMock, + mockColonyActionData, + recipientProfileWithFallbackMock, + tokenDataMock, +} from './ActionsComponents/constants'; const MSG = defineMessages({ loading: { @@ -161,6 +167,21 @@ const ActionsPage = () => { colonyActionData?.colonyAction?.actionInitiator || '', ); + // It's temporary condition for displaying DAOIncorporation motion. + // Remove this condition when DAOIncorporation motion data are fetched from the backend. + if (transactionHash === 'DAOIncorporation' && colonyData) { + return ( + + ); + } + if (!isTransactionFormat(transactionHash) || colonyActionError) { return (
diff --git a/src/modules/dashboard/components/ActionsPage/DetailsWidget/DetailsWidget.tsx b/src/modules/dashboard/components/ActionsPage/DetailsWidget/DetailsWidget.tsx index c930ea68e0..220a604261 100644 --- a/src/modules/dashboard/components/ActionsPage/DetailsWidget/DetailsWidget.tsx +++ b/src/modules/dashboard/components/ActionsPage/DetailsWidget/DetailsWidget.tsx @@ -11,6 +11,8 @@ import { AnyUser, Colony } from '~data/index'; import { ColonyActions, ColonyMotions } from '~types/index'; import { splitTransactionHash } from '~utils/strings'; import { getDetailsForAction } from '~utils/colonyActions'; +import LinkedIncorporation from '~dashboard/Incorporation/LinkedIncorporation'; + import { EventValues } from '../../ActionsPageFeed/ActionsPageFeed'; import { ACTION_TYPES_ICONS_MAP } from '../../ActionsPage/staticMaps'; @@ -73,6 +75,14 @@ const MSG = defineMessages({ false {reward} }`, }, + source: { + id: 'dashboard.ActionsPage.DetailsWidget.source', + defaultMessage: 'Source', + }, + cost: { + id: 'dashboard.ActionsPage.DetailsWidget.cost', + defaultMessage: 'Cost', + }, }); interface Props { @@ -109,6 +119,7 @@ const DetailsWidget = ({ */ const Amount = () => values?.amount as ReactElement; const Symbol = () => values?.tokenSymbol as ReactElement; + const Cost = () => values?.cost as ReactElement; const detailsForAction = getDetailsForAction(actionType); @@ -143,16 +154,17 @@ const DetailsWidget = ({
- {values?.motionDomain && ( -
-
- -
-
- + {values?.motionDomain && + actionType !== ColonyMotions.DAOIncorporationMotion && ( +
+
+ +
+
+ +
-
- )} + )} {detailsForAction.FromDomain && values?.fromDomain && (
@@ -259,6 +271,33 @@ const DetailsWidget = ({
{values.colonyName}
)} + {detailsForAction.Source && values?.source && ( +
+
+ +
+ +
+ )} + {values?.cost && detailsForAction.Cost && ( +
+
+ +
+
+ {values?.token && ( + + )} +
+ +
+
+
+ )} {!!shortenedHash && (
@@ -274,6 +313,12 @@ const DetailsWidget = ({
)} + {detailsForAction.LinkedIncorporation && values?.incorporationName && ( + + )}
); }; diff --git a/src/modules/dashboard/components/ActionsPage/staticMaps.ts b/src/modules/dashboard/components/ActionsPage/staticMaps.ts index 588673cf9e..3c05ebd121 100644 --- a/src/modules/dashboard/components/ActionsPage/staticMaps.ts +++ b/src/modules/dashboard/components/ActionsPage/staticMaps.ts @@ -17,6 +17,9 @@ export enum ActionPageDetails { Name = 'Name', Permissions = 'Permissions', ReputationChange = 'ReputationChange', + Source = 'Source', + Cost = 'Cost', + LinkedIncorporation = 'LinkedIncorporation', } type EventRolesMap = Partial< @@ -97,6 +100,7 @@ export const ACTION_TYPES_ICONS_MAP: { [ColonyMotions.EmitDomainReputationPenaltyMotion]: 'emoji-firebolt', [ColonyMotions.EmitDomainReputationRewardMotion]: 'emoji-shooting-star', [ColonyMotions.UnlockTokenMotion]: 'emoji-padlock', + [ColonyMotions.DAOIncorporationMotion]: 'flag', [ColonyActions.Generic]: 'circle-check-primary', }; @@ -279,4 +283,9 @@ export const DETAILS_FOR_ACTION: ActionsDetailsMap = { ActionPageDetails.ReputationChange, ], [ColonyMotions.UnlockTokenMotion]: [], + [ColonyMotions.DAOIncorporationMotion]: [ + ActionPageDetails.Source, + ActionPageDetails.Cost, + ActionPageDetails.LinkedIncorporation, + ], }; diff --git a/src/modules/dashboard/components/ActionsPageFeed/ActionsPageFeed.tsx b/src/modules/dashboard/components/ActionsPageFeed/ActionsPageFeed.tsx index e5787a31b1..5ba24f89f9 100644 --- a/src/modules/dashboard/components/ActionsPageFeed/ActionsPageFeed.tsx +++ b/src/modules/dashboard/components/ActionsPageFeed/ActionsPageFeed.tsx @@ -71,6 +71,9 @@ export interface EventValues { isSmiteAction?: boolean; changes?: ReactElement[]; funds?: ReactElement[]; + source?: OneDomain; + cost?: string | ReactElement; + incorporationName?: string; } export type FeedItemWithId = T & { uniqueId: string }; diff --git a/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css new file mode 100644 index 0000000000..a2737205c2 --- /dev/null +++ b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css @@ -0,0 +1,49 @@ +@value passedColor: var(--primary); +@value failedColor: var(--pink); + +.wrapper { + margin: 60px 0; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + line-height: 18px; +} + +.titleWrapper { + display: flex; + align-items: center; + margin-bottom: 12px; + padding-bottom: 10px; + border-bottom: 1px solid color-mod(var(--temp-grey-blue-7) alpha(15%)); +} + +.statusWrapper { + display: flex; + justify-content: space-between; + align-items: center; +} + +.line { + width: 7px; + border-top: 1px solid var(--dark); +} + +.dot { + margin: 0 2px; + height: 7px; + width: 7px; + min-width: 7px; + border: 1px solid var(--dark); + border-radius: 50%; + background-color: transparent; +} + +.title { + margin-left: 8px; + font-size: var(--size-smallish); + color: color-mod(var(--dark) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.link:hover { + color: var(--action-secondary); +} diff --git a/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css.d.ts b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css.d.ts new file mode 100644 index 0000000000..fa565c824b --- /dev/null +++ b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.css.d.ts @@ -0,0 +1,9 @@ +export const passedColor: string; +export const failedColor: string; +export const wrapper: string; +export const titleWrapper: string; +export const statusWrapper: string; +export const line: string; +export const dot: string; +export const title: string; +export const link: string; diff --git a/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.tsx b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.tsx new file mode 100644 index 0000000000..8eb56e34cf --- /dev/null +++ b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/LinkedIncorporation.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import Link from '~core/Link'; + +import styles from './LinkedIncorporation.css'; + +const MSG = defineMessages({ + title: { + id: 'dashboard.ExpenditurePage.Stages.LinkedIncorporation.title', + defaultMessage: 'Linked Incorporation', + }, +}); + +const displayName = 'dashboard.ExpenditurePage.Stages.LinkedIncorporation'; + +interface Props { + link: string; + name: string; +} + +const LinkedIncorporation = ({ link, name }: Props) => ( +
+
+
+
+
+
+ +
+
+
+ + {name} + +
+
+); + +LinkedIncorporation.displayName = displayName; + +export default LinkedIncorporation; diff --git a/src/modules/dashboard/components/Incorporation/LinkedIncorporation/index.ts b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/index.ts new file mode 100644 index 0000000000..429a5865a6 --- /dev/null +++ b/src/modules/dashboard/components/Incorporation/LinkedIncorporation/index.ts @@ -0,0 +1 @@ +export { default } from './LinkedIncorporation'; diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.css b/src/modules/pages/components/IncorporationPage/IncorporationPage.css index 7984904f8f..7cbcac48ce 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.css +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.css @@ -36,6 +36,7 @@ } .mainContainer { + padding: 76px 100px 70px 25px; padding-bottom: 50px; height: 600px; min-height: 100%; diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index e5475565aa..3ab4fc6120 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { useParams } from 'react-router'; +import { useParams, useHistory } from 'react-router'; import { Formik } from 'formik'; import classNames from 'classnames'; @@ -26,8 +26,6 @@ import styles from './IncorporationPage.css'; const displayName = 'pages.IncorporationPage'; -export type InitialValuesType = typeof initialValues; - const IncorporationPage = () => { const { colonyName } = useParams<{ colonyName: string; @@ -36,6 +34,7 @@ const IncorporationPage = () => { const { data: colonyData, loading } = useColonyFromNameQuery({ variables: { name: colonyName, address: '' }, }); + const history = useHistory(); const [isFormEditable, setFormEditable] = useState(false); const [formValues, setFormValues] = useState(formValuesMock); const [shouldValidate, setShouldValidate] = useState(false); @@ -56,18 +55,22 @@ const IncorporationPage = () => { setActiveStageId(StagesEnum.Payment); }, []); + const handleConfirmPayment = useCallback(() => { + // Redirection to the Actions page is a mock action. + const txHash = 'DAOIncorporation'; + history.push(`/colony/${colonyName}/tx/${txHash}`); + setActiveStageId(StagesEnum.Processing); + }, [colonyName, history]); + const handlePay = useCallback(() => { if (!colonyData) return; openPayDialog({ - onClick: () => { - // add a logic to pay for incorporation - setActiveStageId(StagesEnum.Processing); - }, + onClick: handleConfirmPayment, isVotingExtensionEnabled: true, colony: colonyData.processedColony, }); - }, [colonyData, openPayDialog]); + }, [colonyData, openPayDialog, handleConfirmPayment]); const buttonAction = useMemo(() => { switch (activeStageId) { @@ -159,7 +162,9 @@ const IncorporationPage = () => {
{/* user passed to VerifiactionBanner is a mock */} diff --git a/src/modules/pages/components/IncorporationPage/constants.ts b/src/modules/pages/components/IncorporationPage/constants.ts index 311d840016..25c51db865 100644 --- a/src/modules/pages/components/IncorporationPage/constants.ts +++ b/src/modules/pages/components/IncorporationPage/constants.ts @@ -53,7 +53,7 @@ const MSG = defineMessages({ }, complete: { id: 'dashboard.IncorporationPage.complete', - defaultMessage: 'Create Application', + defaultMessage: 'Complete', }, completeDesc: { id: 'dashboard.IncorporationPage.completeDesc', diff --git a/src/types/colonyMotions.ts b/src/types/colonyMotions.ts index cb3c1ef0e7..69733b00d2 100644 --- a/src/types/colonyMotions.ts +++ b/src/types/colonyMotions.ts @@ -14,6 +14,7 @@ export enum ColonyMotions { VersionUpgradeMotion = 'VersionUpgradeMotion', EmitDomainReputationPenaltyMotion = 'EmitDomainReputationPenaltyMotion', EmitDomainReputationRewardMotion = 'EmitDomainReputationRewardMotion', + DAOIncorporationMotion = 'DAOIncorporationMotion', } export const motionNameMapping = { @@ -28,4 +29,5 @@ export const motionNameMapping = { upgrade: ColonyMotions.VersionUpgradeMotion, emitDomainReputationPenalty: ColonyMotions.EmitDomainReputationPenaltyMotion, emitDomainReputationReward: ColonyMotions.EmitDomainReputationRewardMotion, + DAOIncorporation: ColonyMotions.DAOIncorporationMotion, };