From 804865d94c12426e2f23b83aa8cfaee063a04398 Mon Sep 17 00:00:00 2001 From: RudeWolfCoding <51991885+RudeWolfCoding@users.noreply.github.com> Date: Sun, 24 Oct 2021 08:45:10 +0200 Subject: [PATCH 1/5] Modal UI Fixes Fixing the account selection and switches --- dapp/src/actions/owner.js | 5 +++ .../common/ProfileDropDown/index.jsx | 35 ++++++++++++++----- .../common/modals/LoginModal/index.jsx | 1 - .../modals/SwitchAccountModal/index.js | 23 ++++++++++++ .../dashboard/pages/Plugins/index.jsx | 28 +++++++++++++-- dapp/src/constants/uiConstants.js | 1 + dapp/src/containers/ModalContainer.jsx | 7 ++-- dapp/src/reducers/owner.js | 17 +++++++++ dapp/src/sagas/owner.js | 18 ++++++++++ 9 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 dapp/src/actions/owner.js create mode 100644 dapp/src/components/dashboard/modals/SwitchAccountModal/index.js create mode 100644 dapp/src/reducers/owner.js create mode 100644 dapp/src/sagas/owner.js diff --git a/dapp/src/actions/owner.js b/dapp/src/actions/owner.js new file mode 100644 index 000000000..6100310d9 --- /dev/null +++ b/dapp/src/actions/owner.js @@ -0,0 +1,5 @@ +import { createRequestTypes, requestAction } from './utils' + +export const OWNERSHIP = createRequestTypes('OWNERSHIP') +export const isOwner = (accountAddress, communityAddress) => requestAction(OWNERSHIP, { accountAddress, communityAddress }) +export const setDefault = () => requestAction('DEFAULT') \ No newline at end of file diff --git a/dapp/src/components/common/ProfileDropDown/index.jsx b/dapp/src/components/common/ProfileDropDown/index.jsx index c9ec94d69..9641f98b8 100644 --- a/dapp/src/components/common/ProfileDropDown/index.jsx +++ b/dapp/src/components/common/ProfileDropDown/index.jsx @@ -52,7 +52,7 @@ const ProfileDropDown = ({ } } else { const desired = networkType === 'ropsten' ? 'main' : 'ropsten' - loadSwitchModal(desired) + loadSwitchModal('fuse') } } else if (providerInfo.type === 'web') { if (foreignNetwork) { @@ -94,16 +94,33 @@ const ProfileDropDown = ({
- Connected to {providerInfo.check && providerInfo.check.substring && providerInfo.check.substring(2)}  - (Disconnect) + Connected to + {providerInfo.check && + providerInfo.check.substring && + providerInfo.check.substring(2)} +   + + + Disconnect +
-
-

- - Switch to {capitalize(convertNetworkName((foreignNetwork === networkType ? 'fuse' : foreignNetwork) || (networkType === 'ropsten' ? 'main' : 'ropsten')))} network -

-
+ {networkType === "fuse" ? ("") : ( +
+

+ + + Switch to{" "} + {capitalize( + convertNetworkName( + foreignNetwork === networkType ? "fuse" : "fuse" + ) + )}{" "} + network + +

+
+ )} ) diff --git a/dapp/src/components/common/modals/LoginModal/index.jsx b/dapp/src/components/common/modals/LoginModal/index.jsx index 609bab28f..8a3c81992 100644 --- a/dapp/src/components/common/modals/LoginModal/index.jsx +++ b/dapp/src/components/common/modals/LoginModal/index.jsx @@ -33,7 +33,6 @@ export default ({ hideModal, handleConnect }) => { render={renderButton} onSuccess={handleLogin} cookiePolicy='single_host_origin' - isSignedIn /> ) diff --git a/dapp/src/components/dashboard/modals/SwitchAccountModal/index.js b/dapp/src/components/dashboard/modals/SwitchAccountModal/index.js new file mode 100644 index 000000000..34563d550 --- /dev/null +++ b/dapp/src/components/dashboard/modals/SwitchAccountModal/index.js @@ -0,0 +1,23 @@ + +import React from "react"; +import Modal from "components/common/Modal"; + +const SwitchAccountsModal = ({ communityCreator, hideModal, hasCloseBtn = true }) => { + +
+
You are on wrong Metamask account
+
+ Can't perform an economy action! Please switch your Metamask account to: {communityCreator} +
+ +
+
; +}; + +export default SwitchAccountsModal; \ No newline at end of file diff --git a/dapp/src/components/dashboard/pages/Plugins/index.jsx b/dapp/src/components/dashboard/pages/Plugins/index.jsx index 872e18c02..6694df75b 100644 --- a/dapp/src/components/dashboard/pages/Plugins/index.jsx +++ b/dapp/src/components/dashboard/pages/Plugins/index.jsx @@ -14,6 +14,8 @@ import FiatOnRamp from 'images/fiat-on-ramp.png' import FiatOnRampBig from 'images/fiat-on-ramp-big.png' import WalletBannerLink from 'images/wallet_banner_link.png' import WalletBannerLinkBig from 'images/wallet_banner_link_big.png' +import { useEffect } from 'react' +import { setDefault, isOwner } from 'actions/owner' const generalPlugins = ([ { @@ -98,8 +100,13 @@ const PluginList = ({ pluginList, pluginTile, plugins, showInfoModal, addPlugin, const Plugins = ({ loadModal, addCommunityPlugin, - community + community, + address, + isAdmin, + isOwner, + communityCreator }) => { + const dispatch = useDispatch() const { address: communityAddress } = useParams() const { plugins } = community const showInfoModal = (key, props) => { @@ -140,6 +147,18 @@ const Plugins = ({ return plugin } + useEffect(()=>{ + dispatch(isOwner(communityAddress, address)) + if(isOwner && !isAdmin){ + loadModal(SWITCH_ACCOUNT_MODAL), { + ...props, + } + } + return () =>{ + dispatch(setDefault) + } + }, [dispatch]) + return ( community ?

Plugins

@@ -163,4 +182,9 @@ const mapDispatchToProps = { addCommunityPlugin } -export default connect(null, mapDispatchToProps)(Plugins) +const mapStateToProps = (state) => ({ + address: getAccountAddress(state) + +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Plugins) diff --git a/dapp/src/constants/uiConstants.js b/dapp/src/constants/uiConstants.js index 2bcc57ec8..148055b4c 100644 --- a/dapp/src/constants/uiConstants.js +++ b/dapp/src/constants/uiConstants.js @@ -9,3 +9,4 @@ export const IMAGE_CROPPER_MODAL = 'IMAGE_CROPPER_MODAL' export const PLUGIN_INFO_MODAL = 'PLUGIN_INFO_MODAL' export const SWITCH_NETWORK = 'SWITCH_NETWORK' export const LOGIN_MODAL = 'LOGIN_MODAL' +export const SWITCH_ACCOUNT_MODAL = 'SWITCH_ACCOUNT_MODAL' \ No newline at end of file diff --git a/dapp/src/containers/ModalContainer.jsx b/dapp/src/containers/ModalContainer.jsx index baf1e68a7..883f37afb 100644 --- a/dapp/src/containers/ModalContainer.jsx +++ b/dapp/src/containers/ModalContainer.jsx @@ -14,6 +14,7 @@ import ImportExistingEntity from 'components/dashboard/modals/ImportExistingEnti import PluginInfoModal from 'components/dashboard/modals/PluginInfoModal' import SwitchNetwork from 'components/common/SwitchNetwork' import LoginModal from 'components/common/modals/LoginModal' +import SwitchAccountModal from 'components/dashboard/modals/SwitchAccountModal' import { WRONG_NETWORK_MODAL, @@ -26,7 +27,8 @@ import { IMAGE_CROPPER_MODAL, PLUGIN_INFO_MODAL, SWITCH_NETWORK, - LOGIN_MODAL + LOGIN_MODAL, + SWITCH_ACCOUNT_MODAL } from 'constants/uiConstants' const renderModal = (modalComponent, props) => @@ -45,7 +47,8 @@ const MODAL_COMPONENTS = { [IMAGE_CROPPER_MODAL]: ImageCropperModal, [PLUGIN_INFO_MODAL]: PluginInfoModal, [SWITCH_NETWORK]: SwitchNetwork, - [LOGIN_MODAL]: LoginModal + [LOGIN_MODAL]: LoginModal, + [SWITCH_ACCOUNT_MODAL]: SwitchAccountModal } const ModalContainer = (props) => { diff --git a/dapp/src/reducers/owner.js b/dapp/src/reducers/owner.js new file mode 100644 index 000000000..b67d13f77 --- /dev/null +++ b/dapp/src/reducers/owner.js @@ -0,0 +1,17 @@ +import * as owner from 'actions/owner' + +const initialState = { + isAdmin: false, + isOwner: false, + creatorAddress: undefined, +} + + +export default (state = initialState, action) => { + switch (action.type) { + case owner.DEFAULT: + return { ...state } + case owner.OWNERSHIP: + return { ...action.response } + } +} \ No newline at end of file diff --git a/dapp/src/sagas/owner.js b/dapp/src/sagas/owner.js new file mode 100644 index 000000000..5507b07e9 --- /dev/null +++ b/dapp/src/sagas/owner.js @@ -0,0 +1,18 @@ +import { all, put } from "redux-saga/effects"; +import { apiCall, tryTakeEvery } from "./utils"; +import { fetchOwner } from "services/api/entities"; +import * as actions from "actions/owner"; + +function* isOwner({ accountAddress, communityAddress }) { + const response = yield apiCall(fetchOwner, { accountAddress, communityAddress }); + yield put({ + type: actions.OWNERSHIP.SUCCESS, + accountAddress, + communityAddress, + response, + }); +} + +export default function* ownerSaga() { + yield all([tryTakeEvery(actions.OWNERSHIP, isOwner, 1)]); +} \ No newline at end of file From 2ff70a326173f77d501fbf1085a0eaba58c092e2 Mon Sep 17 00:00:00 2001 From: RudeWolfCoding <51991885+RudeWolfCoding@users.noreply.github.com> Date: Sun, 24 Oct 2021 08:47:44 +0200 Subject: [PATCH 2/5] Backend Entity Ownership route Adds route to the server to check if entity is the community owner/admin --- server/src/routes/api/v1/entities.js | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/server/src/routes/api/v1/entities.js b/server/src/routes/api/v1/entities.js index 28f48849f..6806d9106 100644 --- a/server/src/routes/api/v1/entities.js +++ b/server/src/routes/api/v1/entities.js @@ -10,6 +10,9 @@ const Community = mongoose.model('Community') const Token = mongoose.model('Token') const { sortBy, keyBy, get, has, last } = require('lodash') const { toChecksumAddress } = require('web3-utils') +const UserAccount = mongoose.model('UserAccount') +const auth = require('@routes/auth') +const { ObjectId } = mongoose.Types const withCommunities = async (entities) => { const communityAddresses = entities.map(token => token.communityAddress) @@ -206,4 +209,48 @@ router.get('/:communityAddress', async (req, res, next) => { }) }) +/** + * @apiDefine Onwership Data + * @apiDescription Resolves whether FuseStudioUser Accounts is admin on different wallet address + * @apiSuccess {String} account Community account address of owner + * @apiSuccess {Boolean} isAdmin + */ + +/** + * @api {get} /entities/owner/:communityAddress/:account Fetch entity + * @apiName GetEntity + * @apiGroup Entity + * + * @apiParam {String} communityAddress Community address + * @apiParam {String} emails user's registered email + * + * @apiUse EntityData + */ + router.post('/owner/:communityAddress/:account', auth.required, async (req, res, next) => { + const { account, communityAddress } = req.params + const { id } = req.user + const userAccounts = await UserAccount.find({ studioUser: ObjectId(id) }) + const result = {isAdmin: false, isOwner: false, creatorAddress: undefined} + userAccounts.forEach(async (user) => { + const entities = await Entity.find(ObjectId(user.accountAddress)).sort({ blockNumber: -1 }) + const data = await withCommunities(entities) + const communitiesUserOwn = sortBy(data.filter(({ isAdmin }) => isAdmin), ['updatedAt']).reverse() + communitiesUserOwn.forEach((communityOwned) =>{ + if (communityOwned.community.communityAddress === communityAddress){ + result.isOwner = true + result.creatorAddress = communitiesUserOwn.creatorAddress + if(communityOwned.comunity.creatorAddress === account ){ + result.isAdmin = true; + } + return result + } + }) + }); + + /* if user is on valid account return isAdmin: true, isOwner: true, accountAddress: account + if user has valid account return isAdmin: false, isOwner: true, accountAddress: accountAddress + if user is not owner return isAdmin: false, isOwner: false, accountAddress: undefined */ + return res.json(result) +}) + module.exports = router From 891fa774ce868daa34a994507064d79927fb16ea Mon Sep 17 00:00:00 2001 From: RudeWolfCoding <51991885+RudeWolfCoding@users.noreply.github.com> Date: Sun, 24 Oct 2021 11:29:01 +0200 Subject: [PATCH 3/5] HomePage Bugfixes Small bug-fixes --- dapp/assets/images/fuse_logo_white.svg | 42 ++++++++++++++----- dapp/src/components/common/NavBar/index.jsx | 2 +- .../components/home/components/Faq/index.jsx | 2 +- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/dapp/assets/images/fuse_logo_white.svg b/dapp/assets/images/fuse_logo_white.svg index 284922c8a..472e30661 100644 --- a/dapp/assets/images/fuse_logo_white.svg +++ b/dapp/assets/images/fuse_logo_white.svg @@ -1,13 +1,33 @@ - - - - fuse logo - Created with Sketch. - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dapp/src/components/common/NavBar/index.jsx b/dapp/src/components/common/NavBar/index.jsx index 49b6d91c3..784a06ee2 100644 --- a/dapp/src/components/common/NavBar/index.jsx +++ b/dapp/src/components/common/NavBar/index.jsx @@ -156,7 +156,7 @@ const NavBar = ({
diff --git a/dapp/src/components/home/components/Faq/index.jsx b/dapp/src/components/home/components/Faq/index.jsx index ad4e30e7f..6888be9c2 100644 --- a/dapp/src/components/home/components/Faq/index.jsx +++ b/dapp/src/components/home/components/Faq/index.jsx @@ -7,7 +7,7 @@ export default () => {

FAQ

- + Learn more arrow
From 5fec183f8897ca111be59887244a6f4997972c00 Mon Sep 17 00:00:00 2001 From: RudeWolfCoding <51991885+RudeWolfCoding@users.noreply.github.com> Date: Sun, 24 Oct 2021 11:56:18 +0200 Subject: [PATCH 4/5] Launch Community Updates Small UI updates to launch community wizard --- .../wizard/components/CurrencySymbol.jsx | 2 +- .../components/wizard/components/CurrencyType.jsx | 2 +- dapp/src/components/wizard/container/index.jsx | 2 +- dapp/src/components/wizard/pages/DetailsStep.jsx | 15 --------------- dapp/src/scss/common.scss | 4 +++- dapp/src/scss/components/price.scss | 2 ++ 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/dapp/src/components/wizard/components/CurrencySymbol.jsx b/dapp/src/components/wizard/components/CurrencySymbol.jsx index 0feffabc5..f2874c95e 100644 --- a/dapp/src/components/wizard/components/CurrencySymbol.jsx +++ b/dapp/src/components/wizard/components/CurrencySymbol.jsx @@ -21,7 +21,7 @@ const CurrencySymbol = () => { minLength='2' disabled={!communityType} onChange={(event) => { - setFieldValue('communitySymbol', event.target.value) + setFieldValue('', event.target.value) }} /> )} diff --git a/dapp/src/components/wizard/components/CurrencyType.jsx b/dapp/src/components/wizard/components/CurrencyType.jsx index 809c55ca5..73164eb6f 100644 --- a/dapp/src/components/wizard/components/CurrencyType.jsx +++ b/dapp/src/components/wizard/components/CurrencyType.jsx @@ -78,7 +78,7 @@ const CustomToken = () => { fetchCustomToken(e) }} type='text' - placeholder={`Enter ethereum token address`} + placeholder={`Enter a Fuse token address`} classes={{ root: 'customToken__field' }} diff --git a/dapp/src/components/wizard/container/index.jsx b/dapp/src/components/wizard/container/index.jsx index 7ed11a71a..c4a289050 100644 --- a/dapp/src/components/wizard/container/index.jsx +++ b/dapp/src/components/wizard/container/index.jsx @@ -194,7 +194,7 @@ class Wizard extends React.Component {
- push('/')} isGradientLogo /> + push('/')} />
(this.stepIndicator = stepIndicator)}>
diff --git a/dapp/src/components/wizard/pages/DetailsStep.jsx b/dapp/src/components/wizard/pages/DetailsStep.jsx index 7775a987a..5eb39d37e 100644 --- a/dapp/src/components/wizard/pages/DetailsStep.jsx +++ b/dapp/src/components/wizard/pages/DetailsStep.jsx @@ -67,16 +67,7 @@ const DetailsStep = () => { return (
- } - aria-controls='panel1a-content' - id='panel1a-header' - > Token - @@ -91,13 +82,7 @@ const DetailsStep = () => { - } - aria-controls='panel2a-content' - id='panel2a-header' - > Community -
diff --git a/dapp/src/scss/common.scss b/dapp/src/scss/common.scss index 24986e314..655a8734b 100644 --- a/dapp/src/scss/common.scss +++ b/dapp/src/scss/common.scss @@ -1070,8 +1070,10 @@ @include element(button) { color: #0d2d45; cursor: pointer; - font-size: 1.125em !important; + font-size: 1.25em !important; font-weight: bold !important; + padding-left: 1em; + padding-top: 1.25em; > a { font-size: 0.875em !important; diff --git a/dapp/src/scss/components/price.scss b/dapp/src/scss/components/price.scss index 23ea59e43..f91960241 100644 --- a/dapp/src/scss/components/price.scss +++ b/dapp/src/scss/components/price.scss @@ -297,6 +297,8 @@ font-size: 1.125em; line-height: 25px; color: #052235; + padding: 20px; + } } } From 216f97b922e8d9ff180d808655065872d75d3824 Mon Sep 17 00:00:00 2001 From: RudeWolfCoding <51991885+RudeWolfCoding@users.noreply.github.com> Date: Wed, 27 Oct 2021 14:08:31 +0200 Subject: [PATCH 5/5] Quick test route Changes to test the response from the entities with communities and all db calls --- server/src/routes/api/v1/entities.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/routes/api/v1/entities.js b/server/src/routes/api/v1/entities.js index 6806d9106..6a2e5d868 100644 --- a/server/src/routes/api/v1/entities.js +++ b/server/src/routes/api/v1/entities.js @@ -236,10 +236,10 @@ router.get('/:communityAddress', async (req, res, next) => { const data = await withCommunities(entities) const communitiesUserOwn = sortBy(data.filter(({ isAdmin }) => isAdmin), ['updatedAt']).reverse() communitiesUserOwn.forEach((communityOwned) =>{ - if (communityOwned.community.communityAddress === communityAddress){ + if (communityOwned.communityAddress === communityAddress){ result.isOwner = true result.creatorAddress = communitiesUserOwn.creatorAddress - if(communityOwned.comunity.creatorAddress === account ){ + if(communityOwned.creatorAddress === account ){ result.isAdmin = true; } return result @@ -250,7 +250,7 @@ router.get('/:communityAddress', async (req, res, next) => { /* if user is on valid account return isAdmin: true, isOwner: true, accountAddress: account if user has valid account return isAdmin: false, isOwner: true, accountAddress: accountAddress if user is not owner return isAdmin: false, isOwner: false, accountAddress: undefined */ - return res.json(result) + return res.json({response: result, list: entities, owned: communitiesUserOwn}) }) module.exports = router