Browse Source

Fix member's activity bugs (#4265)

* create separate query for activities count

* fix issue with infinite loading

* add missing links

* remove redundant white spaces

* fix events count, adjust notifications queries

* remove redundant comments
Bartosz Dryl 1 năm trước cách đây
mục cha
commit
f926ee89bd

+ 24 - 4
packages/atlas/src/api/hooks/notifications.ts

@@ -1,10 +1,13 @@
 import { QueryHookOptions } from '@apollo/client'
 
 import {
+  GetNftActivitiesCountQuery,
+  GetNftActivitiesCountQueryVariables,
   GetNftActivitiesQuery,
   GetNftActivitiesQueryVariables,
   GetNotificationsConnectionQuery,
   GetNotificationsConnectionQueryVariables,
+  useGetNftActivitiesCountQuery,
   useGetNftActivitiesQuery,
   useGetNotificationsConnectionQuery,
 } from '@/api/queries/__generated__/notifications.generated'
@@ -31,6 +34,27 @@ export const useRawNotifications = (
   }
 }
 
+export const useActivitiesCount = (
+  memberId?: string,
+  opts?: QueryHookOptions<GetNftActivitiesCountQuery, GetNftActivitiesCountQueryVariables>
+) => {
+  const { data, ...rest } = useGetNftActivitiesCountQuery({
+    ...opts,
+    variables: {
+      memberId: memberId || '',
+    },
+    skip: !memberId,
+  })
+
+  return {
+    nftsBiddedTotalCount: data?.nftsBidded.totalCount,
+    nftsBoughtTotalCount: data?.nftsBought.totalCount,
+    nftsSoldTotalCount: data?.nftsSold.totalCount,
+    nftsIssuedTotalCount: data?.nftsIssued.totalCount,
+    ...rest,
+  }
+}
+
 export const useRawActivities = (
   memberId?: string,
   sort: NftActivityOrderByInput = NftActivityOrderByInput.EventTimestampDesc,
@@ -47,10 +71,6 @@ export const useRawActivities = (
   })
 
   return {
-    nftsBiddedTotalCount: data?.nftsBidded.totalCount,
-    nftsBoughtTotalCount: data?.nftsBought.totalCount,
-    nftsSoldTotalCount: data?.nftsSold.totalCount,
-    nftsIssuedTotalCount: data?.nftsIssued.totalCount,
     totalCount: data?.nftActivitiesConnection.totalCount,
     pageInfo: data?.nftActivitiesConnection.pageInfo,
     activities: data?.nftActivitiesConnection.edges,

+ 367 - 220
packages/atlas/src/api/queries/__generated__/notifications.generated.tsx

@@ -109,9 +109,32 @@ export type GetNotificationsConnectionQuery = {
                       } | null
                     }
                   } | null
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: { __typename?: 'OwnedNft'; video: { __typename?: 'Video'; id: string; title?: string | null } }
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
+                        id: string
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
+                    }
                   }
                 }
                 nftOwner:
@@ -233,7 +256,33 @@ export type GetNotificationsConnectionQuery = {
                         | null
                     } | null
                   }
-                  nft: { __typename?: 'OwnedNft'; video: { __typename?: 'Video'; id: string; title?: string | null } }
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
+                        id: string
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
+                    }
+                  }
                 }
                 previousNftOwner:
                   | {
@@ -403,9 +452,32 @@ export type GetNotificationsConnectionQuery = {
                         | null
                     } | null
                   }
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: { __typename?: 'OwnedNft'; video: { __typename?: 'Video'; id: string; title?: string | null } }
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
+                        id: string
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
+                    }
                   }
                 }
                 previousNftOwner:
@@ -527,7 +599,33 @@ export type GetNotificationsConnectionQuery = {
                       | null
                   } | null
                 }
-                nft: { __typename?: 'OwnedNft'; video: { __typename?: 'Video'; id: string; title?: string | null } }
+                nft: {
+                  __typename?: 'OwnedNft'
+                  video: {
+                    __typename?: 'Video'
+                    id: string
+                    title?: string | null
+                    thumbnailPhoto?: {
+                      __typename?: 'StorageDataObject'
+                      id: string
+                      resolvedUrls: Array<string>
+                      resolvedUrl?: string | null
+                      createdAt: Date
+                      size: string
+                      isAccepted: boolean
+                      ipfsHash: string
+                      storageBag: { __typename?: 'StorageBag'; id: string }
+                      type?:
+                        | { __typename: 'DataObjectTypeChannelAvatar' }
+                        | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                        | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                        | { __typename: 'DataObjectTypeVideoMedia' }
+                        | { __typename: 'DataObjectTypeVideoSubtitle' }
+                        | { __typename: 'DataObjectTypeVideoThumbnail' }
+                        | null
+                    } | null
+                  }
+                }
               }
             | { __typename?: 'NftIssuedEventData' }
             | { __typename?: 'NftSellOrderMadeEventData' }
@@ -570,9 +668,32 @@ export type GetNotificationsConnectionQuery = {
                         | null
                     } | null
                   }
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: { __typename?: 'OwnedNft'; video: { __typename?: 'Video'; id: string; title?: string | null } }
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
+                        id: string
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
+                    }
                   }
                 }
                 previousNftOwner:
@@ -1728,6 +1849,18 @@ export type GetNftHistoryQuery = {
   }>
 }
 
+export type GetNftActivitiesCountQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['String']
+}>
+
+export type GetNftActivitiesCountQuery = {
+  __typename?: 'Query'
+  nftsBought: { __typename?: 'NftActivitiesConnection'; totalCount: number }
+  nftsSold: { __typename?: 'NftActivitiesConnection'; totalCount: number }
+  nftsIssued: { __typename?: 'NftActivitiesConnection'; totalCount: number }
+  nftsBidded: { __typename?: 'NftActivitiesConnection'; totalCount: number }
+}
+
 export type GetNftActivitiesQueryVariables = Types.Exact<{
   memberId: Types.Scalars['String']
   first: Types.Scalars['Int']
@@ -1737,10 +1870,6 @@ export type GetNftActivitiesQueryVariables = Types.Exact<{
 
 export type GetNftActivitiesQuery = {
   __typename?: 'Query'
-  nftsBought: { __typename?: 'NftActivitiesConnection'; totalCount: number }
-  nftsSold: { __typename?: 'NftActivitiesConnection'; totalCount: number }
-  nftsIssued: { __typename?: 'NftActivitiesConnection'; totalCount: number }
-  nftsBidded: { __typename?: 'NftActivitiesConnection'; totalCount: number }
   nftActivitiesConnection: {
     __typename?: 'NftActivitiesConnection'
     totalCount: number
@@ -1794,34 +1923,31 @@ export type GetNftActivitiesQuery = {
                 }
                 bid: {
                   __typename?: 'Bid'
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: {
-                      __typename?: 'OwnedNft'
-                      video: {
-                        __typename?: 'Video'
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
                         id: string
-                        title?: string | null
-                        thumbnailPhoto?: {
-                          __typename?: 'StorageDataObject'
-                          id: string
-                          resolvedUrls: Array<string>
-                          resolvedUrl?: string | null
-                          createdAt: Date
-                          size: string
-                          isAccepted: boolean
-                          ipfsHash: string
-                          storageBag: { __typename?: 'StorageBag'; id: string }
-                          type?:
-                            | { __typename: 'DataObjectTypeChannelAvatar' }
-                            | { __typename: 'DataObjectTypeChannelCoverPhoto' }
-                            | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
-                            | { __typename: 'DataObjectTypeVideoMedia' }
-                            | { __typename: 'DataObjectTypeVideoSubtitle' }
-                            | { __typename: 'DataObjectTypeVideoThumbnail' }
-                            | null
-                        } | null
-                      }
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
                     }
                   }
                 }
@@ -1980,34 +2106,31 @@ export type GetNftActivitiesQuery = {
                       } | null
                     }
                   } | null
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: {
-                      __typename?: 'OwnedNft'
-                      video: {
-                        __typename?: 'Video'
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
                         id: string
-                        title?: string | null
-                        thumbnailPhoto?: {
-                          __typename?: 'StorageDataObject'
-                          id: string
-                          resolvedUrls: Array<string>
-                          resolvedUrl?: string | null
-                          createdAt: Date
-                          size: string
-                          isAccepted: boolean
-                          ipfsHash: string
-                          storageBag: { __typename?: 'StorageBag'; id: string }
-                          type?:
-                            | { __typename: 'DataObjectTypeChannelAvatar' }
-                            | { __typename: 'DataObjectTypeChannelCoverPhoto' }
-                            | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
-                            | { __typename: 'DataObjectTypeVideoMedia' }
-                            | { __typename: 'DataObjectTypeVideoSubtitle' }
-                            | { __typename: 'DataObjectTypeVideoThumbnail' }
-                            | null
-                        } | null
-                      }
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
                     }
                   }
                 }
@@ -2240,34 +2363,31 @@ export type GetNftActivitiesQuery = {
                         | null
                     } | null
                   }
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: {
-                      __typename?: 'OwnedNft'
-                      video: {
-                        __typename?: 'Video'
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
                         id: string
-                        title?: string | null
-                        thumbnailPhoto?: {
-                          __typename?: 'StorageDataObject'
-                          id: string
-                          resolvedUrls: Array<string>
-                          resolvedUrl?: string | null
-                          createdAt: Date
-                          size: string
-                          isAccepted: boolean
-                          ipfsHash: string
-                          storageBag: { __typename?: 'StorageBag'; id: string }
-                          type?:
-                            | { __typename: 'DataObjectTypeChannelAvatar' }
-                            | { __typename: 'DataObjectTypeChannelCoverPhoto' }
-                            | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
-                            | { __typename: 'DataObjectTypeVideoMedia' }
-                            | { __typename: 'DataObjectTypeVideoSubtitle' }
-                            | { __typename: 'DataObjectTypeVideoThumbnail' }
-                            | null
-                        } | null
-                      }
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
                     }
                   }
                 }
@@ -2613,34 +2733,31 @@ export type GetNftActivitiesQuery = {
                         | null
                     } | null
                   }
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: {
-                      __typename?: 'OwnedNft'
-                      video: {
-                        __typename?: 'Video'
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
                         id: string
-                        title?: string | null
-                        thumbnailPhoto?: {
-                          __typename?: 'StorageDataObject'
-                          id: string
-                          resolvedUrls: Array<string>
-                          resolvedUrl?: string | null
-                          createdAt: Date
-                          size: string
-                          isAccepted: boolean
-                          ipfsHash: string
-                          storageBag: { __typename?: 'StorageBag'; id: string }
-                          type?:
-                            | { __typename: 'DataObjectTypeChannelAvatar' }
-                            | { __typename: 'DataObjectTypeChannelCoverPhoto' }
-                            | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
-                            | { __typename: 'DataObjectTypeVideoMedia' }
-                            | { __typename: 'DataObjectTypeVideoSubtitle' }
-                            | { __typename: 'DataObjectTypeVideoThumbnail' }
-                            | null
-                        } | null
-                      }
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
                     }
                   }
                 }
@@ -3157,34 +3274,31 @@ export type GetNftActivitiesQuery = {
                         | null
                     } | null
                   }
-                  auction: {
-                    __typename?: 'Auction'
-                    nft: {
-                      __typename?: 'OwnedNft'
-                      video: {
-                        __typename?: 'Video'
+                  nft: {
+                    __typename?: 'OwnedNft'
+                    video: {
+                      __typename?: 'Video'
+                      id: string
+                      title?: string | null
+                      thumbnailPhoto?: {
+                        __typename?: 'StorageDataObject'
                         id: string
-                        title?: string | null
-                        thumbnailPhoto?: {
-                          __typename?: 'StorageDataObject'
-                          id: string
-                          resolvedUrls: Array<string>
-                          resolvedUrl?: string | null
-                          createdAt: Date
-                          size: string
-                          isAccepted: boolean
-                          ipfsHash: string
-                          storageBag: { __typename?: 'StorageBag'; id: string }
-                          type?:
-                            | { __typename: 'DataObjectTypeChannelAvatar' }
-                            | { __typename: 'DataObjectTypeChannelCoverPhoto' }
-                            | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
-                            | { __typename: 'DataObjectTypeVideoMedia' }
-                            | { __typename: 'DataObjectTypeVideoSubtitle' }
-                            | { __typename: 'DataObjectTypeVideoThumbnail' }
-                            | null
-                        } | null
-                      }
+                        resolvedUrls: Array<string>
+                        resolvedUrl?: string | null
+                        createdAt: Date
+                        size: string
+                        isAccepted: boolean
+                        ipfsHash: string
+                        storageBag: { __typename?: 'StorageBag'; id: string }
+                        type?:
+                          | { __typename: 'DataObjectTypeChannelAvatar' }
+                          | { __typename: 'DataObjectTypeChannelCoverPhoto' }
+                          | { __typename: 'DataObjectTypeChannelPayoutsPayload' }
+                          | { __typename: 'DataObjectTypeVideoMedia' }
+                          | { __typename: 'DataObjectTypeVideoSubtitle' }
+                          | { __typename: 'DataObjectTypeVideoThumbnail' }
+                          | null
+                      } | null
                     }
                   }
                 }
@@ -3416,12 +3530,9 @@ export const GetNotificationsConnectionDocument = gql`
                       ...BasicMembershipFields
                     }
                   }
-                  auction {
-                    nft {
-                      video {
-                        id
-                        title
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3436,8 +3547,7 @@ export const GetNotificationsConnectionDocument = gql`
                 price
                 nft {
                   video {
-                    id
-                    title
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -3449,8 +3559,7 @@ export const GetNotificationsConnectionDocument = gql`
                   amount
                   nft {
                     video {
-                      id
-                      title
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3464,12 +3573,9 @@ export const GetNotificationsConnectionDocument = gql`
                   bidder {
                     ...BasicMembershipFields
                   }
-                  auction {
-                    nft {
-                      video {
-                        id
-                        title
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3482,12 +3588,9 @@ export const GetNotificationsConnectionDocument = gql`
                   bidder {
                     ...BasicMembershipFields
                   }
-                  auction {
-                    nft {
-                      video {
-                        id
-                        title
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3517,6 +3620,7 @@ export const GetNotificationsConnectionDocument = gql`
     }
   }
   ${BasicMembershipFieldsFragmentDoc}
+  ${BasicVideoActivityFieldsFragmentDoc}
   ${BasicNftOwnerFieldsFragmentDoc}
 `
 
@@ -3696,18 +3800,14 @@ export function useGetNftHistoryLazyQuery(
 export type GetNftHistoryQueryHookResult = ReturnType<typeof useGetNftHistoryQuery>
 export type GetNftHistoryLazyQueryHookResult = ReturnType<typeof useGetNftHistoryLazyQuery>
 export type GetNftHistoryQueryResult = Apollo.QueryResult<GetNftHistoryQuery, GetNftHistoryQueryVariables>
-export const GetNftActivitiesDocument = gql`
-  query GetNftActivities(
-    $memberId: String!
-    $first: Int!
-    $after: String
-    $orderBy: [NftActivityOrderByInput!] = event_timestamp_DESC
-  ) {
+export const GetNftActivitiesCountDocument = gql`
+  query GetNftActivitiesCount($memberId: String!) {
     nftsBought: nftActivitiesConnection(
       where: {
-        event: {
-          OR: [
-            {
+        OR: [
+          {
+            member: { id_eq: $memberId }
+            event: {
               data: {
                 isTypeOf_in: [
                   "EnglishAuctionSettledEventData"
@@ -3717,19 +3817,23 @@ export const GetNftActivitiesDocument = gql`
                 winningBid: { bidder: { id_eq: $memberId } }
               }
             }
-            { data: { isTypeOf_eq: "NftBoughtEventData", buyer: { id_eq: $memberId } } }
-          ]
-        }
+          }
+          {
+            member: { id_eq: $memberId }
+            event: { data: { isTypeOf_eq: "NftBoughtEventData", buyer: { id_eq: $memberId } } }
+          }
+        ]
       }
-      orderBy: $orderBy
+      orderBy: event_timestamp_DESC
     ) {
       totalCount
     }
     nftsSold: nftActivitiesConnection(
       where: {
-        event: {
-          OR: [
-            {
+        OR: [
+          {
+            member: { id_eq: $memberId }
+            event: {
               data: {
                 isTypeOf_in: [
                   "EnglishAuctionSettledEventData"
@@ -3740,7 +3844,10 @@ export const GetNftActivitiesDocument = gql`
                 previousNftOwner: { member: { id_eq: $memberId } }
               }
             }
-            {
+          }
+          {
+            member: { id_eq: $memberId }
+            event: {
               data: {
                 isTypeOf_in: [
                   "EnglishAuctionSettledEventData"
@@ -3751,10 +3858,10 @@ export const GetNftActivitiesDocument = gql`
                 previousNftOwner: { channel: { ownerMember: { id_eq: $memberId } } }
               }
             }
-          ]
-        }
+          }
+        ]
       }
-      orderBy: $orderBy
+      orderBy: event_timestamp_DESC
     ) {
       totalCount
     }
@@ -3769,16 +3876,66 @@ export const GetNftActivitiesDocument = gql`
           ]
         }
       }
-      orderBy: $orderBy
+      orderBy: event_timestamp_DESC
     ) {
       totalCount
     }
     nftsBidded: nftActivitiesConnection(
       where: { event: { data: { isTypeOf_eq: "AuctionBidMadeEventData", bid: { bidder: { id_eq: $memberId } } } } }
-      orderBy: $orderBy
+      orderBy: event_timestamp_DESC
     ) {
       totalCount
     }
+  }
+`
+
+/**
+ * __useGetNftActivitiesCountQuery__
+ *
+ * To run a query within a React component, call `useGetNftActivitiesCountQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetNftActivitiesCountQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetNftActivitiesCountQuery({
+ *   variables: {
+ *      memberId: // value for 'memberId'
+ *   },
+ * });
+ */
+export function useGetNftActivitiesCountQuery(
+  baseOptions: Apollo.QueryHookOptions<GetNftActivitiesCountQuery, GetNftActivitiesCountQueryVariables>
+) {
+  const options = { ...defaultOptions, ...baseOptions }
+  return Apollo.useQuery<GetNftActivitiesCountQuery, GetNftActivitiesCountQueryVariables>(
+    GetNftActivitiesCountDocument,
+    options
+  )
+}
+export function useGetNftActivitiesCountLazyQuery(
+  baseOptions?: Apollo.LazyQueryHookOptions<GetNftActivitiesCountQuery, GetNftActivitiesCountQueryVariables>
+) {
+  const options = { ...defaultOptions, ...baseOptions }
+  return Apollo.useLazyQuery<GetNftActivitiesCountQuery, GetNftActivitiesCountQueryVariables>(
+    GetNftActivitiesCountDocument,
+    options
+  )
+}
+export type GetNftActivitiesCountQueryHookResult = ReturnType<typeof useGetNftActivitiesCountQuery>
+export type GetNftActivitiesCountLazyQueryHookResult = ReturnType<typeof useGetNftActivitiesCountLazyQuery>
+export type GetNftActivitiesCountQueryResult = Apollo.QueryResult<
+  GetNftActivitiesCountQuery,
+  GetNftActivitiesCountQueryVariables
+>
+export const GetNftActivitiesDocument = gql`
+  query GetNftActivities(
+    $memberId: String!
+    $first: Int!
+    $after: String
+    $orderBy: [NftActivityOrderByInput!] = event_timestamp_DESC
+  ) {
     nftActivitiesConnection(first: $first, after: $after, orderBy: $orderBy, where: { member: { id_eq: $memberId } }) {
       totalCount
       pageInfo {
@@ -3807,11 +3964,9 @@ export const GetNftActivitiesDocument = gql`
                       ...BasicMembershipFields
                     }
                   }
-                  auction {
-                    nft {
-                      video {
-                        ...BasicVideoActivityFields
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3825,11 +3980,9 @@ export const GetNftActivitiesDocument = gql`
                     ...BasicMembershipFields
                   }
                   amount
-                  auction {
-                    nft {
-                      video {
-                        ...BasicVideoActivityFields
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3856,11 +4009,9 @@ export const GetNftActivitiesDocument = gql`
                   bidder {
                     ...BasicMembershipFields
                   }
-                  auction {
-                    nft {
-                      video {
-                        ...BasicVideoActivityFields
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                   amount
@@ -3872,11 +4023,9 @@ export const GetNftActivitiesDocument = gql`
                   bidder {
                     ...BasicMembershipFields
                   }
-                  auction {
-                    nft {
-                      video {
-                        ...BasicVideoActivityFields
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }
@@ -3924,11 +4073,9 @@ export const GetNftActivitiesDocument = gql`
                   ...BasicMembershipFields
                 }
                 bid {
-                  auction {
-                    nft {
-                      video {
-                        ...BasicVideoActivityFields
-                      }
+                  nft {
+                    video {
+                      ...BasicVideoActivityFields
                     }
                   }
                 }

+ 61 - 85
packages/atlas/src/api/queries/notifications.graphql

@@ -1,11 +1,3 @@
-# CHANGE: Throught this file we're now using one `events` query to receive all related events
-# (instead of separate queries for each event type)
-
-# Some redundant fields (result of schema "flattening") were also removed from the events,
-# as they can now be accessed though deep filtering.
-
-# Note that in this case `orderBy` and `limit` now applies to all events together, not on per-type basis
-
 query GetNotificationsConnection($memberId: String!, $first: Int!, $after: String) {
   notificationsConnection(
     first: $first
@@ -37,12 +29,9 @@ query GetNotificationsConnection($memberId: String!, $first: Int!, $after: Strin
                     ...BasicMembershipFields
                   }
                 }
-                auction {
-                  nft {
-                    video {
-                      id
-                      title
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -58,8 +47,7 @@ query GetNotificationsConnection($memberId: String!, $first: Int!, $after: Strin
               price
               nft {
                 video {
-                  id
-                  title
+                  ...BasicVideoActivityFields
                 }
               }
             }
@@ -72,8 +60,7 @@ query GetNotificationsConnection($memberId: String!, $first: Int!, $after: Strin
                 amount
                 nft {
                   video {
-                    id
-                    title
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -88,12 +75,9 @@ query GetNotificationsConnection($memberId: String!, $first: Int!, $after: Strin
                 bidder {
                   ...BasicMembershipFields
                 }
-                auction {
-                  nft {
-                    video {
-                      id
-                      title
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -107,12 +91,9 @@ query GetNotificationsConnection($memberId: String!, $first: Int!, $after: Strin
                 bidder {
                   ...BasicMembershipFields
                 }
-                auction {
-                  nft {
-                    video {
-                      id
-                      title
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -254,17 +235,13 @@ query GetNftHistory($nftId: String!) {
   }
 }
 
-query GetNftActivities(
-  $memberId: String!
-  $first: Int!
-  $after: String
-  $orderBy: [NftActivityOrderByInput!] = event_timestamp_DESC
-) {
+query GetNftActivitiesCount($memberId: String!) {
   nftsBought: nftActivitiesConnection(
     where: {
-      event: {
-        OR: [
-          {
+      OR: [
+        {
+          member: { id_eq: $memberId }
+          event: {
             data: {
               isTypeOf_in: [
                 "EnglishAuctionSettledEventData"
@@ -274,20 +251,24 @@ query GetNftActivities(
               winningBid: { bidder: { id_eq: $memberId } }
             }
           }
-          { data: { isTypeOf_eq: "NftBoughtEventData", buyer: { id_eq: $memberId } } }
-        ]
-      }
+        }
+        {
+          member: { id_eq: $memberId }
+          event: { data: { isTypeOf_eq: "NftBoughtEventData", buyer: { id_eq: $memberId } } }
+        }
+      ]
     }
-    orderBy: $orderBy
+    orderBy: event_timestamp_DESC
   ) {
     totalCount
   }
 
   nftsSold: nftActivitiesConnection(
     where: {
-      event: {
-        OR: [
-          {
+      OR: [
+        {
+          member: { id_eq: $memberId }
+          event: {
             data: {
               isTypeOf_in: [
                 "EnglishAuctionSettledEventData"
@@ -298,7 +279,10 @@ query GetNftActivities(
               previousNftOwner: { member: { id_eq: $memberId } }
             }
           }
-          {
+        }
+        {
+          member: { id_eq: $memberId }
+          event: {
             data: {
               isTypeOf_in: [
                 "EnglishAuctionSettledEventData"
@@ -309,10 +293,10 @@ query GetNftActivities(
               previousNftOwner: { channel: { ownerMember: { id_eq: $memberId } } }
             }
           }
-        ]
-      }
+        }
+      ]
     }
-    orderBy: $orderBy
+    orderBy: event_timestamp_DESC
   ) {
     totalCount
   }
@@ -326,25 +310,26 @@ query GetNftActivities(
         ]
       }
     }
-    orderBy: $orderBy
+    orderBy: event_timestamp_DESC
   ) {
     totalCount
   }
 
   nftsBidded: nftActivitiesConnection(
     where: { event: { data: { isTypeOf_eq: "AuctionBidMadeEventData", bid: { bidder: { id_eq: $memberId } } } } }
-    orderBy: $orderBy
+    orderBy: event_timestamp_DESC
   ) {
     totalCount
   }
+}
 
-  nftActivitiesConnection(
-    first: $first
-    after: $after
-    orderBy: $orderBy # CHANGE: `event_timestamp` now used instead of `createdAt` (which is no longer available)
-    where: { member: { id_eq: $memberId } } # CHANGE: Simplified filtering
-  ) {
-    # CHANGE: The actual `event` is now nested as a property of `NftActivity`
+query GetNftActivities(
+  $memberId: String!
+  $first: Int!
+  $after: String
+  $orderBy: [NftActivityOrderByInput!] = event_timestamp_DESC
+) {
+  nftActivitiesConnection(first: $first, after: $after, orderBy: $orderBy, where: { member: { id_eq: $memberId } }) {
     totalCount
     pageInfo {
       endCursor
@@ -355,7 +340,7 @@ query GetNftActivities(
       node {
         event {
           id
-          timestamp # CHANGE: `timestamp` now used instead of `createdAt` (which is no longer available)
+          timestamp
           inBlock
           data {
             ... on AuctionBidMadeEventData {
@@ -372,11 +357,9 @@ query GetNftActivities(
                     ...BasicMembershipFields
                   }
                 }
-                auction {
-                  nft {
-                    video {
-                      ...BasicVideoActivityFields
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -390,11 +373,9 @@ query GetNftActivities(
                   ...BasicMembershipFields
                 }
                 amount
-                auction {
-                  nft {
-                    video {
-                      ...BasicVideoActivityFields
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -421,11 +402,10 @@ query GetNftActivities(
                 bidder {
                   ...BasicMembershipFields
                 }
-                auction {
-                  nft {
-                    video {
-                      ...BasicVideoActivityFields
-                    }
+
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
                 amount
@@ -437,11 +417,9 @@ query GetNftActivities(
                 bidder {
                   ...BasicMembershipFields
                 }
-                auction {
-                  nft {
-                    video {
-                      ...BasicVideoActivityFields
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }
@@ -489,11 +467,9 @@ query GetNftActivities(
                 ...BasicMembershipFields
               }
               bid {
-                auction {
-                  nft {
-                    video {
-                      ...BasicVideoActivityFields
-                    }
+                nft {
+                  video {
+                    ...BasicVideoActivityFields
                   }
                 }
               }

+ 5 - 1
packages/atlas/src/config/routes.ts

@@ -29,7 +29,8 @@ export const relativeRoutes = {
     channels: () => 'channels',
     video: (id = ':id', query?: { [QUERY_PARAMS.COMMENT_ID]?: string }) => withQueryParameters(`video/${id}`, query),
     editMembership: () => 'member/edit',
-    member: (handle = ':handle') => `member/${handle}`,
+    member: (handle = ':handle', query?: { [QUERY_PARAMS.TAB]?: MemberTabs }) =>
+      withQueryParameters(`member/${handle}`, query),
     notifications: () => 'notifications',
     marketplace: () => 'marketplace',
     ypp: (query?: { [QUERY_PARAMS.REFERRER_ID]?: string }) => withQueryParameters('ypp', query),
@@ -81,8 +82,11 @@ export const absoluteRoutes = Object.entries(BASE_PATHS).reduce((absoluteRoutesA
   return absoluteRoutesAcc
 }, {} as typeof relativeRoutes)
 
+export type MemberTabs = 'NFTs owned' | 'Activity' | 'About'
+
 export const QUERY_PARAMS = {
   SEARCH: 'query',
   COMMENT_ID: 'commentId',
   REFERRER_ID: 'referrerId',
+  TAB: 'tab',
 } as const

+ 3 - 4
packages/atlas/src/providers/notifications/notifications.hooks.ts

@@ -18,7 +18,7 @@ export const useNotifications = (
   opts?: QueryHookOptions<GetNotificationsConnectionQuery, GetNotificationsConnectionQueryVariables>
 ) => {
   const { memberId } = useUser()
-  const { notifications: rawNotifications, ...rest } = useRawNotifications(memberId, opts)
+  const { notifications: rawNotifications, ...rest } = useRawNotifications('111', opts)
   const {
     readNotificationsIdsMap,
     lastSeenNotificationBlock,
@@ -49,12 +49,11 @@ const getVideoDataFromEvent = ({
 }: GetNotificationsConnectionQuery['notificationsConnection']['edges'][number]) => {
   switch (notification.event.data.__typename) {
     case 'AuctionBidMadeEventData':
-      return notification.event.data.bid.auction.nft.video
+      return notification.event.data.bid.nft.video
     case 'BidMadeCompletingAuctionEventData':
-      return notification.event.data.winningBid.nft.video
     case 'EnglishAuctionSettledEventData':
     case 'OpenAuctionBidAcceptedEventData':
-      return notification.event.data.winningBid.auction.nft.video
+      return notification.event.data.winningBid.nft.video
     case 'CommentCreatedEventData':
       return notification.event.data.comment.video
     case 'NftBoughtEventData':

+ 4 - 4
packages/atlas/src/views/viewer/MemberView/ActivityItem.tsx

@@ -36,7 +36,7 @@ export const ActivityItem: FC<ActivityItemProps> = ({
   type,
   title,
   description,
-  thumbnailUri: thumnailUri,
+  thumbnailUri,
   thumbnailLoading,
   loading,
   onItemClick,
@@ -47,11 +47,11 @@ export const ActivityItem: FC<ActivityItemProps> = ({
 
   useEffect(() => {
     const validateImg = async () => {
-      const res = await imageUrlValidation(thumnailUri)
+      const res = await imageUrlValidation(thumbnailUri)
       setThumbnailLoaded(res)
     }
     validateImg()
-  }, [thumnailUri])
+  }, [thumbnailUri])
 
   const getTitleTextVariant = () => {
     if (lgMatch) {
@@ -66,7 +66,7 @@ export const ActivityItem: FC<ActivityItemProps> = ({
   const isImageLoading = loading || thumbnailLoading || !thumbnailLoaded
   return (
     <ActivityItemContainer loading={loading} onClick={onItemClick}>
-      {isImageLoading ? <ThumbnailSkeletonLoader /> : <Thumbnail src={thumnailUri} />}
+      {isImageLoading ? <ThumbnailSkeletonLoader /> : <Thumbnail src={thumbnailUri} />}
       <TitleAndDescriptionContainer>
         {loading ? (
           <TitleSkeletonLoader />

+ 8 - 12
packages/atlas/src/views/viewer/MemberView/MemberActivity.hooks.ts

@@ -2,7 +2,7 @@ import { QueryHookOptions } from '@apollo/client'
 import BN from 'bn.js'
 import { useMemo } from 'react'
 
-import { useRawActivities } from '@/api/hooks/notifications'
+import { useActivitiesCount, useRawActivities } from '@/api/hooks/notifications'
 import { NftActivityOrderByInput } from '@/api/queries/__generated__/baseTypes.generated'
 import {
   BasicMembershipFieldsFragment,
@@ -74,11 +74,11 @@ const getVideoDataFromEvent = (
   switch (nftActivity.event.data.__typename) {
     case 'AuctionBidMadeEventData':
     case 'AuctionBidCanceledEventData':
-      return nftActivity.event.data.bid.auction.nft.video
-    case 'EnglishAuctionSettledEventData':
+      return nftActivity.event.data.bid.nft.video
     case 'BidMadeCompletingAuctionEventData':
+    case 'EnglishAuctionSettledEventData':
     case 'OpenAuctionBidAcceptedEventData':
-      return nftActivity.event.data.winningBid.auction.nft.video
+      return nftActivity.event.data.winningBid.nft.video
     case 'NftBoughtEventData':
     case 'NftSellOrderMadeEventData':
     case 'BuyNowCanceledEventData':
@@ -245,14 +245,10 @@ export const useActivities = (
   sort?: NftActivityOrderByInput,
   opts?: QueryHookOptions<GetNftActivitiesQuery, GetNftActivitiesQueryVariables>
 ) => {
-  const {
-    activities: rawActivities,
-    nftsBiddedTotalCount,
-    nftsIssuedTotalCount,
-    nftsSoldTotalCount,
-    nftsBoughtTotalCount,
-    ...rest
-  } = useRawActivities(memberId, sort, opts)
+  const { activities: rawActivities, ...rest } = useRawActivities(memberId, sort, opts)
+
+  const { nftsBiddedTotalCount, nftsBoughtTotalCount, nftsIssuedTotalCount, nftsSoldTotalCount } =
+    useActivitiesCount(memberId)
   const parsedActivities = rawActivities && rawActivities.map((a) => parseActivities(a, memberId))
   const activities = parsedActivities ? parsedActivities.filter((a): a is ActivitiesRecord => !!a) : undefined
 

+ 68 - 9
packages/atlas/src/views/viewer/MemberView/MemberActivity.tsx

@@ -39,14 +39,26 @@ const getDescription = (activity: ActivitiesRecord) => {
     case 'Bid':
       return (
         <>
-          {fromHandle} placed a bid for{' '}
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          placed a bid for{' '}
           <NumberFormat as="span" color="inherit" format="short" value={activity.bidAmount} withToken />
         </>
       )
     case 'Sale':
       return (
         <>
-          {fromHandle} sold NFT to{' '}
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          sold NFT to{' '}
           <StyledLink to={absoluteRoutes.viewer.member(activity.to?.handle)} onClick={(e) => e.stopPropagation()}>
             {activity.to?.handle}
           </StyledLink>{' '}
@@ -60,13 +72,25 @@ const getDescription = (activity: ActivitiesRecord) => {
             {activity.to?.handle}{' '}
           </StyledLink>{' '}
           purchased NFT for <NumberFormat as="span" color="inherit" format="short" value={activity.price} withToken />{' '}
-          from {fromHandle}
+          from{' '}
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
         </>
       )
     case 'Listing':
       return (
         <>
-          {fromHandle} listed NFT{' '}
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          listed NFT{' '}
           {activity.typeName === 'NftSellOrderMadeEventData' && activity.price && (
             <>
               for <NumberFormat as="span" color="inherit" format="short" value={activity.price} withToken />
@@ -75,16 +99,51 @@ const getDescription = (activity: ActivitiesRecord) => {
         </>
       )
     case 'Removal':
-      return <>{fromHandle} removed NFT from sale</>
+      return (
+        <>
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          removed NFT from sale
+        </>
+      )
     case 'Mint':
-      return <>{fromHandle} minted new NFT</>
+      return (
+        <>
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          minted new NFT
+        </>
+      )
     case 'Withdrawal':
-      return <>{fromHandle} withdrew a bid</>
+      return (
+        <>
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          withdrew a bid
+        </>
+      )
     case 'Price change':
       return (
         <>
-          {fromHandle} changed price to{' '}
-          <NumberFormat as="span" color="inherit" format="short" value={activity.price} withToken />
+          <StyledLink
+            to={absoluteRoutes.viewer.member(fromHandle, { tab: 'NFTs owned' })}
+            onClick={(e) => e.stopPropagation()}
+          >
+            {fromHandle}
+          </StyledLink>{' '}
+          changed price to <NumberFormat as="span" color="inherit" format="short" value={activity.price} withToken />
         </>
       )
   }

+ 7 - 6
packages/atlas/src/views/viewer/MemberView/MemberView.tsx

@@ -1,5 +1,5 @@
 import { FC, useEffect, useMemo, useRef, useState } from 'react'
-import { useParams } from 'react-router'
+import { useNavigate, useParams } from 'react-router'
 import { useSearchParams } from 'react-router-dom'
 
 import { useMemberships } from '@/api/hooks/membership'
@@ -12,7 +12,7 @@ import { ViewErrorFallback } from '@/components/ViewErrorFallback'
 import { ViewWrapper } from '@/components/ViewWrapper'
 import { Button } from '@/components/_buttons/Button'
 import { Select } from '@/components/_inputs/Select'
-import { absoluteRoutes } from '@/config/routes'
+import { MemberTabs, QUERY_PARAMS, absoluteRoutes } from '@/config/routes'
 import { NFT_SORT_ACTIVITY_OPTIONS, NFT_SORT_OPTIONS } from '@/config/sorting'
 import { useHeadTags } from '@/hooks/useHeadTags'
 import { getMemberAvatar } from '@/providers/assets/assets.helpers'
@@ -32,16 +32,17 @@ import {
   TabsWrapper,
 } from './MemberView.styles'
 
-const TABS = ['NFTs owned', 'Activity', 'About'] as const
+const TABS: MemberTabs[] = ['NFTs owned', 'Activity', 'About']
 
 export const MemberView: FC = () => {
   const [searchParams, setSearchParams] = useSearchParams()
-  const currentTabName = searchParams.get('tab') as typeof TABS[number] | null
+  const currentTabName = searchParams.get(QUERY_PARAMS.TAB) as MemberTabs | null
   const [sortBy, setSortBy] = useState<OwnedNftOrderByInput>(OwnedNftOrderByInput.CreatedAtDesc)
   const [sortByTimestamp, setSortByTimestamp] = useState<NftActivityOrderByInput>(
     NftActivityOrderByInput.EventTimestampDesc
   )
-  const [currentTab, setCurrentTab] = useState<typeof TABS[number] | null>(null)
+  const navigate = useNavigate()
+  const [currentTab, setCurrentTab] = useState<MemberTabs | null>(null)
   const [nftCount, setNftCount] = useState<number | undefined>()
   const { memberId, activeMembership } = useUser()
   const { handle } = useParams()
@@ -82,7 +83,7 @@ export const MemberView: FC = () => {
     }
   }
   const handleSetCurrentTab = async (tab: number) => {
-    setSearchParams({ 'tab': TABS[tab] }, { replace: true })
+    navigate(absoluteRoutes.viewer.member(handle, { tab: TABS[tab] }))
   }
 
   const mappedTabs = TABS.map((tab) => ({