Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: V4 create behind feature flag [1/n] #4444

Merged
merged 4 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions src/packages/v4/components/Create/Create.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { t, Trans } from '@lingui/macro'
import { DeployButtonText } from 'components/buttons/DeployProjectButtonText'
import {
CYCLE_EXPLANATION,
RECONFIG_RULES_EXPLANATION,
} from 'components/strings'
import { readNetwork } from 'constants/networks'
import { NetworkName } from 'models/networkName'
import { useRouter } from 'next/router'
import { CreateBadge } from './components/CreateBadge'
import { FundingCyclesPage } from './components/pages/FundingCycles/FundingCyclesPage'
import { NftRewardsPage } from './components/pages/NftRewards/NftRewardsPage'
import { PayoutsPage } from './components/pages/PayoutsPage/PayoutsPage'
import { ProjectDetailsPage } from './components/pages/ProjectDetails/ProjectDetailsPage'
import { ProjectTokenPage } from './components/pages/ProjectToken/ProjectTokenPage'
import { ReconfigurationRulesPage } from './components/pages/ReconfigurationRules/ReconfigurationRulesPage'
import { DeploySuccess } from './components/pages/ReviewDeploy/components/DeploySuccess'
import { ReviewDeployPage } from './components/pages/ReviewDeploy/ReviewDeployPage'
import { Wizard } from './components/Wizard/Wizard'
import { useLoadingInitialStateFromQuery } from './hooks/useLoadInitialStateFromQuery'

export function Create() {
const router = useRouter()
const deployedProjectId = router.query.deployedProjectId as string
const initialStateLoading = useLoadingInitialStateFromQuery()

if (initialStateLoading) return <>XX</>//<Loading />

if (deployedProjectId) {
const projectId = parseInt(deployedProjectId)
return <DeploySuccess projectId={projectId} />
}

return (
<div className="mt-12 md:mt-10">
<h1 className="mb-0 text-center font-heading text-base font-medium uppercase text-black dark:text-slate-100">
<Trans>Create a project</Trans>
</h1>
{/* TODO: Remove wizard-create once form item css override is replaced */}
<div className="wizard-create">
<Wizard className="pb-28" doneText={<DeployButtonText />}>
<Wizard.Page
name="projectDetails"
title={t`Project Details`}
description={t`Enter your project's details. You can edit your project's details at any time after you deploy your project, but the transaction will cost gas.`}
>
<ProjectDetailsPage />
</Wizard.Page>
<Wizard.Page
name="fundingCycles"
title={t`Cycles`}
description={CYCLE_EXPLANATION}
>
<FundingCyclesPage />
</Wizard.Page>
<Wizard.Page
name="payouts"
title={t`Payouts`}
description={
<Trans>
Pay out ETH from your project to any Ethereum wallet or Juicebox
project. ETH which <em>isn't</em> paid out will be available for
token redemptions, or for use in future cycles. Payouts reset
each cycle.
</Trans>
}
>
<PayoutsPage />
</Wizard.Page>
<Wizard.Page
name="projectToken"
title={t`Token`}
description={
<Trans>
When people pay your project, they receive its tokens. Project
tokens can be used for governance or community access, and token
holders can redeem their tokens to reclaim some ETH from your
project. You can also reserve some tokens for recipients of your
choosing.
</Trans>
}
>
<ProjectTokenPage />
</Wizard.Page>
<Wizard.Page
name="nftRewards"
title={
<div className="flex items-center gap-3">
<Trans>NFTs</Trans>
<CreateBadge.Optional />
</div>
}
description={
<Trans>Reward your supporters with custom NFTs.</Trans>
}
>
<NftRewardsPage />
</Wizard.Page>
<Wizard.Page
name="reconfigurationRules"
title={<Trans>Edit Deadline</Trans>}
description={RECONFIG_RULES_EXPLANATION}
>
<ReconfigurationRulesPage />
</Wizard.Page>
<Wizard.Page
className="max-w-full md:w-full md:max-w-3xl"
name="reviewDeploy"
title={t`Review & Deploy`}
description={
<Trans>
Review your project and deploy it to{' '}
{readNetwork.name ?? NetworkName.mainnet}.
</Trans>
}
>
<ReviewDeployPage />
</Wizard.Page>
</Wizard>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Trans } from '@lingui/macro'
import { Badge } from 'components/Badge'

export const DefaultBadge = () => {
return (
<Badge variant="info" upperCase className="text-xs">
<Trans>Default</Trans>
</Badge>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Trans } from '@lingui/macro'
import { Badge } from 'components/Badge'

export const OptionalBadge = () => {
return (
<Badge variant="default" upperCase className="text-xs">
<Trans>Optional</Trans>
</Badge>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Trans } from '@lingui/macro'
import { Tooltip } from 'antd'
import { Badge } from 'components/Badge'
import { ReactNode } from 'react'

export const RecommendedBadge = ({ tooltip }: { tooltip?: ReactNode }) => {
return (
<Tooltip title={tooltip}>
<Badge variant="info" upperCase className="text-xs">
<Trans>Recommended</Trans>
</Badge>
</Tooltip>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Trans } from '@lingui/macro'
import { Badge } from 'components/Badge'

export const SkippedBadge = () => {
return (
<Badge variant="default" upperCase className="text-xs">
<Trans>Skipped</Trans>
</Badge>
)
}
11 changes: 11 additions & 0 deletions src/packages/v4/components/Create/components/CreateBadge/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DefaultBadge } from './DefaultBadge'
import { OptionalBadge } from './OptionalBadge'
import { RecommendedBadge } from './RecommendedBadge'
import { SkippedBadge } from './SkippedBadge'

export const CreateBadge = {
Default: DefaultBadge,
Skipped: SkippedBadge,
Recommended: RecommendedBadge,
Optional: OptionalBadge,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DownOutlined } from '@ant-design/icons'
import { Collapse } from 'antd'
import { CreateCollapsePanel } from './CreateCollapsePanel'

export const CreateCollapse: React.FC<
React.PropsWithChildren<{
activeKey?: string | number | (string | number)[]
onChange?: (key: string | string[]) => void
}>
> & {
Panel: typeof CreateCollapsePanel
} = ({ activeKey, onChange, children }) => {
return (
<Collapse
className="create-collapse" // ant override
expandIconPosition="end"
bordered={false}
ghost
expandIcon={({ isActive }) => (
<DownOutlined className="text-grey-500" rotate={isActive ? 180 : 0} />
)}
onChange={onChange}
{...(activeKey ? { activeKey } : {})}
>
{children}
</Collapse>
)
}

CreateCollapse.Panel = CreateCollapsePanel
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Collapse, CollapsePanelProps, Divider } from 'antd'

export const CreateCollapsePanel: React.FC<
React.PropsWithChildren<CollapsePanelProps & { hideDivider?: boolean }>
> = ({ hideDivider, ...props }) => {
return (
<Collapse.Panel {...props}>
{
<>
{props.children}
{!hideDivider && <Divider className="mb-0" />}
</>
}
</Collapse.Panel>
)
}
21 changes: 21 additions & 0 deletions src/packages/v4/components/Create/components/Icons/Infinity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Icon from '@ant-design/icons'
import { Property } from 'csstype'
import { SVGAttributes } from 'react'

const _SVG: React.FC<
React.PropsWithChildren<SVGAttributes<SVGSVGElement>>
> = props => (
<svg
width="1em"
height="1em"
viewBox="0 0 36 37"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path d="M27.5497 26.4389C23.5016 26.4389 20.6485 23.8011 17.9892 20.9696C15.3192 23.7688 12.2077 26.4389 7.84737 26.4389C3.48702 26.4389 1 22.5522 1 18.7194C1 16.76 1.58138 14.9189 2.64724 13.5301C3.89614 11.8936 5.74794 11 7.85814 11C12.2185 11 15.33 13.67 18 16.4693C20.6593 13.6377 23.5123 11 27.5605 11C32.4484 11 35 14.8866 35 18.7194C35 22.5522 32.4376 26.4389 27.5497 26.4389V26.4389ZM20.0887 18.7194C22.4142 21.2065 24.6859 23.3705 27.5497 23.3705C30.575 23.3705 31.9208 21.0342 31.9208 18.7194C31.9208 16.4047 30.5643 14.0684 27.5497 14.0684C24.6859 14.0684 22.4142 16.2324 20.0887 18.7194V18.7194ZM7.84737 14.0684C4.8651 14.0684 4.0684 16.9968 4.0684 18.7194C4.0684 20.4421 4.8651 23.3705 7.84737 23.3705C11.088 23.3705 13.4997 21.2495 15.9006 18.7194C13.4997 16.1894 11.088 14.0684 7.84737 14.0684V14.0684Z" />
</svg>
)

export const InfinityIcon = ({ fill }: { fill?: Property.Fill }) => {
return <Icon component={() => <_SVG />} style={{ fill }} />
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Icon from '@ant-design/icons'
import { Property } from 'csstype'
import { SVGAttributes } from 'react'

const _SVG: React.FC<
React.PropsWithChildren<SVGAttributes<SVGSVGElement>>
> = props => (
<svg
width="1em"
height="1em"
viewBox="0 0 36 37"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path d="M9.01999 33.67L3.17999 27.83C3.05999 27.71 3.05999 27.52 3.17999 27.41L14.42 16.17L9.47999 11.23C9.41999 11.17 9.34999 11.14 9.26999 11.14H4.88999C4.75999 11.14 4.64999 11.06 4.60999 10.93L2.71999 5.25004C2.67999 5.14004 2.71999 5.02004 2.78999 4.94004L5.17999 2.55004C5.25999 2.47004 5.37999 2.44004 5.48999 2.48004L11.17 4.38004C11.29 4.42004 11.38 4.54004 11.38 4.66004V9.04004C11.38 9.12004 11.41 9.20004 11.47 9.25004L15.9 13.68C15.78 13.09 15.73 12.49 15.73 11.89C15.73 6.18004 20.92 1.66004 26.83 2.81004C27.86 3.01004 28.84 3.42004 29.74 3.94004L30.86 4.59004C31.03 4.69004 31.06 4.92004 30.92 5.06004L26.15 9.82004C25.91 10.06 25.65 10.32 25.55 10.45C25.65 10.58 25.91 10.83 26.15 11.08L26.49 11.42C26.72 11.65 26.98 11.91 27.12 12.02C27.25 11.92 27.5 11.66 27.75 11.42L32.43 6.74004C32.58 6.59004 32.84 6.64004 32.92 6.84004L33.55 8.37004C34.01 9.49004 34.24 10.67 34.24 11.89C34.24 16.18 31.31 19.8 27.34 20.84L33.9 27.4C34.02 27.52 34.02 27.71 33.9 27.82L28.06 33.66C27.94 33.78 27.75 33.78 27.64 33.66L18.56 24.58L9.46999 33.67C9.34999 33.79 9.15999 33.79 9.04999 33.67H9.01999ZM6.92999 27.62L9.23999 29.93L20.33 18.84C20.46 18.71 20.59 18.6 20.74 18.5C20.82 18.44 20.91 18.39 21 18.34C21.36 18.15 21.65 18.06 22.06 18.02C22.09 18.02 22.13 18.02 22.16 18.02C22.52 17.99 22.89 18.02 23.26 18.12C23.51 18.19 23.78 18.24 24.04 18.28C24.35 18.32 24.66 18.35 24.98 18.35C28.54 18.35 31.44 15.45 31.44 11.89C31.44 11.83 31.44 11.76 31.44 11.7L29.73 13.41C29.08 14.06 28.64 14.5 28 14.71C27.43 14.9 26.82 14.9 26.25 14.71C25.6 14.5 25.17 14.07 24.52 13.41L24.18 13.07C23.53 12.42 23.09 11.98 22.88 11.34C22.69 10.77 22.69 10.16 22.88 9.59004C23.09 8.94004 23.52 8.51004 24.18 7.86004L26.44 5.60004C25.96 5.49004 25.48 5.43004 24.98 5.43004C21.42 5.43004 18.52 8.33004 18.52 11.89C18.52 12.31 18.56 12.74 18.64 13.15C18.81 14 18.89 14.39 18.84 14.81C18.8 15.22 18.71 15.5 18.52 15.87C18.47 15.97 18.41 16.06 18.35 16.15L18.38 16.18L17.67 16.89C17.67 16.89 17.63 16.93 17.61 16.95L6.92999 27.63V27.62ZM20.52 22.6L27.83 29.91L30.14 27.6L23.57 21.03C23.44 21.01 23.3 20.99 23.17 20.96C22.83 20.89 22.47 20.82 22.32 20.8C22.32 20.8 22.31 20.8 22.3 20.8L21.91 21.19C21.91 21.19 21.91 21.19 21.9 21.19L20.52 22.57V22.6ZM6.90999 8.34004H8.26999C8.43999 8.34004 8.56999 8.21004 8.56999 8.04004V6.68004C8.56999 6.55004 8.48999 6.44004 8.35999 6.40004L6.05999 5.63004L5.84999 5.84004L6.61999 8.14004C6.65999 8.26004 6.77999 8.35004 6.89999 8.35004L6.90999 8.34004Z" />
</svg>
)

export const ManualSettingsIcon = ({ fill }: { fill?: Property.Fill }) => {
return <Icon component={() => <_SVG />} style={{ fill }} />
}
21 changes: 21 additions & 0 deletions src/packages/v4/components/Create/components/Icons/TargetIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Icon from '@ant-design/icons'
import { Property } from 'csstype'
import { SVGAttributes } from 'react'

const _SVG: React.FC<
React.PropsWithChildren<SVGAttributes<SVGSVGElement>>
> = props => (
<svg
width="1em"
height="1em"
viewBox="0 0 36 37"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path d="M18.7313 33.9735C9.2467 34.6315 1.37153 26.7665 2.03961 17.2717C2.61658 9.03216 9.77306 2.77657 18.0329 2.77657H18.6301C18.9135 2.77657 19.0451 2.90816 19.0451 3.08024V5.35776C19.0451 5.52984 18.9135 5.66143 18.7414 5.66143H17.9924C10.9068 5.66143 4.88398 11.2894 4.87386 18.3751C4.87386 25.3999 10.5828 31.1191 17.6179 31.1191C24.6529 31.1191 30.3315 25.0963 30.3315 18.0005V17.2515C30.3315 17.0794 30.4631 16.9478 30.6352 16.9478H32.9127C33.0848 16.9478 33.2163 17.0794 33.2163 17.2515V17.9702C33.2163 26.2401 26.9709 33.3865 18.7212 33.9735H18.7313ZM17.5065 26.9284C12.8907 26.8778 9.13535 23.1224 9.08474 18.5066C9.03413 13.8909 13.1235 9.86219 17.9215 9.86219H18.6301C18.9236 9.86219 19.0552 9.99378 19.0552 10.1659V12.4434C19.0552 12.6155 18.9236 12.747 18.7516 12.747H17.8507C14.8545 12.747 12.2024 14.9841 11.9797 17.9702C11.7267 21.4118 14.5812 24.2662 18.0329 24.0233C21.019 23.8006 23.256 21.1486 23.256 18.1524V17.2515C23.256 17.0794 23.3876 16.9478 23.5597 16.9478H25.8372C26.0093 16.9478 26.1408 17.0794 26.1408 17.2515V18.0815C26.1408 22.8795 22.3045 26.979 17.5065 26.9183V26.9284ZM17.3952 20.2274L15.7857 18.618C15.6642 18.4965 15.6642 18.3042 15.7857 18.1929L21.7478 12.2308C21.8085 12.1701 21.8389 12.0992 21.8389 12.0182V8.01993C21.8389 7.93895 21.8692 7.85797 21.93 7.80736L27.6288 2.08825C27.7705 1.94654 28.0236 1.9769 28.1147 2.16923L29.9772 5.89424C30.0076 5.95497 30.0582 6.00558 30.1088 6.02583L33.8338 7.88834C34.016 7.97944 34.0565 8.23249 33.9148 8.37421L28.2159 14.0731C28.1552 14.1338 28.0843 14.1642 28.0034 14.1642H24.005C23.9241 14.1642 23.8431 14.1945 23.7925 14.2553L17.8304 20.2173C17.709 20.3388 17.5166 20.3388 17.4053 20.2173L17.3952 20.2274ZM24.7237 11.2894H26.9304L29.3395 8.88032L27.8616 8.14139L27.1227 6.66354L24.7136 9.07265V11.2793L24.7237 11.2894Z" />
</svg>
)

export const TargetIcon = ({ fill }: { fill?: Property.Fill }) => {
return <Icon component={() => <_SVG />} style={{ fill }} />
}
21 changes: 21 additions & 0 deletions src/packages/v4/components/Create/components/Icons/TokensIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Icon from '@ant-design/icons'
import { Property } from 'csstype'
import { SVGAttributes } from 'react'

const _SVG: React.FC<
React.PropsWithChildren<SVGAttributes<SVGSVGElement>>
> = props => (
<svg
width="1em"
height="1em"
viewBox="0 0 36 37"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path d="M14.1701 33.7402C7.94012 33.7402 2.87012 28.6702 2.87012 22.4402C2.87012 17.0802 6.62012 12.5802 11.6401 11.4302C12.8001 6.36016 17.3701 2.66016 22.6601 2.66016C28.8901 2.66016 33.9601 7.73016 33.9601 13.9602C33.9601 19.2502 30.2601 23.8102 25.1901 24.9802C24.0401 30.0002 19.5401 33.7502 14.1801 33.7502L14.1701 33.7402ZM13.0101 14.0202C8.87012 14.5902 5.67012 18.1502 5.67012 22.4402C5.67012 27.1302 9.48012 30.9402 14.1701 30.9402C18.8601 30.9402 22.6701 27.1302 22.6701 22.4402C22.6701 17.7502 18.8601 13.9402 14.1701 13.9402C13.7901 13.9402 13.4201 13.9602 13.0501 14.0102C13.0401 14.0102 13.0201 14.0102 13.0101 14.0102V14.0202ZM14.6301 11.1502C20.5001 11.3902 25.2201 16.1102 25.4601 21.9802C28.8001 20.8102 31.1601 17.6102 31.1601 13.9502C31.1601 9.26016 27.3501 5.45016 22.6601 5.45016C19.0001 5.45016 15.8001 7.80016 14.6301 11.1402V11.1502Z" />
</svg>
)

export const TokensIcon = ({ fill }: { fill?: Property.Fill }) => {
return <Icon component={() => <_SVG />} style={{ fill }} />
}
11 changes: 11 additions & 0 deletions src/packages/v4/components/Create/components/Icons/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { InfinityIcon } from './Infinity'
import { ManualSettingsIcon } from './ManualSettingsIcon'
import { TargetIcon } from './TargetIcon'
import { TokensIcon } from './TokensIcon'

export const Icons = {
ManualSettings: ManualSettingsIcon,
Target: TargetIcon,
Infinity: InfinityIcon,
Tokens: TokensIcon,
}
12 changes: 12 additions & 0 deletions src/packages/v4/components/Create/components/OptionalHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Trans } from '@lingui/macro'

export const OptionalHeader = ({ header }: { header: string }) => {
return (
<>
{header}{' '}
<span>
(<Trans>Optional</Trans>)
</span>
</>
)
}
Loading
Loading