4 ProductFilters, ProductSort, PaginationParams, PaginatedResponse
5} from "../../shared/types.ts";
6import { getImageUrl } from "../../shared/utils.ts";
7
8// User queries
80 slug: row.slug,
81 description: row.description,
82 imageUrl: row.image_url,
83 productCount: row.product_count
84 }));
99 slug: category.slug,
100 description: category.description,
101 imageUrl: category.image_url,
102 productCount: 0 // Will be filled separately if needed
103 };
180 category: row.category_name || 'Uncategorized',
181 brand: row.brand,
182 imageUrl: getImageUrl(row.image_url),
183 images: row.images ? JSON.parse(row.images).map(getImageUrl) : [getImageUrl(row.image_url)],
184 inStock: Boolean(row.in_stock),
185 stockQuantity: row.stock_quantity,
224 category: row.category_name || 'Uncategorized',
225 brand: row.brand,
226 imageUrl: getImageUrl(row.image_url),
227 images: row.images ? JSON.parse(row.images).map(getImageUrl) : [getImageUrl(row.image_url)],
228 inStock: Boolean(row.in_stock),
229 stockQuantity: row.stock_quantity,
265 category: row.category_name || 'Uncategorized',
266 brand: row.brand,
267 imageUrl: getImageUrl(row.image_url),
268 images: row.images ? JSON.parse(row.images).map(getImageUrl) : [getImageUrl(row.image_url)],
269 inStock: Boolean(row.in_stock),
270 stockQuantity: row.stock_quantity,
312 category: row.category_name || 'Uncategorized',
313 brand: row.brand,
314 imageUrl: getImageUrl(row.image_url),
315 images: row.images ? JSON.parse(row.images).map(getImageUrl) : [getImageUrl(row.image_url)],
316 inStock: Boolean(row.in_stock),
317 stockQuantity: row.stock_quantity,
471 // Get order items
472 const itemsResult = await sqlite.execute(`
473 SELECT oi.*, p.name, p.description, p.image_url, p.brand
474 FROM order_items oi
475 JOIN products p ON oi.product_id = p.id
490 category: '',
491 brand: item.brand,
492 imageUrl: getImageUrl(item.image_url),
493 images: [getImageUrl(item.image_url)],
494 inStock: true,
495 stockQuantity: 0,
25 slug TEXT UNIQUE NOT NULL,
26 description TEXT,
27 image_url TEXT,
28 created_at DATETIME DEFAULT CURRENT_TIMESTAMP
29 )
40 category_id INTEGER,
41 brand TEXT NOT NULL,
42 image_url TEXT NOT NULL,
43 images TEXT, -- JSON array of image URLs
44 in_stock BOOLEAN DEFAULT TRUE,
45 stock_quantity INTEGER DEFAULT 0,
180 categoryId: 2,
181 brand: 'Apple',
182 imageUrl: 'laptop-1.jpg',
183 images: JSON.stringify(['laptop-1.jpg', 'laptop-2.jpg', 'laptop-3.jpg']),
184 stockQuantity: 15,
185 rating: 4.8,
193 categoryId: 3,
194 brand: 'Apple',
195 imageUrl: 'phone-1.jpg',
196 images: JSON.stringify(['phone-1.jpg', 'phone-2.jpg']),
197 stockQuantity: 25,
198 rating: 4.9,
207 categoryId: 4,
208 brand: 'Sony',
209 imageUrl: 'headphones-1.jpg',
210 images: JSON.stringify(['headphones-1.jpg']),
211 stockQuantity: 30,
212 rating: 4.7,
220 categoryId: 5,
221 brand: 'Apple',
222 imageUrl: 'watch-1.jpg',
223 images: JSON.stringify(['watch-1.jpg']),
224 stockQuantity: 20,
225 rating: 4.6,
229 {
230 name: 'Canon EOS R6 Mark II',
231 description: 'Professional mirrorless camera with exceptional image quality.',
232 price: 2499.00,
233 categoryId: 6,
234 brand: 'Canon',
235 imageUrl: 'camera-1.jpg',
236 images: JSON.stringify(['camera-1.jpg']),
237 stockQuantity: 8,
238 rating: 4.9,
246 categoryId: 2,
247 brand: 'Apple',
248 imageUrl: 'tablet-1.jpg',
249 images: JSON.stringify(['tablet-1.jpg']),
250 stockQuantity: 18,
251 rating: 4.8,
259 categoryId: 4,
260 brand: 'Sonos',
261 imageUrl: 'speaker-1.jpg',
262 images: JSON.stringify(['speaker-1.jpg']),
263 stockQuantity: 35,
264 rating: 4.5,
272 categoryId: 2,
273 brand: 'Logitech',
274 imageUrl: 'keyboard-1.jpg',
275 images: JSON.stringify(['keyboard-1.jpg']),
276 stockQuantity: 50,
277 rating: 4.4,
285 INSERT INTO products (
286 name, description, price, original_price, category_id, brand,
287 image_url, images, stock_quantity, rating, review_count, featured
288 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
289 `, [
290 product.name, product.description, product.price, product.originalPrice || null,
291 product.categoryId, product.brand, product.imageUrl, product.images,
292 product.stockQuantity, product.rating, product.reviewCount, product.featured
293 ]);
106}
107
108export function getImageUrl(filename: string): string {
109 // For demo purposes, using placeholder images
110 const imageMap: Record<string, string> = {
111 'laptop-1.jpg': 'https://images.unsplash.com/photo-1496181133206-80ce9b88a853?w=500&h=500&fit=crop',
112 'phone-1.jpg': 'https://images.unsplash.com/photo-1511707171634-5f897ff02aa9?w=500&h=500&fit=crop',
113 'headphones-1.jpg': 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=500&h=500&fit=crop',
114 'watch-1.jpg': 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=500&h=500&fit=crop',
115 'camera-1.jpg': 'https://images.unsplash.com/photo-1502920917128-1aa500764cbd?w=500&h=500&fit=crop',
116 'tablet-1.jpg': 'https://images.unsplash.com/photo-1544244015-0df4b3ffc6b0?w=500&h=500&fit=crop',
117 'speaker-1.jpg': 'https://images.unsplash.com/photo-1608043152269-423dbba4e7e1?w=500&h=500&fit=crop',
118 'keyboard-1.jpg': 'https://images.unsplash.com/photo-1541140532154-b024d705b90a?w=500&h=500&fit=crop',
119 };
120
121 return imageMap[filename] || `https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=500&h=500&fit=crop&q=80`;
122}
123