Browse Source

Managing owned nfts changes (#4277)

* fix change price dialog

* fix remove from sale copy
Bartosz Dryl 1 year ago
parent
commit
0e38efa847

+ 52 - 19
packages/atlas/src/components/_overlays/ChangePriceDialog/ChangePriceDialog.tsx

@@ -1,9 +1,10 @@
 import styled from '@emotion/styled'
 import styled from '@emotion/styled'
 import BN from 'bn.js'
 import BN from 'bn.js'
-import { FC, useEffect, useState } from 'react'
+import { FC, useEffect } from 'react'
+import { Controller, useForm } from 'react-hook-form'
 
 
 import { Fee } from '@/components/Fee'
 import { Fee } from '@/components/Fee'
-import { Text } from '@/components/Text'
+import { FormField } from '@/components/_inputs/FormField'
 import { TokenInput } from '@/components/_inputs/TokenInput'
 import { TokenInput } from '@/components/_inputs/TokenInput'
 import { DialogModal } from '@/components/_overlays/DialogModal'
 import { DialogModal } from '@/components/_overlays/DialogModal'
 import { tokenNumberToHapiBn } from '@/joystream-lib/utils'
 import { tokenNumberToHapiBn } from '@/joystream-lib/utils'
@@ -13,6 +14,7 @@ import { sizes } from '@/styles'
 type ChangePriceDialogProps = {
 type ChangePriceDialogProps = {
   onModalClose: () => void
   onModalClose: () => void
   isOpen: boolean
   isOpen: boolean
+  currentPrice: number
   onChangePrice: (id: string, price: BN) => void
   onChangePrice: (id: string, price: BN) => void
   nftId: string | null
   nftId: string | null
   memberId: string | null
   memberId: string | null
@@ -21,31 +23,46 @@ type ChangePriceDialogProps = {
 export const ChangePriceDialog: FC<ChangePriceDialogProps> = ({
 export const ChangePriceDialog: FC<ChangePriceDialogProps> = ({
   onModalClose,
   onModalClose,
   isOpen,
   isOpen,
+  currentPrice,
   onChangePrice,
   onChangePrice,
   nftId,
   nftId,
   memberId,
   memberId,
 }) => {
 }) => {
-  const [price, setPrice] = useState<number | null>(null)
-  const amountBn = tokenNumberToHapiBn(price || 0)
+  const {
+    reset,
+    handleSubmit,
+    watch,
+    control,
+    formState: { errors },
+  } = useForm<{ price: number }>({
+    defaultValues: {
+      price: currentPrice,
+    },
+  })
+  const amountBn = tokenNumberToHapiBn(watch('price') || 0)
   const { fullFee, loading: feeLoading } = useFee(
   const { fullFee, loading: feeLoading } = useFee(
     'changeNftPriceTx',
     'changeNftPriceTx',
     isOpen && memberId && nftId ? [memberId, nftId, amountBn.toString()] : undefined
     isOpen && memberId && nftId ? [memberId, nftId, amountBn.toString()] : undefined
   )
   )
 
 
-  const handleSubmitPriceChange = () => {
-    if (!nftId || !price) {
-      return
-    }
-    setPrice(null)
-    onModalClose()
-    onChangePrice(nftId, tokenNumberToHapiBn(price))
-  }
+  useEffect(() => {
+    reset({ price: currentPrice })
+  }, [currentPrice, reset])
 
 
   useEffect(() => {
   useEffect(() => {
     if (!isOpen) {
     if (!isOpen) {
-      setPrice(null)
+      reset({ price: currentPrice })
     }
     }
-  }, [isOpen])
+  }, [currentPrice, isOpen, reset])
+
+  const handleSubmitPriceChange = () => {
+    handleSubmit((data) => {
+      if (!nftId) {
+        return
+      }
+      onChangePrice(nftId, tokenNumberToHapiBn(data.price))
+    })()
+  }
 
 
   return (
   return (
     <DialogModal
     <DialogModal
@@ -53,7 +70,6 @@ export const ChangePriceDialog: FC<ChangePriceDialogProps> = ({
       show={isOpen}
       show={isOpen}
       primaryButton={{
       primaryButton={{
         text: 'Change price',
         text: 'Change price',
-        disabled: !price,
         onClick: handleSubmitPriceChange,
         onClick: handleSubmitPriceChange,
       }}
       }}
       secondaryButton={{
       secondaryButton={{
@@ -64,10 +80,27 @@ export const ChangePriceDialog: FC<ChangePriceDialogProps> = ({
       additionalActionsNode={<Fee amount={fullFee} loading={feeLoading} variant="h200" />}
       additionalActionsNode={<Fee amount={fullFee} loading={feeLoading} variant="h200" />}
     >
     >
       <>
       <>
-        <Text as="p" variant="t200" color="colorText">
-          You can update the price of this NFT anytime.
-        </Text>
-        <StyledTokenInput value={price} onChange={(value) => setPrice(value)} />
+        <Controller
+          control={control}
+          name="price"
+          rules={{
+            validate: {
+              valid: (val) => {
+                if (!val) {
+                  return 'Provide a price.'
+                }
+                if (val === currentPrice) {
+                  return 'Provide new price.'
+                }
+              },
+            },
+          }}
+          render={({ field: { onChange, value } }) => (
+            <FormField error={errors.price?.message}>
+              <StyledTokenInput value={value} onChange={(value) => onChange(value)} />
+            </FormField>
+          )}
+        />
       </>
       </>
     </DialogModal>
     </DialogModal>
   )
   )

+ 6 - 2
packages/atlas/src/hooks/useNftTransactions.tsx

@@ -105,8 +105,12 @@ export const useNftTransactions = () => {
 
 
       openModal({
       openModal({
         title: 'Remove from sale?',
         title: 'Remove from sale?',
-        description: 'Are you sure you want to remove this NFT from sale? You can put it back on sale anytime.',
-        type: 'warning',
+        description: `Are you sure you want to remove this NFT from sale? ${
+          saleType === 'buyNow'
+            ? 'You can put it back on sale anytime.'
+            : 'You may lose the bids that were already placed.'
+        } `,
+        type: 'destructive',
         primaryButton: {
         primaryButton: {
           text: 'Remove',
           text: 'Remove',
           onClick: () => {
           onClick: () => {

+ 6 - 0
packages/atlas/src/providers/nftActions/nftActions.provider.tsx

@@ -6,6 +6,7 @@ import { AcceptBidDialog } from '@/components/_overlays/AcceptBidDialog'
 import { ChangePriceDialog } from '@/components/_overlays/ChangePriceDialog'
 import { ChangePriceDialog } from '@/components/_overlays/ChangePriceDialog'
 import { useNftState } from '@/hooks/useNftState'
 import { useNftState } from '@/hooks/useNftState'
 import { useNftTransactions } from '@/hooks/useNftTransactions'
 import { useNftTransactions } from '@/hooks/useNftTransactions'
+import { hapiBnToTokenNumber } from '@/joystream-lib/utils'
 import { useTokenPrice } from '@/providers/joystream/joystream.hooks'
 import { useTokenPrice } from '@/providers/joystream/joystream.hooks'
 import { useUser } from '@/providers/user/user.hooks'
 import { useUser } from '@/providers/user/user.hooks'
 
 
@@ -67,6 +68,10 @@ export const NftActionsProvider: FC<PropsWithChildren> = ({ children }) => {
     [closeNftAction, currentAction, currentNftId, isBuyNowClicked, transactions]
     [closeNftAction, currentAction, currentNftId, isBuyNowClicked, transactions]
   )
   )
 
 
+  const currentBuyNowPrice =
+    (nft?.transactionalStatus?.__typename === 'TransactionalStatusBuyNow' &&
+      hapiBnToTokenNumber(new BN(nft.transactionalStatus.price))) ||
+    0
   return (
   return (
     <NftActionsContext.Provider value={value}>
     <NftActionsContext.Provider value={value}>
       <AcceptBidDialog
       <AcceptBidDialog
@@ -78,6 +83,7 @@ export const NftActionsProvider: FC<PropsWithChildren> = ({ children }) => {
         ownerId={nft?.owner.__typename === 'NftOwnerMember' ? nft.owner.member.id : nft?.owner.channel.ownerMember?.id}
         ownerId={nft?.owner.__typename === 'NftOwnerMember' ? nft.owner.member.id : nft?.owner.channel.ownerMember?.id}
       />
       />
       <ChangePriceDialog
       <ChangePriceDialog
+        currentPrice={currentBuyNowPrice}
         isOpen={currentAction === 'change-price'}
         isOpen={currentAction === 'change-price'}
         onModalClose={closeNftAction}
         onModalClose={closeNftAction}
         onChangePrice={transactions.changeNftPrice}
         onChangePrice={transactions.changeNftPrice}