import { Injectable } from '@angular/core'; import { Observable, of, delay } from 'rxjs'; import { Project, Category, Subcategory, Item, ItemsListResponse } from '../models'; @Injectable({ providedIn: 'root' }) export class MockDataService { private projects: Project[] = [ { id: 'dexar', name: 'dexar', displayName: 'Dexar Marketplace', active: true, logoUrl: 'https://via.placeholder.com/150?text=Dexar' }, { id: 'novo', name: 'novo', displayName: 'Novo Shop', active: true, logoUrl: 'https://via.placeholder.com/150?text=Novo' } ]; private categories: Category[] = [ { id: 'cat1', name: 'Electronics', visible: true, priority: 1, img: 'https://via.placeholder.com/400x300?text=Electronics', projectId: 'dexar', subcategories: [ { id: 'sub1', name: 'Smartphones', visible: true, priority: 1, img: 'https://via.placeholder.com/400x300?text=Smartphones', categoryId: 'cat1', itemCount: 15 }, { id: 'sub2', name: 'Laptops', visible: true, priority: 2, img: 'https://via.placeholder.com/400x300?text=Laptops', categoryId: 'cat1', itemCount: 12 } ] }, { id: 'cat2', name: 'Clothing', visible: true, priority: 2, img: 'https://via.placeholder.com/400x300?text=Clothing', projectId: 'dexar', subcategories: [ { id: 'sub3', name: 'Men', visible: true, priority: 1, img: 'https://via.placeholder.com/400x300?text=Men', categoryId: 'cat2', itemCount: 25 } ] }, { id: 'cat3', name: 'Home & Garden', visible: false, priority: 3, img: 'https://via.placeholder.com/400x300?text=Home', projectId: 'novo', subcategories: [] } ]; private items: Item[] = [ { id: 'item1', name: 'iPhone 15 Pro Max', visible: true, priority: 1, quantity: 50, price: 1299, currency: 'USD', imgs: [ 'https://via.placeholder.com/600x400?text=iPhone+Front', 'https://via.placeholder.com/600x400?text=iPhone+Back' ], tags: ['new', 'featured', 'bestseller'], simpleDescription: 'Latest iPhone with titanium design and A17 Pro chip', description: [ { key: 'Color', value: 'Natural Titanium' }, { key: 'Storage', value: '256GB' }, { key: 'Display', value: '6.7 inch Super Retina XDR' }, { key: 'Chip', value: 'A17 Pro' } ], subcategoryId: 'sub1', comments: [ { id: 'c1', text: 'Great phone! Battery life is amazing.', createdAt: new Date('2024-01-10'), author: 'John Doe' } ] }, { id: 'item2', name: 'Samsung Galaxy S24 Ultra', visible: true, priority: 2, quantity: 35, price: 1199, currency: 'USD', imgs: ['https://via.placeholder.com/600x400?text=Samsung+S24'], tags: ['new', 'android'], simpleDescription: 'Premium Samsung flagship with S Pen', description: [ { key: 'Color', value: 'Titanium Gray' }, { key: 'Storage', value: '512GB' }, { key: 'RAM', value: '12GB' } ], subcategoryId: 'sub1' }, { id: 'item3', name: 'Google Pixel 8 Pro', visible: true, priority: 3, quantity: 20, price: 999, currency: 'USD', imgs: ['https://via.placeholder.com/600x400?text=Pixel+8'], tags: ['sale', 'android', 'ai'], simpleDescription: 'Best AI photography phone', description: [ { key: 'Color', value: 'Bay Blue' }, { key: 'Storage', value: '256GB' } ], subcategoryId: 'sub1' }, { id: 'item4', name: 'MacBook Pro 16"', visible: true, priority: 1, quantity: 15, price: 2499, currency: 'USD', imgs: ['https://via.placeholder.com/600x400?text=MacBook'], tags: ['featured', 'professional'], simpleDescription: 'Powerful laptop for professionals', description: [ { key: 'Processor', value: 'M3 Max' }, { key: 'RAM', value: '36GB' }, { key: 'Storage', value: '1TB SSD' } ], subcategoryId: 'sub2' }, { id: 'item5', name: 'Dell XPS 15', visible: true, priority: 2, quantity: 0, price: 1799, currency: 'USD', imgs: ['https://via.placeholder.com/600x400?text=Dell+XPS'], tags: ['out-of-stock'], simpleDescription: 'Premium Windows laptop', description: [ { key: 'Processor', value: 'Intel Core i9' }, { key: 'RAM', value: '32GB' } ], subcategoryId: 'sub2' } ]; // Generate more items for testing infinite scroll private generateMoreItems(subcategoryId: string, count: number): Item[] { const items: Item[] = []; for (let i = 6; i <= count + 5; i++) { items.push({ id: `item${i}`, name: `Test Product ${i}`, visible: Math.random() > 0.3, priority: i, quantity: Math.floor(Math.random() * 100), price: Math.floor(Math.random() * 1000) + 100, currency: 'USD', imgs: [`https://via.placeholder.com/600x400?text=Product+${i}`], tags: ['test'], simpleDescription: `This is test product number ${i}`, description: [{ key: 'Size', value: 'Medium' }], subcategoryId }); } return items; } getProjects(): Observable { return of(this.projects).pipe(delay(300)); } getCategories(projectId: string): Observable { const cats = this.categories.filter(c => c.projectId === projectId); return of(cats).pipe(delay(300)); } getCategory(categoryId: string): Observable { const cat = this.categories.find(c => c.id === categoryId)!; return of(cat).pipe(delay(200)); } updateCategory(categoryId: string, data: Partial): Observable { const cat = this.categories.find(c => c.id === categoryId)!; Object.assign(cat, data); return of(cat).pipe(delay(300)); } createCategory(projectId: string, data: Partial): Observable { const newCat: Category = { id: `cat${Date.now()}`, name: data.name || 'New Category', visible: data.visible ?? true, priority: data.priority || 99, img: data.img, projectId, subcategories: [] }; this.categories.push(newCat); return of(newCat).pipe(delay(300)); } deleteCategory(categoryId: string): Observable { const index = this.categories.findIndex(c => c.id === categoryId); if (index > -1) this.categories.splice(index, 1); return of(void 0).pipe(delay(300)); } getSubcategory(subcategoryId: string): Observable { let sub: Subcategory | undefined; for (const cat of this.categories) { sub = cat.subcategories?.find(s => s.id === subcategoryId); if (sub) break; } return of(sub!).pipe(delay(200)); } updateSubcategory(subcategoryId: string, data: Partial): Observable { let sub: Subcategory | undefined; for (const cat of this.categories) { sub = cat.subcategories?.find(s => s.id === subcategoryId); if (sub) { Object.assign(sub, data); break; } } return of(sub!).pipe(delay(300)); } createSubcategory(categoryId: string, data: Partial): Observable { const cat = this.categories.find(c => c.id === categoryId)!; const newSub: Subcategory = { id: `sub${Date.now()}`, name: data.name || 'New Subcategory', visible: data.visible ?? true, priority: data.priority || 99, img: data.img, categoryId, itemCount: 0 }; if (!cat.subcategories) cat.subcategories = []; cat.subcategories.push(newSub); return of(newSub).pipe(delay(300)); } deleteSubcategory(subcategoryId: string): Observable { for (const cat of this.categories) { const index = cat.subcategories?.findIndex(s => s.id === subcategoryId) ?? -1; if (index > -1) { cat.subcategories?.splice(index, 1); break; } } return of(void 0).pipe(delay(300)); } getItems(subcategoryId: string, page = 1, limit = 20, search?: string, filters?: any): Observable { let allItems = [...this.items, ...this.generateMoreItems(subcategoryId, 50)]; // Filter by subcategory allItems = allItems.filter(item => item.subcategoryId === subcategoryId); // Apply search if (search) { allItems = allItems.filter(item => item.name.toLowerCase().includes(search.toLowerCase()) ); } // Apply visibility filter if (filters?.visible !== undefined) { allItems = allItems.filter(item => item.visible === filters.visible); } const total = allItems.length; const start = (page - 1) * limit; const end = start + limit; const items = allItems.slice(start, end); return of({ items, total, page, limit, hasMore: end < total }).pipe(delay(400)); } getItem(itemId: string): Observable { const item = this.items.find(i => i.id === itemId)!; return of(item).pipe(delay(200)); } updateItem(itemId: string, data: Partial): Observable { const item = this.items.find(i => i.id === itemId)!; Object.assign(item, data); return of(item).pipe(delay(300)); } createItem(subcategoryId: string, data: Partial): Observable { const newItem: Item = { id: `item${Date.now()}`, name: data.name || 'New Item', visible: data.visible ?? true, priority: data.priority || 99, quantity: data.quantity || 0, price: data.price || 0, currency: data.currency || 'USD', imgs: data.imgs || [], tags: data.tags || [], simpleDescription: data.simpleDescription || '', description: data.description || [], subcategoryId }; this.items.push(newItem); return of(newItem).pipe(delay(300)); } deleteItem(itemId: string): Observable { const index = this.items.findIndex(i => i.id === itemId); if (index > -1) this.items.splice(index, 1); return of(void 0).pipe(delay(300)); } bulkUpdateItems(itemIds: string[], data: Partial): Observable { itemIds.forEach(id => { const item = this.items.find(i => i.id === id); if (item) Object.assign(item, data); }); return of(void 0).pipe(delay(400)); } uploadImage(file: File): Observable<{ url: string }> { // Simulate upload const url = `https://via.placeholder.com/600x400?text=${encodeURIComponent(file.name)}`; return of({ url }).pipe(delay(1000)); } }