Skip to content

Commit

Permalink
Merge pull request #10911 from hassnian/issue-10845-0
Browse files Browse the repository at this point in the history
feat:  Offers tab in `profile` and `gallery item`
  • Loading branch information
vikiival authored Sep 9, 2024
2 parents 37cb8ae + 00d13ba commit 9fd91c4
Show file tree
Hide file tree
Showing 33 changed files with 1,334 additions and 96 deletions.
3 changes: 3 additions & 0 deletions components/gallery/GalleryItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ const mediaItemRef = ref<{
const galleryDescriptionRef = ref<{ isLewd: boolean } | null>(null)
const preferencesStore = usePreferencesStore()
const pageViewCount = usePageViews()
const fiatStore = useFiatStore()
const galleryItem = useGalleryItem()
const {
Expand Down Expand Up @@ -385,6 +386,8 @@ function toggleFallback() {
isFullscreen.value = isCurrentlyFullscreen
}
}
onBeforeMount(() => fiatStore.fetchFiatPrice())
</script>

<style lang="scss">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@
v-slot="props"
width="20%"
field="meta"
:label="`${$t(`tabs.tabActivity.price`)} (${chainSymbol})`"
:label="$t(`amount`)"
>
<p v-if="Number(props.row.meta)">
{{ formatPrice(props.row.meta)[0] }}
<span class="text-k-grey">
${{ formatPrice(props.row.meta)[1] }}</span>
{{ formatPrice(props.row.meta).amount }}
<span class="text-k-grey">{{ formatPrice(props.row.meta).price }}</span>
</p>
</NeoTableColumn>

Expand Down Expand Up @@ -135,10 +134,6 @@ import itemEvents from '@/queries/subsquid/general/itemEvents.graphql'
import Identity from '@/components/identity/IdentityIndex.vue'
import { formatToNow } from '@/utils/format/time'
import formatBalance, {
formatNumber,
withoutDigitSeparator,
} from '@/utils/format/balance'
import { parseDate } from '@/utils/datetime'
import type { Interaction } from '@/components/rmrk/service/scheme'
Expand All @@ -149,13 +144,8 @@ const dprops = defineProps<{
interactions: string[]
}>()
const { decimals, chainSymbol } = useChain()
const { urlPrefix, client } = usePrefix()
const tokenPrice = ref(0)
onMounted(async () => {
tokenPrice.value = await getApproximatePriceOf(chainSymbol.value)
})
const { format: formatPrice } = useFormatAmount()
const interaction = computed(() =>
dprops.interactions.map((key) => {
Expand Down Expand Up @@ -213,14 +203,6 @@ watchEffect(() => {
events.value = itemEvents.events
}
})
const formatPrice = (price) => {
const tokenAmount = formatBalance(price, decimals.value, false)
const flatPrice = `${formatNumber(
Number(withoutDigitSeparator(tokenAmount)) * tokenPrice.value,
)}`
return [formatNumber(tokenAmount), flatPrice]
}
</script>

<style lang="scss" scoped>
Expand Down
15 changes: 15 additions & 0 deletions components/gallery/GalleryItemTabsPanel/GalleryItemOffers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<div class="h-full flex flex-col">
<GalleryItemOffersTable
:nft-id="nftId"
/>
</div>
</template>

<script setup lang="ts">
import GalleryItemOffersTable from './GalleryItemOffersTable.vue'
defineProps<{
nftId: string
}>()
</script>
198 changes: 198 additions & 0 deletions components/gallery/GalleryItemTabsPanel/GalleryItemOffersTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<template>
<div
class="gallery-item-offers-table flex flex-col !py-6"
data-testid="gallery-item-offers-table"
>
<div
v-if="loading"
class="p-5"
>
<NeoSkeleton
animated
size="large"
:count="3"
/>
</div>
<NeoTable
v-else-if="offers.length"
:data="offers"
hoverable
class="py-5 max-md:!top-0"
>
<!-- price -->
<NeoTableColumn
v-slot="{ row }: {row: NFTOfferItem}"
width="20%"
field="price"
:label="$t('amount')"
>
<p
v-if="Number(row.price)"
class="flex gap-2"
>
<span> {{ format(row.price).amount }} </span>
<span class="text-k-grey"> {{ format(row.price).price }} </span>
</p>
</NeoTableColumn>

<!-- expiration -->
<NeoTableColumn
v-slot="{ row }: {row: NFTOfferItem}"
width="15%"
field="expiration"
:label="$t('expiration')"
>
<p class="capitalize">
{{ row.expirationDate ? formatToNow(row.expirationDate, false) : '--' }}
</p>
</NeoTableColumn>

<!-- from -->
<NeoTableColumn
v-slot="{ row }: {row: NFTOfferItem}"
width="20%"
field="caller"
:label="$t('tabs.tabActivity.from')"
>
<div class="flex items-center gap-2">
<ProfileAvatar
:size="24"
:address="row.caller"
/>

<nuxt-link
:to="`/${urlPrefix}/u/${row.caller}`"
class="text-k-blue hover:text-k-blue-hover"
>
<Identity
:address="row.caller"
/>
</nuxt-link>
</div>
</NeoTableColumn>

<!-- action -->
<NeoTableColumn
v-slot="{ row }"
width="10%"
>
<OfferOwnerButton
class="max-md:!w-full"
:offer="row as NFTOfferItem"
@click="selectOffer"
/>
</NeoTableColumn>
</NeoTable>
<div
v-else
class="p-5"
>
{{ $t('tabs.tabActivity.empty') }}
</div>
</div>

<OfferOverviewModal
v-model="isWithdrawOfferModalOpen"
:offer="selectedOffer!"
@close="closeOfferOverviewModal"
/>
</template>

<script setup lang="ts">
import {
NeoSkeleton,
NeoTable,
NeoTableColumn,
} from '@kodadot1/brick'
import type { UnwrapRef } from 'vue'
import { formatToNow } from '@/utils/format/time'
import Identity from '@/components/identity/IdentityIndex.vue'
import useSubscriptionGraphql from '@/composables/useSubscriptionGraphql'
const props = defineProps<{
nftId: string
}>()
const { urlPrefix } = usePrefix()
const { format } = useFormatAmount()
const isWithdrawOfferModalOpen = ref(false)
const loading = ref(false)
const offers = ref<UnwrapRef<ReturnType<typeof useOffers>['offers']>>([])
const selectedOffer = ref<NFTOfferItem>()
const stopWatch = ref(() => {})
useSubscriptionGraphql({
query: `
offers (
where: { status_eq: ACTIVE, desired: { id_eq: "${props.nftId}" } }
orderBy: blockNumber_DESC
) {
id
}`,
onChange: ({ data: { offers: newOffers } }) => {
stopWatch.value?.()
offers.value = []
const { offers: offersData, loading: offersLoading } = useOffers({
where: { id_in: newOffers.map(offer => offer.id) },
})
stopWatch.value = watchEffect(() => {
loading.value = offersLoading.value
offers.value = offersData.value
})
},
})
const selectOffer = (offer: NFTOfferItem) => {
selectedOffer.value = offer
isWithdrawOfferModalOpen.value = true
}
const closeOfferOverviewModal = () => {
isWithdrawOfferModalOpen.value = false
selectedOffer.value = undefined
}
</script>

<style lang="scss" scoped>
@import '@/assets/styles/abstracts/variables';
.gallery-item-offers-table {
overflow-y: auto;
@include desktop {
:deep(table tr > *:first-child) {
padding-left: 2rem;
}
:deep(table tbody > tr > td) {
vertical-align: middle;
height: 3.25rem;
&:last-child {
padding: 0;
}
}
}
}
@include touch {
.gallery-item-offers-table {
:deep(.o-table__td) {
@apply border-inherit;
padding: 0;
&:before {
font-weight: 400 !important;
}
}
:deep(.o-table__td:not(:nth-last-child(1)):not(:nth-last-child(2))) {
padding: 0 0 1rem 0;
}
.o-table__td:last-child button {
margin-top: 1.5rem
}
}
}
</style>
20 changes: 18 additions & 2 deletions components/gallery/GalleryItemTabsPanel/GalleryItemTabsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,22 @@
/>
</NeoTabItem>

<!-- chart -->
<!-- offers -->
<NeoTabItem
v-if="offerVisible(urlPrefix)"
value="2"
:label="$t('offers')"
data-testid="offers-activity"
>
<GalleryItemOffers
v-if="nft?.id"
:nft-id="nft.id"
/>
</NeoTabItem>

<!-- chart -->
<NeoTabItem
value="3"
:label="$t('tabs.chart')"
class="p-5"
>
Expand All @@ -31,10 +44,11 @@

<script setup lang="ts">
import { NeoTabItem, NeoTabs } from '@kodadot1/brick'
import type { GalleryItem } from '../useGalleryItem'
import GalleryItemActivity from './GalleryItemActivity.vue'
import GalleryItemOffers from './GalleryItemOffers.vue'
import GalleryItemChart from './GalleryItemChart.vue'
import { offerVisible } from '@/utils/config/permission.config'
const props = withDefaults(
defineProps<{
Expand All @@ -46,6 +60,8 @@ const props = withDefaults(
},
)
const { urlPrefix } = usePrefix()
const nft = computed(() => props.galleryItem.nft.value)
const active = ref('1')
Expand Down
Loading

0 comments on commit 9fd91c4

Please sign in to comment.