diff --git a/src/apps/Organization/Address.js b/src/apps/Organization/Address.js new file mode 100644 index 000000000..229be3e18 --- /dev/null +++ b/src/apps/Organization/Address.js @@ -0,0 +1,52 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Box, Info, GU, textStyle } from '@aragon/ui' +import LocalIdentityBadge from '../../components/IdentityBadge/LocalIdentityBadge' +import { network } from '../../environment' + +const Address = ({ + checksummedDaoAddr, + shortAddresses, + depositFundsHelpText, +}) => ( + +

+ {checksummedDaoAddr + ? `This organization is deployed on the Ethereum ${network.name}.` + : 'Resolving DAO address…'} +

+ {checksummedDaoAddr && ( + +
+ +
+ + + Do not send ETH or ERC20 tokens to this address. + {' '} + {depositFundsHelpText} + +
+ )} +
+) + +Address.propTypes = { + checksummedDaoAddr: PropTypes.string.isRequired, + shortAddresses: PropTypes.bool.isRequired, + depositFundsHelpText: PropTypes.string.isRequired, +} + +export default Address diff --git a/src/apps/Organization/Apps.js b/src/apps/Organization/Apps.js new file mode 100644 index 000000000..576fe2fb6 --- /dev/null +++ b/src/apps/Organization/Apps.js @@ -0,0 +1,69 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Box, GU, textStyle } from '@aragon/ui' +import LocalIdentityBadge from '../../components/IdentityBadge/LocalIdentityBadge' +import { AppType } from '../../prop-types' +import Label from './Label' + +const Apps = ({ appsLoading, apps, shortAddresses }) => { + const apmApps = apps.filter(app => !app.isAragonOsInternalApp) + + return appsLoading ? ( + +
+ Loading apps… +
+
+ ) : ( + + + + ) +} + +Apps.propTypes = { + apps: PropTypes.arrayOf(AppType).isRequired, + appsLoading: PropTypes.bool.isRequired, + shortAddresses: PropTypes.bool.isRequired, +} + +export default Apps diff --git a/src/apps/Organization/BasicInfo.js b/src/apps/Organization/BasicInfo.js new file mode 100644 index 000000000..0c8647fc0 --- /dev/null +++ b/src/apps/Organization/BasicInfo.js @@ -0,0 +1,66 @@ +import React, { useState } from 'react' +import { Box, Button, GU, TextInput } from '@aragon/ui' +import Label from './Label' + +const BasicInfo = () => { + const [basicInfo, setBasicInfo] = useState({ + name: '', + website: '', + description: '', + }) + + const changeBasicInfo = ({ target: { name, value } }) => { + const newBasicInfo = { ...basicInfo } + newBasicInfo[name] = value + setBasicInfo(newBasicInfo) + } + + const saveBasicInfo = () => { + console.log('save basic info:', basicInfo) + } + + return ( + +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+ ) +} + +export default BasicInfo diff --git a/src/apps/Organization/Brand.js b/src/apps/Organization/Brand.js new file mode 100644 index 000000000..6ad0d9c6d --- /dev/null +++ b/src/apps/Organization/Brand.js @@ -0,0 +1,167 @@ +import React, { useState } from 'react' +import Dropzone from 'react-dropzone' +import { + Box, + Button, + DropDown, + GU, + Info, + Text, + TextInput, + useTheme, +} from '@aragon/ui' +import organizationLogoPlaceholder from '../../assets/organization-logo-placeholder.png' +import organizationBackground from '../../assets/organization-background.png' +import Label from './Label' + +const Brand = () => { + const theme = useTheme() + const [accentColor, setAccentColor] = useState('') + const [preferredTheme, setPreferredTheme] = useState(0) + const changePreferredTheme = index => setPreferredTheme(index) + const changeAccentColor = e => setAccentColor(e.target.value) + const saveColors = () => { + console.log('save accent color:', accentColor, 'theme:', preferredTheme) + } + const colorRX = /^#(([a-f0-9]{3}){1,2})$/i + const colorError = accentColor && !colorRX.test(accentColor) + + return ( + +
+
+
+ +
+
+
+ + +
+ ) +} + +export default Brand diff --git a/src/apps/Organization/Label.js b/src/apps/Organization/Label.js new file mode 100644 index 000000000..15e954f8b --- /dev/null +++ b/src/apps/Organization/Label.js @@ -0,0 +1,32 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { textStyle, unselectable, useTheme } from '@aragon/ui' + +const Label = ({ text, block, children }) => { + const theme = useTheme() + return ( + + ) +} + +Label.defaultProps = { + block: false, +} + +Label.propTypes = { + text: PropTypes.string.isRequired, + block: PropTypes.bool.isRequired, + children: PropTypes.node, +} + +export default Label diff --git a/src/apps/Organization/Organization.js b/src/apps/Organization/Organization.js index 546705973..7869cdea4 100644 --- a/src/apps/Organization/Organization.js +++ b/src/apps/Organization/Organization.js @@ -1,213 +1,17 @@ import React, { useCallback, useState } from 'react' import PropTypes from 'prop-types' -import { - Box, - Button, - Card, - Header, - IconCoin, - Info, - Layout, - Link, - GU, - Tabs, - Text, - TextInput, - textStyle, - unselectable, - useLayout, - useTheme, -} from '@aragon/ui' -import LocalIdentityBadge from '../../components/IdentityBadge/LocalIdentityBadge' +import { Box, Header, Layout, Link, GU, Tabs, useLayout } from '@aragon/ui' import { appIds, network } from '../../environment' -import { sanitizeNetworkType } from '../../network-config' import { AppType, DaoAddressType, EthereumAddressType } from '../../prop-types' -import providerString from '../../provider-strings' import airdrop, { testTokensEnabled } from '../../testnet/airdrop' import { toChecksumAddress } from '../../web3-utils' import useAppWidth from '../useAppWidth' -import noTokensConnectedPNG from '../../assets/no-tokens-connected.png' -import organizationLogoPlaceholder from '../../assets/organization-logo-placeholder.png' -import organizationBackground from '../../assets/organization-background.png' -import styled from 'styled-components' - -const Address = ({ - checksummedDaoAddr, - shortAddresses, - depositFundsHelpText, -}) => ( -
-

- {checksummedDaoAddr - ? `This organization is deployed on the Ethereum ${network.name}.` - : 'Resolving DAO address…'} -

- {checksummedDaoAddr && ( - -
- -
- - - Do not send ETH or ERC20 tokens to this address. - {' '} - {depositFundsHelpText} - -
- )} -
-) - -Address.propTypes = { - checksummedDaoAddr: PropTypes.string.isRequired, - shortAddresses: PropTypes.bool.isRequired, - depositFundsHelpText: PropTypes.string.isRequired, -} - -const RequestTokens = ({ - handleDepositTestTokens, - handleOpenFinanceApp, - enableTransactions, - walletNetwork, - walletProviderId, -}) => ( -
-

- Deposit some tokens into your organization for testing purposes. -

-
-) - -RequestTokens.propTypes = { - handleDepositTestTokens: PropTypes.func.isRequired, - handleOpenFinanceApp: PropTypes.func.isRequired, - enableTransactions: PropTypes.bool.isRequired, - walletNetwork: PropTypes.string.isRequired, - walletProviderId: PropTypes.string.isRequired, -} - -const Apps = ({ appsLoading, apps, shortAddresses }) => { - const theme = useTheme() - const apmApps = apps.filter(app => !app.isAragonOsInternalApp) - - return appsLoading ? ( -
-
- Loading apps… -
-
- ) : ( -
- -
- ) -} - -Apps.propTypes = { - apps: PropTypes.arrayOf(AppType).isRequired, - appsLoading: PropTypes.bool.isRequired, - shortAddresses: PropTypes.bool.isRequired, -} +import BasicInfo from './BasicInfo' +import Address from './Address' +import RequestTokens from './RequestTokens' +import Apps from './Apps' +import Brand from './Brand' +import Tokens from './Tokens' const Organization = React.memo(function Organization({ account, @@ -221,9 +25,10 @@ const Organization = React.memo(function Organization({ walletWeb3, walletProviderId, }) { - const theme = useTheme() const { layoutName } = useLayout() const [selectedTab, setSelectedTab] = useState(0) + const [tabsVisible, setTabsVisible] = useState(true) + const toggleTabsVisible = () => setTabsVisible(!tabsVisible) const handleDepositTestTokens = useCallback(() => { const finance = apps.find(app => app.appId === appIds.Finance) @@ -251,6 +56,22 @@ const Organization = React.memo(function Organization({ const enableTransactions = !!account && walletNetwork === network.type const shortAddresses = layoutName !== 'large' + const connectedTokens = [ + { + tokenName: 'Ethical Token', + tokenSymbol: 'ETC', + tokenDescription: + 'This is a token. It will do what tokens do, unless told otherwise. Then it will do something else.', + tokenAddress: '0x5Fef2867d4BbF1E7423Bb7FB9031402D4F99d2b0', + }, + { + tokenName: 'Unethical Token', + tokenSymbol: 'ETZ', + tokenDescription: 'This is a very unethical token.', + tokenAddress: '0x5Fef2867d4BbF1E7423Bb7FB9031402D4F99d2b0', + }, + ] + const depositFundsHelpText = appsLoading ? ( '' ) : hasFinanceApp || hasAgentApp ? ( @@ -273,11 +94,13 @@ const Organization = React.memo(function Organization({
- + {tabsVisible && ( + + )} {selectedTab === 0 && ( @@ -307,146 +130,23 @@ const Organization = React.memo(function Organization({ {selectedTab === 1 && ( -
-
-
- -
- -
- -
-
- -
- -
- - -
- -
-
-
- -
- -
- - Please keep 1:1 ratio -
- -
- - - - - -
-
-
+ +
)} + {selectedTab === 2 && ( -
-
+
+
)} + {selectedTab === 3 && ( - - -
- - No tokens connected - Connect a token to your organization. - -
-
-
+ )} ) @@ -471,11 +171,6 @@ const Section = ({ ...props }) => { const OpenAppButton = props => -const NoTokensCard = styled(Card)` - width: 100%; - height: 364px; -` - export default props => { const appWidth = useAppWidth() return ( diff --git a/src/apps/Organization/RequestTokens.js b/src/apps/Organization/RequestTokens.js new file mode 100644 index 000000000..90bf77471 --- /dev/null +++ b/src/apps/Organization/RequestTokens.js @@ -0,0 +1,90 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { + Box, + Button, + ButtonText, + IconCoin, + Info, + GU, + textStyle, +} from '@aragon/ui' +import { network } from '../../environment' +import { sanitizeNetworkType } from '../../network-config' +import providerString from '../../provider-strings' + +const OpenAppButton = props => ( + +) + +const RequestTokens = ({ + handleDepositTestTokens, + handleOpenFinanceApp, + enableTransactions, + walletNetwork, + walletProviderId, +}) => ( + +

+ Deposit some tokens into your organization for testing purposes. +

+ + + +) + +const TokenDetails = ({ token }) => { + const theme = useTheme() + const { layoutName } = useLayout() + const [removeDialogOpen, setRemoveDialogOpen] = useState(false) + const oneColumn = layoutName === 'small' + const toggleRemoveDialog = () => setRemoveDialogOpen(!removeDialogOpen) + + return ( + + + + Remove token + + + This action will remove your token from the organization, until you + decide to reconnect it. + +
+ + +
+
+ + +
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+ + +
+
+ +
+ console.log(acceptedFiles)}> + {({ getRootProps, getInputProps, isDragActive }) => ( +
+ +
+ +
+ + Please keep 1:1 ratio +
+ )} +
+
+
+
+ ) +} + +TokenDetails.propTypes = { + token: PropTypes.object.isRequired, +} + +const Tokens = ({ connectedTokens, toggleTabsVisible }) => { + const { layoutName } = useLayout() + const theme = useTheme() + const [currentToken, setCurrentToken] = useState(-1) + const compactMode = layoutName === 'small' + const rowHeight = compactMode ? null : 350 + + if (connectedTokens.length === 0) { + return + } + + if (currentToken > -1) { + return ( + + + { + setCurrentToken(-1) + toggleTabsVisible() + }} + /> + + + + ) + } + + return ( + + {connectedTokens.map((token, i) => { + const handleOpen = () => { + setCurrentToken(i) + toggleTabsVisible() + } + + return ( + + + + {token.tokenName}{' '} + + ({token.tokenSymbol}) + + + + + ) + })} + + ) +} +Tokens.propTypes = { + connectedTokens: PropTypes.arrayOf(PropTypes.object).isRequired, + toggleTabsVisible: PropTypes.func.isRequired, +} + +const NoTokensCard = styled(Card)` + width: 100%; + height: 364px; +` +const TokenDetailsCard = styled(Card)` + width: 100%; + height: unset; +` + +export default Tokens