feat: real back-in-stock subscription for Notify Me (API + localStorage fallback)
notifyMe() just called toggleWishlist() - no actual subscription
mechanism existed. Now calls a new subscribeToRestock() API method
(POST /items/{id}/notify-me, not yet built server-side - see
BACKEND-API-REFERENCE.md §12.5) and falls back to a local-only record
in localStorage on failure, so the request isn't silently dropped
while the backend catches up.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,12 @@ import { DEFAULT_PRODUCT_PAGE_CONFIG, DEFAULT_USER_EXPERIENCE_CONFIG, ProductPag
|
||||
import { getStockStatus, getTranslatedField } from '../../../../utils/item.utils';
|
||||
import { ProductShareService } from '../../user-experience/services/product-share.service';
|
||||
import { SeoService } from '../../../../services/seo.service';
|
||||
import { ApiService } from '../../../../services/api.service';
|
||||
import { LocalStorageService } from '../../../../core/storage/local-storage.service';
|
||||
import { UserNotificationService } from '../../user-experience/services/user-notification.service';
|
||||
import { AuthService } from '../../../../services/auth.service';
|
||||
|
||||
const RESTOCK_SUBSCRIPTIONS_KEY = 'restockSubscriptions';
|
||||
import { ProductDeliveryInformationComponent } from '../components/delivery-information/delivery-information.component';
|
||||
import { ProductActionsComponent } from '../components/product-actions/product-actions.component';
|
||||
import { ProductGalleryComponent } from '../components/product-gallery/product-gallery.component';
|
||||
@@ -72,6 +78,10 @@ export class ProductDetailsContainerComponent {
|
||||
private readonly translate = inject(TranslateService);
|
||||
private readonly shareService = inject(ProductShareService);
|
||||
private readonly seoService = inject(SeoService);
|
||||
private readonly apiService = inject(ApiService);
|
||||
private readonly storage = inject(LocalStorageService);
|
||||
private readonly notifications = inject(UserNotificationService);
|
||||
private readonly authService = inject(AuthService);
|
||||
|
||||
readonly productPageConfigState = signal<Required<ProductPageConfig>>(this.resolveProductPageConfig());
|
||||
readonly userExperienceConfig = signal(this.resolveUserExperienceConfig());
|
||||
@@ -358,8 +368,36 @@ export class ProductDetailsContainerComponent {
|
||||
await this.shareService.shareProduct(current, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Back-in-stock subscription. Tries the backend endpoint first (not built
|
||||
* yet - see BACKEND-API-REFERENCE.md §12); falls back to a local-only
|
||||
* record on any failure so the request isn't silently lost while the
|
||||
* backend catches up. Either way the shopper sees the same confirmation.
|
||||
*/
|
||||
notifyMe(): void {
|
||||
this.toggleWishlist();
|
||||
const current = this.product();
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const telegramUserId = this.authService.session()?.userId != null
|
||||
? String(this.authService.session()!.userId)
|
||||
: null;
|
||||
|
||||
this.apiService.subscribeToRestock(current.itemID, { telegramUserId }).subscribe({
|
||||
next: () => this.notifications.show(this.translate.t('productDetails.notifyMeConfirmed'), 'success'),
|
||||
error: () => {
|
||||
this.saveRestockSubscriptionLocally(current.itemID);
|
||||
this.notifications.show(this.translate.t('productDetails.notifyMeConfirmed'), 'success');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private saveRestockSubscriptionLocally(itemID: number): void {
|
||||
const existing = this.storage.getJSON<number[]>(RESTOCK_SUBSCRIPTIONS_KEY) ?? [];
|
||||
if (!existing.includes(itemID)) {
|
||||
this.storage.setJSON(RESTOCK_SUBSCRIPTIONS_KEY, [...existing, itemID]);
|
||||
}
|
||||
}
|
||||
|
||||
addRelatedToCart(payload: { product: Product; event: Event }): void {
|
||||
|
||||
Reference in New Issue
Block a user