Enhance checkout flow with new components and validation

- 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.
This commit is contained in:
Bastian Masanek
2025-11-03 15:38:16 +01:00
parent 47fe14c6cc
commit 527379a2cd
44 changed files with 4957 additions and 142 deletions

View File

@@ -0,0 +1,85 @@
/**
* POST /api/orders/confirm/[id]
*
* Confirm an order after mock payment
*
* Security:
* - Requires authentication
* - Users can only confirm their own orders
* - Order must be in 'pending' status
*
* Behavior:
* - Updates order status: 'pending' → 'completed'
* - Stores completion timestamp
* - Clears user's cart
* - Returns order details
*
* Response:
* {
* success: true
* order: Order
* message: string
* }
*/
import { eq, and } from 'drizzle-orm'
import { orders, cartItems } from '../../../database/schema'
export default defineEventHandler(async (event) => {
// Require authentication
const { user } = await requireUserSession(event)
// Get order ID from URL parameter
const orderId = getRouterParam(event, 'id')
if (!orderId) {
throw createError({
statusCode: 400,
statusMessage: 'Order ID is required',
})
}
const db = useDatabase()
// Fetch order
const order = await db.query.orders.findFirst({
where: and(eq(orders.id, orderId), eq(orders.userId, user.id)),
})
if (!order) {
throw createError({
statusCode: 404,
statusMessage: 'Order not found',
})
}
// Validate order status
if (order.status !== 'pending') {
throw createError({
statusCode: 400,
statusMessage: `Order cannot be confirmed. Current status: ${order.status}`,
})
}
// Update order status to completed
const [updatedOrder] = await db
.update(orders)
.set({
status: 'completed',
paymentCompletedAt: new Date(),
paymentId: `MOCK-${Date.now()}`, // Mock payment ID
updatedAt: new Date(),
})
.where(eq(orders.id, orderId))
.returning()
// Clear user's cart
const cart = await getOrCreateCart(event)
await db.delete(cartItems).where(eq(cartItems.cartId, cart.id))
return {
success: true,
order: updatedOrder,
message: 'Bestellung erfolgreich bestätigt',
}
})