- 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.
90 lines
2.0 KiB
TypeScript
90 lines
2.0 KiB
TypeScript
/**
|
|
* GET /api/orders/[id]
|
|
*
|
|
* Fetch order details by ID
|
|
*
|
|
* Security:
|
|
* - Requires authentication
|
|
* - Users can only access their own orders
|
|
*
|
|
* Response:
|
|
* {
|
|
* id: string
|
|
* orderNumber: string
|
|
* totalAmount: string
|
|
* status: string
|
|
* billingAddress: BillingAddress
|
|
* items: OrderItem[]
|
|
* createdAt: Date
|
|
* }
|
|
*/
|
|
|
|
import { eq, and } from 'drizzle-orm'
|
|
import { orders, orderItems } 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 with items
|
|
const order = await db.query.orders.findFirst({
|
|
where: and(eq(orders.id, orderId), eq(orders.userId, user.id)),
|
|
with: {
|
|
items: {
|
|
with: {
|
|
product: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if (!order) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Order not found',
|
|
})
|
|
}
|
|
|
|
// Transform items to include price and product snapshot data
|
|
const transformedItems = order.items.map((item: any) => ({
|
|
id: item.id,
|
|
orderId: item.orderId,
|
|
productId: item.productId,
|
|
quantity: item.quantity,
|
|
priceSnapshot: item.priceSnapshot,
|
|
productSnapshot: item.productSnapshot,
|
|
product: {
|
|
id: item.product.id,
|
|
name: item.product.name,
|
|
description: item.product.description,
|
|
imageUrl: item.product.imageUrl,
|
|
},
|
|
subtotal: Number.parseFloat(item.priceSnapshot) * item.quantity,
|
|
}))
|
|
|
|
return {
|
|
id: order.id,
|
|
orderNumber: order.orderNumber,
|
|
totalAmount: order.totalAmount,
|
|
status: order.status,
|
|
billingAddress: order.billingAddress,
|
|
items: transformedItems,
|
|
paymentId: order.paymentId,
|
|
paymentCompletedAt: order.paymentCompletedAt,
|
|
createdAt: order.createdAt,
|
|
updatedAt: order.updatedAt,
|
|
}
|
|
})
|