- Added AddressForm and CheckoutForm components for user input during checkout. - Implemented validation using Zod and VeeValidate for billing address fields. - Created OrderSummary and MockPayPalButton components for order confirmation and payment simulation. - Updated CartSheet and CartSidebar to navigate to the new checkout page at '/kasse'. - Introduced new API endpoints for validating checkout data and creating orders. - Enhanced user experience with responsive design and error handling. These changes complete the checkout functionality, allowing users to enter billing information, simulate payment, and confirm orders.
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
/**
|
|
* Seed test products for checkout testing
|
|
*/
|
|
import { drizzle } from 'drizzle-orm/postgres-js'
|
|
import postgres from 'postgres'
|
|
import { products, productRoleVisibility } from '../server/database/schema'
|
|
|
|
const connectionString = process.env.DATABASE_URL || 'postgresql://dev:dev_password_change_me@localhost:5432/experimenta_dev'
|
|
const client = postgres(connectionString)
|
|
const db = drizzle(client, { logger: false })
|
|
|
|
async function seedProducts() {
|
|
console.log('🌱 Seeding test products...')
|
|
|
|
// Insert test products
|
|
const testProducts = [
|
|
{
|
|
navProductId: 'MAK-001',
|
|
name: 'Makerspace Jahreskarte Erwachsene',
|
|
description: 'Jahrespass für den Makerspace - für Erwachsene ab 18 Jahren',
|
|
price: '89.00',
|
|
category: 'makerspace-annual-pass',
|
|
active: true,
|
|
stockQuantity: 100,
|
|
},
|
|
{
|
|
navProductId: 'MAK-002',
|
|
name: 'Makerspace Jahreskarte Kinder',
|
|
description: 'Jahrespass für den Makerspace - für Kinder und Jugendliche',
|
|
price: '49.00',
|
|
category: 'makerspace-annual-pass',
|
|
active: true,
|
|
stockQuantity: 100,
|
|
},
|
|
{
|
|
navProductId: 'EXP-001',
|
|
name: 'experimenta Jahreskarte',
|
|
description: 'Jahrespass für die experimenta - freier Eintritt für ein Jahr',
|
|
price: '129.00',
|
|
category: 'annual-pass',
|
|
active: true,
|
|
stockQuantity: 50,
|
|
},
|
|
]
|
|
|
|
for (const product of testProducts) {
|
|
console.log(` Adding product: ${product.name}`)
|
|
|
|
// Insert product
|
|
const [insertedProduct] = await db
|
|
.insert(products)
|
|
.values(product)
|
|
.onConflictDoUpdate({
|
|
target: products.navProductId,
|
|
set: {
|
|
name: product.name,
|
|
description: product.description,
|
|
price: product.price,
|
|
category: product.category,
|
|
active: product.active,
|
|
stockQuantity: product.stockQuantity,
|
|
updatedAt: new Date(),
|
|
},
|
|
})
|
|
.returning()
|
|
|
|
console.log(` ✓ Product ID: ${insertedProduct.id}`)
|
|
|
|
// Assign role visibility based on category
|
|
const roleMapping: Record<string, string[]> = {
|
|
'makerspace-annual-pass': ['private', 'educator'],
|
|
'annual-pass': ['private'],
|
|
'educator-annual-pass': ['educator'],
|
|
}
|
|
|
|
const roles = roleMapping[product.category] || ['private']
|
|
|
|
for (const roleCode of roles) {
|
|
await db
|
|
.insert(productRoleVisibility)
|
|
.values({
|
|
productId: insertedProduct.id,
|
|
roleCode: roleCode as 'private' | 'educator' | 'company',
|
|
})
|
|
.onConflictDoNothing()
|
|
|
|
console.log(` ✓ Assigned role: ${roleCode}`)
|
|
}
|
|
}
|
|
|
|
console.log('✅ Products seeded successfully!')
|
|
await client.end()
|
|
}
|
|
|
|
seedProducts().catch((error) => {
|
|
console.error('❌ Error seeding products:', error)
|
|
process.exit(1)
|
|
})
|