From cc0aa93b89d5c5558d2274a25a02ed8008bdb868 Mon Sep 17 00:00:00 2001 From: Alec Menconi Date: Tue, 30 Jan 2024 00:26:53 -0500 Subject: [PATCH] Improved cart quantities and fixed Sweep to Cart function --- .../filter-storage/filter-storage.service.ts | 2 +- .../cart-modal/cart-modal.component.html | 16 +- .../cart-modal/cart-modal.component.ts | 42 +++-- .../checkout/checkout-overlay.component.html | 12 +- .../components/cart/services/cart.service.ts | 30 ++-- .../collection-card.component.html | 6 +- .../member-edit-drawer.component.html | 4 +- .../nft-checkout/nft-checkout.component.ts | 3 + .../pages/collection/collection.page.ts | 13 +- .../collection/nfts/collectionNfts.service.ts | 5 + .../pages/collection/nfts/nfts.page.html | 37 +++-- .../pages/collection/nfts/nfts.page.ts | 150 +++++++++++++----- src/app/pages/nft/pages/nft/nft.page.html | 85 +++++----- src/app/pages/nft/pages/nft/nft.page.ts | 25 +-- src/app/pages/nft/services/helper.service.ts | 65 ++++++-- 15 files changed, 301 insertions(+), 194 deletions(-) diff --git a/src/app/@core/services/filter-storage/filter-storage.service.ts b/src/app/@core/services/filter-storage/filter-storage.service.ts index b9a092c..f1020c7 100644 --- a/src/app/@core/services/filter-storage/filter-storage.service.ts +++ b/src/app/@core/services/filter-storage/filter-storage.service.ts @@ -195,7 +195,7 @@ export class FilterStorageService { public marketNftsResetVisible$: BehaviorSubject = new BehaviorSubject(false); public marketNftsFilters$: BehaviorSubject = new BehaviorSubject({ - sortBy: this.marketNftsFiltersOptions.sortItems[0].value, + sortBy: this.marketNftsFiltersOptions.sortItems[2].value, }); public marketCollectionsFiltersOptions = { diff --git a/src/app/components/cart/components/cart-modal/cart-modal.component.html b/src/app/components/cart/components/cart-modal/cart-modal.component.html index 63213ac..ad1d1d0 100644 --- a/src/app/components/cart/components/cart-modal/cart-modal.component.html +++ b/src/app/components/cart/components/cart-modal/cart-modal.component.html @@ -100,11 +100,11 @@ *ngIf="discount(item.collection, item.nft) < 1" > {{ - cartItemPrices[item.nft.uid]?.originalPrice + cartItemPrices[item.nft.uid].originalPrice | formatToken - : (item.nft?.placeholderNft - ? item.collection?.mintingData?.network - : item.nft?.mintingData?.network) + : (item.nft.placeholderNft + ? item.collection.mintingData?.network + : item.nft.mintingData?.network) : true : true | async @@ -112,11 +112,11 @@
{{ - cartItemPrices[item.nft.uid]?.discountedPrice + cartItemPrices[item.nft.uid].discountedPrice | formatToken - : (item.nft?.placeholderNft - ? item.collection?.mintingData?.network - : item.nft?.mintingData?.network) + : (item.nft.placeholderNft + ? item.collection.mintingData?.network + : item.nft.mintingData?.network) : true : true | async diff --git a/src/app/components/cart/components/cart-modal/cart-modal.component.ts b/src/app/components/cart/components/cart-modal/cart-modal.component.ts index cb354c4..ae7d3e5 100644 --- a/src/app/components/cart/components/cart-modal/cart-modal.component.ts +++ b/src/app/components/cart/components/cart-modal/cart-modal.component.ts @@ -46,7 +46,6 @@ export class CartModalComponent implements OnInit, OnDestroy { ngOnInit() { this.subscriptions.add( this.cartService.getCartItems().subscribe((items) => { - // console.log('[CartModalComponent-ngOnInit] Cart items updated:', items); this.cartItemsStatus = items.map((item) => this.cartItemStatus(item)); this.cartItemsQuantities = items.map((item) => this.cartItemSaleAvailableQty(item)); items.forEach((item) => { @@ -77,19 +76,15 @@ export class CartModalComponent implements OnInit, OnDestroy { } private refreshCartData() { - // console.log('Refreshing cart items...'); const cartItems = this.cartService.getCartItems().getValue(); - // console.log('Current cart items:', cartItems); const freshDataObservables = cartItems.map((item) => this.nftApi.getNftById(item.nft.uid).pipe( take(1), map((freshNft) => { - // console.log(`Fetched fresh data for NFT ${item.nft.uid}:`, freshNft); return freshNft ? { ...item, nft: freshNft } : item; }), catchError((error) => { - // console.error(`Error fetching fresh data for NFT ${item.nft.uid}:`, error); return of(item); }), ), @@ -97,8 +92,6 @@ export class CartModalComponent implements OnInit, OnDestroy { forkJoin(freshDataObservables).subscribe( (freshCartItems) => { - // console.log('Fresh cart items:', freshCartItems); - this.cartService.updateCartItems(freshCartItems); this.cartItemsStatus = freshCartItems.map((item) => this.cartItemStatus(item)); @@ -111,8 +104,6 @@ export class CartModalComponent implements OnInit, OnDestroy { this.cartItemPrices[item.nft.uid] = { originalPrice, discountedPrice }; }); - // console.log('Finished refreshing cart items.'); - this.cd.markForCheck(); }, (error) => { @@ -124,17 +115,25 @@ export class CartModalComponent implements OnInit, OnDestroy { public updateQuantity(event: Event, itemId: string): void { const inputElement = event.target as HTMLInputElement; - const newQuantity = Number(inputElement.value); - - if (newQuantity === 0) { - this.cartService.removeFromCart(itemId); - } else { - const cartItems = this.cartService.getCartItems().getValue(); - const itemIndex = cartItems.findIndex((cartItem) => cartItem.nft.uid === itemId); - if (itemIndex !== -1) { - cartItems[itemIndex].quantity = newQuantity; - this.cartService.saveCartItems(); + let newQuantity = Number(inputElement.value); + + const cartItems = this.cartService.getCartItems().getValue(); + const itemIndex = cartItems.findIndex((cartItem) => cartItem.nft.uid === itemId); + + if (itemIndex !== -1) { + const maxQuantity = this.cartItemsQuantities[itemIndex]; + const minQuantity = 1; + + if (newQuantity < minQuantity) { + newQuantity = minQuantity; + inputElement.value = minQuantity.toString(); + } else if (newQuantity > maxQuantity) { + newQuantity = maxQuantity; + inputElement.value = maxQuantity.toString(); } + + cartItems[itemIndex].quantity = newQuantity; + this.cartService.saveCartItems(); } } @@ -170,20 +169,15 @@ export class CartModalComponent implements OnInit, OnDestroy { } public cartItemStatus(item: CartItem): any { - // console.log("[cart-modal.component-cartItemStatus] function called"); const itemAvailable = this.cartService.isCartItemAvailableForSale(item); if (itemAvailable) { - // console.log("[cart-modal.component-cartItemStatus] returning Available, itemAvailable: " + itemAvailable); return 'Available'; } - // console.log("[cart-modal.component-cartItemStatus] returning Not Available, itemAvailable: " + itemAvailable); return 'Not Available'; } private cartItemSaleAvailableQty(item: CartItem): number { - // console.log("[cart-modal.component-cartItemSaleAvailableQty] function called"); const availQty = this.cartService.getAvailableNftQuantity(item); - // console.log("[cart-modal.component] cartItemSaleAvailableQty, qty: " + availQty); return availQty; } diff --git a/src/app/components/cart/components/checkout/checkout-overlay.component.html b/src/app/components/cart/components/checkout/checkout-overlay.component.html index a1be5fd..140a55a 100644 --- a/src/app/components/cart/components/checkout/checkout-overlay.component.html +++ b/src/app/components/cart/components/checkout/checkout-overlay.component.html @@ -58,9 +58,9 @@

Network/Token: {{ group.tokenSy {{ item.salePrice | formatToken - : (item.nft?.placeholderNft - ? item.collection?.mintingData?.network - : item.nft?.mintingData?.network) + : (item.nft.placeholderNft + ? item.collection.mintingData?.network + : item.nft.mintingData?.network) : true : true | async @@ -70,9 +70,9 @@

Network/Token: {{ group.tokenSy {{ item.quantity * item.salePrice | formatToken - : (item.nft?.placeholderNft - ? item.collection?.mintingData?.network - : item.nft?.mintingData?.network) + : (item.nft.placeholderNft + ? item.collection.mintingData?.network + : item.nft.mintingData?.network) : true : true | async diff --git a/src/app/components/cart/services/cart.service.ts b/src/app/components/cart/services/cart.service.ts index 01abd0a..b4cc607 100644 --- a/src/app/components/cart/services/cart.service.ts +++ b/src/app/components/cart/services/cart.service.ts @@ -25,9 +25,7 @@ export class CartService { private notification: NzNotificationService, private helperService: HelperService, public auth: AuthService, - ) { - // console.log('CartService instance created'); - } + ) {} public showCart(): void { this.showCartSubject.next(true); @@ -59,9 +57,7 @@ export class CartService { ` has been added to your cart.`, '', ); - // console.log('[CartService] NFT added to cart:', cartItem); } else { - // console.log('[CartService] NFT is already in the cart:', cartItem); this.notification.error($localize`This NFT already exists in your cart.`, ''); } } @@ -71,7 +67,6 @@ export class CartService { const updatedCartItems = this.cartItemsSubject.value.filter((item) => item.nft.uid !== itemId); this.cartItemsSubject.next(updatedCartItems); this.saveCartItems(); - // console.log('[CartService-removeFromCart] Cart updated:', updatedCartItems); } public removeItemsFromCart(itemIds: string[]): void { @@ -95,33 +90,32 @@ export class CartService { } public getCartItems(): BehaviorSubject { - // console.log('[CartService] getCartItems function called.'); return this.cartItemsSubject; } public updateCartItems(updatedItems: CartItem[]): void { - this.cartItemsSubject.next(updatedItems); // Update the BehaviorSubject with the new cart items - this.saveCartItems(); // Save the updated cart items to local storage or your backend + this.cartItemsSubject.next(updatedItems); + this.saveCartItems(); } public saveCartItems(): void { - // console.log('[CartService] getCartItems function called.'); setItem(StorageItem.CartItems, this.cartItemsSubject.value); - // console.log('[CartService] Saving cart items to local storage:', this.cartItemsSubject.value); } private loadCartItems(): CartItem[] { - // console.log('[CartService] Loading cart items from local storage'); const items = getItem(StorageItem.CartItems) as CartItem[]; - // console.log('[CartService] Cart items loaded from local storage:', items); return items || []; } public isNftAvailableForSale(nft: Nft, collection: Collection): boolean { const isLocked = this.helperService.isLocked(nft, collection, true); - const isOwner = nft.owner === this.auth.member$.value?.uid; + + let isOwner = false; + if (nft.owner != null && this.auth.member$.value?.uid != null) { + isOwner = nft.owner === this.auth.member$.value?.uid; + } + const availableForSale = this.helperService.isAvailableForSale(nft, collection); - // console.log(`[cart.service-isNftAvailableForSale] results for NFT ${nft.name}; availableForSale: ${availableForSale}, isLocked: ${isLocked}, isOwner: ${isOwner}`); return !isLocked && availableForSale && (!isOwner || !nft.owner); } @@ -135,16 +129,12 @@ export class CartService { cartItem.nft, cartItem.collection, ); - // console.log("[cart.service-getAvailableNftQuantity] function called for cartItem.nft.name: " + cartItem.nft.name + ", isAvailableForSale: " + isAvailableForSale); if (cartItem.nft.placeholderNft && isAvailableForSale) { - // console.log("[service-getAvailableNftQuantity] returning qty, placeholder: " + cartItem.nft.placeholderNft + ". availableNfts " + cartItem.collection.availableNfts); return cartItem.collection.availableNfts || 0; } else if (isAvailableForSale) { - // console.log("[service-getAvailableNftQuantity] returning 1, isAvailableForSale: " + isAvailableForSale + ". placeholder: " + cartItem.nft.placeholderNft); return 1; } - // console.log("[service-getAvailableNftQuantity] returning 0, isAvailableForSale: " + isAvailableForSale + ". placeholder: " + cartItem.nft.placeholderNft); return 0; } @@ -176,6 +166,6 @@ export class CartService { public calcPrice(item: CartItem, discount: number): number { const itemPrice = item.nft?.availablePrice || item.nft?.price || 0; - return this.calc(itemPrice, discount); // assuming calc method applies the discount + return this.calc(itemPrice, discount); } } diff --git a/src/app/components/collection/components/collection-card/collection-card.component.html b/src/app/components/collection/components/collection-card/collection-card.component.html index 088f29a..802d069 100644 --- a/src/app/components/collection/components/collection-card/collection-card.component.html +++ b/src/app/components/collection/components/collection-card/collection-card.component.html @@ -106,9 +106,9 @@ class="text-sm font-medium truncate text-foregrounds-primary dark:text-foregrounds-primary-dark" > {{ - collection?.floorPrice - ? (collection?.floorPrice - | formatToken : collection?.mintingData?.network : false : true : 2 + collection.floorPrice + ? (collection.floorPrice + | formatToken : collection.mintingData?.network : false : true : 2 | async) : '-' }} diff --git a/src/app/components/member/components/member-edit-drawer/member-edit-drawer.component.html b/src/app/components/member/components/member-edit-drawer/member-edit-drawer.component.html index 7048756..31bf548 100644 --- a/src/app/components/member/components/member-edit-drawer/member-edit-drawer.component.html +++ b/src/app/components/member/components/member-edit-drawer/member-edit-drawer.component.html @@ -84,7 +84,7 @@

Avatar

[nzValue]="s.value" > Avatar

(); public purchasedNft?: Nft | null; @@ -156,6 +158,7 @@ export class NftCheckoutComponent implements OnInit, OnDestroy { ) {} public ngOnInit(): void { + console.log('[nft-checkout] loaded, qty passed in: ', this.nftQuantity); this.receivedTransactions = false; const listeningToTransaction: string[] = []; this.transaction$.pipe(untilDestroyed(this)).subscribe((val) => { diff --git a/src/app/pages/collection/pages/collection/collection.page.ts b/src/app/pages/collection/pages/collection/collection.page.ts index 2094b3c..1ef8688 100644 --- a/src/app/pages/collection/pages/collection/collection.page.ts +++ b/src/app/pages/collection/pages/collection/collection.page.ts @@ -32,7 +32,15 @@ import { RANKING_TEST, } from '@build-5/interfaces'; import { NzNotificationService } from 'ng-zorro-antd/notification'; -import { BehaviorSubject, first, firstValueFrom, skip, Subscription } from 'rxjs'; +import { + Subject, + BehaviorSubject, + first, + firstValueFrom, + skip, + Subscription, + takeUntil, +} from 'rxjs'; import { DataService } from '../../services/data.service'; import { NotificationService } from './../../../../@core/services/notification/notification.service'; @@ -51,6 +59,7 @@ export class CollectionPage implements OnInit, OnDestroy { private guardiansSubscription$?: Subscription; private guardiansRankModeratorSubscription$?: Subscription; private subscriptions$: Subscription[] = []; + private destroy$ = new Subject(); constructor( public deviceService: DeviceService, @@ -309,6 +318,8 @@ export class CollectionPage implements OnInit, OnDestroy { public ngOnDestroy(): void { this.cancelSubscriptions(); this.guardiansSubscription$?.unsubscribe(); + this.destroy$.next(); + this.destroy$.complete(); } public get networkTypes(): typeof Network { diff --git a/src/app/pages/collection/pages/collection/nfts/collectionNfts.service.ts b/src/app/pages/collection/pages/collection/nfts/collectionNfts.service.ts index c345567..59010db 100644 --- a/src/app/pages/collection/pages/collection/nfts/collectionNfts.service.ts +++ b/src/app/pages/collection/pages/collection/nfts/collectionNfts.service.ts @@ -20,6 +20,11 @@ export class CollectionNftStateService { } private updateAvailableNftsCount(nfts: Nft[], collection: Collection) { + console.log( + '[collectionNfts.service-updateAvailableNftsCount] function called with (nfts, collection): ', + nfts, + collection, + ); const availableNftsCount = nfts.filter((nft) => this.cartService.isNftAvailableForSale(nft, collection), ).length; diff --git a/src/app/pages/collection/pages/collection/nfts/nfts.page.html b/src/app/pages/collection/pages/collection/nfts/nfts.page.html index f49c797..0e647f4 100644 --- a/src/app/pages/collection/pages/collection/nfts/nfts.page.html +++ b/src/app/pages/collection/pages/collection/nfts/nfts.page.html @@ -11,23 +11,34 @@
{{ state.nbHits | number }} records -
- - +
+ + + {{ sweepCount }} + + + No NFTs available to sweep. +
- {{ sweepCount }} -
diff --git a/src/app/pages/collection/pages/collection/nfts/nfts.page.ts b/src/app/pages/collection/pages/collection/nfts/nfts.page.ts index 42e3477..db9b7a6 100644 --- a/src/app/pages/collection/pages/collection/nfts/nfts.page.ts +++ b/src/app/pages/collection/pages/collection/nfts/nfts.page.ts @@ -6,6 +6,7 @@ import { OnChanges, OnInit, OnDestroy, + SimpleChanges, } from '@angular/core'; import { NftApi } from '@api/nft.api'; import { CollectionApi } from '@api/collection.api'; @@ -26,7 +27,6 @@ import { switchMap } from 'rxjs/operators'; import { CartService } from '@components/cart/services/cart.service'; import { NzNotificationService } from 'ng-zorro-antd/notification'; import { state } from '@angular/animations'; - import { CollectionNftStateService } from './collectionNfts.service'; // used in src/app/pages/collection/pages/collection/collection.page.ts @@ -81,61 +81,91 @@ export class CollectionNFTsPage implements OnInit, OnChanges, OnDestroy { ) {} public ngOnInit(): void { - if (this.collectionId) { - this.collectionApi - .getCollectionById(this.collectionId) - .pipe(take(1)) - .subscribe({ - next: (collectionData) => { - if (collectionData) { - this.collection = collectionData; - this.collectionNftStateService.setListedNfts(this.originalNfts, this.collection); - } - }, - error: (err) => { - // console.error('Error fetching collection:', err); - this.notification.error($localize`Error occurred while fetching collection.`, ''); - }, - }); - } - + console.log('ngOnInit fires'); this.collectionNftStateService.availableNftsCount$ .pipe(takeUntil(this.destroy$)) .subscribe((count) => { this.availableNftsCount = count; + console.log('[ngOnInit] this.availableNftsCount is set to count: ', count); + this.cd.markForCheck(); }); - // Algolia change detection bug fix - setInterval(() => this.cd.markForCheck(), 500); + if (this.collectionId) { + this.loadCollection(this.collectionId); + } } - public ngOnChanges(): void { - // TODO comeup with better process. - setTimeout(() => { + public ngOnChanges(changes: SimpleChanges): void { + console.log('ngOnChanges fires'); + if (changes.collectionId) { + this.resetComponentState(); if (this.collectionId) { - this.filterStorageService.marketNftsFilters$.next({ - ...this.filterStorageService.marketNftsFilters$.value, - refinementList: { - ...this.filterStorageService.marketNftsFilters$.value.refinementList, - collection: [this.collectionId], - }, - }); - - this.config = { - indexName: COL.NFT, - searchClient: this.algoliaService.searchClient, - initialUiState: { - nft: this.filterStorageService.marketNftsFilters$.value, - }, - }; + this.loadCollection(this.collectionId); } - }, 500); + } + } + + private resetComponentState(): void { + console.log('resetComponentState fires'); + this.availableNftsCount = 0; + this.sweepCount = 1; + this.cd.markForCheck(); + } + + private loadCollection(collectionId: string): void { + console.log(`loadCollection fires for collectionId: ${collectionId}`); + this.collectionApi + .getCollectionById(collectionId) + .pipe(take(1)) + .subscribe({ + next: (collectionData) => { + console.log('Full response from getCollectionById:', collectionData); + if (collectionData) { + this.collection = collectionData; + const listedNfts = this.collectionNftStateService.getListedNfts(); + if (this.originalNfts.length > 0 && listedNfts.length === 0) { + this.collectionNftStateService.setListedNfts(this.originalNfts, this.collection); + } + this.initializeAlgoliaFilters(collectionId); + } + }, + error: (err) => { + this.notification.error($localize`Error occurred while fetching collection.`, ''); + }, + }); + } + + private initializeAlgoliaFilters(collectionId: string): void { + console.log('initializeAlgoliaFilters fires with collectionId: ', collectionId); + + console.log('Current filters:', this.filterStorageService.marketNftsFilters$.value); + this.filterStorageService.marketNftsFilters$.next({ + ...this.filterStorageService.marketNftsFilters$.value, + refinementList: { + ...this.filterStorageService.marketNftsFilters$.value.refinementList, + collection: [collectionId], + }, + }); + console.log('Updated filters:', this.filterStorageService.marketNftsFilters$.value); + + this.config = { + indexName: COL.NFT, + searchClient: this.algoliaService.searchClient, + initialUiState: { + nft: this.filterStorageService.marketNftsFilters$.value, + }, + }; + + this.cd.markForCheck(); } public captureOriginalHits(hits: any[]) { + console.log('captureOriginalHits fires'); + // console.log('[nfts.page-captureOriginalHits] function called with following hits (hits, this.collection): ', hits, this.collection); if (hits && hits.length > 0 && this.collection) { this.originalNfts = hits; this.collectionNftStateService.setListedNfts(hits, this.collection); + // console.log('[nfts.page-captureOriginalHits] hits if passed, originalNfts set to hits and collectionNftStateService.setListedNfts given (hits, this.collection): ', hits, this.collection); } } @@ -144,12 +174,22 @@ export class CollectionNFTsPage implements OnInit, OnChanges, OnDestroy { } public convertAllToSoonaverseModel = (algoliaItems: any[]) => { - this.captureOriginalHits(algoliaItems); + console.log('convertAllToSoonaverseModel fires'); + // console.log('[nfts.page-convertAllToSoonaverseModel] function called with following algoliaItems: ', algoliaItems); + if (this.originalNfts.length !== algoliaItems.length && algoliaItems.length > 0) { + // console.log('[nfts.page-convertAllToSoonaverseModel] run captureOriginalHits since aligoliaItems and originalNfts lengths dont match, (alogliaItems.length, originalNfts.length): ', algoliaItems.length, this.originalNfts.length); + this.captureOriginalHits(algoliaItems); + } + console.log('Before processing:', algoliaItems); const transformedItems = algoliaItems.map((algolia) => ({ ...algolia, availableFrom: Timestamp.fromMillis(+algolia.availableFrom), })); + console.log('After processing:', transformedItems); + + this.cd.markForCheck(); + return transformedItems; }; @@ -162,6 +202,7 @@ export class CollectionNFTsPage implements OnInit, OnChanges, OnDestroy { } public sweepToCart(count: number) { + console.log('[nfts.page-sweepToCart] function called with following count: ', count); if (!this.collectionId) { this.notification.error($localize`Collection ID is not available.`, ''); return; @@ -174,16 +215,36 @@ export class CollectionNFTsPage implements OnInit, OnChanges, OnDestroy { filter((collection): collection is Collection => collection !== undefined), switchMap((collection: Collection) => { const listedNfts = this.collectionNftStateService.getListedNfts(); + console.log( + '[nfts.page-sweepToCart] listedNfts set to this.collectionNftStateService: ', + listedNfts, + ); const nftsForSale = listedNfts.filter((nft) => this.cartService.isNftAvailableForSale(nft, collection), ); + console.log( + '[nfts.page-sweepToCart] nftsForSale set to filtered listedNfts that pass true for "isNftAvailableForSale", nftsForSale: ', + nftsForSale, + ); - const nftsToAdd = nftsForSale.slice(0, Math.min(count, 20)).sort((a, b) => { - const priceA = a.availablePrice != null ? a.availablePrice : 0; - const priceB = b.availablePrice != null ? b.availablePrice : 0; + const getEffectivePrice = (nft) => nft?.availablePrice || nft?.price || 0; + + const sortedNfts = nftsForSale.sort((a, b) => { + const priceA = getEffectivePrice(a); + const priceB = getEffectivePrice(b); return priceA - priceB; }); + console.log( + '[nfts.page-sweepToCart] sortedNfts set to nftsToAdd sorted by "effective price" low to high, sortedNfts: ', + sortedNfts, + ); + + const nftsToAdd = sortedNfts.slice(0, Math.min(count, sortedNfts.length)); + console.log( + '[nfts.page-sweepToCart] nftsToAdd set to first N sorted NFTs based on price, nftsToAdd: ', + nftsToAdd, + ); nftsToAdd.forEach((nft) => { const cartItem = { nft, collection, quantity: 1, salePrice: 0 }; @@ -207,6 +268,7 @@ export class CollectionNFTsPage implements OnInit, OnChanges, OnDestroy { } public ngOnDestroy(): void { + console.log('ngOnDestroy fires'); this.destroy$.next(); this.destroy$.complete(); } diff --git a/src/app/pages/nft/pages/nft/nft.page.html b/src/app/pages/nft/pages/nft/nft.page.html index fed7c6f..247ddc2 100644 --- a/src/app/pages/nft/pages/nft/nft.page.html +++ b/src/app/pages/nft/pages/nft/nft.page.html @@ -13,12 +13,6 @@ > {{ getCollectionTypeString(collectionType) }} - - {{ getCollectionStatusString(collectionMinting) }} - {{ getTitle(data.nft$ | async) }} >
-
-
- - - - - - - - -
-
+ + + + + + + + +
+ +
@@ -805,6 +801,7 @@

[isOpen]="isCheckoutOpen" [nft]="data.nft$ | async" [collection]="data.collection$ | async" + [nftQuantity]="nftQtySelected" (wenOnClose)="isCheckoutOpen = false" > { - // console.log('[OnInit] Current NFT:', nft); this.currentNft = nft; }); this.deviceService.viewWithSearch$.next(false); @@ -279,8 +279,6 @@ export class NFTPage implements OnInit, OnDestroy { this.data.collection$.pipe(skip(1), untilDestroyed(this)).subscribe(async (p) => { if (p) { this.collectionType = p.type; - // this.collectionMinting = p.status; - // console.log('[nft.page-p] collectionMinting set to: ', p.status) this.collectionSubscriptions$.forEach((s) => { s.unsubscribe(); }); @@ -476,6 +474,7 @@ export class NFTPage implements OnInit, OnDestroy { } public buy(event?: MouseEvent): void { + console.log('Buy now NFT button pressed, qty to pass: ', this.nftQtySelected); if (event) { event.stopPropagation(); event.preventDefault(); @@ -556,18 +555,22 @@ export class NFTPage implements OnInit, OnDestroy { public addToCart(nft: Nft): void { if (nft && this.data.collection$) { - // console.log('[addToCart-this.data.collection$.value', this.data.collection$.value) - // console.log('[addToCart-this.data.nft$.value', this.data.nft$.value) this.data.collection$.pipe(take(1)).subscribe((collection) => { if (collection) { - this.cartService.addToCart({ nft, collection, quantity: 1, salePrice: 0 }); - // console.log('Added to cart:', nft, collection); - } else { - // console.error('Collection is undefined or null'); + this.cartService.addToCart({ + nft, + collection, + quantity: this.nftQtySelected, + salePrice: 0, + }); + console.log( + 'Added to cart (nft, collection, qty):', + nft, + collection, + this.nftQtySelected, + ); } }); - } else { - // console.error('NFT is undefined or null'); } } diff --git a/src/app/pages/nft/services/helper.service.ts b/src/app/pages/nft/services/helper.service.ts index f0e5081..13dc28c 100644 --- a/src/app/pages/nft/services/helper.service.ts +++ b/src/app/pages/nft/services/helper.service.ts @@ -111,6 +111,10 @@ export class HelperService { } public isDateInFuture(date?: Timestamp | null): boolean { + if (!date) { + return false; + } + if (!this.getDate(date)) { return false; } @@ -124,19 +128,40 @@ export class HelperService { } public getDate(date: any): any { - // console.log(`[getDate] Original input:`, date); - if (typeof date === 'object') { - if (date?.toDate) { - const dateFromObject = date.toDate(); - // console.log(`[getDate] Object with toDate method detected, toDate result:`, dateFromObject); - return dateFromObject; - } else if (date?.seconds) { - const dateFromSeconds = new Date(date.seconds * 1000); // Convert to milliseconds - // console.log(`[getDate] Object with seconds property detected, converted to Date:`, dateFromSeconds); - return dateFromSeconds; + if (!date) { + console.warn('getDate called with null or undefined:', date); + return undefined; + } + + if (typeof date === 'number') { + return new Date(date); + } else if (typeof date === 'object') { + // Checking if toDate exists and is a function + if (date.toDate && typeof date.toDate === 'function') { + try { + return date.toDate(); + } catch (e) { + console.error('Error calling toDate:', e); + } + } + + // Checking if seconds exists and is a number + if ('seconds' in date && !isNaN(Number(date.seconds))) { + const seconds = Number(date.seconds); + return new Date(seconds * 1000); + } + + // Checking if toMillis exists and is a function + if (date.toMillis && typeof date.toMillis === 'function') { + try { + return new Date(date.toMillis()); + } catch (e) { + console.error('Error calling toMillis:', e); + } } } - // console.log(`[getDate] Returning undefined, input could not be parsed as a date.`); + + console.warn('Unrecognized date format:', date); return undefined; } @@ -172,9 +197,7 @@ export class HelperService { } public isAvailableForSale(nft?: Nft | null, col?: Collection | null): boolean { - // console.log("[NFThelper-isAvailableForSale] function called"); if (!col || !nft?.availableFrom || col?.status === CollectionStatus.MINTING) { - // console.log("[NFT helper.service.ts] isAvailableForSale function returning false. nft name: " + nft?.name + ", col name: " + col?.name) return false; } @@ -182,13 +205,21 @@ export class HelperService { col.approved === true && !!this.getDate(nft.availableFrom) && dayjs(this.getDate(nft.availableFrom)).isSameOrBefore(dayjs(), 's'); - // console.log("[NFT helper.service.ts] isAvailableForSale function returning " + isAvail + ". nft name: " + nft?.name + ", col name: " + col?.name + ". nft.availableFrom: " + nft.availableFrom.seconds); - // console.log("col.approved: " + (col.approved === true)); - // console.log("!!this.getDate(nft.availableFrom): " + !!this.getDate(nft.availableFrom) + ", this.getDate(nft.availableFrom): " + this.getDate(nft.availableFrom)); - // console.log("dayjs(this.getDate(nft.availableFrom)).isSameOrBefore(dayjs(), 's')" + dayjs(this.getDate(nft.availableFrom)).isSameOrBefore(dayjs(), 's')); return isAvail; } + public getAvailNftQty(nft?: Nft | null, col?: Collection | null): number { + const isAvailableForSale = this.isAvailableForSale(nft, col); + + if (nft?.placeholderNft && isAvailableForSale) { + return col?.availableNfts || 0; + } else if (isAvailableForSale) { + return 1; + } + + return 0; + } + public canBeSetForSale(nft?: Nft | null): boolean { if (nft?.auctionFrom || nft?.availableFrom) { return false;