diff --git a/bo/src/components/TopBar.vue b/bo/src/components/TopBar.vue index 856bf7d..6f0b00d 100644 --- a/bo/src/components/TopBar.vue +++ b/bo/src/components/TopBar.vue @@ -28,6 +28,9 @@ const authStore = useAuthStore() Addresses + + Cart +
diff --git a/bo/src/components/customer/PageCart.vue b/bo/src/components/customer/PageCart.vue index ea5d2bc..06f1b5f 100644 --- a/bo/src/components/customer/PageCart.vue +++ b/bo/src/components/customer/PageCart.vue @@ -1,9 +1,218 @@ \ No newline at end of file +const cartStore = useCartStore() +const addressStore = useAddressStore() +const { t } = useI18n() +const router = useRouter() + +const selectedAddress = ref(cartStore.selectedAddressId) +const selectedDeliveryMethod = ref(cartStore.selectedDeliveryMethodId) +const addressSearchQuery = ref('') + +watch(addressSearchQuery, (val) => { + addressStore.setSearchQuery(val) +}) + +watch(selectedAddress, (newValue) => { + cartStore.setSelectedAddress(newValue) +}) + +watch(selectedDeliveryMethod, (newValue) => { + if (newValue) { + cartStore.setDeliveryMethod(newValue) + } +}) + +const canPlaceOrder = computed(() => { + return cartStore.items.length > 0 && + cartStore.selectedAddressId !== null && + cartStore.selectedDeliveryMethodId !== null +}) + +function increaseQuantity(item: CartItem) { + cartStore.updateQuantity(item.id, item.quantity + 1) +} + +function decreaseQuantity(item: CartItem) { + cartStore.updateQuantity(item.id, item.quantity - 1) +} + +function removeItem(itemId: number) { + cartStore.removeItem(itemId) +} + +function placeOrder() { + if (canPlaceOrder.value) { + console.log('Placing order...') + alert(t('Order placed successfully!')) + cartStore.clearCart() + router.push({ name: 'home' }) + } +} + +function cancelOrder() { + router.back() +} + diff --git a/bo/src/router/index.ts b/bo/src/router/index.ts index eed2bb9..f205fa4 100644 --- a/bo/src/router/index.ts +++ b/bo/src/router/index.ts @@ -33,6 +33,7 @@ const router = createRouter({ { path: 'products-datail/', component: () => import('../components/admin/ProductDetailView.vue'), name: 'product-detail' }, { path: 'product-card-full/', component: () => import('../components/customer/PageProductCardFull.vue'), name: 'product-card-full' }, { path: 'addresses', component: () => import('../components/customer/PageAddresses.vue'), name: 'addresses' }, + { path: 'cart', component: () => import('../components/customer/PageCart.vue'), name: 'cart' }, ], }, { diff --git a/bo/src/stores/cart.ts b/bo/src/stores/cart.ts new file mode 100644 index 0000000..e9fcff5 --- /dev/null +++ b/bo/src/stores/cart.ts @@ -0,0 +1,113 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' + +export interface CartItem { + id: number + productId: number + name: string + image: string + price: number + quantity: number +} + +export interface DeliveryMethod { + id: number + name: string + price: number + description: string +} + +export const useCartStore = defineStore('cart', () => { + const items = ref([]) + const selectedAddressId = ref(null) + const selectedDeliveryMethodId = ref(null) + const shippingCost = ref(0) + const vatRate = ref(0.23) // 23% VAT + + const deliveryMethods = ref([ + { id: 1, name: 'Standard Delivery', price: 0, description: '5-7 business days' }, + { id: 2, name: 'Express Delivery', price: 15, description: '2-3 business days' }, + { id: 3, name: 'Priority Delivery', price: 30, description: 'Next business day' } + ]) + + function initMockData() { + items.value = [ + { id: 1, productId: 101, name: 'Premium Widget Pro', image: '/img/product-1.jpg', price: 129.99, quantity: 2 }, + { id: 2, productId: 102, name: 'Ultra Gadget X', image: '/img/product-2.jpg', price: 89.50, quantity: 1 }, + { id: 3, productId: 103, name: 'Mega Tool Set', image: '/img/product-3.jpg', price: 249.00, quantity: 3 } + ] + } + + const productsTotal = computed(() => { + return items.value.reduce((sum, item) => sum + (item.price * item.quantity), 0) + }) + + const vatAmount = computed(() => { + return productsTotal.value * vatRate.value + }) + + const orderTotal = computed(() => { + return productsTotal.value + shippingCost.value + vatAmount.value + }) + + const itemCount = computed(() => { + return items.value.reduce((sum, item) => sum + item.quantity, 0) + }) + + function updateQuantity(itemId: number, quantity: number) { + const item = items.value.find(i => i.id === itemId) + if (item) { + if (quantity <= 0) { + removeItem(itemId) + } else { + item.quantity = quantity + } + } + } + + function removeItem(itemId: number) { + const index = items.value.findIndex(i => i.id === itemId) + if (index !== -1) { + items.value.splice(index, 1) + } + } + + function clearCart() { + items.value = [] + selectedAddressId.value = null + selectedDeliveryMethodId.value = null + shippingCost.value = 0 + } + + function setSelectedAddress(addressId: number | null) { + selectedAddressId.value = addressId + } + + function setDeliveryMethod(methodId: number) { + selectedDeliveryMethodId.value = methodId + const method = deliveryMethods.value.find(m => m.id === methodId) + if (method) { + shippingCost.value = method.price + } + } + + initMockData() + + return { + items, + selectedAddressId, + selectedDeliveryMethodId, + shippingCost, + vatRate, + deliveryMethods, + productsTotal, + vatAmount, + orderTotal, + itemCount, + updateQuantity, + removeItem, + clearCart, + setSelectedAddress, + setDeliveryMethod + } +})