Skip to content

Commit

Permalink
Merge branch 'crt' into feature/sell-tokens-amm
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/atlas/src/joystream-lib/extrinsics.ts
  • Loading branch information
WRadoslaw committed Oct 16, 2023
2 parents 8d8bbf2 + 401407d commit 206b016
Show file tree
Hide file tree
Showing 30 changed files with 3,801 additions and 1,871 deletions.
2 changes: 2 additions & 0 deletions packages/atlas/atlas.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ analytics:
id: '$VITE_SEGMENT_ID'

legal:
crtTnc: |
This is a temporary placeholder for the Creator Tokens Terms and Conditions. The final version will be added here soon.
termsOfService: |
# Terms of Service
Expand Down
16 changes: 8 additions & 8 deletions packages/atlas/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@
"@joystream/prettier-config": "^1.0.0",
"@modyfi/vite-plugin-yaml": "^1.0.3",
"@rollup/plugin-babel": "^6.0.3",
"@storybook/addon-actions": "7.0.7",
"@storybook/addon-docs": "7.0.7",
"@storybook/addon-essentials": "7.0.7",
"@storybook/addon-links": "7.0.7",
"@storybook/addons": "7.0.7",
"@storybook/react-vite": "7.0.7",
"@storybook/theming": "7.0.7",
"@storybook/addon-actions": "7.4.6",
"@storybook/addon-docs": "7.4.6",
"@storybook/addon-essentials": "7.4.6",
"@storybook/addon-links": "7.4.6",
"@storybook/addons": "7.4.6",
"@storybook/react-vite": "7.4.6",
"@storybook/theming": "7.4.6",
"@svgr/cli": "^6.5.1",
"@testing-library/dom": "^8.19.0",
"@testing-library/jest-dom": "^5.16.5",
Expand Down Expand Up @@ -151,7 +151,7 @@
"react-hooks-testing-library": "^0.6.0",
"rimraf": "^3.0.2",
"rollup-plugin-visualizer": "^5.8.3",
"storybook": "7.0.7",
"storybook": "7.4.6",
"style-dictionary": "^3.7.1",
"vite": "^4.3.9",
"vite-plugin-checker": "^0.5.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ const dollarSmallNumberFormatter = new Intl.NumberFormat('en-US', {
maximumSignificantDigits: 3,
})

const formatNumberShort = (num: number): string => {
export const formatNumberShort = (num: number): string => {
return numberCompactFormatter.format(num).replaceAll(',', ' ')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const StudioEntrypoint: FC<StudioEntrypointProps> = ({ enterLocation }) =
}

if (channelSet) {
return <Navigate to={DEFAULT_ROUTE} replace />
return <Navigate to={enterLocation || DEFAULT_ROUTE} replace />
}

return <StudioLoading />
Expand Down
4 changes: 2 additions & 2 deletions packages/atlas/src/components/WidgetTile/WidgetTile.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export const Wrapper = styled.div`
padding: ${sizes(6)};
}
`
export const Content = styled.div`
export const Content = styled.div<{ withButton?: boolean }>`
display: grid;
align-self: flex-end;
gap: ${sizes(4)};
${media.md} {
gap: ${sizes(6)};
grid-template-columns: 1fr auto;
align-items: center;
${(props) => (props.withButton ? 'grid-template-columns: 1fr auto;' : '')}
}
`

Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/src/components/WidgetTile/WidgetTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const WidgetTile: FC<WidgetTileProps> = ({
{withTooltip && <Information {...tooltip} />}
{withCustomTopRightNode && customTopRightNode}
</Title>
<Content>
<Content withButton={!!button}>
{withCustomNode && customNode}
{loading && (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const SignUpModal = () => {
const [emailAlreadyTakenError, setEmailAlreadyTakenError] = useState(false)
const [hasNavigatedBack, setHasNavigatedBack] = useState(false)
const [primaryButtonProps, setPrimaryButtonProps] = useState<DialogButtonProps>({ text: 'Continue' })
const [amountOfTokens, setAmountofTokens] = useState<number>()
const [amountOfTokens] = useState<number>()
const [memberId, setMemberId] = useState<string | null>(null)
const syncState = useRef<'synced' | 'tried' | null>(null)
const ytResponseData = useYppStore((state) => state.ytResponseData)
Expand Down Expand Up @@ -128,7 +128,7 @@ export const SignUpModal = () => {
setAuthModalOpenName(undefined)
setYppModalOpenName('ypp-sync-options')
} else {
setAmountofTokens(amountOfTokens)
amountOfTokens
goToNextStep()
}
},
Expand Down Expand Up @@ -174,7 +174,7 @@ export const SignUpModal = () => {
setAuthModalOpenName(undefined)
setYppModalOpenName('ypp-sync-options')
} else {
setAmountofTokens(amountOfTokens)
amountOfTokens
goToNextStep()
}
},
Expand Down
49 changes: 26 additions & 23 deletions packages/atlas/src/components/_charts/LineChart/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ import { ReactNode } from 'react'

import { cVar, sizes } from '@/styles'

export const defaultChartTheme = {
tooltip: {
container: {
background: cVar('colorBackgroundStrong'),
},
},

axis: {
ticks: {
line: {
stroke: cVar('colorBackgroundAlpha'),
},
text: {
fill: cVar('colorTextMuted'),
font: cVar('typographyDesktopT100'),
},
},
},
grid: {
line: {
stroke: cVar('colorBackgroundAlpha'),
},
},
}

const defaultJoystreamProps: Omit<LineSvgProps, 'data'> = {
isInteractive: true,
useMesh: true,
Expand All @@ -29,29 +54,7 @@ const defaultJoystreamProps: Omit<LineSvgProps, 'data'> = {
tickValues: 6,
},
colors: (d) => d.color,
theme: {
tooltip: {
container: {
background: cVar('colorBackgroundStrong'),
},
},
axis: {
ticks: {
line: {
stroke: cVar('colorBackgroundAlpha'),
},
text: {
fill: cVar('colorTextMuted'),
font: cVar('typographyDesktopT100'),
},
},
},
grid: {
line: {
stroke: cVar('colorBackgroundAlpha'),
},
},
},
theme: defaultChartTheme,
}
export type LineChartProps = {
tooltip?: (point: Point) => ReactNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { useCallback, useMemo, useState } from 'react'
import { useCallback, useMemo, useRef, useState } from 'react'

import { BuyMarketTokenSuccess } from '@/components/_crt/BuyMarketTokenModal/steps/BuyMarketTokenSuccess'
import { DialogProps } from '@/components/_overlays/Dialog'
import { DialogModal } from '@/components/_overlays/DialogModal'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { tokenNumberToHapiBn } from '@/joystream-lib/utils'
import { useJoystream } from '@/providers/joystream'
import { useSnackbar } from '@/providers/snackbars'
import { useTransaction } from '@/providers/transactions/transactions.hooks'
import { useUser } from '@/providers/user/user.hooks'

import { BuyMarketTokenConditions } from './steps/BuyMarketTokenConditions'
import { BuySaleTokenForm, getTokenDetails } from './steps/BuyMarketTokenForm'
Expand All @@ -23,8 +28,12 @@ export const BuyMarketTokenModal = ({ tokenId, onClose }: BuySaleTokenModalProps
const { title } = getTokenDetails(tokenId)
const [activeStep, setActiveStep] = useState(BUY_MARKET_TOKEN_STEPS.form)
const [primaryButtonProps, setPrimaryButtonProps] = useState<DialogProps['primaryButton']>()
const amountRef = useRef<number | null>(null)
const { memberId } = useUser()
const smMatch = useMediaMatch('sm')

const { displaySnackbar } = useSnackbar()
const { joystream, proxyCallback } = useJoystream()
const handleTransaction = useTransaction()
const secondaryButton = useMemo(() => {
switch (activeStep) {
case BUY_MARKET_TOKEN_STEPS.conditions:
Expand All @@ -47,7 +56,30 @@ export const BuyMarketTokenModal = ({ tokenId, onClose }: BuySaleTokenModalProps
setPrimaryButtonProps,
}

const onSubmitConditions = useCallback(() => setActiveStep(BUY_MARKET_TOKEN_STEPS.success), [])
const onSubmitConditions = useCallback(async () => {
if (!joystream || !memberId || !amountRef.current) {
return
}

handleTransaction({
txFactory: async (updateStatus) =>
(await joystream.extrinsics).purchaseTokenOnMarket(
tokenId,
memberId,
tokenNumberToHapiBn(amountRef.current as number).toString(),
proxyCallback(updateStatus)
),
onTxSync: async () => {
setActiveStep(BUY_MARKET_TOKEN_STEPS.success)
},
onError: () => {
setActiveStep(BUY_MARKET_TOKEN_STEPS.form)
displaySnackbar({
title: 'Something went wrong',
})
},
})
}, [displaySnackbar, handleTransaction, joystream, memberId, proxyCallback, tokenId])

return (
<DialogModal
Expand All @@ -63,7 +95,10 @@ export const BuyMarketTokenModal = ({ tokenId, onClose }: BuySaleTokenModalProps
{activeStep === BUY_MARKET_TOKEN_STEPS.form && (
<BuySaleTokenForm
{...commonProps}
onSubmit={() => setActiveStep(BUY_MARKET_TOKEN_STEPS.conditions)}
onSubmit={(tokens) => {
setActiveStep(BUY_MARKET_TOKEN_STEPS.conditions)
amountRef.current = tokens
}}
tokenId={tokenId}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMemo, useState } from 'react'
import { useMemo } from 'react'
import { Controller, useForm } from 'react-hook-form'

import { FlexBox } from '@/components/FlexBox/FlexBox'
import { Information } from '@/components/Information'
Expand All @@ -12,7 +13,8 @@ import { DetailsContent } from '@/components/_nft/NftTile'
import { atlasConfig } from '@/config'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { useMountEffect } from '@/hooks/useMountEffect'
import { useJoystream } from '@/providers/joystream'
import { hapiBnToTokenNumber } from '@/joystream-lib/utils'
import { useJoystream, useSubscribeAccountBalance } from '@/providers/joystream'

import { CommonProps } from './types'

Expand All @@ -25,11 +27,13 @@ export const getTokenDetails = (_: string) => ({

type BuySaleTokenFormProps = {
tokenId: string
onSubmit: () => void
onSubmit: (tokens: number | null) => void
} & CommonProps

export const BuySaleTokenForm = ({ tokenId, setPrimaryButtonProps, onSubmit }: BuySaleTokenFormProps) => {
const [tokens, setTokens] = useState<number | null>(null)
const { control, watch, handleSubmit } = useForm<{ tokens: number | null }>()
const { accountBalance } = useSubscribeAccountBalance()
const tokens = watch('tokens')
const { pricePerUnit, tokensOnSale, userBalance, title } = getTokenDetails(tokenId)
const { tokenPrice } = useJoystream()
const tokenInUsd = (tokens || 0) * pricePerUnit * (tokenPrice ?? 0)
Expand Down Expand Up @@ -70,7 +74,7 @@ export const BuySaleTokenForm = ({ tokenId, setPrimaryButtonProps, onSubmit }: B
useMountEffect(() => {
setPrimaryButtonProps({
text: 'Continue',
onClick: () => onSubmit(),
onClick: () => handleSubmit((data) => onSubmit(data.tokens))(),
})
})

Expand All @@ -97,21 +101,40 @@ export const BuySaleTokenForm = ({ tokenId, setPrimaryButtonProps, onSubmit }: B
withDenomination
/>
</FlexBox>
<FormField label="Tokens to spend">
<TokenInput
value={tokens}
onChange={setTokens}
placeholder="0"
nodeEnd={
<FlexBox gap={2} alignItems="baseline">
<Text variant="t300" as="p" color="colorTextMuted">
${tokenInUsd.toFixed(2)}
</Text>
<TextButton onClick={() => setTokens(Math.floor(userBalance / pricePerUnit))}>Max</TextButton>
</FlexBox>
}
/>
</FormField>
<Controller
name="tokens"
control={control}
rules={{
max: {
value: accountBalance ? hapiBnToTokenNumber(accountBalance) : 0,
message: 'Amount exceeds your account balance',
},
required: true,
}}
render={({ field }) => (
<FormField label="Tokens to spend">
<TokenInput
value={field.value}
onChange={field.onChange}
placeholder="0"
nodeEnd={
<FlexBox gap={2} alignItems="baseline">
<Text variant="t300" as="p" color="colorTextMuted">
${tokenInUsd.toFixed(2)}
</Text>
<TextButton
onClick={() =>
accountBalance && field.onChange(Math.floor(hapiBnToTokenNumber(accountBalance) / pricePerUnit))
}
>
Max
</TextButton>
</FlexBox>
}
/>
</FormField>
)}
/>

<FlexBox flow="column" gap={2}>
{details.map((row, i) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ApolloProvider } from '@apollo/client'
import { Meta, StoryFn } from '@storybook/react'

import { createApolloClient } from '@/api'
import { CrtMarketSaleViewProps, MarketDrawer } from '@/components/_crt/MarketDrawer'
import { AuthProvider } from '@/providers/auth/auth.provider'
import { ConfirmationModalProvider } from '@/providers/confirmationModal'
import { JoystreamProvider } from '@/providers/joystream/joystream.provider'
import { OverlayManagerProvider } from '@/providers/overlayManager'
import { SegmentAnalyticsProvider } from '@/providers/segmentAnalytics/segment.provider'
import { UserProvider } from '@/providers/user/user.provider'
import { WalletProvider } from '@/providers/wallet/wallet.provider'

export default {
title: 'crt/CrtMarket',
component: MarketDrawer,
decorators: [
(Story) => (
<JoystreamProvider>
<ApolloProvider client={createApolloClient()}>
<WalletProvider>
<SegmentAnalyticsProvider>
<ConfirmationModalProvider>
<AuthProvider>
<UserProvider>
<OverlayManagerProvider>
<Story />
</OverlayManagerProvider>
</UserProvider>
</AuthProvider>
</ConfirmationModalProvider>
</SegmentAnalyticsProvider>
</WalletProvider>
</ApolloProvider>
</JoystreamProvider>
),
],
} as Meta<CrtMarketSaleViewProps>

const Template: StoryFn<CrtMarketSaleViewProps> = (args) => <MarketDrawer {...args} />

export const Default = Template.bind({})
Default.args = {
show: true,
onClose: () => {
return null
},
tokenName: 'JBC',
}
Loading

0 comments on commit 206b016

Please sign in to comment.