From b823c1b58da8cd42c2ae014620770c04b258a23a Mon Sep 17 00:00:00 2001 From: Dokril Date: Sat, 6 Dec 2025 11:20:38 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D1=82=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=B8=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85,=20DTO=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BA=D0=B0=D1=82=D0=B5=D0=B3=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=B9=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B6=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=D0=B8=D0=B9=20=D0=B8=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/seed.ts | 120 +++++++++++++++++++++++ backend/src/wishlist/dto/category.dto.ts | 2 +- frontend/src/components/EventForm.tsx | 17 ++-- 3 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 backend/seed.ts diff --git a/backend/seed.ts b/backend/seed.ts new file mode 100644 index 0000000..c8966c3 --- /dev/null +++ b/backend/seed.ts @@ -0,0 +1,120 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './src/app.module'; +import { WishlistCategoriesService } from './src/wishlist/categories.service'; +import { WishlistService } from './src/wishlist/wishlist.service'; + +async function seed() { + const app = await NestFactory.createApplicationContext(AppModule); + + const categoriesService = app.get(WishlistCategoriesService); + const wishlistService = app.get(WishlistService); + + console.log('🌱 Seeding wishlist categories...'); + + // Создать категории + const category1 = await categoriesService.create({ + name: 'БЮДЖЕТНО', + slug: 'tier-1', + minPrice: 0, + maxPrice: 150000, // 1500 руб + color: '#00ff41', + icon: '🟢', + order: 1, + }); + + const category2 = await categoriesService.create({ + name: 'СРЕДНИЙ', + slug: 'tier-2', + minPrice: 150001, + maxPrice: 500000, // 5000 руб + color: '#00cc33', + icon: '🟡', + order: 2, + }); + + const category3 = await categoriesService.create({ + name: 'ТОП', + slug: 'tier-3', + minPrice: 500001, + maxPrice: null, // без ограничения + color: '#009922', + icon: '🔴', + order: 3, + }); + + console.log(`✅ Created 3 categories`); + + console.log('🌱 Seeding wishlist items...'); + + // Создать примерные товары + await wishlistService.create({ + title: 'Зерновой Кофе (Эфиопия)', + description: 'Люблю светлую обжарку. Желательно Эфиопия или Кения. Нужен именно в зернах.', + price: 85000, // 850 руб + currency: 'RUB', + link: 'https://ozon.ru', + imageUrls: ['https://images.unsplash.com/photo-1497935586351-b67a49e012bf?w=500'], + categoryId: category1.id, + }); + + await wishlistService.create({ + title: 'Молескин в точку', + description: 'Черный, классический. Обязательно в точку, а не в линейку.', + price: 120000, // 1200 руб + currency: 'RUB', + link: 'https://wildberries.ru', + imageUrls: ['https://images.unsplash.com/photo-1531346878377-a513bc957374?w=500'], + categoryId: category1.id, + }); + + await wishlistService.create({ + title: 'Винил: Daft Punk', + description: 'Альбом "Random Access Memories". Мечтаю послушать его на проигрывателе.', + price: 350000, // 3500 руб + currency: 'RUB', + link: 'https://market.yandex.ru', + imageUrls: ['https://images.unsplash.com/photo-1603048588665-791ca8aea617?w=500'], + categoryId: category2.id, + }); + + await wishlistService.create({ + title: 'D&D Стартовый набор', + description: '5-я редакция. Хочу попробовать поиграть с друзьями.', + price: 290000, // 2900 руб + currency: 'RUB', + link: 'https://hobbygames.ru', + imageUrls: ['https://images.unsplash.com/photo-1632501641765-e568d90e09b2?w=500'], + categoryId: category2.id, + }); + + await wishlistService.create({ + title: 'LEGO Speed Champions', + description: 'Любая машинка из этой серии, желательно Porsche или Ferrari.', + price: 250000, // 2500 руб + currency: 'RUB', + link: 'https://detmir.ru', + imageUrls: ['https://images.unsplash.com/photo-1585366119957-e9730b6d0f60?w=500'], + categoryId: category2.id, + }); + + await wishlistService.create({ + title: 'Keychron K2', + description: 'Механическая клавиатура. Свичи Red или Brown. Нужна подсветка.', + price: 900000, // 9000 руб + currency: 'RUB', + link: 'https://geekboards.ru', + imageUrls: ['https://images.unsplash.com/photo-1595225476474-87563907a212?w=500'], + categoryId: category3.id, + }); + + console.log(`✅ Created 6 wishlist items`); + console.log('✨ Seeding completed!'); + + await app.close(); + process.exit(0); +} + +seed().catch((error) => { + console.error('❌ Seeding failed:', error); + process.exit(1); +}); diff --git a/backend/src/wishlist/dto/category.dto.ts b/backend/src/wishlist/dto/category.dto.ts index 2406f9e..ef66c79 100644 --- a/backend/src/wishlist/dto/category.dto.ts +++ b/backend/src/wishlist/dto/category.dto.ts @@ -4,7 +4,7 @@ export const CreateWishlistCategorySchema = z.object({ name: z.string().min(1).max(100), slug: z.string().regex(/^[a-z0-9-]+$/), minPrice: z.number().int().min(0).default(0), - maxPrice: z.number().int().positive().optional(), + maxPrice: z.number().int().positive().optional().nullable(), color: z.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(), icon: z.string().optional(), order: z.number().int().default(0), diff --git a/frontend/src/components/EventForm.tsx b/frontend/src/components/EventForm.tsx index 139b49e..7686859 100644 --- a/frontend/src/components/EventForm.tsx +++ b/frontend/src/components/EventForm.tsx @@ -51,11 +51,10 @@ export function EventForm({ onEventCreated }: EventFormProps) { setEventType('recurring'); setFormData({ ...formData, startYear: undefined, endYear: undefined, endMonth: undefined, endDay: undefined }); }} - className={`px-4 py-2 rounded-lg font-medium transition-colors ${ - eventType === 'recurring' + className={`px-4 py-2 rounded-lg font-medium transition-colors ${eventType === 'recurring' ? 'bg-blue-600 text-white' : 'bg-gray-800 text-gray-400 hover:bg-gray-700' - }`} + }`} > Праздник (ежегодно) @@ -65,22 +64,20 @@ export function EventForm({ onEventCreated }: EventFormProps) { setEventType('anniversary'); setFormData({ ...formData, endYear: undefined, endMonth: undefined, endDay: undefined }); }} - className={`px-4 py-2 rounded-lg font-medium transition-colors ${ - eventType === 'anniversary' + className={`px-4 py-2 rounded-lg font-medium transition-colors ${eventType === 'anniversary' ? 'bg-blue-600 text-white' : 'bg-gray-800 text-gray-400 hover:bg-gray-700' - }`} + }`} > Годовщина (с годом) @@ -116,7 +113,7 @@ export function EventForm({ onEventCreated }: EventFormProps) { setFormData({