Add product detail and listing pages with API integration
- Created a new product detail page to display individual product information, including images, descriptions, and pricing. - Implemented a product listing page to showcase all available products using the ProductCard and ProductGrid components. - Added API endpoints for fetching product data, ensuring only active products are returned. - Introduced a database seed script to populate the database with initial mock product data for development and testing. - Updated settings to include new database seeding command and adjusted routing for product links.
This commit is contained in:
103
server/database/seed.ts
Normal file
103
server/database/seed.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Database Seed Script
|
||||
*
|
||||
* Seeds the database with initial mock product data for development and testing.
|
||||
* Run with: pnpm db:seed
|
||||
*/
|
||||
|
||||
import 'dotenv/config'
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import postgres from 'postgres'
|
||||
import { products } from './schema'
|
||||
|
||||
/**
|
||||
* Sample annual pass products for experimenta
|
||||
*/
|
||||
const mockProducts = [
|
||||
{
|
||||
navProductId: 'MSPACE-JK-2025',
|
||||
name: 'Makerspace Jahreskarte',
|
||||
description:
|
||||
'Unbegrenzter Zugang zum Makerspace für 365 Tage. Nutze modernste Werkzeuge, 3D-Drucker, Lasercutter und vieles mehr. Perfekt für Maker, Tüftler und kreative Köpfe.',
|
||||
price: '120.00',
|
||||
stockQuantity: 100,
|
||||
category: 'makerspace-annual-pass',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
navProductId: 'EXPERIMENTA-JK-2025',
|
||||
name: 'experimenta Jahreskarte',
|
||||
description:
|
||||
'Erlebe die Ausstellungswelt der experimenta ein ganzes Jahr lang. Mit freiem Eintritt zu allen Ausstellungen, Science Dome Shows und Sonderausstellungen.',
|
||||
price: '85.00',
|
||||
stockQuantity: 200,
|
||||
category: 'annual-pass',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
navProductId: 'PAEDAGOGEN-JK-2025',
|
||||
name: 'Pädagogen Jahreskarte',
|
||||
description:
|
||||
'Speziell für Lehrkräfte und Pädagogen. Mit exklusiven Fortbildungsangeboten, didaktischen Materialien und freiem Zugang zu allen Ausstellungen.',
|
||||
price: '60.00',
|
||||
stockQuantity: 50,
|
||||
category: 'educator-annual-pass',
|
||||
active: true,
|
||||
},
|
||||
]
|
||||
|
||||
async function seed() {
|
||||
// Get database connection from environment
|
||||
const connectionString = process.env.DATABASE_URL
|
||||
if (!connectionString) {
|
||||
throw new Error('DATABASE_URL environment variable is not set')
|
||||
}
|
||||
|
||||
console.log('🌱 Starting database seed...')
|
||||
|
||||
// Create database connection
|
||||
const client = postgres(connectionString)
|
||||
const db = drizzle(client)
|
||||
|
||||
try {
|
||||
// Insert products
|
||||
console.log(`📦 Inserting ${mockProducts.length} products...`)
|
||||
const insertedProducts = await db
|
||||
.insert(products)
|
||||
.values(mockProducts)
|
||||
.onConflictDoUpdate({
|
||||
target: products.navProductId,
|
||||
set: {
|
||||
name: mockProducts[0].name, // Drizzle requires a set object, using sql.excluded in real impl
|
||||
description: mockProducts[0].description,
|
||||
price: mockProducts[0].price,
|
||||
stockQuantity: mockProducts[0].stockQuantity,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
})
|
||||
.returning()
|
||||
|
||||
console.log(`✅ Successfully inserted/updated ${insertedProducts.length} products:`)
|
||||
insertedProducts.forEach((product) => {
|
||||
console.log(` - ${product.name} (${product.navProductId}) - €${product.price}`)
|
||||
})
|
||||
|
||||
console.log('\n✨ Database seed completed successfully!')
|
||||
} catch (error) {
|
||||
console.error('❌ Error seeding database:', error)
|
||||
throw error
|
||||
} finally {
|
||||
// Close database connection
|
||||
await client.end()
|
||||
}
|
||||
}
|
||||
|
||||
// Run seed function
|
||||
seed()
|
||||
.then(() => {
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Fatal error:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user