diff --git a/bo/src/components/admin/PageProductsList.vue b/bo/src/components/admin/PageProductsList.vue
index 4f3dfb1..8482ed4 100644
--- a/bo/src/components/admin/PageProductsList.vue
+++ b/bo/src/components/admin/PageProductsList.vue
@@ -121,4 +121,5 @@ function goToProduct(productId: number) {
params: { id: productId }
})
}
-
\ No newline at end of file
+
+
diff --git a/bo/src/components/customer/Cart1.vue b/bo/src/components/customer/Cart1.vue
deleted file mode 100644
index 2ae6fbd..0000000
--- a/bo/src/components/customer/Cart1.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
- {{ t('Cart Items') }}
-
-
-
-
-
-
-
![]()
-
-
-
{{ item.name }}
-
{{ item.product_number }}
-
${{ (item.price * item.quantity).toFixed(2) }}
-
-
-
-
-
-
-
-
{{ t('Your cart is empty') }}
-
-
-
-
- {{ t('Continue to Checkout') }}
-
-
- {{ t('Cancel') }}
-
-
-
-
-
-
-
diff --git a/bo/src/components/customer/CartSelector.vue b/bo/src/components/customer/CartSelector.vue
new file mode 100644
index 0000000..6025d8c
--- /dev/null
+++ b/bo/src/components/customer/CartSelector.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ t('Create New Cart') }}
+
+
+
+
+
+
+ {{ t('Cancel') }}
+
+
+ {{ t('Create and Continue') }}
+
+
+
+
+
+
+
+
{{ t('Edit Cart Name') }}
+
+
+
+
+
+
+ {{ t('Cancel') }}
+
+
+ {{ t('Save') }}
+
+
+
+
+
+
+
+
{{ t('Delete Cart') }}
+
+ {{ t('Are you sure you want to delete') }} "{{ deletingCart.name }}"?
+
+
+
+ {{ t('Cancel') }}
+
+
+ {{ t('Delete') }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bo/src/components/customer/PageCart.vue b/bo/src/components/customer/PageCart.vue
index 833e0a5..971e175 100644
--- a/bo/src/components/customer/PageCart.vue
+++ b/bo/src/components/customer/PageCart.vue
@@ -188,10 +188,7 @@ function removeItem(itemId: number) {
function placeOrder() {
if (canPlaceOrder.value) {
- console.log('Placing order...')
- alert(t('Order placed successfully!'))
- cartStore.clearCart()
- router.push({ name: 'home' })
+ router.push({ name: 'checkout' })
}
}
diff --git a/bo/src/components/customer/PageCarts.vue b/bo/src/components/customer/PageCarts.vue
new file mode 100644
index 0000000..4c4bd3a
--- /dev/null
+++ b/bo/src/components/customer/PageCarts.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+ {{ t('Shopping') }}
+
+
{{
+ cartStore.activeCart?.name }}
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+ {{ item.name }}
+
+
+ {{ item.product_number }}
+
+
+ ${{ item.price.toFixed(2) }}
+
+
+
+ ${{ (item.price * item.quantity).toFixed(2) }}
+
+
+
cartStore.updateQuantity(item.id, val)" />
+
+
+
+
+
+
+
+
+
+
+
{{ t('Your cart is empty') }}
+
+ {{ t('Continue Shopping') }}
+
+
+
+
+
+ {{ t('Continue to Checkout') }}
+
+
+ {{ t('Cancel') }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bo/src/components/customer/PageCheckout.vue b/bo/src/components/customer/PageCheckout.vue
new file mode 100644
index 0000000..3597186
--- /dev/null
+++ b/bo/src/components/customer/PageCheckout.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+ {{ t('Checkout') }}
+
+
+
+
+
+ {{ t('Order Summary') }}
+
+
+
+ {{ t('Products') }}
+ {{ cartStore.items.length }} {{ t('items')
+ }}
+
+
+ {{ t('Products total') }}
+ ${{ cartStore.productsTotal.toFixed(2)
+ }}
+
+
+ {{ t('VAT') }}
+ ${{ cartStore.vatAmount.toFixed(2) }}
+
+
+
+
+ {{ t('Total') }}
+
+ ${{ cartStore.orderTotal.toFixed(2) }}
+
+
+
+
+
+
+
![]()
+
+
+
{{ item.name }}
+
x{{ item.quantity }}
+
${{ (item.price * item.quantity).toFixed(2)
+ }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bo/src/router/index.ts b/bo/src/router/index.ts
index 7727497..d7cef2e 100644
--- a/bo/src/router/index.ts
+++ b/bo/src/router/index.ts
@@ -33,7 +33,8 @@ const router = createRouter({
{ path: 'customer-data', component: () => import('@/components/customer/PageCustomerData.vue'), name: 'customer-data' },
{ path: 'create-account', component: () => import('@/components/customer/PageCreateAccount.vue'), name: 'create-account' },
{ path: 'cart', component: () => import('@/components/customer/PageCart.vue'), name: 'cart' },
- { path: 'cart1', component: () => import('@/components/customer/Cart1.vue'), name: 'cart1' },
+ { path: 'carts', component: () => import('@/components/customer/PageCarts.vue'), name: 'carts' },
+ { path: 'checkout', component: () => import('@/components/customer/PageCheckout.vue'), name: 'checkout' },
{ path: 'products-list', component: () => import('@/components/admin/PageProductsList.vue'), name: 'products-list' },
{ path: 'login', component: () => import('@/views/LoginView.vue'), name: 'login', meta: { guest: true, } },
{ path: 'register', component: () => import('@/views/RegisterView.vue'), name: 'register', meta: { guest: true } },
diff --git a/bo/src/stores/cart.ts b/bo/src/stores/cart.ts
index e2e9577..e43e416 100644
--- a/bo/src/stores/cart.ts
+++ b/bo/src/stores/cart.ts
@@ -18,8 +18,16 @@ export interface DeliveryMethod {
description: string
}
+export interface Cart {
+ id: string
+ name: string
+ items: CartItem[]
+}
+
export const useCartStore = defineStore('cart', () => {
- const items = ref
([])
+ const carts = ref([])
+ const activeCartId = ref(null)
+
const selectedAddressId = ref(null)
const selectedDeliveryMethodId = ref(null)
const shippingCost = ref(0)
@@ -31,13 +39,15 @@ export const useCartStore = defineStore('cart', () => {
{ id: 3, name: 'Priority Delivery', price: 30, description: 'Next business day' }
])
- function initMockData() {
- items.value = [
- { id: 1, productId: 101, name: 'Premium Widget Pro', product_number: 'NC209/7000', image: '/img/product-1.jpg', price: 129.99, quantity: 2 },
- { id: 2, productId: 102, name: 'Ultra Gadget X', product_number: 'NC234/6453', image: '/img/product-2.jpg', price: 89.50, quantity: 1 },
- { id: 3, productId: 103, name: 'Mega Tool Set', product_number: 'NC324/9030', image: '/img/product-3.jpg', price: 249.00, quantity: 3 }
- ]
- }
+ const items = computed(() => {
+ if (!activeCartId.value) return []
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ return cart ? cart.items : []
+ })
+
+ const activeCart = computed(() => {
+ return carts.value.find(c => c.id === activeCartId.value) || null
+ })
const productsTotal = computed(() => {
return items.value.reduce((sum, item) => sum + (item.price * item.quantity), 0)
@@ -55,8 +65,63 @@ export const useCartStore = defineStore('cart', () => {
return items.value.reduce((sum, item) => sum + item.quantity, 0)
})
+ function createCart(name: string): Cart {
+ const newCart: Cart = {
+ id: `cart-${Date.now()}`,
+ name,
+ items: []
+ }
+ carts.value.push(newCart)
+ activeCartId.value = newCart.id
+
+ return newCart
+ }
+
+ function deleteCart(cartId: string) {
+ const index = carts.value.findIndex(c => c.id === cartId)
+ if (index !== -1) {
+ carts.value.splice(index, 1)
+ if (activeCartId.value === cartId) {
+ const firstCart = carts.value[0]
+ activeCartId.value = firstCart ? firstCart.id : null
+ }
+ }
+ }
+
+ function renameCart(cartId: string, newName: string) {
+ const cart = carts.value.find(c => c.id === cartId)
+ if (cart) {
+ cart.name = newName
+ }
+ }
+
+ function setActiveCart(cartId: string) {
+ const cart = carts.value.find(c => c.id === cartId)
+ if (cart) {
+ activeCartId.value = cartId
+ }
+ }
+
+ function addItemToActiveCart(item: CartItem) {
+ if (!activeCartId.value) {
+ createCart('Cart 1')
+ }
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ if (cart) {
+ const existingItem = cart.items.find(i => i.productId === item.productId)
+ if (existingItem) {
+ existingItem.quantity += item.quantity
+ } else {
+ cart.items.push(item)
+ }
+ }
+ }
+
function updateQuantity(itemId: number, quantity: number) {
- const item = items.value.find(i => i.id === itemId)
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ if (!cart) return
+
+ const item = cart.items.find(i => i.id === itemId)
if (item) {
if (quantity <= 0) {
removeItem(itemId)
@@ -67,12 +132,14 @@ export const useCartStore = defineStore('cart', () => {
}
function deleteProduct(id: number): boolean {
- const index = items.value.findIndex(a => a.id === id)
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ if (!cart) return false
+
+ const index = cart.items.findIndex(a => a.id === id)
if (index === -1) return false
- items.value.splice(index, 1)
+ cart.items.splice(index, 1)
resetProductPagination()
-
return true
}
@@ -81,14 +148,20 @@ export const useCartStore = defineStore('cart', () => {
}
function removeItem(itemId: number) {
- const index = items.value.findIndex(i => i.id === itemId)
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ if (!cart) return
+
+ const index = cart.items.findIndex(i => i.id === itemId)
if (index !== -1) {
- items.value.splice(index, 1)
+ cart.items.splice(index, 1)
}
}
function clearCart() {
- items.value = []
+ const cart = carts.value.find(c => c.id === activeCartId.value)
+ if (cart) {
+ cart.items = []
+ }
selectedAddressId.value = null
selectedDeliveryMethodId.value = null
shippingCost.value = 0
@@ -106,9 +179,40 @@ export const useCartStore = defineStore('cart', () => {
}
}
+ function initMockData() {
+ const cart1: Cart = {
+ id: 'cart-1',
+ name: 'Cart 1',
+ items: [
+ { id: 1, productId: 101, name: 'Premium Widget Pro', product_number: 'NC209/7000', image: '/img/product-1.jpg', price: 129.99, quantity: 2 },
+ { id: 2, productId: 102, name: 'Ultra Gadget X', product_number: 'NC234/6453', image: '/img/product-2.jpg', price: 89.50, quantity: 1 }
+ ]
+ }
+
+ const cart2: Cart = {
+ id: 'cart-2',
+ name: 'Cart 2',
+ items: [
+ { id: 3, productId: 103, name: 'Mega Tool Set', product_number: 'NC324/9030', image: '/img/product-3.jpg', price: 249.00, quantity: 3 }
+ ]
+ }
+
+ const cart3: Cart = {
+ id: 'cart-3',
+ name: 'Cart 3',
+ items: []
+ }
+
+ carts.value = [cart1, cart2, cart3]
+ activeCartId.value = 'cart-1'
+ }
+
initMockData()
return {
+ carts,
+ activeCartId,
+ activeCart,
items,
selectedAddressId,
selectedDeliveryMethodId,
@@ -119,8 +223,14 @@ export const useCartStore = defineStore('cart', () => {
vatAmount,
orderTotal,
itemCount,
- deleteProduct,
+
+ createCart,
+ deleteCart,
+ renameCart,
+ setActiveCart,
+ addItemToActiveCart,
updateQuantity,
+ deleteProduct,
removeItem,
clearCart,
setSelectedAddress,