@@ -12,6 +12,11 @@ import {
12
12
Heading ,
13
13
Icon ,
14
14
Image ,
15
+ NumberDecrementStepper ,
16
+ NumberIncrementStepper ,
17
+ NumberInput ,
18
+ NumberInputField ,
19
+ NumberInputStepper ,
15
20
Spinner ,
16
21
Stack ,
17
22
Tab ,
@@ -138,6 +143,8 @@ const ConnectWalletButton: React.FC = () => (
138
143
const ClaimButton : React . FC < ClaimPageProps > = ( { module, sdk, chainId } ) => {
139
144
const { address } = useWeb3 ( ) ;
140
145
146
+ const [ quantity , setQuantity ] = useState ( 1 ) ;
147
+
141
148
const [ claimSuccess , setClaimSuccess ] = useState ( false ) ;
142
149
143
150
const claimed = useQuery (
@@ -152,20 +159,39 @@ const ClaimButton: React.FC<ClaimPageProps> = ({ module, sdk, chainId }) => {
152
159
{ enabled : ! ! module } ,
153
160
) ;
154
161
162
+ const unclaimed = useQuery (
163
+ [ "numbers" , "available" ] ,
164
+ ( ) => module ?. totalUnclaimedSupply ( ) ,
165
+ { enabled : ! ! module } ,
166
+ ) ;
167
+
155
168
const claimCondition = useQuery (
156
169
[ "claimcondition" ] ,
157
170
( ) => module ?. getActiveClaimCondition ( ) ,
158
171
{ enabled : ! ! module } ,
159
172
) ;
160
173
161
- const priceToMint = BigNumber . from ( claimCondition ?. data ?. price || 0 ) ;
174
+ const priceToMint = BigNumber . from (
175
+ claimCondition ?. data ?. pricePerToken || 0 ,
176
+ ) . mul ( quantity ) ;
162
177
const currency = claimCondition ?. data ?. currency ;
178
+ const quantityLimit = claimCondition ?. data ?. quantityLimitPerTransaction || 1 ;
179
+
180
+ const quantityLimitBigNumber = useMemo ( ( ) => {
181
+ const bn = BigNumber . from ( quantityLimit ) ;
182
+ const unclaimedBn = BigNumber . from ( unclaimed . data || 0 ) ;
183
+
184
+ if ( unclaimedBn . lt ( bn ) ) {
185
+ return unclaimedBn ;
186
+ }
187
+ return bn ;
188
+ } , [ quantityLimit ] ) ;
163
189
164
190
const tokenModule = useMemo ( ( ) => {
165
191
if ( ! currency || ! sdk ) {
166
192
return undefined ;
167
193
}
168
- return sdk . getCurrencyModule ( currency ) ;
194
+ return sdk . getTokenModule ( currency ) ;
169
195
} , [ currency , sdk ] ) ;
170
196
171
197
const formatedPrice = useFormatedValue ( priceToMint , tokenModule , chainId ) ;
@@ -184,10 +210,10 @@ const ClaimButton: React.FC<ClaimPageProps> = ({ module, sdk, chainId }) => {
184
210
if ( ! address || ! module ) {
185
211
throw new Error ( "No address or module" ) ;
186
212
}
187
- return module . claim ( 1 ) ;
213
+ return module . claim ( quantity ) ;
188
214
} ,
189
215
{
190
- onSuccess : ( ) => queryClient . invalidateQueries ( "numbers" ) ,
216
+ onSuccess : ( ) => queryClient . invalidateQueries ( ) ,
191
217
onError : ( err ) => {
192
218
const anyErr = err as any ;
193
219
let message = "" ;
@@ -214,31 +240,60 @@ const ClaimButton: React.FC<ClaimPageProps> = ({ module, sdk, chainId }) => {
214
240
215
241
const isLoading = totalAvailable . isLoading || claimed . isLoading ;
216
242
217
- const canClaim = isNotSoldOut && address ;
243
+ const canClaim = ! ! isNotSoldOut && ! ! address ;
244
+
245
+ const showQuantityInput =
246
+ canClaim &&
247
+ quantityLimitBigNumber . gt ( 1 ) &&
248
+ quantityLimitBigNumber . lte ( 1000 ) ;
218
249
219
250
return (
220
251
< Stack spacing = { 4 } align = "center" w = "100%" >
221
252
{ address ? (
222
- < Button
223
- isLoading = { isLoading || claimMutation . isLoading }
224
- isDisabled = { ! canClaim }
225
- leftIcon = { < IoDiamondOutline /> }
226
- onClick = { ( ) => claimMutation . mutate ( ) }
227
- isFullWidth
228
- colorScheme = "blue"
229
- >
230
- { ! isNotSoldOut
231
- ? "Sold out"
232
- : canClaim
233
- ? `Mint${
234
- priceToMint . eq ( 0 )
235
- ? " (Free)"
236
- : formatedPrice
237
- ? ` (${ formatedPrice } )`
238
- : ""
239
- } `
240
- : "Minting Unavailable" }
241
- </ Button >
253
+ < Flex w = "100%" direction = { { base : "column" , md : "row" } } gap = { 2 } >
254
+ { showQuantityInput && (
255
+ < NumberInput
256
+ inputMode = "numeric"
257
+ value = { quantity }
258
+ onChange = { ( stringValue , value ) => {
259
+ if ( stringValue === "" ) {
260
+ setQuantity ( 0 ) ;
261
+ } else {
262
+ setQuantity ( value ) ;
263
+ }
264
+ } }
265
+ min = { 1 }
266
+ max = { quantityLimitBigNumber . toNumber ( ) }
267
+ maxW = { { base : "100%" , md : "100px" } }
268
+ >
269
+ < NumberInputField />
270
+ < NumberInputStepper >
271
+ < NumberIncrementStepper />
272
+ < NumberDecrementStepper />
273
+ </ NumberInputStepper >
274
+ </ NumberInput >
275
+ ) }
276
+ < Button
277
+ isLoading = { isLoading || claimMutation . isLoading }
278
+ isDisabled = { ! canClaim }
279
+ leftIcon = { < IoDiamondOutline /> }
280
+ onClick = { ( ) => claimMutation . mutate ( ) }
281
+ isFullWidth
282
+ colorScheme = "blue"
283
+ >
284
+ { ! isNotSoldOut
285
+ ? "Sold out"
286
+ : canClaim
287
+ ? `Mint${ showQuantityInput ? ` ${ quantity } ` : "" } ${
288
+ priceToMint . eq ( 0 )
289
+ ? " (Free)"
290
+ : formatedPrice
291
+ ? ` (${ formatedPrice } )`
292
+ : ""
293
+ } `
294
+ : "Minting Unavailable" }
295
+ </ Button >
296
+ </ Flex >
242
297
) : (
243
298
< ConnectWalletButton />
244
299
) }
@@ -250,7 +305,7 @@ const ClaimButton: React.FC<ClaimPageProps> = ({ module, sdk, chainId }) => {
250
305
} ;
251
306
252
307
const ClaimPage : React . FC < ClaimPageProps > = ( { module, sdk, chainId } ) => {
253
- const { data, isLoading, error } = useQuery (
308
+ const { data, isLoading } = useQuery (
254
309
"module_metadata" ,
255
310
( ) => module ?. getMetadata ( ) ,
256
311
{ enabled : ! ! module } ,
@@ -339,7 +394,7 @@ const InventoryPage: React.FC<ModuleInProps> = ({ module }) => {
339
394
) ;
340
395
}
341
396
342
- if ( ! ownedDropsMetadata ) {
397
+ if ( ! ownedDropsMetadata ?. length ) {
343
398
return (
344
399
< Center w = "100%" h = "100%" >
345
400
< Stack direction = "row" align = "center" >
@@ -457,7 +512,7 @@ const DropWidget: React.FC<DropWidgetProps> = ({
457
512
} , [ owned . data , isSoldOut ] ) ;
458
513
459
514
return (
460
- < AspectRatio ratio = { 1 } w = "600px " >
515
+ < AspectRatio ratio = { { base : 1 / 1.5 , sm : 1 } } w = "100% " >
461
516
< Flex
462
517
flexDir = "column"
463
518
borderRadius = "1rem"
0 commit comments