useGetNftSlot.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { differenceInHours, differenceInSeconds, format } from 'date-fns'
  2. import { useCallback } from 'react'
  3. import { NftStatus } from '@/api/hooks/nfts'
  4. import { SvgActionAuction, SvgActionBuyNow, SvgActionClock } from '@/assets/icons'
  5. import { PillGroup } from '@/components/Pill'
  6. import { PillProps } from '@/components/Pill/types'
  7. import { SlotsObject } from '@/components/_video/VideoThumbnail'
  8. import { formatDurationShort } from '@/utils/time'
  9. import { useMsTimestamp } from './useMsTimestamp'
  10. import { EnglishTimerState } from './useNftState'
  11. type UseGetSlotsOpts = {
  12. status?: NftStatus['status']
  13. timerLoading?: boolean
  14. withNftLabel?: boolean
  15. startsAtDate?: Date
  16. auctionPlannedEndDate?: Date
  17. needsSettling?: boolean
  18. hasBuyNowPrice?: boolean
  19. englishTimerState?: EnglishTimerState
  20. }
  21. export const useGetNftSlot = ({
  22. englishTimerState,
  23. timerLoading,
  24. auctionPlannedEndDate,
  25. hasBuyNowPrice,
  26. needsSettling,
  27. startsAtDate,
  28. withNftLabel,
  29. status,
  30. }: UseGetSlotsOpts): SlotsObject['bottomLeft'] => {
  31. const msTimestamp = useMsTimestamp({
  32. shouldStop: timerLoading || englishTimerState === 'expired' || !englishTimerState,
  33. })
  34. const generatePills: () => PillProps[] = useCallback(() => {
  35. const buyNowPill: PillProps = { icon: <SvgActionBuyNow />, variant: 'overlay', title: 'Buy now', withTooltip: true }
  36. switch (status) {
  37. case 'buy-now':
  38. return [buyNowPill]
  39. case 'auction': {
  40. const additionalBuyNowPill = hasBuyNowPrice ? [buyNowPill] : []
  41. if (needsSettling) {
  42. return [
  43. {
  44. icon: <SvgActionAuction />,
  45. label: 'To be settled',
  46. variant: 'overlay',
  47. },
  48. ...additionalBuyNowPill,
  49. ]
  50. }
  51. if (timerLoading) {
  52. return [
  53. {
  54. icon: <SvgActionAuction />,
  55. label: 'Loading',
  56. variant: 'overlay',
  57. },
  58. ...additionalBuyNowPill,
  59. ]
  60. }
  61. switch (englishTimerState) {
  62. case 'upcoming': {
  63. const diff = startsAtDate && differenceInSeconds(new Date(), startsAtDate) * -1
  64. const diffTime =
  65. diff && diff < 3600
  66. ? `Starts in ${formatDurationShort(diff)}`
  67. : startsAtDate && ` ${format(startsAtDate, 'd MMM')} at ${format(startsAtDate, 'HH:mm')}`
  68. return [
  69. {
  70. icon: <SvgActionClock />,
  71. label: diffTime,
  72. variant: 'overlay',
  73. },
  74. ...additionalBuyNowPill,
  75. ]
  76. }
  77. case 'running': {
  78. const diff = auctionPlannedEndDate && differenceInSeconds(auctionPlannedEndDate, new Date())
  79. const lessThanMinute = auctionPlannedEndDate && differenceInSeconds(auctionPlannedEndDate, msTimestamp) < 60
  80. const lessThanHour = auctionPlannedEndDate && differenceInHours(auctionPlannedEndDate, msTimestamp) < 1
  81. return [
  82. {
  83. icon: <SvgActionAuction />,
  84. label: diff ? (lessThanMinute ? '< 1 min' : formatDurationShort(diff, true)) : undefined,
  85. variant: lessThanHour ? 'danger' : 'overlay',
  86. },
  87. ...additionalBuyNowPill,
  88. ]
  89. }
  90. case 'expired':
  91. return [
  92. {
  93. icon: <SvgActionAuction />,
  94. label: 'Auction ended',
  95. variant: 'overlay',
  96. },
  97. ...additionalBuyNowPill,
  98. ]
  99. default:
  100. return []
  101. }
  102. }
  103. default:
  104. return []
  105. }
  106. }, [
  107. status,
  108. hasBuyNowPrice,
  109. needsSettling,
  110. timerLoading,
  111. englishTimerState,
  112. startsAtDate,
  113. auctionPlannedEndDate,
  114. msTimestamp,
  115. ])
  116. const nftPill: PillProps[] = withNftLabel ? [{ label: 'NFT', variant: 'overlay', title: 'NFT' }] : []
  117. return {
  118. element: <PillGroup items={[...nftPill, ...generatePills()]} />,
  119. }
  120. }