2026-02-20 10:44:03 +04:00
|
|
|
|
import { HttpInterceptorFn, HttpResponse } from '@angular/common/http';
|
|
|
|
|
|
import { of, delay } from 'rxjs';
|
|
|
|
|
|
import { environment } from '../../environments/environment';
|
|
|
|
|
|
|
|
|
|
|
|
// ─── Mock Categories (backOffice format: string IDs, img, subcategories, visible) ───
|
|
|
|
|
|
|
|
|
|
|
|
const MOCK_CATEGORIES = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'electronics',
|
|
|
|
|
|
categoryID: 1,
|
|
|
|
|
|
name: 'Электроника',
|
|
|
|
|
|
parentID: 0,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1498049794561-7780e7231661?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1498049794561-7780e7231661?w=400&h=300&fit=crop',
|
|
|
|
|
|
projectId: 'dexar',
|
|
|
|
|
|
itemCount: 15,
|
|
|
|
|
|
subcategories: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'smartphones',
|
|
|
|
|
|
name: 'Смартфоны',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?w=400&h=300&fit=crop',
|
|
|
|
|
|
categoryId: 'electronics',
|
|
|
|
|
|
parentId: 'electronics',
|
|
|
|
|
|
itemCount: 8,
|
|
|
|
|
|
hasItems: true,
|
|
|
|
|
|
subcategories: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'laptops',
|
|
|
|
|
|
name: 'Ноутбуки',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1496181133206-80ce9b88a853?w=400&h=300&fit=crop',
|
|
|
|
|
|
categoryId: 'electronics',
|
|
|
|
|
|
parentId: 'electronics',
|
|
|
|
|
|
itemCount: 6,
|
|
|
|
|
|
hasItems: true,
|
|
|
|
|
|
subcategories: []
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'clothing',
|
|
|
|
|
|
categoryID: 2,
|
|
|
|
|
|
name: 'Одежда',
|
|
|
|
|
|
parentID: 0,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=400&h=300&fit=crop',
|
|
|
|
|
|
projectId: 'dexar',
|
|
|
|
|
|
itemCount: 25,
|
|
|
|
|
|
subcategories: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'mens',
|
|
|
|
|
|
name: 'Мужская',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1490578474895-699cd4e2cf59?w=400&h=300&fit=crop',
|
|
|
|
|
|
categoryId: 'clothing',
|
|
|
|
|
|
parentId: 'clothing',
|
|
|
|
|
|
itemCount: 12,
|
|
|
|
|
|
hasItems: true,
|
|
|
|
|
|
subcategories: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'womens',
|
|
|
|
|
|
name: 'Женская',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1487222477894-8943e31ef7b2?w=400&h=300&fit=crop',
|
|
|
|
|
|
categoryId: 'clothing',
|
|
|
|
|
|
parentId: 'clothing',
|
|
|
|
|
|
itemCount: 13,
|
|
|
|
|
|
hasItems: true,
|
|
|
|
|
|
subcategories: []
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'home',
|
|
|
|
|
|
categoryID: 3,
|
|
|
|
|
|
name: 'Дом и сад',
|
|
|
|
|
|
parentID: 0,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 3,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&h=300&fit=crop',
|
|
|
|
|
|
projectId: 'dexar',
|
|
|
|
|
|
itemCount: 8,
|
|
|
|
|
|
subcategories: []
|
|
|
|
|
|
},
|
|
|
|
|
|
// Subcategories as flat entries (for the legacy flat category list)
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'smartphones',
|
|
|
|
|
|
categoryID: 11,
|
|
|
|
|
|
name: 'Смартфоны',
|
|
|
|
|
|
parentID: 1,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?w=400&h=300&fit=crop',
|
|
|
|
|
|
itemCount: 8
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'laptops',
|
|
|
|
|
|
categoryID: 12,
|
|
|
|
|
|
name: 'Ноутбуки',
|
|
|
|
|
|
parentID: 1,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1496181133206-80ce9b88a853?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1496181133206-80ce9b88a853?w=400&h=300&fit=crop',
|
|
|
|
|
|
itemCount: 6
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'mens',
|
|
|
|
|
|
categoryID: 21,
|
|
|
|
|
|
name: 'Мужская одежда',
|
|
|
|
|
|
parentID: 2,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1490578474895-699cd4e2cf59?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1490578474895-699cd4e2cf59?w=400&h=300&fit=crop',
|
|
|
|
|
|
itemCount: 12
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'womens',
|
|
|
|
|
|
categoryID: 22,
|
|
|
|
|
|
name: 'Женская одежда',
|
|
|
|
|
|
parentID: 2,
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
img: 'https://images.unsplash.com/photo-1487222477894-8943e31ef7b2?w=400&h=300&fit=crop',
|
|
|
|
|
|
icon: 'https://images.unsplash.com/photo-1487222477894-8943e31ef7b2?w=400&h=300&fit=crop',
|
|
|
|
|
|
itemCount: 13
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// ─── Mock Items (backOffice format with ALL fields) ───
|
|
|
|
|
|
|
|
|
|
|
|
const MOCK_ITEMS: any[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'iphone15',
|
|
|
|
|
|
itemID: 101,
|
|
|
|
|
|
name: 'iPhone 15 Pro Max',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
quantity: 50,
|
|
|
|
|
|
price: 149990,
|
|
|
|
|
|
discount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.8,
|
|
|
|
|
|
remainings: 'high',
|
|
|
|
|
|
categoryID: 11,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1695048133142-1a20484d2569?w=600&h=400&fit=crop',
|
|
|
|
|
|
'https://images.unsplash.com/photo-1592750475338-74b7b21085ab?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1695048133142-1a20484d2569?w=600&h=400&fit=crop' },
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1592750475338-74b7b21085ab?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['new', 'featured', 'apple'],
|
|
|
|
|
|
badges: ['new', 'bestseller'],
|
2026-03-24 00:09:11 +04:00
|
|
|
|
colour: 'Натуральный титан',
|
|
|
|
|
|
size: '',
|
|
|
|
|
|
names: [
|
|
|
|
|
|
{ language: 'ru', value: 'iPhone 15 Pro Max' },
|
|
|
|
|
|
{ language: 'en', value: 'iPhone 15 Pro Max' },
|
|
|
|
|
|
{ language: 'hy', value: 'iPhone 15 Pro Max' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptions: [
|
|
|
|
|
|
{ language: 'ru', value: 'Новейший iPhone с титановым корпусом и чипом A17 Pro' },
|
|
|
|
|
|
{ language: 'en', value: 'Latest iPhone with titanium body and A17 Pro chip' }
|
|
|
|
|
|
],
|
|
|
|
|
|
attributes: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Натуральный титан' },
|
|
|
|
|
|
{ key: 'Память', value: '256 ГБ' },
|
|
|
|
|
|
{ key: 'Процессор', value: 'A17 Pro' }
|
|
|
|
|
|
],
|
2026-02-20 10:44:03 +04:00
|
|
|
|
simpleDescription: 'Новейший iPhone с титановым корпусом и чипом A17 Pro',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Натуральный титан' },
|
|
|
|
|
|
{ key: 'Память', value: '256 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '6.7" Super Retina XDR' },
|
|
|
|
|
|
{ key: 'Процессор', value: 'A17 Pro' },
|
|
|
|
|
|
{ key: 'Камера', value: '48 Мп основная' },
|
|
|
|
|
|
{ key: 'Аккумулятор', value: '4441 мАч' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Натуральный титан' },
|
|
|
|
|
|
{ key: 'Память', value: '256 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '6.7" Super Retina XDR' },
|
|
|
|
|
|
{ key: 'Процессор', value: 'A17 Pro' },
|
|
|
|
|
|
{ key: 'Камера', value: '48 Мп основная' },
|
|
|
|
|
|
{ key: 'Аккумулятор', value: '4441 мАч' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'smartphones',
|
|
|
|
|
|
translations: {
|
|
|
|
|
|
en: {
|
|
|
|
|
|
name: 'iPhone 15 Pro Max',
|
|
|
|
|
|
simpleDescription: 'Latest iPhone with titanium body and A17 Pro chip',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Color', value: 'Natural Titanium' },
|
|
|
|
|
|
{ key: 'Storage', value: '256GB' },
|
|
|
|
|
|
{ key: 'Display', value: '6.7" Super Retina XDR' },
|
|
|
|
|
|
{ key: 'Chip', value: 'A17 Pro' },
|
|
|
|
|
|
{ key: 'Camera', value: '48MP main' },
|
|
|
|
|
|
{ key: 'Battery', value: '4441 mAh' }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c1', text: 'Отличный телефон! Камера просто огонь 🔥', author: 'Иван Петров', stars: 5, createdAt: '2025-12-15T10:30:00Z' },
|
|
|
|
|
|
{ id: 'c2', text: 'Батарея держит весь день, очень доволен.', author: 'Мария Козлова', stars: 4, createdAt: '2026-01-05T14:20:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 5, content: 'Отличный телефон! Камера просто огонь 🔥', userID: 'Иван Петров', timestamp: '2025-12-15T10:30:00Z' },
|
|
|
|
|
|
{ rating: 4, content: 'Батарея держит весь день, очень доволен.', userID: 'Мария Козлова', timestamp: '2026-01-05T14:20:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'samsung-s24',
|
|
|
|
|
|
itemID: 102,
|
|
|
|
|
|
name: 'Samsung Galaxy S24 Ultra',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
quantity: 35,
|
|
|
|
|
|
price: 129990,
|
|
|
|
|
|
discount: 10,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.6,
|
|
|
|
|
|
remainings: 'high',
|
|
|
|
|
|
categoryID: 11,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1610945415295-d9bbf067e59c?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1610945415295-d9bbf067e59c?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['new', 'android', 'samsung'],
|
|
|
|
|
|
badges: ['new', 'sale'],
|
2026-03-24 00:09:11 +04:00
|
|
|
|
colour: 'Титановый серый',
|
|
|
|
|
|
size: '',
|
|
|
|
|
|
names: [
|
|
|
|
|
|
{ language: 'ru', value: 'Samsung Galaxy S24 Ultra' },
|
|
|
|
|
|
{ language: 'en', value: 'Samsung Galaxy S24 Ultra' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptions: [
|
|
|
|
|
|
{ language: 'ru', value: 'Премиальный флагман Samsung с S Pen' },
|
|
|
|
|
|
{ language: 'en', value: 'Premium Samsung flagship with S Pen' }
|
|
|
|
|
|
],
|
|
|
|
|
|
attributes: [
|
|
|
|
|
|
{ key: 'Память', value: '512 ГБ' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '12 ГБ' }
|
|
|
|
|
|
],
|
2026-02-20 10:44:03 +04:00
|
|
|
|
simpleDescription: 'Премиальный флагман Samsung с S Pen',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Титановый серый' },
|
|
|
|
|
|
{ key: 'Память', value: '512 ГБ' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '12 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '6.8" Dynamic AMOLED 2X' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Титановый серый' },
|
|
|
|
|
|
{ key: 'Память', value: '512 ГБ' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '12 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '6.8" Dynamic AMOLED 2X' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'smartphones',
|
|
|
|
|
|
translations: {
|
|
|
|
|
|
en: {
|
|
|
|
|
|
name: 'Samsung Galaxy S24 Ultra',
|
|
|
|
|
|
simpleDescription: 'Premium Samsung flagship with S Pen',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Color', value: 'Titanium Gray' },
|
|
|
|
|
|
{ key: 'Storage', value: '512GB' },
|
|
|
|
|
|
{ key: 'RAM', value: '12GB' },
|
|
|
|
|
|
{ key: 'Display', value: '6.8" Dynamic AMOLED 2X' }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c3', text: 'S Pen — топ, использую каждый день.', author: 'Алексей', stars: 5, createdAt: '2026-01-20T08:10:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 5, content: 'S Pen — топ, использую каждый день.', userID: 'Алексей', timestamp: '2026-01-20T08:10:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'pixel-8',
|
|
|
|
|
|
itemID: 103,
|
|
|
|
|
|
name: 'Google Pixel 8 Pro',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 3,
|
|
|
|
|
|
quantity: 20,
|
|
|
|
|
|
price: 89990,
|
|
|
|
|
|
discount: 15,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.5,
|
|
|
|
|
|
remainings: 'medium',
|
|
|
|
|
|
categoryID: 11,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1598327105666-5b89351aff97?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1598327105666-5b89351aff97?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['sale', 'android', 'ai', 'google'],
|
|
|
|
|
|
badges: ['sale', 'hot'],
|
|
|
|
|
|
simpleDescription: 'Лучший смартфон для ИИ-фотографии',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Bay Blue' },
|
|
|
|
|
|
{ key: 'Память', value: '256 ГБ' },
|
|
|
|
|
|
{ key: 'Процессор', value: 'Tensor G3' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Цвет', value: 'Bay Blue' },
|
|
|
|
|
|
{ key: 'Память', value: '256 ГБ' },
|
|
|
|
|
|
{ key: 'Процессор', value: 'Tensor G3' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'smartphones',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [],
|
|
|
|
|
|
callbacks: [],
|
|
|
|
|
|
questions: [
|
|
|
|
|
|
{ question: 'Поддерживает eSIM?', answer: 'Да, поддерживает dual eSIM.', upvotes: 12, downvotes: 0 }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'macbook-pro',
|
|
|
|
|
|
itemID: 104,
|
|
|
|
|
|
name: 'MacBook Pro 16" M3 Max',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
quantity: 15,
|
|
|
|
|
|
price: 299990,
|
|
|
|
|
|
discount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.9,
|
|
|
|
|
|
remainings: 'low',
|
|
|
|
|
|
categoryID: 12,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1517336714731-489689fd1ca8?w=600&h=400&fit=crop',
|
|
|
|
|
|
'https://images.unsplash.com/photo-1541807084-5c52b6b3adef?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1517336714731-489689fd1ca8?w=600&h=400&fit=crop' },
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1541807084-5c52b6b3adef?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['featured', 'professional', 'apple'],
|
|
|
|
|
|
badges: ['exclusive', 'limited'],
|
|
|
|
|
|
simpleDescription: 'Мощный ноутбук для профессионалов',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Процессор', value: 'Apple M3 Max' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '36 ГБ' },
|
|
|
|
|
|
{ key: 'Память', value: '1 ТБ SSD' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '16.2" Liquid Retina XDR' },
|
|
|
|
|
|
{ key: 'Батарея', value: 'До 22 ч' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Процессор', value: 'Apple M3 Max' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '36 ГБ' },
|
|
|
|
|
|
{ key: 'Память', value: '1 ТБ SSD' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '16.2" Liquid Retina XDR' },
|
|
|
|
|
|
{ key: 'Батарея', value: 'До 22 ч' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'laptops',
|
|
|
|
|
|
translations: {
|
|
|
|
|
|
en: {
|
|
|
|
|
|
name: 'MacBook Pro 16" M3 Max',
|
|
|
|
|
|
simpleDescription: 'Powerful laptop for professionals',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Chip', value: 'Apple M3 Max' },
|
|
|
|
|
|
{ key: 'RAM', value: '36GB' },
|
|
|
|
|
|
{ key: 'Storage', value: '1TB SSD' },
|
|
|
|
|
|
{ key: 'Display', value: '16.2" Liquid Retina XDR' },
|
|
|
|
|
|
{ key: 'Battery', value: 'Up to 22h' }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c4', text: 'Невероятная производительность. Рендер в 3 раза быстрее.', author: 'Дизайнер Про', stars: 5, createdAt: '2025-11-15T12:00:00Z' },
|
|
|
|
|
|
{ id: 'c5', text: 'Стоит каждого рубля. Экран — сказка.', author: 'Видеоредактор', stars: 5, createdAt: '2026-02-01T09:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 5, content: 'Невероятная производительность. Рендер в 3 раза быстрее.', userID: 'Дизайнер Про', timestamp: '2025-11-15T12:00:00Z' },
|
|
|
|
|
|
{ rating: 5, content: 'Стоит каждого рубля. Экран — сказка.', userID: 'Видеоредактор', timestamp: '2026-02-01T09:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'dell-xps',
|
|
|
|
|
|
itemID: 105,
|
|
|
|
|
|
name: 'Dell XPS 15',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
quantity: 3,
|
|
|
|
|
|
price: 179990,
|
|
|
|
|
|
discount: 5,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.3,
|
|
|
|
|
|
remainings: 'low',
|
|
|
|
|
|
categoryID: 12,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1593642702749-b7d2a804c22e?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1593642702749-b7d2a804c22e?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['windows', 'professional'],
|
|
|
|
|
|
badges: ['limited'],
|
|
|
|
|
|
simpleDescription: 'Тонкий и мощный Windows ноутбук',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Процессор', value: 'Intel Core i9-13900H' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '32 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '15.6" OLED 3.5K' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Процессор', value: 'Intel Core i9-13900H' },
|
|
|
|
|
|
{ key: 'ОЗУ', value: '32 ГБ' },
|
|
|
|
|
|
{ key: 'Дисплей', value: '15.6" OLED 3.5K' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'laptops',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [],
|
|
|
|
|
|
callbacks: [],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'jacket-leather',
|
|
|
|
|
|
itemID: 201,
|
|
|
|
|
|
name: 'Кожаная куртка Premium',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
quantity: 8,
|
|
|
|
|
|
price: 34990,
|
|
|
|
|
|
discount: 20,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.7,
|
|
|
|
|
|
remainings: 'medium',
|
|
|
|
|
|
categoryID: 21,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1551028719-00167b16eac5?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1551028719-00167b16eac5?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['leather', 'premium', 'winter'],
|
|
|
|
|
|
badges: ['sale', 'bestseller'],
|
|
|
|
|
|
simpleDescription: 'Стильная мужская кожаная куртка из натуральной кожи',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Материал', value: 'Натуральная кожа' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'S, M, L, XL, XXL' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Чёрный' },
|
|
|
|
|
|
{ key: 'Подкладка', value: 'Полиэстер 100%' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Материал', value: 'Натуральная кожа' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'S, M, L, XL, XXL' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Чёрный' },
|
|
|
|
|
|
{ key: 'Подкладка', value: 'Полиэстер 100%' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'mens',
|
|
|
|
|
|
translations: {
|
|
|
|
|
|
en: {
|
|
|
|
|
|
name: 'Premium Leather Jacket',
|
|
|
|
|
|
simpleDescription: 'Stylish men\'s genuine leather jacket',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Material', value: 'Genuine Leather' },
|
|
|
|
|
|
{ key: 'Sizes', value: 'S, M, L, XL, XXL' },
|
|
|
|
|
|
{ key: 'Color', value: 'Black' },
|
|
|
|
|
|
{ key: 'Lining', value: '100% Polyester' }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c6', text: 'Качество кожи отличное, сидит идеально.', author: 'Антон', stars: 5, createdAt: '2026-01-10T16:30:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 5, content: 'Качество кожи отличное, сидит идеально.', userID: 'Антон', timestamp: '2026-01-10T16:30:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'dress-silk',
|
|
|
|
|
|
itemID: 202,
|
|
|
|
|
|
name: 'Шёлковое платье Elegance',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
quantity: 12,
|
|
|
|
|
|
price: 18990,
|
|
|
|
|
|
discount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.9,
|
|
|
|
|
|
remainings: 'high',
|
|
|
|
|
|
categoryID: 22,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1595777457583-95e059d581b8?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1595777457583-95e059d581b8?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['silk', 'elegant', 'new'],
|
|
|
|
|
|
badges: ['new', 'featured'],
|
|
|
|
|
|
simpleDescription: 'Элегантное шёлковое платье для особых случаев',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Материал', value: '100% Шёлк' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'XS, S, M, L' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Бордовый' },
|
|
|
|
|
|
{ key: 'Длина', value: 'Миди' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Материал', value: '100% Шёлк' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'XS, S, M, L' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Бордовый' },
|
|
|
|
|
|
{ key: 'Длина', value: 'Миди' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'womens',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c7', text: 'Восхитительное платье! Ткань потрясающая.', author: 'Елена', stars: 5, createdAt: '2026-02-14T20:00:00Z' },
|
|
|
|
|
|
{ id: 'c8', text: 'Идеально на вечер. Рекомендую!', author: 'Наталья', stars: 5, createdAt: '2026-02-10T11:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 5, content: 'Восхитительное платье! Ткань потрясающая.', userID: 'Елена', timestamp: '2026-02-14T20:00:00Z' },
|
|
|
|
|
|
{ rating: 5, content: 'Идеально на вечер. Рекомендую!', userID: 'Наталья', timestamp: '2026-02-10T11:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'hoodie-basic',
|
|
|
|
|
|
itemID: 203,
|
|
|
|
|
|
name: 'Худи Oversize Basic',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 3,
|
|
|
|
|
|
quantity: 45,
|
|
|
|
|
|
price: 5990,
|
|
|
|
|
|
discount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.2,
|
|
|
|
|
|
remainings: 'high',
|
|
|
|
|
|
categoryID: 21,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1556821840-3a63f95609a7?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1556821840-3a63f95609a7?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['casual', 'basic'],
|
|
|
|
|
|
badges: [],
|
|
|
|
|
|
simpleDescription: 'Удобное худи свободного кроя на каждый день',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Материал', value: 'Хлопок 80%, Полиэстер 20%' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'S, M, L, XL' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Серый меланж' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Материал', value: 'Хлопок 80%, Полиэстер 20%' },
|
|
|
|
|
|
{ key: 'Размеры', value: 'S, M, L, XL' },
|
|
|
|
|
|
{ key: 'Цвет', value: 'Серый меланж' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'mens',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [],
|
|
|
|
|
|
callbacks: [],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'sneakers-run',
|
|
|
|
|
|
itemID: 204,
|
|
|
|
|
|
name: 'Кроссовки AirPulse Run',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 2,
|
|
|
|
|
|
quantity: 0,
|
|
|
|
|
|
price: 12990,
|
|
|
|
|
|
discount: 30,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.4,
|
|
|
|
|
|
remainings: 'out',
|
|
|
|
|
|
categoryID: 21,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['sport', 'running'],
|
|
|
|
|
|
badges: ['sale', 'hot'],
|
|
|
|
|
|
simpleDescription: 'Лёгкие беговые кроссовки с пенной амортизацией',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Верх', value: 'Текстильная сетка' },
|
|
|
|
|
|
{ key: 'Подошва', value: 'Пена EVA' },
|
|
|
|
|
|
{ key: 'Вес', value: '260 г' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Верх', value: 'Текстильная сетка' },
|
|
|
|
|
|
{ key: 'Подошва', value: 'Пена EVA' },
|
|
|
|
|
|
{ key: 'Вес', value: '260 г' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'mens',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [
|
|
|
|
|
|
{ id: 'c9', text: 'Нет в наличии уже месяц... Верните!', author: 'Бегун42', stars: 3, createdAt: '2026-02-05T07:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
callbacks: [
|
|
|
|
|
|
{ rating: 3, content: 'Нет в наличии уже месяц... Верните!', userID: 'Бегун42', timestamp: '2026-02-05T07:00:00Z' }
|
|
|
|
|
|
],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'lamp-smart',
|
|
|
|
|
|
itemID: 301,
|
|
|
|
|
|
name: 'Умная лампа Homelight Pro',
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
priority: 1,
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
price: 3990,
|
|
|
|
|
|
discount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
rating: 4.1,
|
|
|
|
|
|
remainings: 'high',
|
|
|
|
|
|
categoryID: 3,
|
|
|
|
|
|
imgs: [
|
|
|
|
|
|
'https://images.unsplash.com/photo-1507473885765-e6ed057ab6fe?w=600&h=400&fit=crop'
|
|
|
|
|
|
],
|
|
|
|
|
|
photos: [
|
|
|
|
|
|
{ url: 'https://images.unsplash.com/photo-1507473885765-e6ed057ab6fe?w=600&h=400&fit=crop' }
|
|
|
|
|
|
],
|
|
|
|
|
|
tags: ['smart-home', 'lighting'],
|
|
|
|
|
|
badges: ['featured'],
|
|
|
|
|
|
simpleDescription: 'Wi-Fi лампа с управлением через приложение и голосом',
|
|
|
|
|
|
description: [
|
|
|
|
|
|
{ key: 'Яркость', value: '1100 лм' },
|
|
|
|
|
|
{ key: 'Цветовая t°', value: '2700K–6500K' },
|
|
|
|
|
|
{ key: 'Совместимость', value: 'Алиса, Google Home, Alexa' }
|
|
|
|
|
|
],
|
|
|
|
|
|
descriptionFields: [
|
|
|
|
|
|
{ key: 'Яркость', value: '1100 лм' },
|
|
|
|
|
|
{ key: 'Цветовая t°', value: '2700K–6500K' },
|
|
|
|
|
|
{ key: 'Совместимость', value: 'Алиса, Google Home, Alexa' }
|
|
|
|
|
|
],
|
|
|
|
|
|
subcategoryId: 'home',
|
|
|
|
|
|
translations: {},
|
|
|
|
|
|
comments: [],
|
|
|
|
|
|
callbacks: [],
|
|
|
|
|
|
questions: []
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// ─── Helper ───
|
|
|
|
|
|
|
|
|
|
|
|
function getAllVisibleItems(): any[] {
|
|
|
|
|
|
return MOCK_ITEMS.filter(i => i.visible !== false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getItemsByCategoryId(categoryID: number): any[] {
|
|
|
|
|
|
return getAllVisibleItems().filter(i => i.categoryID === categoryID);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function respond<T>(body: T, delayMs = 150) {
|
|
|
|
|
|
return of(new HttpResponse({ status: 200, body })).pipe(delay(delayMs));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ─── The Interceptor ───
|
|
|
|
|
|
|
|
|
|
|
|
export const mockDataInterceptor: HttpInterceptorFn = (req, next) => {
|
|
|
|
|
|
if (!(environment as any).useMockData) {
|
|
|
|
|
|
return next(req);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const url = req.url;
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /ping
|
|
|
|
|
|
if (url.endsWith('/ping') && req.method === 'GET') {
|
|
|
|
|
|
return respond({ message: 'pong (mock)' });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /category (all categories flat list)
|
|
|
|
|
|
if (url.endsWith('/category') && req.method === 'GET') {
|
|
|
|
|
|
return respond(MOCK_CATEGORIES);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /category/:id (items for a category)
|
|
|
|
|
|
const catItemsMatch = url.match(/\/category\/(\d+)$/);
|
|
|
|
|
|
if (catItemsMatch && req.method === 'GET') {
|
|
|
|
|
|
const catId = parseInt(catItemsMatch[1], 10);
|
|
|
|
|
|
const items = getItemsByCategoryId(catId);
|
|
|
|
|
|
return respond(items);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /item/:id
|
|
|
|
|
|
const itemMatch = url.match(/\/item\/(\d+)$/);
|
|
|
|
|
|
if (itemMatch && req.method === 'GET') {
|
|
|
|
|
|
const itemId = parseInt(itemMatch[1], 10);
|
|
|
|
|
|
const item = MOCK_ITEMS.find(i => i.itemID === itemId);
|
|
|
|
|
|
if (item) {
|
|
|
|
|
|
return respond(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
return of(new HttpResponse({ status: 404, body: { error: 'Item not found' } })).pipe(delay(100));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /searchitems?search=...
|
|
|
|
|
|
if (url.includes('/searchitems') && req.method === 'GET') {
|
|
|
|
|
|
const search = req.params.get('search')?.toLowerCase() || '';
|
|
|
|
|
|
const items = getAllVisibleItems().filter(i =>
|
|
|
|
|
|
i.name.toLowerCase().includes(search) ||
|
|
|
|
|
|
i.simpleDescription?.toLowerCase().includes(search) ||
|
|
|
|
|
|
i.tags?.some((t: string) => t.toLowerCase().includes(search))
|
|
|
|
|
|
);
|
|
|
|
|
|
return respond({
|
|
|
|
|
|
items,
|
|
|
|
|
|
total: items.length,
|
|
|
|
|
|
count: items.length,
|
|
|
|
|
|
skip: 0
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /randomitems
|
|
|
|
|
|
if (url.includes('/randomitems') && req.method === 'GET') {
|
|
|
|
|
|
const count = parseInt(req.params.get('count') || '5', 10);
|
|
|
|
|
|
const shuffled = [...getAllVisibleItems()].sort(() => Math.random() - 0.5);
|
|
|
|
|
|
return respond(shuffled.slice(0, count));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── GET /cart (return empty)
|
|
|
|
|
|
if (url.endsWith('/cart') && req.method === 'GET') {
|
|
|
|
|
|
return respond([]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 02:25:50 +04:00
|
|
|
|
// ── POST /websession/:id (add to cart)
|
|
|
|
|
|
if (url.match(/\/websession\/[^/]+$/) && req.method === 'POST') {
|
|
|
|
|
|
return respond({
|
|
|
|
|
|
sessionId: 'mock-session',
|
|
|
|
|
|
Status: true,
|
|
|
|
|
|
cart: req.body
|
|
|
|
|
|
});
|
2026-02-20 10:44:03 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 02:25:50 +04:00
|
|
|
|
// ── POST /websession/:id/qr (create payment QR)
|
|
|
|
|
|
if (url.match(/\/websession\/[^/]+\/qr$/) && req.method === 'POST') {
|
|
|
|
|
|
return respond({
|
|
|
|
|
|
qrId: 'mock-qr-' + Date.now(),
|
|
|
|
|
|
qrStatus: 'NEW',
|
|
|
|
|
|
qrExpirationDate: new Date(Date.now() + 180000).toISOString(),
|
|
|
|
|
|
Payload: 'https://example.com/pay/mock',
|
|
|
|
|
|
qrUrl: 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=mock-payment'
|
|
|
|
|
|
}, 300);
|
2026-02-20 10:44:03 +04:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 02:25:50 +04:00
|
|
|
|
// ── POST /items/:id/callback (review)
|
|
|
|
|
|
if (url.match(/\/items\/\d+\/callback$/) && req.method === 'POST') {
|
2026-02-20 10:44:03 +04:00
|
|
|
|
return respond({ message: 'Review submitted (mock)' }, 200);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── POST /purchase-email
|
|
|
|
|
|
if (url.endsWith('/purchase-email') && req.method === 'POST') {
|
|
|
|
|
|
return respond({ message: 'Email sent (mock)' }, 200);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 02:25:50 +04:00
|
|
|
|
// ── GET /websession/:id/:qrId (check QR payment status)
|
|
|
|
|
|
if (url.match(/\/websession\/[^/]+\/[^/]+$/) && !url.match(/\/websession\/[^/]+\/qr$/) && req.method === 'GET') {
|
2026-02-20 10:44:03 +04:00
|
|
|
|
return respond({
|
|
|
|
|
|
paymentStatus: 'SUCCESS',
|
|
|
|
|
|
code: 'SUCCESS',
|
|
|
|
|
|
amount: 0,
|
|
|
|
|
|
currency: 'RUB',
|
|
|
|
|
|
qrId: 'mock',
|
|
|
|
|
|
transactionId: 999,
|
|
|
|
|
|
transactionDate: new Date().toISOString(),
|
|
|
|
|
|
additionalInfo: '',
|
|
|
|
|
|
paymentPurpose: '',
|
|
|
|
|
|
createDate: new Date().toISOString(),
|
|
|
|
|
|
order: 'mock-order',
|
2026-03-24 02:25:50 +04:00
|
|
|
|
qrExpirationDate: new Date().toISOString()
|
2026-02-20 10:44:03 +04:00
|
|
|
|
}, 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Fallback — pass through
|
|
|
|
|
|
return next(req);
|
|
|
|
|
|
};
|