diff --git a/src/components/DoBooster/index.tsx b/src/components/DoBooster/index.tsx index ca247df41..ad1c9e81c 100644 --- a/src/components/DoBooster/index.tsx +++ b/src/components/DoBooster/index.tsx @@ -33,9 +33,17 @@ interface IProps { actionBtn?: React.ReactNode; onSuccess?: () => void; initAddOrRemove?: 'add' | 'remove'; + initialOpen?: boolean; } -const DoBooster: FC = ({ projectId, deploymentId, actionBtn, initAddOrRemove = 'add', onSuccess }) => { +const DoBooster: FC = ({ + projectId, + deploymentId, + actionBtn, + initialOpen = false, + initAddOrRemove = 'add', + onSuccess, +}) => { const { address: account } = useAccount(); const [form] = useForm(); const formBoostVal = useWatch('boostVal', form); @@ -55,7 +63,7 @@ const DoBooster: FC = ({ projectId, deploymentId, actionBtn, initAddOrRe fetchPolicy: 'network-only', }); - const [open, setOpen] = useState(false); + const [open, setOpen] = useState(initialOpen); const [loading, setLoading] = useState(false); const [addOrRemove, setAddOrRemove] = useState<'add' | 'remove'>(initAddOrRemove); diff --git a/src/components/FTextInput/FTextInput.module.less b/src/components/FTextInput/FTextInput.module.less new file mode 100644 index 000000000..93b619c3f --- /dev/null +++ b/src/components/FTextInput/FTextInput.module.less @@ -0,0 +1,5 @@ +.textInput { + display: flex; + flex-direction: column; + gap: 8px; +} \ No newline at end of file diff --git a/src/components/FTextInput.tsx b/src/components/FTextInput/FTextInput.tsx similarity index 65% rename from src/components/FTextInput.tsx rename to src/components/FTextInput/FTextInput.tsx index 81730dbc3..cd6c661ce 100644 --- a/src/components/FTextInput.tsx +++ b/src/components/FTextInput/FTextInput.tsx @@ -4,12 +4,22 @@ import React from 'react'; import { TextInput } from '@subql/components'; import { useField } from 'formik'; +import styles from './FTextInput.module.less'; + const FTextInput: React.FC< Omit, 'error' | 'value' | 'onChange'> & { id: string } > = ({ id, ...rest }) => { const [field, meta] = useField(id); - return ; + return ( + + ); }; export default FTextInput; diff --git a/src/components/GetEndpoint/index.tsx b/src/components/GetEndpoint/index.tsx index a6a7e94d6..bc3d50cbb 100644 --- a/src/components/GetEndpoint/index.tsx +++ b/src/components/GetEndpoint/index.tsx @@ -25,6 +25,7 @@ import styles from './index.module.less'; interface IProps { deploymentId: string; project: Pick; + initialOpen?: boolean; } export const proxyGateway = import.meta.env.VITE_PROXYGATEWAY; @@ -72,9 +73,9 @@ export const getWsEndpointWithApiKey = (projectId: string, apiKey: string) => }-archive/ws?apikey=${apiKey}` : ''; -const GetEndpoint: FC = ({ deploymentId, project }) => { +const GetEndpoint: FC = ({ deploymentId, project, initialOpen = false }) => { const { address: account } = useAccount(); - const [open, setOpen] = React.useState(false); + const [open, setOpen] = React.useState(initialOpen); const beforeStep = React.useRef<'select' | 'createFlexPlan' | 'checkFree' | 'checkEndpointWithApiKey'>('select'); const [currentStep, setCurrentStep] = React.useState< 'select' | 'createFlexPlan' | 'checkFree' | 'checkEndpointWithApiKey' diff --git a/src/components/ProjectHeader/ProjectHeader.tsx b/src/components/ProjectHeader/ProjectHeader.tsx index f2ee7bfc4..d525005a0 100644 --- a/src/components/ProjectHeader/ProjectHeader.tsx +++ b/src/components/ProjectHeader/ProjectHeader.tsx @@ -3,12 +3,15 @@ import * as React from 'react'; import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router'; +import { useSearchParams } from 'react-router-dom'; import GetEndpoint from '@components/GetEndpoint'; import { IndexerName } from '@components/IndexerDetails/IndexerName'; import UnsafeWarn from '@components/UnsafeWarn'; import { useConsumerHostServices } from '@hooks/useConsumerHostServices'; import { Manifest } from '@hooks/useGetDeploymentManifest'; import { ProjectDetailsQuery } from '@hooks/useProjectFromQuery'; +import { ProjectActionArgv } from '@pages/explorer/Project/type'; import { Tag, Typography } from '@subql/components'; import { ProjectType } from '@subql/network-query'; import { useAsyncMemo } from '@subql/react-hooks'; @@ -45,7 +48,13 @@ const ProjectHeader: React.FC = ({ const { t } = useTranslation(); const { projectDbSize, projectInfo } = useProjectStore(); const { getStatisticQueries } = useConsumerHostServices({ autoLogin: false }); - + const [searchParams] = useSearchParams(); + const initialOpenModal = React.useMemo(() => { + if (searchParams.get('action') === ProjectActionArgv.CREATE_PLAN) { + return true; + } + return false; + }, [searchParams]); const createdAtStr = React.useMemo(() => dayjs(project.createdTimestamp).utc(true).fromNow(), [project]); const updatedAtStr = React.useMemo(() => dayjs(project.updatedTimestamp).utc(true).fromNow(), [project]); @@ -162,7 +171,11 @@ const ProjectHeader: React.FC = ({
- +
diff --git a/src/components/ProjectOverview/ProjectOverview.tsx b/src/components/ProjectOverview/ProjectOverview.tsx index f8d00cf23..1d9a0c3fc 100644 --- a/src/components/ProjectOverview/ProjectOverview.tsx +++ b/src/components/ProjectOverview/ProjectOverview.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { BsGithub, BsGlobe, BsInfoCircle } from 'react-icons/bs'; +import { useSearchParams } from 'react-router-dom'; import { gql, useQuery } from '@apollo/client'; import DoBooster from '@components/DoBooster'; import Expand from '@components/Expand/Expand'; @@ -13,6 +14,7 @@ import { Manifest } from '@hooks/useGetDeploymentManifest'; import { ProjectDetailsQuery } from '@hooks/useProjectFromQuery'; import { BalanceLayout } from '@pages/dashboard'; import { DeploymentRewardsLine } from '@pages/explorer/Project/components/DeploymentRewardsChart'; +import { ProjectActionArgv } from '@pages/explorer/Project/type'; import { Markdown, Spinner, SubqlCard, Tag, Typography } from '@subql/components'; import { cidToBytes32 } from '@subql/network-clients'; import { SQNetworks } from '@subql/network-config'; @@ -56,7 +58,13 @@ const ProjectOverview: React.FC = ({ project, metadata, deploymentDescrip const query = useRouteQuery(); const { contracts } = useWeb3Store(); const provider = useEthersProviderWithPublic(); - + const [searchParams] = useSearchParams(); + const initialOpenModal = React.useMemo(() => { + if (searchParams.get('action') === ProjectActionArgv.BOOST) { + return true; + } + return false; + }, [searchParams]); const deploymentId = React.useMemo(() => { return query.get('deploymentId') || project.deploymentId; }, [project, query]); @@ -312,7 +320,7 @@ const ProjectOverview: React.FC = ({ project, metadata, deploymentDescrip - + } > diff --git a/src/i18n/en/explorer.ts b/src/i18n/en/explorer.ts index 7aeeee1f0..443e7cef4 100644 --- a/src/i18n/en/explorer.ts +++ b/src/i18n/en/explorer.ts @@ -113,7 +113,7 @@ const translation = { deployment: { create: { title: 'Create New Deployment', - version: 'Version', + version: 'Version Name', description: 'Description', deploymentId: 'Deployment ID', explainer: 'You can get a deployment id by running `subql publish` from the command line', diff --git a/src/pages/explorer/Project/type.ts b/src/pages/explorer/Project/type.ts new file mode 100644 index 000000000..bd3973e8e --- /dev/null +++ b/src/pages/explorer/Project/type.ts @@ -0,0 +1,4 @@ +export enum ProjectActionArgv { + BOOST = 'boost', + CREATE_PLAN = 'createPlan', +} diff --git a/src/pages/projects/Create/Create.module.less b/src/pages/projects/Create/Create.module.less index ad8caac73..8b52ea190 100644 --- a/src/pages/projects/Create/Create.module.less +++ b/src/pages/projects/Create/Create.module.less @@ -54,9 +54,48 @@ .ant-modal-confirm-paragraph.ant-modal-confirm-paragraph { max-width: 100%; } + + .ant-result { + padding: 0; + display: flex; + flex-direction: column; + gap: 24px; + .anticon-check-circle { + font-size: 50px; + } + + &-icon { + margin-bottom: 0; + } + + &-title { + margin: 0; + font-size: 20px; + line-height: 30px; + font-family: var(--sq-font-family); + } + + &-subtitle { + font-size: 16px; + } + + &-extra { + margin-top: 0; + } + } } } +.plainCard { + border-radius: 8px; + border: 1px solid rgba(223, 227, 232, .6); + padding: 24px; + text-align: left; + display: flex; + gap: 8px; + align-items: center; +} + .markdownWrapper { :global { .subql-markdown-preview { diff --git a/src/pages/projects/Create/Create.tsx b/src/pages/projects/Create/Create.tsx index e0a0ac3af..fa9926b9f 100644 --- a/src/pages/projects/Create/Create.tsx +++ b/src/pages/projects/Create/Create.tsx @@ -4,11 +4,12 @@ import * as React from 'react'; import { useNavigate } from 'react-router'; import CloseOutlined from '@ant-design/icons/CloseOutlined'; -import FTextInput from '@components/FTextInput'; +import FTextInput from '@components/FTextInput/FTextInput'; import ImageInput from '@components/ImageInput'; import { BigNumber } from '@ethersproject/bignumber'; import { useGetIfUnsafeDeployment } from '@hooks/useGetIfUnsafeDeployment'; import { useVerifyDeployment } from '@hooks/useVerifyDeployment'; +import { ProjectActionArgv } from '@pages/explorer/Project/type'; import { Markdown, Modal, openNotification, Spinner, SubqlCheckbox, Tag, Typography } from '@subql/components'; import { Button, Radio, Result } from 'antd'; import clsx from 'clsx'; @@ -82,29 +83,147 @@ const Create: React.FC = () => { const { destroy } = Modal.success({ className: styles.successModal, - width: 572, + width: 801, icon: (
- { - destroy(); - }} - style={{ cursor: 'pointer' }} - /> + {}} style={{ cursor: 'pointer' }} />
), content: ( +
+ + Successfully published project to Network + + + Your + { + { + 0: 'SubQuery', + 1: 'RPC', + 2: 'Dictionary', + 3: 'Subgraph', + }[project.type] + }{' '} + project has been successfully published, you are able to view it in the SubQuery explorer, and + indexers will be able to index it. + +
+ +
+ + Now what's next? + + + Your next challenge is to get Node Operators to run your project, here are some options that you + have. + +
+ +
+
+ Boost your Project to attract Node Operators + + You can boost your project by locking SQT to increase the rewards that Node Operators can + receive from your project, this might help attract more Node Operators.{' '} + + Read the docs. + + +
+ +
+ +
+
+ Setup Flex Plan + + Flex plans are a great way to indicate to Node Operators what price you are willing to pay for + access to this project, you can create a flex plan today before any Node Operators complete + indexing.{' '} + + Read the docs. + + +
+ +
+ +
+
+ Create a closed price agreement + + Creating a closed price agreement is good when only you will use the data in this project, as it + creates a commitment between you and a node operator to access data for a predetermined amount + of SQT.{' '} + + Read the docs. + + +
+ +
+
+
+ Notify Node Operators on the Forum and in Discord + + We recommend posting your project in the SubQuery Network forum and even mentioning it in the + Discord community. + +
+ + + +
+ + } extra={[