From 1152c5013ff4ff045cca15e475a7fbe5c90786b7 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 30 Dec 2022 16:15:35 +0100 Subject: [PATCH 01/16] added Stages section --- .../Stages/StageItem/StageItem.css | 51 ++++++ .../Stages/StageItem/StageItem.css.d.ts | 8 + .../Stages/StageItem/StageItem.tsx | 42 +++++ .../Stages/StageItem/index.ts | 1 + .../DAOIncorporation/Stages/Stages.css | 104 ++++++++++++ .../DAOIncorporation/Stages/Stages.css.d.ts | 10 ++ .../DAOIncorporation/Stages/Stages.tsx | 152 ++++++++++++++++++ .../Stages/StagesButton/StagesButton.css | 14 ++ .../Stages/StagesButton/StagesButton.css.d.ts | 3 + .../Stages/StagesButton/StagesButton.tsx | 85 ++++++++++ .../Stages/StagesButton/index.ts | 1 + .../DAOIncorporation/Stages/index.ts | 1 + .../components/IncorporationPage/constants.ts | 1 + 13 files changed, 473 insertions(+) create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/index.ts diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css new file mode 100644 index 0000000000..3bbfbd6273 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css @@ -0,0 +1,51 @@ +.container { + display: flex; + align-items: baseline; + padding: 9px 0; + position: relative; +} + +.dot { + margin-right: 14px; + height: 7px; + width: 7px; + min-width: 7px; + border: 1px solid var(--temp-grey-blue-7); + border-radius: 50%; +} + +.verticalLine { + height: 60%; + position: absolute; + bottom: -7px; + left: 3px; + border-left: 1px solid var(--temp-grey-6); +} + +.activeDot { + border: 1px solid var(--primary); + background-color: var(--primary); +} + +.label { + margin-bottom: 8px; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: var(--dark); + letter-spacing: var(--spacing-medium); +} + +.activeLabel { + color: var(--temp-grey-blue-7); +} + +.description { + font-size: var(--size-tiny); + font-weight: var(--weight-bold); + color: var(--temp-grey-blue-7); + letter-spacing: var(--spacing-medium); +} + +.completedLabel { + color: var(--temp-grey-blue-7); +} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts new file mode 100644 index 0000000000..76c5a5b024 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts @@ -0,0 +1,8 @@ +export const container: string; +export const dot: string; +export const verticalLine: string; +export const activeDot: string; +export const label: string; +export const activeLabel: string; +export const description: string; +export const completedLabel: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx new file mode 100644 index 0000000000..cf9ad5e928 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { FormattedMessage, MessageDescriptor } from 'react-intl'; +import classNames from 'classnames'; + +import styles from './StageItem.css'; + +interface Props { + title?: MessageDescriptor; + description?: MessageDescriptor; + isActive: boolean; + isLast?: boolean; +} +const displayName = 'dashboard.ExpenditurePage.Stages.StageItem'; + +const StageItem = ({ title, description, isActive, isLast }: Props) => { + return ( +
+
+ {!isLast &&
} +
+
+ +
+
+ +
+
+
+ ); +}; + +StageItem.displayName = displayName; + +export default StageItem; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts new file mode 100644 index 0000000000..234df6a6cb --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts @@ -0,0 +1 @@ +export { default } from './StageItem'; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css new file mode 100644 index 0000000000..cb87d68bb6 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css @@ -0,0 +1,104 @@ +@value iconColor: var(--temp-grey-blue-7); + +.mainContainer { + padding-top: 20px; + max-width: 340px; +} + +.stagesText { + display: flex; + align-items: center; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + line-height: 18px; + color: var(--temp-grey-blue-7); +} + +.statusContainer { + display: flex; + justify-content: space-between; + padding: 10px 0; + border-bottom: 1px solid var(--temp-grey-6); +} + +.statusContainer:first-child { + padding-top: 0; +} + +.icon svg { + height: 18px; + width: 18px; + fill: var(--temp-grey-blue-7); +} + +.buttonsContainer { + display: flex; + align-items: center; +} + +.buttonsContainer button:not(:last-of-type) { + margin-right: 30px; +} + +.buttonsContainer button { + &:disabled { + height: 20px; + border: none; + border-radius: 5px; + background-color: var(--colony-light-blue); + font-weight: var(--weight-bold); + color: var(--temp-grey-blue-7); + } + + &:disabled:hover { + background-color: var(--colony-light-blue); + color: var(--temp-grey-blue-7); + cursor: default; + } +} + +.iconButton { + margin-left: 0; + padding: 0; + border: none; + background-color: transparent; +} + +.iconButton i { + display: flex; +} + +.iconButton:hover { + cursor: pointer; +} + +.iconButtonDisabled { + opacity: 0.5; +} + +.iconWrapper { + position: relative; +} + +.iconWrapper:hover { + &::after { + height: 30px; + width: 30px; + position: absolute; + top: 0; + left: 0; + border-radius: 50%; + background-color: var(--action-secondary); + transform: translate(-6px, -6px); + content: ''; + opacity: 0.1; + } +} + +.iconButtonDisabled:hover { + cursor: not-allowed; +} + +.buttonTooltip { + max-width: 192px; +} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts new file mode 100644 index 0000000000..1c668b5f59 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts @@ -0,0 +1,10 @@ +export const iconColor: string; +export const mainContainer: string; +export const stagesText: string; +export const statusContainer: string; +export const icon: string; +export const buttonsContainer: string; +export const iconButton: string; +export const iconButtonDisabled: string; +export const iconWrapper: string; +export const buttonTooltip: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx new file mode 100644 index 0000000000..d07cff6cf7 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx @@ -0,0 +1,152 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; +import copyToClipboard from 'copy-to-clipboard'; +import classNames from 'classnames'; + +import Button from '~core/Button'; +import Icon from '~core/Icon'; +import { Tooltip } from '~core/Popover'; + +import StageItem from './StageItem'; +import StagesButton from './StagesButton'; +import styles from './Stages.css'; +import { StageObject } from '~pages/IncorporationPage/types'; +import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; + +const MSG = defineMessages({ + stages: { + id: 'dashboard.DAOIncorporation.Stages.stages', + defaultMessage: 'Stages', + }, + deleteDraft: { + id: 'dashboard.DAOIncorporation.Stages.deleteDraft', + defaultMessage: 'Delete draft', + }, + tooltipDeleteText: { + id: 'dashboard.DAOIncorporation.Stages.tooltipDeleteText', + defaultMessage: 'Delete', + }, + tooltipShareText: { + id: 'dashboard.DAOIncorporation.Stages.tooltipShareText', + defaultMessage: 'Share URL', + }, +}); + +const displayName = 'dashboard.DAOIncorporation.Stages'; + +export interface Props { + stages: StageObject[]; + activeStageId: StagesEnum; + buttonDisabled?: boolean; + buttonAction?: VoidFunction; +} + +const Stages = ({ + stages, + activeStageId, + buttonDisabled, + buttonAction, +}: Props) => { + const [valueIsCopied, setValueIsCopied] = useState(false); + const userFeedbackTimer = useRef(null); + + const handleClipboardCopy = () => { + copyToClipboard(window.location.href); + setValueIsCopied(true); + userFeedbackTimer.current = setTimeout(() => setValueIsCopied(false), 2000); + }; + + useEffect(() => () => clearTimeout(userFeedbackTimer.current), [ + userFeedbackTimer, + ]); + + const activeIndex = stages.findIndex((stage) => stage.id === activeStageId); + const activeStage = stages.find((stage) => stage.id === activeStageId); + + return ( +
+
+
+ +
+
+ <> + + + + +
+
+ {stages.map(({ id, title, description }, index) => ( + + ))} +
+ ); +}; + +Stages.displayName = displayName; + +export default Stages; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css new file mode 100644 index 0000000000..5f73f896d7 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css @@ -0,0 +1,14 @@ +.button { + composes: themePrimary main from '~core/Button/Button.css'; + padding: 0; + height: 29px; + width: 100px; +} + +.buttonTooltip { + max-width: 192px; +} + +.buttonWithTooltip { + margin-left: 20px; +} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts new file mode 100644 index 0000000000..5941522346 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts @@ -0,0 +1,3 @@ +export const button: string; +export const buttonTooltip: string; +export const buttonWithTooltip: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx new file mode 100644 index 0000000000..0cc9e5c55e --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx @@ -0,0 +1,85 @@ +import React from 'react'; +import { useIntl } from 'react-intl'; + +import Button from '~core/Button'; +import { Tooltip } from '~core/Popover'; +import { Stages } from '~pages/IncorporationPage/constants'; +import { StageObject } from '~pages/IncorporationPage/types'; + +import styles from './StagesButton.css'; + +const displayName = 'dashboard.ExpenditurePage.Stages.StagesButton'; + +interface Props { + activeStage?: StageObject; + buttonDisabled?: boolean; + buttonAction?: VoidFunction; +} + +const StagesButton = ({ activeStage, buttonDisabled, buttonAction }: Props) => { + const { formatMessage } = useIntl(); + const buttonText = + typeof activeStage?.buttonText === 'string' + ? activeStage.buttonText + : activeStage?.buttonText && formatMessage(activeStage.buttonText); + + if (!activeStage) return null; + + if ( + activeStage.id === Stages.Processing || + activeStage.id === Stages.Complete + ) { + return null; + } + + if (activeStage?.buttonTooltip) { + return ( + + + {typeof activeStage.buttonTooltip === 'string' + ? activeStage.buttonTooltip + : formatMessage(activeStage.buttonTooltip)} +
+ } + popperOptions={{ + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 8], + }, + }, + ], + }} + > + + + + ); + } + + return ( + + ); +}; + +StagesButton.displayName = displayName; + +export default StagesButton; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts new file mode 100644 index 0000000000..4085c13edd --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts @@ -0,0 +1 @@ +export { default } from './StagesButton'; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts new file mode 100644 index 0000000000..11bb6dccd3 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts @@ -0,0 +1 @@ +export { default } from './Stages'; diff --git a/src/modules/pages/components/IncorporationPage/constants.ts b/src/modules/pages/components/IncorporationPage/constants.ts index 311d840016..ddaae0e2e3 100644 --- a/src/modules/pages/components/IncorporationPage/constants.ts +++ b/src/modules/pages/components/IncorporationPage/constants.ts @@ -144,6 +144,7 @@ export const stages: StageObject[] = [ title: MSG.create, description: MSG.createDesc, buttonText: MSG.createButtonText, + buttonTooltip: MSG.createTooltip, }, { id: Stages.Created, From 2ee1fc2d5f373f73ef2d7174c158d7ca3ca8bcf8 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Mon, 2 Jan 2023 14:15:19 +0100 Subject: [PATCH 02/16] added validation --- .../Stages/StageItem/StageItem.css | 51 ------ .../Stages/StageItem/StageItem.css.d.ts | 8 - .../Stages/StageItem/StageItem.tsx | 42 ----- .../Stages/StageItem/index.ts | 1 - .../DAOIncorporation/Stages/Stages.css | 104 ------------ .../DAOIncorporation/Stages/Stages.css.d.ts | 10 -- .../DAOIncorporation/Stages/Stages.tsx | 152 ------------------ .../Stages/StagesButton/StagesButton.css | 14 -- .../Stages/StagesButton/StagesButton.css.d.ts | 3 - .../Stages/StagesButton/StagesButton.tsx | 85 ---------- .../Stages/StagesButton/index.ts | 1 - .../DAOIncorporation/Stages/index.ts | 1 - .../Incorporation/Stages/FormStages.tsx | 108 +++++++++++++ .../components/IncorporationPage/constants.ts | 1 - 14 files changed, 108 insertions(+), 473 deletions(-) delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/index.ts create mode 100644 src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css deleted file mode 100644 index 3bbfbd6273..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css +++ /dev/null @@ -1,51 +0,0 @@ -.container { - display: flex; - align-items: baseline; - padding: 9px 0; - position: relative; -} - -.dot { - margin-right: 14px; - height: 7px; - width: 7px; - min-width: 7px; - border: 1px solid var(--temp-grey-blue-7); - border-radius: 50%; -} - -.verticalLine { - height: 60%; - position: absolute; - bottom: -7px; - left: 3px; - border-left: 1px solid var(--temp-grey-6); -} - -.activeDot { - border: 1px solid var(--primary); - background-color: var(--primary); -} - -.label { - margin-bottom: 8px; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: var(--dark); - letter-spacing: var(--spacing-medium); -} - -.activeLabel { - color: var(--temp-grey-blue-7); -} - -.description { - font-size: var(--size-tiny); - font-weight: var(--weight-bold); - color: var(--temp-grey-blue-7); - letter-spacing: var(--spacing-medium); -} - -.completedLabel { - color: var(--temp-grey-blue-7); -} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts deleted file mode 100644 index 76c5a5b024..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.css.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const container: string; -export const dot: string; -export const verticalLine: string; -export const activeDot: string; -export const label: string; -export const activeLabel: string; -export const description: string; -export const completedLabel: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx deleted file mode 100644 index cf9ad5e928..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/StageItem.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import { FormattedMessage, MessageDescriptor } from 'react-intl'; -import classNames from 'classnames'; - -import styles from './StageItem.css'; - -interface Props { - title?: MessageDescriptor; - description?: MessageDescriptor; - isActive: boolean; - isLast?: boolean; -} -const displayName = 'dashboard.ExpenditurePage.Stages.StageItem'; - -const StageItem = ({ title, description, isActive, isLast }: Props) => { - return ( -
-
- {!isLast &&
} -
-
- -
-
- -
-
-
- ); -}; - -StageItem.displayName = displayName; - -export default StageItem; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts deleted file mode 100644 index 234df6a6cb..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StageItem/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './StageItem'; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css deleted file mode 100644 index cb87d68bb6..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css +++ /dev/null @@ -1,104 +0,0 @@ -@value iconColor: var(--temp-grey-blue-7); - -.mainContainer { - padding-top: 20px; - max-width: 340px; -} - -.stagesText { - display: flex; - align-items: center; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - line-height: 18px; - color: var(--temp-grey-blue-7); -} - -.statusContainer { - display: flex; - justify-content: space-between; - padding: 10px 0; - border-bottom: 1px solid var(--temp-grey-6); -} - -.statusContainer:first-child { - padding-top: 0; -} - -.icon svg { - height: 18px; - width: 18px; - fill: var(--temp-grey-blue-7); -} - -.buttonsContainer { - display: flex; - align-items: center; -} - -.buttonsContainer button:not(:last-of-type) { - margin-right: 30px; -} - -.buttonsContainer button { - &:disabled { - height: 20px; - border: none; - border-radius: 5px; - background-color: var(--colony-light-blue); - font-weight: var(--weight-bold); - color: var(--temp-grey-blue-7); - } - - &:disabled:hover { - background-color: var(--colony-light-blue); - color: var(--temp-grey-blue-7); - cursor: default; - } -} - -.iconButton { - margin-left: 0; - padding: 0; - border: none; - background-color: transparent; -} - -.iconButton i { - display: flex; -} - -.iconButton:hover { - cursor: pointer; -} - -.iconButtonDisabled { - opacity: 0.5; -} - -.iconWrapper { - position: relative; -} - -.iconWrapper:hover { - &::after { - height: 30px; - width: 30px; - position: absolute; - top: 0; - left: 0; - border-radius: 50%; - background-color: var(--action-secondary); - transform: translate(-6px, -6px); - content: ''; - opacity: 0.1; - } -} - -.iconButtonDisabled:hover { - cursor: not-allowed; -} - -.buttonTooltip { - max-width: 192px; -} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts deleted file mode 100644 index 1c668b5f59..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.css.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const iconColor: string; -export const mainContainer: string; -export const stagesText: string; -export const statusContainer: string; -export const icon: string; -export const buttonsContainer: string; -export const iconButton: string; -export const iconButtonDisabled: string; -export const iconWrapper: string; -export const buttonTooltip: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx deleted file mode 100644 index d07cff6cf7..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/Stages.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; -import copyToClipboard from 'copy-to-clipboard'; -import classNames from 'classnames'; - -import Button from '~core/Button'; -import Icon from '~core/Icon'; -import { Tooltip } from '~core/Popover'; - -import StageItem from './StageItem'; -import StagesButton from './StagesButton'; -import styles from './Stages.css'; -import { StageObject } from '~pages/IncorporationPage/types'; -import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; - -const MSG = defineMessages({ - stages: { - id: 'dashboard.DAOIncorporation.Stages.stages', - defaultMessage: 'Stages', - }, - deleteDraft: { - id: 'dashboard.DAOIncorporation.Stages.deleteDraft', - defaultMessage: 'Delete draft', - }, - tooltipDeleteText: { - id: 'dashboard.DAOIncorporation.Stages.tooltipDeleteText', - defaultMessage: 'Delete', - }, - tooltipShareText: { - id: 'dashboard.DAOIncorporation.Stages.tooltipShareText', - defaultMessage: 'Share URL', - }, -}); - -const displayName = 'dashboard.DAOIncorporation.Stages'; - -export interface Props { - stages: StageObject[]; - activeStageId: StagesEnum; - buttonDisabled?: boolean; - buttonAction?: VoidFunction; -} - -const Stages = ({ - stages, - activeStageId, - buttonDisabled, - buttonAction, -}: Props) => { - const [valueIsCopied, setValueIsCopied] = useState(false); - const userFeedbackTimer = useRef(null); - - const handleClipboardCopy = () => { - copyToClipboard(window.location.href); - setValueIsCopied(true); - userFeedbackTimer.current = setTimeout(() => setValueIsCopied(false), 2000); - }; - - useEffect(() => () => clearTimeout(userFeedbackTimer.current), [ - userFeedbackTimer, - ]); - - const activeIndex = stages.findIndex((stage) => stage.id === activeStageId); - const activeStage = stages.find((stage) => stage.id === activeStageId); - - return ( -
-
-
- -
-
- <> - - - - -
-
- {stages.map(({ id, title, description }, index) => ( - - ))} -
- ); -}; - -Stages.displayName = displayName; - -export default Stages; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css deleted file mode 100644 index 5f73f896d7..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css +++ /dev/null @@ -1,14 +0,0 @@ -.button { - composes: themePrimary main from '~core/Button/Button.css'; - padding: 0; - height: 29px; - width: 100px; -} - -.buttonTooltip { - max-width: 192px; -} - -.buttonWithTooltip { - margin-left: 20px; -} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts deleted file mode 100644 index 5941522346..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.css.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const button: string; -export const buttonTooltip: string; -export const buttonWithTooltip: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx deleted file mode 100644 index 0cc9e5c55e..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/StagesButton.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React from 'react'; -import { useIntl } from 'react-intl'; - -import Button from '~core/Button'; -import { Tooltip } from '~core/Popover'; -import { Stages } from '~pages/IncorporationPage/constants'; -import { StageObject } from '~pages/IncorporationPage/types'; - -import styles from './StagesButton.css'; - -const displayName = 'dashboard.ExpenditurePage.Stages.StagesButton'; - -interface Props { - activeStage?: StageObject; - buttonDisabled?: boolean; - buttonAction?: VoidFunction; -} - -const StagesButton = ({ activeStage, buttonDisabled, buttonAction }: Props) => { - const { formatMessage } = useIntl(); - const buttonText = - typeof activeStage?.buttonText === 'string' - ? activeStage.buttonText - : activeStage?.buttonText && formatMessage(activeStage.buttonText); - - if (!activeStage) return null; - - if ( - activeStage.id === Stages.Processing || - activeStage.id === Stages.Complete - ) { - return null; - } - - if (activeStage?.buttonTooltip) { - return ( - - - {typeof activeStage.buttonTooltip === 'string' - ? activeStage.buttonTooltip - : formatMessage(activeStage.buttonTooltip)} -
- } - popperOptions={{ - modifiers: [ - { - name: 'offset', - options: { - offset: [0, 8], - }, - }, - ], - }} - > - - - - ); - } - - return ( - - ); -}; - -StagesButton.displayName = displayName; - -export default StagesButton; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts deleted file mode 100644 index 4085c13edd..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/StagesButton/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './StagesButton'; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts b/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts deleted file mode 100644 index 11bb6dccd3..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './Stages'; diff --git a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx new file mode 100644 index 0000000000..7abb9c16fd --- /dev/null +++ b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx @@ -0,0 +1,108 @@ +import { useFormikContext, setNestedObjectValues, FormikTouched } from 'formik'; +import React, { useCallback, useMemo } from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import { flattenObject } from '~dashboard/ExpenditurePage/Stages/utils'; +import { FIX_TRIGGER_EVENT_NAME } from '~pages/ExpenditurePage/constants'; +import { StageObject, ValuesType } from '~pages/IncorporationPage/types'; +import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; + +import Stages from './Stages'; +import styles from './Stages.css'; + +const displayName = 'dashboard.Incorporation.Stages.FormStages'; + +const MSG = defineMessages({ + singleErrorMessage: { + id: 'dashboard.Incorporation.Stages.FormStages.singleErrorMessage', + defaultMessage: '{number} required field has an error.', + }, + mulitpleErrorMessage: { + id: 'dashboard.Incorporation.Stages.FormStages.mulitpleErrorMessage', + defaultMessage: '{number} required fields have an error.', + }, + errorMessageAction: { + id: 'dashboard.Incorporation.Stages.FormStages.errorMessageAction', + defaultMessage: 'Fix it!', + }, +}); + +export interface Props { + stages: StageObject[]; + activeStageId: StagesEnum; +} + +const FormStages = ({ stages, activeStageId }: Props) => { + const { values, handleSubmit, validateForm, setTouched, errors: formikErr } = + useFormikContext() || {}; + + const formikErrors = useMemo(() => { + const errorsFlat = flattenObject(formikErr); + return Object.keys(errorsFlat); + }, [formikErr]); + + const handleSaveDraft = useCallback(async () => { + const errors = await validateForm(values); + const errorsLength = Object.keys(errors)?.length; + setTouched(setNestedObjectValues>(errors, true)); + + return !errorsLength && handleSubmit(values as any); + }, [handleSubmit, setTouched, validateForm, values]); + + const handleFixButtonClick = useCallback(() => { + setTouched( + setNestedObjectValues>(formikErr, true), + ); + if (!formikErrors.length) return; + + const firstError = document.getElementsByName(formikErrors[0])?.[0]; + + if (firstError?.tagName.toLowerCase() === 'input') { + (firstError as HTMLElement).focus(); + } else if (firstError?.tagName.toLowerCase() === 'textarea') { + (firstError as HTMLElement).focus(); + } else { + const customEvent = new CustomEvent(FIX_TRIGGER_EVENT_NAME, { + detail: { + name: formikErrors[0], + }, + }); + + window.dispatchEvent(customEvent); + } + }, [setTouched, formikErr, formikErrors]); + + return ( +
+ {!!formikErrors.length && ( +
+

+ 1 + ? { ...MSG.mulitpleErrorMessage } + : { ...MSG.singleErrorMessage })} + values={{ number: formikErrors.length }} + /> +

+ +
+ )} + + +
+ ); +}; + +FormStages.displayName = displayName; + +export default FormStages; diff --git a/src/modules/pages/components/IncorporationPage/constants.ts b/src/modules/pages/components/IncorporationPage/constants.ts index ddaae0e2e3..311d840016 100644 --- a/src/modules/pages/components/IncorporationPage/constants.ts +++ b/src/modules/pages/components/IncorporationPage/constants.ts @@ -144,7 +144,6 @@ export const stages: StageObject[] = [ title: MSG.create, description: MSG.createDesc, buttonText: MSG.createButtonText, - buttonTooltip: MSG.createTooltip, }, { id: Stages.Created, From 92680a78755035c62fc7156755eb8269b0cfb9e3 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Mon, 23 Jan 2023 11:05:36 +0100 Subject: [PATCH 03/16] fixed condition, removed unnecessary type --- .../dashboard/components/Incorporation/Stages/FormStages.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx index 7abb9c16fd..606ef0e586 100644 --- a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx +++ b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx @@ -57,9 +57,7 @@ const FormStages = ({ stages, activeStageId }: Props) => { const firstError = document.getElementsByName(formikErrors[0])?.[0]; - if (firstError?.tagName.toLowerCase() === 'input') { - (firstError as HTMLElement).focus(); - } else if (firstError?.tagName.toLowerCase() === 'textarea') { + if (['textarea', 'input'].includes(firstError?.tagName.toLowerCase())) { (firstError as HTMLElement).focus(); } else { const customEvent = new CustomEvent(FIX_TRIGGER_EVENT_NAME, { From d706bedbd84a6dc74a23e9201d58ced858e2ce65 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Tue, 3 Jan 2023 12:47:51 +0100 Subject: [PATCH 04/16] [wip]locked sidebar form --- .../LockedIncorporationForm.css | 113 +++++++++++++++ .../LockedIncorporationForm.css.d.ts | 13 ++ .../LockedIncorporationForm.tsx | 131 ++++++++++++++++++ .../LockedIncorporationForm/index.ts | 1 + .../LockedProtectors/LockedProtectors.css | 47 +++++++ .../LockedProtectors.css.d.ts | 10 ++ .../LockedProtectors/LockedProtectors.tsx | 101 ++++++++++++++ .../LockedProtectors/index.ts | 1 + .../IncorporationPage/IncorporationPage.tsx | 2 + 9 files changed, 419 insertions(+) create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css new file mode 100644 index 0000000000..825f2e246a --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css @@ -0,0 +1,113 @@ +@value paddingTop: 46px; +@value lockedPaddingTop: 75px; +@value paddingRightLeftBottom: 54px; + +.container { + padding: paddingTop paddingRightLeftBottom paddingRightLeftBottom; +} + +.costRow { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; +} + +.cost { + display: flex; + align-items: center; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.cost i { + margin-right: 8px; +} + +.labelWrapper { + display: flex; + align-items: center; + justify-content: flex-start; +} + +.labelWrapper label { + margin-right: 8px; + width: auto; +} + +.labelWrapper > div { + max-width: 250px; +} + +.nameInputs { + padding: 12px 0 0 0; +} + +.nameInputs input { + height: 44px; + font-size: var(--size-normal); + font-weight: var(--weight-bold); + color: var(--dark); + letter-spacing: var(--spacing-normal); +} + +.nameInputs > div:not(:first-child) { + margin-bottom: 12px; +} + +.nameInputs label { + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); +} + +.namesWrapper { + /* border: 1px solid red */ +} + +.namesWrapper label { + flex: 1; + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.description { + /* border: 1px solid red */ +} + +.descriptionWrapper { + display: flex; + align-items: baseline; +} + +.descriptionWrapper label { + flex: 1; + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.descriptionWrapper > div { + flex: 2.5; + font-size: var(--size-normal); + font-weight: var(--weight-bold); + text-align: right; + color: color-mod(var(--dark) alpha(85%)); + letter-spacing: 0.1px; +} + +.title { + margin-bottom: 16px; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.label { + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); + letter-spacing: var(--spacing-medium); +} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts new file mode 100644 index 0000000000..ac2d41545d --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts @@ -0,0 +1,13 @@ +export const paddingTop: string; +export const lockedPaddingTop: string; +export const paddingRightLeftBottom: string; +export const container: string; +export const costRow: string; +export const cost: string; +export const labelWrapper: string; +export const nameInputs: string; +export const namesWrapper: string; +export const description: string; +export const descriptionWrapper: string; +export const title: string; +export const label: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx new file mode 100644 index 0000000000..f5c6001ebe --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx @@ -0,0 +1,131 @@ +import React from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import { FormSection, InputLabel, SelectHorizontal, Form } from '~core/Fields'; +import { Colony } from '~data/index'; +import Icon from '~core/Icon'; +import { ValuesType } from '~pages/IncorporationPage/types'; + +import LockedProtectors from '../LockedProtectors'; + +import styles from './LockedIncorporationForm.css'; + +export const MSG = defineMessages({ + incorporation: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.incorporation`, + defaultMessage: 'Incorporation', + }, + initialCost: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.initialCost`, + defaultMessage: 'Initial cost', + }, + ongoingCost: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.ongoingCost`, + defaultMessage: 'Ongoing cost', + }, + cost: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.cost`, + defaultMessage: '{icon} {amount} {currency}', + }, + nameLabel: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.nameLabel`, + defaultMessage: 'Corporation name', + }, + descriptionLabel: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.descriptionLabel`, + defaultMessage: 'DAO Purpose', + }, +}); + +const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm`; + +export interface Props { + sidebarRef: HTMLElement | null; + colony: Colony; + formValues: ValuesType; +} + +const LockedIncorporationForm = ({ sidebarRef }: Props) => { + return ( +
+ +
+ +
+
+ +
+
+ +
+
+ , + amount: '5,300', + currency: 'USDC', + }} + /> +
+
+
+ +
+
+ +
+
+ , + amount: '3,800 / year', + currency: 'USDC', + }} + /> +
+
+
+ +
+ {/* */} +
{}}> + + +
+
+ +
+ +
+ WallStreetBets is on a mission to deploy decentralized satellites in + our skies. +
+
+
+ +
+ ); +}; + +LockedIncorporationForm.displayName = displayName; + +export default LockedIncorporationForm; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts new file mode 100644 index 0000000000..836476fa94 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts @@ -0,0 +1 @@ +export { default } from './LockedIncorporationForm'; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css new file mode 100644 index 0000000000..5c898c4e6a --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css @@ -0,0 +1,47 @@ +.wrapper { + /* border: 1px solid red */ +} + +.protectorsLabelWrapper { + /* border: 1px solid red */ +} + +.label { + /* border: 1px solid red */ +} + +.userAvatarContainer { + /* border: 1px solid red */ +} + +.userName { + /* border: 1px solid red */ +} + +.row { + display: flex; +} + +.row label { + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); +} + +.signing { + /* border: 1px solid red */ +} + +.labelWrapper { + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); +} + +.signOptionWrapper { + /* border: 1px solid red */ +} + +.signOptionLabel { + /* border: 1px solid red */ +} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts new file mode 100644 index 0000000000..dc35015ce0 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts @@ -0,0 +1,10 @@ +export const wrapper: string; +export const protectorsLabelWrapper: string; +export const label: string; +export const userAvatarContainer: string; +export const userName: string; +export const row: string; +export const signing: string; +export const labelWrapper: string; +export const signOptionWrapper: string; +export const signOptionLabel: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx new file mode 100644 index 0000000000..1f106508bb --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import { FormSection, InputLabel } from '~core/Fields'; +import QuestionMarkTooltip from '~core/QuestionMarkTooltip'; +import { Colony } from '~data/index'; + +import styles from './LockedProtectors.css'; +import { ValuesType } from '~pages/IncorporationPage/types'; + +export const MSG = defineMessages({ + protectors: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.protectors`, + defaultMessage: 'Protectors', + }, + protectorsTooltip: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.protectorsTooltip`, + defaultMessage: `A Protector's role in a DAO legal corporation is to ratify the decisions of the DAO. Their purpose is to act on behalf of the DAO and handle legal the required administration. Learn more`, + }, + unverified: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.unverified`, + defaultMessage: 'Unverified', + }, + verified: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.verified`, + defaultMessage: 'Verified', + }, + mainContact: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.mainContact`, + defaultMessage: 'Main contact', + }, + signing: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.signing`, + defaultMessage: 'Signing', + }, + mainContactTooltip: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.mainContactTooltip`, + defaultMessage: `The main contact is required during the incorporation process and is also required to use their delivery address details for the registration.`, + }, + signOptionTooltip: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.signOptionTooltip`, + defaultMessage: `Decide the requirements as to how many Protectors are required to sign legal documents to enact the decisions of a DAO.`, + }, +}); + +const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors`; + +export interface Props { + protectors: ValuesType['protectors']; + colony: Colony; +} + +const LockedProtectors = () => { + return ( + <> + +
+
+
+ +
+ +
+
+
+ + {/* {protectors?.map((protector) => { + return ( +
+ +
+ +
+
+ )})} */} +
+ +
+ + {/*
+ +
+ +
+
*/} +
+
+
+
+ + +
+
All need to sign
+
+ + ); +}; + +LockedProtectors.displayName = displayName; + +export default LockedProtectors; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts new file mode 100644 index 0000000000..2c15a2c788 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts @@ -0,0 +1 @@ +export { default } from './LockedProtectors'; diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index e5475565aa..5964a27307 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -23,6 +23,8 @@ import { } from './constants'; import { ValuesType } from './types'; import styles from './IncorporationPage.css'; +import { ValuesType } from './types'; +import LockedIncorporationForm from '~dashboard/DAOIncorporation/IncorporationForm/LockedIncorporationForm'; const displayName = 'pages.IncorporationPage'; From 9c6cd9b9388903ebf6b547ca5f90f4647ad3be73 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Thu, 5 Jan 2023 12:24:08 +0100 Subject: [PATCH 05/16] added locked sidebar --- .../LockedIncorporationForm.css | 48 ++++++--- .../LockedIncorporationForm.css.d.ts | 5 +- .../LockedIncorporationForm.tsx | 43 ++++---- .../LockedProtectors/LockedProtectors.css | 68 ++++++++++--- .../LockedProtectors.css.d.ts | 4 +- .../LockedProtectors/LockedProtectors.tsx | 99 ++++++++++++++----- .../IncorporationForm/constants.ts | 9 ++ 7 files changed, 196 insertions(+), 80 deletions(-) create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css index 825f2e246a..85f0a651fc 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css @@ -2,6 +2,16 @@ @value lockedPaddingTop: 75px; @value paddingRightLeftBottom: 54px; +@keyframes slideDown { + 0% { + max-height: 0; + } + + 100% { + max-height: 180px; + } +} + .container { padding: paddingTop paddingRightLeftBottom paddingRightLeftBottom; } @@ -63,23 +73,10 @@ color: color-mod(var(--dark) alpha(85%)); } -.namesWrapper { - /* border: 1px solid red */ -} - -.namesWrapper label { - flex: 1; - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.description { - /* border: 1px solid red */ -} - .descriptionWrapper { display: flex; align-items: baseline; + padding: 12px 0; } .descriptionWrapper label { @@ -88,7 +85,7 @@ letter-spacing: var(--spacing-medium); } -.descriptionWrapper > div { +.description { flex: 2.5; font-size: var(--size-normal); font-weight: var(--weight-bold); @@ -111,3 +108,24 @@ color: color-mod(var(--temp-grey-blue-7) alpha(85%)); letter-spacing: var(--spacing-medium); } + +.namesWrapper label { + flex: 1; + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); + letter-spacing: var(--spacing-medium); +} + +.namesWrapper ul { + position: static; + overflow: hidden; + animation-name: slideDown; + animation-duration: 250ms; +} + +.namesWrapper span { + font-size: var(--size-smallish); +} + +.namesWrapper li:hover { + background-color: transparent; +} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts index ac2d41545d..ef5111b4ae 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts @@ -6,8 +6,9 @@ export const costRow: string; export const cost: string; export const labelWrapper: string; export const nameInputs: string; -export const namesWrapper: string; -export const description: string; export const descriptionWrapper: string; +export const description: string; export const title: string; export const label: string; +export const namesWrapper: string; +export const slideDown: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx index f5c6001ebe..7c965323a8 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx @@ -1,8 +1,7 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import { FormSection, InputLabel, SelectHorizontal, Form } from '~core/Fields'; -import { Colony } from '~data/index'; import Icon from '~core/Icon'; import { ValuesType } from '~pages/IncorporationPage/types'; @@ -40,12 +39,19 @@ export const MSG = defineMessages({ const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm`; export interface Props { - sidebarRef: HTMLElement | null; - colony: Colony; formValues: ValuesType; } -const LockedIncorporationForm = ({ sidebarRef }: Props) => { +const LockedIncorporationForm = ({ formValues }: Props) => { + const alternativeNames = useMemo( + () => + formValues.alternativeNames.map((name) => ({ + label: name, + value: name, + })), + [formValues.alternativeNames], + ); + return (
@@ -88,9 +94,9 @@ const LockedIncorporationForm = ({ sidebarRef }: Props) => {
-
- {/* */} -
{}}> + {/* A form is used here because the SelectHorizontal component must be wrapped in a Formik form. It doesn't send data anywhere. */} + {}}> +
{ theme: 'alt', width: 'content', }} - options={[ - { label: 'WallStreetBets', value: 'WallStreetBets' }, - { label: 'WallStreetBets2', value: 'WallStreetBets' }, - ]} - scrollContainer={sidebarRef} - placement="bottom" - withDropdownElement - optionSizeLarge + renderActiveOption={() => <>{formValues.name}} + options={alternativeNames} autoHeight unselectable /> - -
+
+
-
- WallStreetBets is on a mission to deploy decentralized satellites in - our skies. -
+
{formValues.purpose}
- +
); }; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css index 5c898c4e6a..508476d5b6 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css @@ -1,47 +1,91 @@ .wrapper { - /* border: 1px solid red */ + margin-top: 32px; } .protectorsLabelWrapper { - /* border: 1px solid red */ + display: flex; + align-items: center; +} + +.protectorsLabelWrapper span { + display: inline-block; + height: 16px; } .label { - /* border: 1px solid red */ + margin-right: 8px; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); } .userAvatarContainer { - /* border: 1px solid red */ + display: flex; + align-items: center; } .userName { - /* border: 1px solid red */ + margin-left: 8px; } .row { display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0; } .row label { font-size: var(--size-smallish); font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); } -.signing { - /* border: 1px solid red */ +.row > span { + display: flex; + justify-content: center; + align-items: center; + height: 20px; + width: 94px; + border-radius: 5px; +} + +.mainContactRow { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; } .labelWrapper { + display: flex; font-size: var(--size-smallish); font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); +} + +.labelWrapper > span { + margin-left: 8px; +} + +.labelWrapper > div { + max-width: 250px; +} + +.protectorsLabelWrapper > div { + max-width: 250px; } .signOptionWrapper { - /* border: 1px solid red */ + display: flex; + align-items: baseline; + justify-content: space-between; + padding: 9px 0; } -.signOptionLabel { - /* border: 1px solid red */ +.signing { + font-size: var(--size-normal); + font-weight: var(--weight-bold); + color: color-mod(var(--dark) alpha(85%)); + letter-spacing: var(--spacing-medium); } diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts index dc35015ce0..e3c52d6de2 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts @@ -4,7 +4,7 @@ export const label: string; export const userAvatarContainer: string; export const userName: string; export const row: string; -export const signing: string; +export const mainContactRow: string; export const labelWrapper: string; export const signOptionWrapper: string; -export const signOptionLabel: string; +export const signing: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx index 1f106508bb..34275d4f53 100644 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx @@ -1,12 +1,16 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import { FormSection, InputLabel } from '~core/Fields'; import QuestionMarkTooltip from '~core/QuestionMarkTooltip'; -import { Colony } from '~data/index'; +import { ValuesType } from '~pages/IncorporationPage/types'; +import UserAvatar from '~core/UserAvatar'; +import UserMention from '~core/UserMention'; +import Tag from '~core/Tag'; + +import { SignOption, VerificationStatus } from '../constants'; import styles from './LockedProtectors.css'; -import { ValuesType } from '~pages/IncorporationPage/types'; export const MSG = defineMessages({ protectors: { @@ -41,19 +45,32 @@ export const MSG = defineMessages({ id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.signOptionTooltip`, defaultMessage: `Decide the requirements as to how many Protectors are required to sign legal documents to enact the decisions of a DAO.`, }, + individual: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.individual`, + defaultMessage: 'Individual signing', + }, + multiple: { + id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.multiple`, + defaultMessage: 'All need to sign', + }, }); const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors`; export interface Props { - protectors: ValuesType['protectors']; - colony: Colony; + formValues: ValuesType; } -const LockedProtectors = () => { +const LockedProtectors = ({ formValues }: Props) => { + const signLabel = useMemo(() => { + return formValues.signOption === SignOption.Individual + ? MSG.individual + : MSG.multiple; + }, [formValues]); + return ( <> - +
@@ -64,34 +81,64 @@ const LockedProtectors = () => {
- {/* {protectors?.map((protector) => { + {formValues.protectors?.map((protector) => { + const { profile } = protector || {}; + const { walletAddress, username, displayName: userDispalyName } = + profile || {}; + return ( -
- -
- +
+ + {protector.verified + ? VerificationStatus.Verified + : VerificationStatus.Unverified} + +
+ +
+ +
+
-
- )})} */} + ); + })} -
- - {/*
- +
+
+ + +
+
+
- +
-
*/} +
-
-
- - + +
+
+ + +
+
+ +
-
All need to sign
-
+ ); }; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts new file mode 100644 index 0000000000..8d8f7ec174 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts @@ -0,0 +1,9 @@ +export enum SignOption { + Individual = 'Individual', + Multiple = 'Multiple', +} + +export enum VerificationStatus { + Verified = 'Verified', + Unverified = 'Unverified', +} From f9dd1db3520e2c80d5432b50bfc7fba76746f16e Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 13 Jan 2023 13:14:21 +0100 Subject: [PATCH 06/16] renamed to Incorporation --- .../LockedIncorporationForm.css | 131 ---------------- .../LockedIncorporationForm.css.d.ts | 14 -- .../LockedIncorporationForm.tsx | 128 --------------- .../LockedIncorporationForm/index.ts | 1 - .../LockedProtectors/LockedProtectors.css | 91 ----------- .../LockedProtectors.css.d.ts | 10 -- .../LockedProtectors/LockedProtectors.tsx | 148 ------------------ .../LockedProtectors/index.ts | 1 - .../IncorporationForm/constants.ts | 9 -- .../IncorporationPage/IncorporationPage.tsx | 2 +- 10 files changed, 1 insertion(+), 534 deletions(-) delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css deleted file mode 100644 index 85f0a651fc..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css +++ /dev/null @@ -1,131 +0,0 @@ -@value paddingTop: 46px; -@value lockedPaddingTop: 75px; -@value paddingRightLeftBottom: 54px; - -@keyframes slideDown { - 0% { - max-height: 0; - } - - 100% { - max-height: 180px; - } -} - -.container { - padding: paddingTop paddingRightLeftBottom paddingRightLeftBottom; -} - -.costRow { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 0; -} - -.cost { - display: flex; - align-items: center; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.cost i { - margin-right: 8px; -} - -.labelWrapper { - display: flex; - align-items: center; - justify-content: flex-start; -} - -.labelWrapper label { - margin-right: 8px; - width: auto; -} - -.labelWrapper > div { - max-width: 250px; -} - -.nameInputs { - padding: 12px 0 0 0; -} - -.nameInputs input { - height: 44px; - font-size: var(--size-normal); - font-weight: var(--weight-bold); - color: var(--dark); - letter-spacing: var(--spacing-normal); -} - -.nameInputs > div:not(:first-child) { - margin-bottom: 12px; -} - -.nameInputs label { - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); -} - -.descriptionWrapper { - display: flex; - align-items: baseline; - padding: 12px 0; -} - -.descriptionWrapper label { - flex: 1; - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.description { - flex: 2.5; - font-size: var(--size-normal); - font-weight: var(--weight-bold); - text-align: right; - color: color-mod(var(--dark) alpha(85%)); - letter-spacing: 0.1px; -} - -.title { - margin-bottom: 16px; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.label { - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.namesWrapper label { - flex: 1; - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); - letter-spacing: var(--spacing-medium); -} - -.namesWrapper ul { - position: static; - overflow: hidden; - animation-name: slideDown; - animation-duration: 250ms; -} - -.namesWrapper span { - font-size: var(--size-smallish); -} - -.namesWrapper li:hover { - background-color: transparent; -} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts deleted file mode 100644 index ef5111b4ae..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.css.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const paddingTop: string; -export const lockedPaddingTop: string; -export const paddingRightLeftBottom: string; -export const container: string; -export const costRow: string; -export const cost: string; -export const labelWrapper: string; -export const nameInputs: string; -export const descriptionWrapper: string; -export const description: string; -export const title: string; -export const label: string; -export const namesWrapper: string; -export const slideDown: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx deleted file mode 100644 index 7c965323a8..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/LockedIncorporationForm.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React, { useMemo } from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; - -import { FormSection, InputLabel, SelectHorizontal, Form } from '~core/Fields'; -import Icon from '~core/Icon'; -import { ValuesType } from '~pages/IncorporationPage/types'; - -import LockedProtectors from '../LockedProtectors'; - -import styles from './LockedIncorporationForm.css'; - -export const MSG = defineMessages({ - incorporation: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.incorporation`, - defaultMessage: 'Incorporation', - }, - initialCost: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.initialCost`, - defaultMessage: 'Initial cost', - }, - ongoingCost: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.ongoingCost`, - defaultMessage: 'Ongoing cost', - }, - cost: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.cost`, - defaultMessage: '{icon} {amount} {currency}', - }, - nameLabel: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.nameLabel`, - defaultMessage: 'Corporation name', - }, - descriptionLabel: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm.descriptionLabel`, - defaultMessage: 'DAO Purpose', - }, -}); - -const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedIncorporationForm`; - -export interface Props { - formValues: ValuesType; -} - -const LockedIncorporationForm = ({ formValues }: Props) => { - const alternativeNames = useMemo( - () => - formValues.alternativeNames.map((name) => ({ - label: name, - value: name, - })), - [formValues.alternativeNames], - ); - - return ( -
- -
- -
-
- -
-
- -
-
- , - amount: '5,300', - currency: 'USDC', - }} - /> -
-
-
- -
-
- -
-
- , - amount: '3,800 / year', - currency: 'USDC', - }} - /> -
-
-
- - {/* A form is used here because the SelectHorizontal component must be wrapped in a Formik form. It doesn't send data anywhere. */} -
{}}> -
- <>{formValues.name}} - options={alternativeNames} - autoHeight - unselectable - /> -
-
-
- -
- -
{formValues.purpose}
-
-
- -
- ); -}; - -LockedIncorporationForm.displayName = displayName; - -export default LockedIncorporationForm; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts deleted file mode 100644 index 836476fa94..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedIncorporationForm/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './LockedIncorporationForm'; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css deleted file mode 100644 index 508476d5b6..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css +++ /dev/null @@ -1,91 +0,0 @@ -.wrapper { - margin-top: 32px; -} - -.protectorsLabelWrapper { - display: flex; - align-items: center; -} - -.protectorsLabelWrapper span { - display: inline-block; - height: 16px; -} - -.label { - margin-right: 8px; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); -} - -.userAvatarContainer { - display: flex; - align-items: center; -} - -.userName { - margin-left: 8px; -} - -.row { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 0; -} - -.row label { - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); -} - -.row > span { - display: flex; - justify-content: center; - align-items: center; - height: 20px; - width: 94px; - border-radius: 5px; -} - -.mainContactRow { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 0; -} - -.labelWrapper { - display: flex; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); -} - -.labelWrapper > span { - margin-left: 8px; -} - -.labelWrapper > div { - max-width: 250px; -} - -.protectorsLabelWrapper > div { - max-width: 250px; -} - -.signOptionWrapper { - display: flex; - align-items: baseline; - justify-content: space-between; - padding: 9px 0; -} - -.signing { - font-size: var(--size-normal); - font-weight: var(--weight-bold); - color: color-mod(var(--dark) alpha(85%)); - letter-spacing: var(--spacing-medium); -} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts deleted file mode 100644 index e3c52d6de2..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.css.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const wrapper: string; -export const protectorsLabelWrapper: string; -export const label: string; -export const userAvatarContainer: string; -export const userName: string; -export const row: string; -export const mainContactRow: string; -export const labelWrapper: string; -export const signOptionWrapper: string; -export const signing: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx deleted file mode 100644 index 34275d4f53..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/LockedProtectors.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { useMemo } from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; - -import { FormSection, InputLabel } from '~core/Fields'; -import QuestionMarkTooltip from '~core/QuestionMarkTooltip'; -import { ValuesType } from '~pages/IncorporationPage/types'; -import UserAvatar from '~core/UserAvatar'; -import UserMention from '~core/UserMention'; -import Tag from '~core/Tag'; - -import { SignOption, VerificationStatus } from '../constants'; - -import styles from './LockedProtectors.css'; - -export const MSG = defineMessages({ - protectors: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.protectors`, - defaultMessage: 'Protectors', - }, - protectorsTooltip: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.protectorsTooltip`, - defaultMessage: `A Protector's role in a DAO legal corporation is to ratify the decisions of the DAO. Their purpose is to act on behalf of the DAO and handle legal the required administration. Learn more`, - }, - unverified: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.unverified`, - defaultMessage: 'Unverified', - }, - verified: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.verified`, - defaultMessage: 'Verified', - }, - mainContact: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.mainContact`, - defaultMessage: 'Main contact', - }, - signing: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.signing`, - defaultMessage: 'Signing', - }, - mainContactTooltip: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.mainContactTooltip`, - defaultMessage: `The main contact is required during the incorporation process and is also required to use their delivery address details for the registration.`, - }, - signOptionTooltip: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.signOptionTooltip`, - defaultMessage: `Decide the requirements as to how many Protectors are required to sign legal documents to enact the decisions of a DAO.`, - }, - individual: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.individual`, - defaultMessage: 'Individual signing', - }, - multiple: { - id: `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors.multiple`, - defaultMessage: 'All need to sign', - }, -}); - -const displayName = `dashboard.DAOIncorporation.IncorporationForm.LockedProtectors`; - -export interface Props { - formValues: ValuesType; -} - -const LockedProtectors = ({ formValues }: Props) => { - const signLabel = useMemo(() => { - return formValues.signOption === SignOption.Individual - ? MSG.individual - : MSG.multiple; - }, [formValues]); - - return ( - <> - -
-
-
- -
- -
-
-
- - {formValues.protectors?.map((protector) => { - const { profile } = protector || {}; - const { walletAddress, username, displayName: userDispalyName } = - profile || {}; - - return ( -
- - {protector.verified - ? VerificationStatus.Verified - : VerificationStatus.Unverified} - -
- -
- -
-
-
- ); - })} -
- -
-
- - -
-
- -
- -
-
-
-
- -
-
- - -
-
- -
-
-
- - ); -}; - -LockedProtectors.displayName = displayName; - -export default LockedProtectors; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts deleted file mode 100644 index 2c15a2c788..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/LockedProtectors/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './LockedProtectors'; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts deleted file mode 100644 index 8d8f7ec174..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum SignOption { - Individual = 'Individual', - Multiple = 'Multiple', -} - -export enum VerificationStatus { - Verified = 'Verified', - Unverified = 'Unverified', -} diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index 5964a27307..b9b3c5b17c 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -24,7 +24,7 @@ import { import { ValuesType } from './types'; import styles from './IncorporationPage.css'; import { ValuesType } from './types'; -import LockedIncorporationForm from '~dashboard/DAOIncorporation/IncorporationForm/LockedIncorporationForm'; +import LockedIncorporationForm from '~dashboard/Incorporation/IncorporationForm/LockedIncorporationForm'; const displayName = 'pages.IncorporationPage'; From 8a4c128df3c9092d85c1b27503c1f96abd660458 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Mon, 23 Jan 2023 09:39:25 +0100 Subject: [PATCH 07/16] fixed type errors --- .../Incorporation/IncorporationForm/Protectors/Protectors.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx index 4fa7617d57..2f5e47a80b 100644 --- a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx +++ b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx @@ -17,7 +17,6 @@ import Button from '~core/Button'; import Link from '~core/Link'; import SingleUserPicker from '../SingleUserPicker'; -import { SignOption } from '../constants'; import styles from './Protectors.css'; From ae6fd159ac98ca5a15f57a79ff40cbd38f9fd376 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Mon, 2 Jan 2023 14:15:19 +0100 Subject: [PATCH 08/16] added validation --- .../SingleUserPicker/SingleUserPicker.css | 35 ++++++ .../SingleUserPicker.css.d.ts | 4 + .../SingleUserPicker/SingleUserPicker.tsx | 70 ++++++++++++ .../SingleUserPicker/index.ts | 1 + .../DAOIncorporation/Stages/FormStages.tsx | 108 ++++++++++++++++++ 5 files changed, 218 insertions(+) create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts create mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css new file mode 100644 index 0000000000..2c0af7fa16 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css @@ -0,0 +1,35 @@ +.protectorWrapper { + display: flex; + justify-content: space-between; + padding: 11px 0 14px; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: color-mod(var(--temp-grey-blue-7) alpha(85%)); +} + +.selectWrapper { + display: flex; + justify-content: flex-start; + align-items: center; +} + +.protectorError { + font-size: var(--size-tiny); + white-space: nowrap; + color: var(--danger); + letter-spacing: var(--spacing-medium); +} + +.protectorWrapper label { + margin-right: 0; +} + +.deleteIcon { + height: 20px; + width: 20px; + fill: var(--pink); +} + +.deleteIcon:hover { + cursor: pointer; +} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts new file mode 100644 index 0000000000..3119c86cca --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts @@ -0,0 +1,4 @@ +export const protectorWrapper: string; +export const selectWrapper: string; +export const protectorError: string; +export const deleteIcon: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx new file mode 100644 index 0000000000..2fe3fcc6fe --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; +import { FieldArrayRenderProps, useField } from 'formik'; + +import { AnyUser } from '~data/index'; +import Icon from '~core/Icon'; +import UserPickerWithSearch from '~core/UserPickerWithSearch'; +import { Props as UserPickerProps } from '~core/UserPickerWithSearch/UserPickerWithSearch'; + +import styles from './SingleUserPicker.css'; + +export const MSG = defineMessages({ + deleteIconTitle: { + id: `dashboard.DAOIncorporation.IncorporationForm.SingleUserPicker.deleteIconTitle`, + defaultMessage: 'Delete recipient', + }, +}); + +const displayName = + 'dashboard.DAOIncorporation.IncorporationForm.SingleUserPicker'; + +export interface Props extends UserPickerProps { + sidebarRef: HTMLElement | null; + name: string; + onSelected?: (value: AnyUser) => void; + remove: FieldArrayRenderProps['remove']; + index: number; + setMainContact: (value: any, shouldValidate?: boolean | undefined) => void; +} + +const SingleUserPicker = ({ + name, + remove, + index, + setMainContact, + ...rest +}: Props) => { + const [, { error, touched, value }] = useField(name); + const [, { value: mainContact }] = useField('mainContact'); + const { formatMessage } = useIntl(); + + const errorMessage = + error && typeof error === 'object' && formatMessage(error); + + return ( +
+
+ + {errorMessage && touched && ( +
{errorMessage}
+ )} +
+ { + remove(index); + if (value.id === mainContact.id) { + setMainContact(undefined); + } + }} + title={MSG.deleteIconTitle} + /> +
+ ); +}; + +SingleUserPicker.displayName = displayName; + +export default SingleUserPicker; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts new file mode 100644 index 0000000000..4168664eb6 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts @@ -0,0 +1 @@ +export { default } from './SingleUserPicker'; diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx new file mode 100644 index 0000000000..37d9f3673c --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx @@ -0,0 +1,108 @@ +import { useFormikContext, setNestedObjectValues, FormikTouched } from 'formik'; +import React, { useCallback, useMemo } from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import { flattenObject } from '~dashboard/ExpenditurePage/Stages/utils'; +import { FIX_TRIGGER_EVENT_NAME } from '~pages/ExpenditurePage/constants'; +import { StageObject, ValuesType } from '~pages/IncorporationPage/types'; +import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; + +import Stages from './Stages'; +import styles from './Stages.css'; + +const displayName = 'dashboard.DAOIncorporation.Stages.FormStages'; + +const MSG = defineMessages({ + singleErrorMessage: { + id: 'dashboard.DAOIncorporation.Stages.FormStages.singleErrorMessage', + defaultMessage: '{number} required field has an error.', + }, + mulitpleErrorMessage: { + id: 'dashboard.DAOIncorporation.Stages.FormStages.mulitpleErrorMessage', + defaultMessage: '{number} required fields have an error.', + }, + errorMessageAction: { + id: 'dashboard.DAOIncorporation.Stages.FormStages.errorMessageAction', + defaultMessage: 'Fix it!', + }, +}); + +export interface Props { + stages: StageObject[]; + activeStageId: StagesEnum; +} + +const FormStages = ({ stages, activeStageId }: Props) => { + const { values, handleSubmit, validateForm, setTouched, errors: formikErr } = + useFormikContext() || {}; + + const formikErrors = useMemo(() => { + const errorsFlat = flattenObject(formikErr); + return Object.keys(errorsFlat); + }, [formikErr]); + + const handleSaveDraft = useCallback(async () => { + const errors = await validateForm(values); + const errorsLength = Object.keys(errors)?.length; + setTouched(setNestedObjectValues>(errors, true)); + + return !errorsLength && handleSubmit(values as any); + }, [handleSubmit, setTouched, validateForm, values]); + + const handleFixButtonClick = useCallback(() => { + setTouched( + setNestedObjectValues>(formikErr, true), + ); + if (!formikErrors.length) return; + + const firstError = document.getElementsByName(formikErrors[0])?.[0]; + + if (firstError?.tagName.toLowerCase() === 'input') { + (firstError as HTMLElement).focus(); + } else if (firstError?.tagName.toLowerCase() === 'textarea') { + (firstError as HTMLElement).focus(); + } else { + const customEvent = new CustomEvent(FIX_TRIGGER_EVENT_NAME, { + detail: { + name: formikErrors[0], + }, + }); + + window.dispatchEvent(customEvent); + } + }, [setTouched, formikErr, formikErrors]); + + return ( +
+ {!!formikErrors.length && ( +
+

+ 1 + ? { ...MSG.mulitpleErrorMessage } + : { ...MSG.singleErrorMessage })} + values={{ number: formikErrors.length }} + /> +

+ +
+ )} + + +
+ ); +}; + +FormStages.displayName = displayName; + +export default FormStages; From f5a59fb0ff3317161770fc19c6fb21c34d84a014 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Thu, 5 Jan 2023 12:24:08 +0100 Subject: [PATCH 09/16] added locked sidebar --- .../DAOIncorporation/IncorporationForm/constants.ts | 9 +++++++++ .../IncorporationForm/Protectors/Protectors.tsx | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts new file mode 100644 index 0000000000..8d8f7ec174 --- /dev/null +++ b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts @@ -0,0 +1,9 @@ +export enum SignOption { + Individual = 'Individual', + Multiple = 'Multiple', +} + +export enum VerificationStatus { + Verified = 'Verified', + Unverified = 'Unverified', +} diff --git a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx index 2f5e47a80b..4fa7617d57 100644 --- a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx +++ b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx @@ -17,6 +17,7 @@ import Button from '~core/Button'; import Link from '~core/Link'; import SingleUserPicker from '../SingleUserPicker'; +import { SignOption } from '../constants'; import styles from './Protectors.css'; From 1253f93e827728f8c425faf826b672e0e5017920 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 13 Jan 2023 13:14:21 +0100 Subject: [PATCH 10/16] renamed to Incorporation --- .../SingleUserPicker/SingleUserPicker.css | 35 ------ .../SingleUserPicker.css.d.ts | 4 - .../SingleUserPicker/SingleUserPicker.tsx | 70 ------------ .../SingleUserPicker/index.ts | 1 - .../IncorporationForm/constants.ts | 9 -- .../DAOIncorporation/Stages/FormStages.tsx | 108 ------------------ 6 files changed, 227 deletions(-) delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts delete mode 100644 src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css deleted file mode 100644 index 2c0af7fa16..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css +++ /dev/null @@ -1,35 +0,0 @@ -.protectorWrapper { - display: flex; - justify-content: space-between; - padding: 11px 0 14px; - font-size: var(--size-smallish); - font-weight: var(--weight-bold); - color: color-mod(var(--temp-grey-blue-7) alpha(85%)); -} - -.selectWrapper { - display: flex; - justify-content: flex-start; - align-items: center; -} - -.protectorError { - font-size: var(--size-tiny); - white-space: nowrap; - color: var(--danger); - letter-spacing: var(--spacing-medium); -} - -.protectorWrapper label { - margin-right: 0; -} - -.deleteIcon { - height: 20px; - width: 20px; - fill: var(--pink); -} - -.deleteIcon:hover { - cursor: pointer; -} diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts deleted file mode 100644 index 3119c86cca..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const protectorWrapper: string; -export const selectWrapper: string; -export const protectorError: string; -export const deleteIcon: string; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx deleted file mode 100644 index 2fe3fcc6fe..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/SingleUserPicker.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react'; -import { defineMessages, useIntl } from 'react-intl'; -import { FieldArrayRenderProps, useField } from 'formik'; - -import { AnyUser } from '~data/index'; -import Icon from '~core/Icon'; -import UserPickerWithSearch from '~core/UserPickerWithSearch'; -import { Props as UserPickerProps } from '~core/UserPickerWithSearch/UserPickerWithSearch'; - -import styles from './SingleUserPicker.css'; - -export const MSG = defineMessages({ - deleteIconTitle: { - id: `dashboard.DAOIncorporation.IncorporationForm.SingleUserPicker.deleteIconTitle`, - defaultMessage: 'Delete recipient', - }, -}); - -const displayName = - 'dashboard.DAOIncorporation.IncorporationForm.SingleUserPicker'; - -export interface Props extends UserPickerProps { - sidebarRef: HTMLElement | null; - name: string; - onSelected?: (value: AnyUser) => void; - remove: FieldArrayRenderProps['remove']; - index: number; - setMainContact: (value: any, shouldValidate?: boolean | undefined) => void; -} - -const SingleUserPicker = ({ - name, - remove, - index, - setMainContact, - ...rest -}: Props) => { - const [, { error, touched, value }] = useField(name); - const [, { value: mainContact }] = useField('mainContact'); - const { formatMessage } = useIntl(); - - const errorMessage = - error && typeof error === 'object' && formatMessage(error); - - return ( -
-
- - {errorMessage && touched && ( -
{errorMessage}
- )} -
- { - remove(index); - if (value.id === mainContact.id) { - setMainContact(undefined); - } - }} - title={MSG.deleteIconTitle} - /> -
- ); -}; - -SingleUserPicker.displayName = displayName; - -export default SingleUserPicker; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts deleted file mode 100644 index 4168664eb6..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/SingleUserPicker/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SingleUserPicker'; diff --git a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts b/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts deleted file mode 100644 index 8d8f7ec174..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/IncorporationForm/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum SignOption { - Individual = 'Individual', - Multiple = 'Multiple', -} - -export enum VerificationStatus { - Verified = 'Verified', - Unverified = 'Unverified', -} diff --git a/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx deleted file mode 100644 index 37d9f3673c..0000000000 --- a/src/modules/dashboard/components/DAOIncorporation/Stages/FormStages.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { useFormikContext, setNestedObjectValues, FormikTouched } from 'formik'; -import React, { useCallback, useMemo } from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; - -import { flattenObject } from '~dashboard/ExpenditurePage/Stages/utils'; -import { FIX_TRIGGER_EVENT_NAME } from '~pages/ExpenditurePage/constants'; -import { StageObject, ValuesType } from '~pages/IncorporationPage/types'; -import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; - -import Stages from './Stages'; -import styles from './Stages.css'; - -const displayName = 'dashboard.DAOIncorporation.Stages.FormStages'; - -const MSG = defineMessages({ - singleErrorMessage: { - id: 'dashboard.DAOIncorporation.Stages.FormStages.singleErrorMessage', - defaultMessage: '{number} required field has an error.', - }, - mulitpleErrorMessage: { - id: 'dashboard.DAOIncorporation.Stages.FormStages.mulitpleErrorMessage', - defaultMessage: '{number} required fields have an error.', - }, - errorMessageAction: { - id: 'dashboard.DAOIncorporation.Stages.FormStages.errorMessageAction', - defaultMessage: 'Fix it!', - }, -}); - -export interface Props { - stages: StageObject[]; - activeStageId: StagesEnum; -} - -const FormStages = ({ stages, activeStageId }: Props) => { - const { values, handleSubmit, validateForm, setTouched, errors: formikErr } = - useFormikContext() || {}; - - const formikErrors = useMemo(() => { - const errorsFlat = flattenObject(formikErr); - return Object.keys(errorsFlat); - }, [formikErr]); - - const handleSaveDraft = useCallback(async () => { - const errors = await validateForm(values); - const errorsLength = Object.keys(errors)?.length; - setTouched(setNestedObjectValues>(errors, true)); - - return !errorsLength && handleSubmit(values as any); - }, [handleSubmit, setTouched, validateForm, values]); - - const handleFixButtonClick = useCallback(() => { - setTouched( - setNestedObjectValues>(formikErr, true), - ); - if (!formikErrors.length) return; - - const firstError = document.getElementsByName(formikErrors[0])?.[0]; - - if (firstError?.tagName.toLowerCase() === 'input') { - (firstError as HTMLElement).focus(); - } else if (firstError?.tagName.toLowerCase() === 'textarea') { - (firstError as HTMLElement).focus(); - } else { - const customEvent = new CustomEvent(FIX_TRIGGER_EVENT_NAME, { - detail: { - name: formikErrors[0], - }, - }); - - window.dispatchEvent(customEvent); - } - }, [setTouched, formikErr, formikErrors]); - - return ( -
- {!!formikErrors.length && ( -
-

- 1 - ? { ...MSG.mulitpleErrorMessage } - : { ...MSG.singleErrorMessage })} - values={{ number: formikErrors.length }} - /> -

- -
- )} - - -
- ); -}; - -FormStages.displayName = displayName; - -export default FormStages; From 36d4af3b8f46618bbcd84f9a31548a404f485f1c Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Mon, 16 Jan 2023 13:32:28 +0100 Subject: [PATCH 11/16] added CancelIncorporationDialog --- .../CancelIncorporationDialog.css | 208 +++++++++++++ .../CancelIncorporationDialog.css.d.ts | 21 ++ .../CancelIncorporationDialog.tsx | 290 ++++++++++++++++++ .../CancelIncorporationDialog/index.ts | 1 + .../CancelIncorporationDialog/types.ts | 4 + .../IncorporationPage/IncorporationPage.tsx | 30 +- 6 files changed, 552 insertions(+), 2 deletions(-) create mode 100644 src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css create mode 100644 src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css.d.ts create mode 100644 src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx create mode 100644 src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/index.ts create mode 100644 src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/types.ts diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css new file mode 100644 index 0000000000..c9f9448f6a --- /dev/null +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css @@ -0,0 +1,208 @@ +@value radioButtonWidth: 340px; +@value buttonWidth: 160px; + +.row { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0 13px; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + line-height: 18px; + color: var(--temp-grey-blue-7); + letter-spacing: 0.5px; +} + +.withoutPadding { + padding: 0; +} + +.forceRow { + align-items: center; + padding-top: 17px; + white-space: nowrap; +} + +.forceRow form { + max-width: 200px; +} + +.title { + display: flex; + justify-content: space-between; + align-items: center; + padding: 9px 0 12px; + width: 100%; + font-size: var(--size-medium-l); + font-weight: var(--weight-bold); + line-height: 24px; + color: var(--dark); + letter-spacing: 0.5px; +} + +.radioGroup { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: var(--dark); + letter-spacing: 0.5px; +} + +.radioWrapper > label { + display: flex; + align-items: center; + margin-bottom: 9px; + padding: 0 7px; + height: 40px; + width: radioButtonWidth; + border: 1px solid color-mod(var(--action-secondary) alpha(25%)); + border-radius: 2px; + background-color: color-mod(var(--action-secondary) alpha(5%)); +} + +.radioWrapper > label > span { + height: 27px; + width: 27px; + top: 0; + border: 1px solid color-mod(var(--action-secondary) alpha(25%)); + background-color: var(--colony-white); + + &::after { + height: 7px; + width: 7px; + } +} + +.selected > label { + border: 1px solid var(--primary); + background-color: color-mod(var(--primary) alpha(12%)); +} + +.textWrapper { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 11px; + margin-bottom: 8px; + width: radioButtonWidth; + color: var(--text); +} + +.textWrapper > span { + height: 16px; +} + +/* this selector is for tooltip wrapper */ +.textWrapper > span ~ div { + max-width: 250px; + white-space: normal; +} + +.message { + display: flex; + align-items: center; + margin-top: 21px; + padding: 0 15px; + height: 46px; + border-radius: 5px; + background-color: color-mod(var(--primary) alpha(15%)); + font-size: var(--size-smallish); + font-weight: var(--weight-bold); + color: var(--text); + letter-spacing: 0.5px; +} + +.messageWarning { + background-color: color-mod(var(--pink) alpha(15%)); +} + +.annotations { + margin: 24px 0 5px; + letter-spacing: 0.5px; +} + +.tokens { + padding: 11px 0 15px; + border-top: 1px solid var(--grey-blue-0); + border-bottom: 1px solid var(--grey-blue-0); +} + +.value { + display: flex; + align-items: center; + font-size: var(--size-smallish); + color: color-mod(var(--dark) alpha(85%)); +} + +.value span { + padding-right: 2px; + font-size: var(--size-smallish); +} + +.paddingBottom { + padding-bottom: 6px; +} + +.tokenIcon { + margin-right: 4px; + height: 16px; + width: 16px; +} + +.tokensWrapper { + text-align: right; +} + +.top { + align-items: flex-start; +} + +.motionActiveItem { + font-size: var(--size-tiny); + font-weight: var(--weight-bold); + color: var(--temp-grey-blue-7); +} + +.forceRow button > div > div { + margin-bottom: 4px; +} + +.toggleContainer i { + margin: 0 -20px 4px 21px; + + /* next lines are used for the correct tooltip arrow placement */ + transform: translateX(-25px); +} + +/* this selector is for tooltip wrapper */ +.toggleContainer > div > div:last-child { + max-width: 250px; + white-space: normal; +} + +/* the following lines center the toggle force row */ + +.toggleContainer label { + display: flex; + align-items: center; + margin-bottom: 0; +} + +.toggleContainer > div { + align-items: center; +} + +.toggleContainer > div > div:first-of-type { + height: 16px; +} + +.toggleContainer > div > span { + height: 16px; +} + +.toggleContainer > div > span > div { + height: 16px; +} diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css.d.ts b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css.d.ts new file mode 100644 index 0000000000..dba11ee95a --- /dev/null +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css.d.ts @@ -0,0 +1,21 @@ +export const radioButtonWidth: string; +export const buttonWidth: string; +export const row: string; +export const withoutPadding: string; +export const forceRow: string; +export const title: string; +export const radioGroup: string; +export const radioWrapper: string; +export const selected: string; +export const textWrapper: string; +export const message: string; +export const messageWarning: string; +export const annotations: string; +export const tokens: string; +export const value: string; +export const paddingBottom: string; +export const tokenIcon: string; +export const tokensWrapper: string; +export const top: string; +export const motionActiveItem: string; +export const toggleContainer: string; diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx new file mode 100644 index 0000000000..6cfa79548a --- /dev/null +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx @@ -0,0 +1,290 @@ +import React, { useCallback, useState } from 'react'; +import * as yup from 'yup'; +import classNames from 'classnames'; +import { FormikProps } from 'formik'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +import { ActionForm, Annotations, Radio, Toggle } from '~core/Fields'; +import { ActionTypes } from '~redux/actionTypes'; +import { Colony, useLoggedInUser } from '~data/index'; +import TokenIcon from '~dashboard/HookedTokenIcon'; +import Dialog, { DialogSection } from '~core/Dialog'; +import Button from '~core/Button'; +import Heading from '~core/Heading'; +import { tokens as tokensMock } from '~dashboard/ExpenditurePage/ExpenditureSettings/constants'; +import { getTokenDecimalsWithFallback } from '~utils/tokens'; +import MotionDomainSelect from '~dashboard/MotionDomainSelect'; +import { useDialogActionPermissions } from '~utils/hooks/useDialogActionPermissions'; +import { hasRoot } from '~modules/users/checks'; +import { useTransformer } from '~utils/hooks'; +import { getAllUserRoles } from '~modules/transformers'; +import Numeral from '~core/Numeral'; +import QuestionMarkTooltip from '~core/QuestionMarkTooltip'; + +import { PenalizeType } from './types'; +import styles from './CancelIncorporationDialog.css'; + +const MSG = defineMessages({ + header: { + id: 'dashboard.CancelExpenditureDialog.CancelIncorporationDialog.header', + defaultMessage: 'Cancel incorporation', + }, + ownersStake: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.ownersStake`, + defaultMessage: `Owner's stake`, + }, + shouldBePenalized: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.shouldBePenalized`, + defaultMessage: 'Should the owner be penalized?', + }, + penalize: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.penalize`, + defaultMessage: 'Penalize', + }, + showMercy: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.showMercy`, + defaultMessage: 'Show mercy', + }, + penalizeMessage: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.penalizeMessage`, + defaultMessage: 'Owner will lose their stake and equivalent reputation.', + }, + mercyMessage: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.mercyMessage`, + defaultMessage: 'Owner will keep their stake and reputation.', + }, + submit: { + id: 'dashboard.CancelExpenditureDialog.CancelIncorporationDialog.submit', + defaultMessage: 'Submit', + }, + textareaLabel: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.textareaLabel`, + defaultMessage: `Explain why you're cancelling incorporation (optional)`, + }, + effectTooltip: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.effectTooltip`, + defaultMessage: `Decide what to do with the owner's stake when cancelling this incorporation.`, + }, + createDomain: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.createDomain`, + defaultMessage: 'Motion will be created in', + }, +}); + +const displayName = 'dashboard.CancelIncorporationDialog'; + +export const validationSchema = yup.object().shape({ + forceAction: yup.bool(), + effect: yup.string().required(), + annotation: yup.string(), +}); + +export interface FormValues { + forceAction: boolean; + effect: PenalizeType; + annotation: string; +} + +interface Props { + close: () => void; + colony: Colony; + onCancelExpenditure: (isForce: boolean) => void; + isVotingExtensionEnabled: boolean; +} + +const CancelIncorporationDialog = ({ + close, + colony, + onCancelExpenditure, + isVotingExtensionEnabled, +}: Props) => { + const [isForce, setIsForce] = useState(false); + + const getFormAction = useCallback( + (actionType: 'SUBMIT' | 'ERROR' | 'SUCCESS') => { + const actionEnd = actionType === 'SUBMIT' ? '' : `_${actionType}`; + + return !isForce + ? ActionTypes[`COLONY_ACTION_GENERIC${actionEnd}`] + : ActionTypes[`COLONY_ACTION_GENERIC${actionEnd}`]; + }, + [isForce], + ); + + const [token] = tokensMock; + const { walletAddress, username, ethereal } = useLoggedInUser(); + const allUserRoles = useTransformer(getAllUserRoles, [colony, walletAddress]); + + const hasRegisteredProfile = !!username && !ethereal; + const canCancelExpenditure = hasRegisteredProfile && hasRoot(allUserRoles); + + const [userHasPermission] = useDialogActionPermissions( + colony.colonyAddress, + canCancelExpenditure, + isVotingExtensionEnabled, + true, + ); + + return ( + + {(formValues: FormikProps) => { + if (formValues.values.forceAction !== isForce) { + setIsForce(formValues.values.forceAction); + } + return ( + + +
+ {colony && } + {canCancelExpenditure && isVotingExtensionEnabled && ( +
+ +
+ )} +
+ + + +
+ +
+ +
+ + + {token.symbol} +
+
+
+ +
+
+ + +
+
+ + + +
+
+ + + +
+
+
+ +
+
+ +
+ +
+
+ +
+ ); + }} +
+ ); +}; + +CancelIncorporationDialog.displayName = displayName; + +export default CancelIncorporationDialog; diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/index.ts b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/index.ts new file mode 100644 index 0000000000..9fb4147cbc --- /dev/null +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/index.ts @@ -0,0 +1 @@ +export { default } from './CancelIncorporationDialog'; diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/types.ts b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/types.ts new file mode 100644 index 0000000000..0c47f25051 --- /dev/null +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/types.ts @@ -0,0 +1,4 @@ +export enum PenalizeType { + Penalize = 'penalize', + Mercy = 'mercy', +} diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index b9b3c5b17c..d1bf9ddf8d 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -23,8 +23,9 @@ import { } from './constants'; import { ValuesType } from './types'; import styles from './IncorporationPage.css'; -import { ValuesType } from './types'; -import LockedIncorporationForm from '~dashboard/Incorporation/IncorporationForm/LockedIncorporationForm'; +import { useDialog } from '~core/Dialog'; +import CancelIncorporationDialog from '~dashboard/Dialogs/CancelIncorporationDialog'; +import IncorporationPaymentDialog from '~dashboard/Dialogs/IncorporationPaymentDialog'; const displayName = 'pages.IncorporationPage'; @@ -43,6 +44,7 @@ const IncorporationPage = () => { const [shouldValidate, setShouldValidate] = useState(false); const [activeStageId, setActiveStageId] = useState(StagesEnum.Payment); const sidebarRef = useRef(null); + const openCancelIncorporationDialog = useDialog(CancelIncorporationDialog); const notVerified = true; // temporary valule @@ -94,6 +96,30 @@ const IncorporationPage = () => { } }, [shouldValidate]); + const handleCancel = (isForce: boolean) => { + if (isForce) { + // temporary action + } else { + // setTimeout is temporary, call to backend should be added here + setTimeout(() => {}, 3000); + } + }; + + const handleCancelIncorporation = useCallback(() => { + if (!colonyData) { + return null; + } + + return ( + colonyData && + openCancelIncorporationDialog({ + onCancelExpenditure: (isForce: boolean) => handleCancel(isForce), + colony: colonyData.processedColony, + isVotingExtensionEnabled: true, // temporary value + }) + ); + }, [colonyData, openCancelIncorporationDialog]); + return isFormEditable ? ( Date: Mon, 16 Jan 2023 13:37:24 +0100 Subject: [PATCH 12/16] fixed types --- .../dashboard/components/Incorporation/Stages/FormStages.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx index 606ef0e586..fdc2c63675 100644 --- a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx +++ b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx @@ -96,6 +96,7 @@ const FormStages = ({ stages, activeStageId }: Props) => { stages={stages} activeStageId={activeStageId} buttonAction={handleSaveDraft} + handleCancelIncorporation={() => {}} />
); From 4b32c085a967c07c5b56e03b3c13c15f06d316e9 Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 27 Jan 2023 14:14:58 +0100 Subject: [PATCH 13/16] added displaying motion --- .../CancelIncorporationDialog.css | 3 +-- .../CancelIncorporationDialog.tsx | 6 ++--- .../IncorporationPage/IncorporationPage.tsx | 23 +++++++++++++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css index c9f9448f6a..fecd6fc544 100644 --- a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.css @@ -5,7 +5,6 @@ display: flex; justify-content: space-between; align-items: center; - padding: 8px 0 13px; font-size: var(--size-smallish); font-weight: var(--weight-bold); line-height: 18px; @@ -125,7 +124,7 @@ } .tokens { - padding: 11px 0 15px; + height: 46px; border-top: 1px solid var(--grey-blue-0); border-bottom: 1px solid var(--grey-blue-0); } diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx index 6cfa79548a..c7d7eddf0f 100644 --- a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx @@ -88,14 +88,14 @@ export interface FormValues { interface Props { close: () => void; colony: Colony; - onCancelExpenditure: (isForce: boolean) => void; + onCancelIncorporation: (isForce: boolean) => void; isVotingExtensionEnabled: boolean; } const CancelIncorporationDialog = ({ close, colony, - onCancelExpenditure, + onCancelIncorporation, isVotingExtensionEnabled, }: Props) => { const [isForce, setIsForce] = useState(false); @@ -272,7 +272,7 @@ const CancelIncorporationDialog = ({ text={{ id: 'button.submit' }} type="submit" onClick={() => { - onCancelExpenditure(formValues.values.forceAction); + onCancelIncorporation(formValues.values.forceAction); close(); formValues.handleSubmit(); }} diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index d1bf9ddf8d..1ab2248e38 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -12,6 +12,12 @@ import LockedIncorporationForm from '~dashboard/Incorporation/IncorporationForm/ import VerificationBanner from '~dashboard/Incorporation/VerificationBanner'; import IncorporationPaymentDialog from '~dashboard/Dialogs/IncorporationPaymentDialog'; import { useDialog } from '~core/Dialog'; +import { + Motion, + MotionStatus, + MotionType, + Status, +} from '~dashboard/ExpenditurePage/Stages/constants'; import { initialValues, @@ -45,6 +51,8 @@ const IncorporationPage = () => { const [activeStageId, setActiveStageId] = useState(StagesEnum.Payment); const sidebarRef = useRef(null); const openCancelIncorporationDialog = useDialog(CancelIncorporationDialog); + const [motion, setMotion] = useState(); + const [status, setStatus] = useState(); const notVerified = true; // temporary valule @@ -99,9 +107,20 @@ const IncorporationPage = () => { const handleCancel = (isForce: boolean) => { if (isForce) { // temporary action + setStatus(Status.ForceCancelled); } else { // setTimeout is temporary, call to backend should be added here - setTimeout(() => {}, 3000); + setMotion({ + type: MotionType.Cancel, + status: MotionStatus.Pending, + }); + setTimeout(() => { + setStatus(Status.Cancelled); + setMotion({ + type: MotionType.Cancel, + status: MotionStatus.Passed, + }); + }, 5000); } }; @@ -113,7 +132,7 @@ const IncorporationPage = () => { return ( colonyData && openCancelIncorporationDialog({ - onCancelExpenditure: (isForce: boolean) => handleCancel(isForce), + onCancelIncorporation: (isForce: boolean) => handleCancel(isForce), colony: colonyData.processedColony, isVotingExtensionEnabled: true, // temporary value }) From f11cd4531888b36b7989fb537f61621a068c5c3e Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 27 Jan 2023 14:17:10 +0100 Subject: [PATCH 14/16] removed duplicated import --- .../Incorporation/IncorporationForm/Protectors/Protectors.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx index 4fa7617d57..2f5e47a80b 100644 --- a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx +++ b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx @@ -17,7 +17,6 @@ import Button from '~core/Button'; import Link from '~core/Link'; import SingleUserPicker from '../SingleUserPicker'; -import { SignOption } from '../constants'; import styles from './Protectors.css'; From 9dfab263084100b91613dd3848fb26392e4b9ade Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Fri, 27 Jan 2023 14:48:10 +0100 Subject: [PATCH 15/16] changed button text --- .../CancelIncorporationDialog.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx index c7d7eddf0f..35ea4834b8 100644 --- a/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx +++ b/src/modules/dashboard/components/Dialogs/CancelIncorporationDialog/CancelIncorporationDialog.tsx @@ -53,9 +53,9 @@ const MSG = defineMessages({ id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.mercyMessage`, defaultMessage: 'Owner will keep their stake and reputation.', }, - submit: { - id: 'dashboard.CancelExpenditureDialog.CancelIncorporationDialog.submit', - defaultMessage: 'Submit', + createMotion: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.createMotion`, + defaultMessage: 'Create Motion', }, textareaLabel: { id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.textareaLabel`, @@ -65,9 +65,9 @@ const MSG = defineMessages({ id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.effectTooltip`, defaultMessage: `Decide what to do with the owner's stake when cancelling this incorporation.`, }, - createDomain: { - id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.createDomain`, - defaultMessage: 'Motion will be created in', + continue: { + id: `dashboard.CancelExpenditureDialog.CancelIncorporationDialog.continue`, + defaultMessage: 'Continue', }, }); @@ -269,7 +269,11 @@ const CancelIncorporationDialog = ({ width: styles.buttonWidth, }} autoFocus - text={{ id: 'button.submit' }} + text={ + formValues.values.forceAction + ? MSG.continue + : MSG.createMotion + } type="submit" onClick={() => { onCancelIncorporation(formValues.values.forceAction); From 1f5f6a198a00f42b2e9344d9ec38366e98bbb65a Mon Sep 17 00:00:00 2001 From: Agnieszka Jarosik Date: Tue, 7 Mar 2023 08:48:18 +0100 Subject: [PATCH 16/16] fixed types --- .../ExpenditurePage/Stages/FormStages.tsx | 6 +- .../ExpenditurePage/Stages/LockedStages.tsx | 8 +- .../ExpenditurePage/Stages/Stages.tsx | 6 +- .../StreamingStagesLocked.tsx | 6 +- .../Protectors/Protectors.tsx | 1 + .../Incorporation/Stages/FormStages.tsx | 107 ------------------ .../ExpenditurePage/ExpenditurePage.tsx | 4 +- .../IncorporationPage/IncorporationPage.tsx | 15 ++- 8 files changed, 23 insertions(+), 130 deletions(-) delete mode 100644 src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx diff --git a/src/modules/dashboard/components/ExpenditurePage/Stages/FormStages.tsx b/src/modules/dashboard/components/ExpenditurePage/Stages/FormStages.tsx index f6573bb4ce..70701baf91 100644 --- a/src/modules/dashboard/components/ExpenditurePage/Stages/FormStages.tsx +++ b/src/modules/dashboard/components/ExpenditurePage/Stages/FormStages.tsx @@ -43,7 +43,7 @@ interface Props { React.SetStateAction >; colony: Colony; - handleCancelExpenditure: () => void; + handleCancel: () => void; } const FormStages = ({ @@ -52,7 +52,7 @@ const FormStages = ({ setActiveStageId, setFormValues, colony, - handleCancelExpenditure, + handleCancel, }: Props) => { const { values, @@ -195,7 +195,7 @@ const FormStages = ({ handleButtonClick, handleDeleteDraft, handleSaveDraft, - handleCancelExpenditure, + handleCancel, colony, }} /> diff --git a/src/modules/dashboard/components/ExpenditurePage/Stages/LockedStages.tsx b/src/modules/dashboard/components/ExpenditurePage/Stages/LockedStages.tsx index 20aa034e4d..c15191c380 100644 --- a/src/modules/dashboard/components/ExpenditurePage/Stages/LockedStages.tsx +++ b/src/modules/dashboard/components/ExpenditurePage/Stages/LockedStages.tsx @@ -35,7 +35,7 @@ interface Props { activeStageId?: string; motion?: Motion; status?: Status; - handleCancelExpenditure?: () => void; + handleCancel?: () => void; colony: Colony; expenditureType?: ExpenditureTypes; formValues?: ValuesType; @@ -47,7 +47,7 @@ const LockedStages = ({ setActiveStageId, motion, status, - handleCancelExpenditure, + handleCancel, formValues, colony, expenditureType, @@ -100,7 +100,7 @@ const LockedStages = ({ motion={motion} colony={colony} activeStageId={activeStageId} - handleCancelExpenditure={handleCancelExpenditure} + handleCancel={handleCancel} fundingSources={formValues?.streaming?.fundingSources} /> ) : ( @@ -112,7 +112,7 @@ const LockedStages = ({ handleButtonClick, motion, status, - handleCancelExpenditure, + handleCancel, formValues, colony, expenditureType, diff --git a/src/modules/dashboard/components/ExpenditurePage/Stages/Stages.tsx b/src/modules/dashboard/components/ExpenditurePage/Stages/Stages.tsx index 00d6b8c77f..12b62c87f5 100644 --- a/src/modules/dashboard/components/ExpenditurePage/Stages/Stages.tsx +++ b/src/modules/dashboard/components/ExpenditurePage/Stages/Stages.tsx @@ -91,7 +91,7 @@ export interface Props { handleButtonClick: () => void; status?: Status; motion?: Motion; - handleCancelExpenditure?: () => void; + handleCancel?: () => void; colony: Colony; buttonDisabled?: boolean; formValues?: ValuesType; @@ -108,7 +108,7 @@ const Stages = ({ handleButtonClick, status, motion, - handleCancelExpenditure, + handleCancel, colony, buttonDisabled, formValues, @@ -301,7 +301,7 @@ const Stages = ({ [styles.iconButtonDisabled]: motion?.status === MotionStatus.Pending, })} - onClick={handleCancelExpenditure} + onClick={handleCancel} disabled={ isCancelled || motion?.status === MotionStatus.Pending } diff --git a/src/modules/dashboard/components/ExpenditurePage/Stages/StreamingStages/StreamingStagesLocked/StreamingStagesLocked.tsx b/src/modules/dashboard/components/ExpenditurePage/Stages/StreamingStages/StreamingStagesLocked/StreamingStagesLocked.tsx index 43d4cc3b87..0ec2aece51 100644 --- a/src/modules/dashboard/components/ExpenditurePage/Stages/StreamingStages/StreamingStagesLocked/StreamingStagesLocked.tsx +++ b/src/modules/dashboard/components/ExpenditurePage/Stages/StreamingStages/StreamingStagesLocked/StreamingStagesLocked.tsx @@ -102,7 +102,7 @@ export interface Props { motion?: Motion; colony?: Colony; activeStageId?: string; - handleCancelExpenditure?: () => void; + handleCancel?: () => void; fundingSources?: FundingSource[]; } @@ -111,7 +111,7 @@ const StreamingStagesLocked = ({ motion, colony, activeStageId, - handleCancelExpenditure, + handleCancel, fundingSources, }: Props) => { const [valueIsCopied, setValueIsCopied] = useState(false); @@ -290,7 +290,7 @@ const StreamingStagesLocked = ({ [styles.iconButtonDisabled]: motion?.status === MotionStatus.Pending || isCancelled, })} - onClick={handleCancelExpenditure} + onClick={handleCancel} disabled={isCancelled || motion?.status === MotionStatus.Pending} > {motion?.status === MotionStatus.Pending || isCancelled ? ( diff --git a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx index 2f5e47a80b..4fa7617d57 100644 --- a/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx +++ b/src/modules/dashboard/components/Incorporation/IncorporationForm/Protectors/Protectors.tsx @@ -17,6 +17,7 @@ import Button from '~core/Button'; import Link from '~core/Link'; import SingleUserPicker from '../SingleUserPicker'; +import { SignOption } from '../constants'; import styles from './Protectors.css'; diff --git a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx b/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx deleted file mode 100644 index fdc2c63675..0000000000 --- a/src/modules/dashboard/components/Incorporation/Stages/FormStages.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { useFormikContext, setNestedObjectValues, FormikTouched } from 'formik'; -import React, { useCallback, useMemo } from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; - -import { flattenObject } from '~dashboard/ExpenditurePage/Stages/utils'; -import { FIX_TRIGGER_EVENT_NAME } from '~pages/ExpenditurePage/constants'; -import { StageObject, ValuesType } from '~pages/IncorporationPage/types'; -import { Stages as StagesEnum } from '~pages/IncorporationPage/constants'; - -import Stages from './Stages'; -import styles from './Stages.css'; - -const displayName = 'dashboard.Incorporation.Stages.FormStages'; - -const MSG = defineMessages({ - singleErrorMessage: { - id: 'dashboard.Incorporation.Stages.FormStages.singleErrorMessage', - defaultMessage: '{number} required field has an error.', - }, - mulitpleErrorMessage: { - id: 'dashboard.Incorporation.Stages.FormStages.mulitpleErrorMessage', - defaultMessage: '{number} required fields have an error.', - }, - errorMessageAction: { - id: 'dashboard.Incorporation.Stages.FormStages.errorMessageAction', - defaultMessage: 'Fix it!', - }, -}); - -export interface Props { - stages: StageObject[]; - activeStageId: StagesEnum; -} - -const FormStages = ({ stages, activeStageId }: Props) => { - const { values, handleSubmit, validateForm, setTouched, errors: formikErr } = - useFormikContext() || {}; - - const formikErrors = useMemo(() => { - const errorsFlat = flattenObject(formikErr); - return Object.keys(errorsFlat); - }, [formikErr]); - - const handleSaveDraft = useCallback(async () => { - const errors = await validateForm(values); - const errorsLength = Object.keys(errors)?.length; - setTouched(setNestedObjectValues>(errors, true)); - - return !errorsLength && handleSubmit(values as any); - }, [handleSubmit, setTouched, validateForm, values]); - - const handleFixButtonClick = useCallback(() => { - setTouched( - setNestedObjectValues>(formikErr, true), - ); - if (!formikErrors.length) return; - - const firstError = document.getElementsByName(formikErrors[0])?.[0]; - - if (['textarea', 'input'].includes(firstError?.tagName.toLowerCase())) { - (firstError as HTMLElement).focus(); - } else { - const customEvent = new CustomEvent(FIX_TRIGGER_EVENT_NAME, { - detail: { - name: formikErrors[0], - }, - }); - - window.dispatchEvent(customEvent); - } - }, [setTouched, formikErr, formikErrors]); - - return ( -
- {!!formikErrors.length && ( -
-

- 1 - ? { ...MSG.mulitpleErrorMessage } - : { ...MSG.singleErrorMessage })} - values={{ number: formikErrors.length }} - /> -

- -
- )} - - {}} - /> -
- ); -}; - -FormStages.displayName = displayName; - -export default FormStages; diff --git a/src/modules/pages/components/ExpenditurePage/ExpenditurePage.tsx b/src/modules/pages/components/ExpenditurePage/ExpenditurePage.tsx index 7bec7ea379..bc544c25ce 100644 --- a/src/modules/pages/components/ExpenditurePage/ExpenditurePage.tsx +++ b/src/modules/pages/components/ExpenditurePage/ExpenditurePage.tsx @@ -587,7 +587,7 @@ const ExpenditurePage = ({ match }: Props) => { activeStageId={activeStageId} setActiveStageId={setActiveStageId} setFormValues={setFormValues} - handleCancelExpenditure={handleCancelExpenditure} + handleCancel={handleCancelExpenditure} colony={colonyData.processedColony} /> ) @@ -638,7 +638,7 @@ const ExpenditurePage = ({ match }: Props) => { stages={stages} activeStageId={activeStageId} setActiveStageId={setActiveStageId} - handleCancelExpenditure={handleCancelExpenditure} + handleCancel={handleCancelExpenditure} colony={colonyData.processedColony} expenditureType={formValues?.expenditure} /> diff --git a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx index 1ab2248e38..025911d5e7 100644 --- a/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx +++ b/src/modules/pages/components/IncorporationPage/IncorporationPage.tsx @@ -10,14 +10,15 @@ import IncorporationForm from '~dashboard/Incorporation/IncorporationForm'; import Stages, { FormStages } from '~dashboard/ExpenditurePage/Stages'; import LockedIncorporationForm from '~dashboard/Incorporation/IncorporationForm/LockedIncorporationForm'; import VerificationBanner from '~dashboard/Incorporation/VerificationBanner'; -import IncorporationPaymentDialog from '~dashboard/Dialogs/IncorporationPaymentDialog'; -import { useDialog } from '~core/Dialog'; import { Motion, MotionStatus, MotionType, Status, } from '~dashboard/ExpenditurePage/Stages/constants'; +import { useDialog } from '~core/Dialog'; +import CancelIncorporationDialog from '~dashboard/Dialogs/CancelIncorporationDialog'; +import IncorporationPaymentDialog from '~dashboard/Dialogs/IncorporationPaymentDialog'; import { initialValues, @@ -29,9 +30,6 @@ import { } from './constants'; import { ValuesType } from './types'; import styles from './IncorporationPage.css'; -import { useDialog } from '~core/Dialog'; -import CancelIncorporationDialog from '~dashboard/Dialogs/CancelIncorporationDialog'; -import IncorporationPaymentDialog from '~dashboard/Dialogs/IncorporationPaymentDialog'; const displayName = 'pages.IncorporationPage'; @@ -51,8 +49,8 @@ const IncorporationPage = () => { const [activeStageId, setActiveStageId] = useState(StagesEnum.Payment); const sidebarRef = useRef(null); const openCancelIncorporationDialog = useDialog(CancelIncorporationDialog); - const [motion, setMotion] = useState(); - const [status, setStatus] = useState(); + const [, setMotion] = useState(); + const [, setStatus] = useState(); const notVerified = true; // temporary valule @@ -179,7 +177,7 @@ const IncorporationPage = () => { setActiveStageId={setActiveStageId} colony={colonyData.processedColony} setFormValues={setFormValues} - handleCancelExpenditure={() => {}} + handleCancel={handleCancelIncorporation} /> )} @@ -226,6 +224,7 @@ const IncorporationPage = () => { handleButtonClick={buttonAction || (() => {})} colony={colonyData?.processedColony} viewFor="incorporation" + handleCancel={handleCancelIncorporation} /> )}