diff --git a/.vscode/settings.json b/.vscode/settings.json
index 1501ec7..55c49a5 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,6 +1,7 @@
{
"i18n-ally.localesPaths": [
"layers/base/locales",
+ "layers/cart/locales",
"layers/auth/locales",
"app/locales"
],
diff --git a/app/components/header/HeaderActions.vue b/app/components/header/HeaderActions.vue
index 3bb4d8d..250e656 100644
--- a/app/components/header/HeaderActions.vue
+++ b/app/components/header/HeaderActions.vue
@@ -4,6 +4,7 @@
+
diff --git a/app/components/header/HeaderProfile.vue b/app/components/header/HeaderProfile.vue
index c3579c1..24fdab8 100644
--- a/app/components/header/HeaderProfile.vue
+++ b/app/components/header/HeaderProfile.vue
@@ -17,7 +17,6 @@ function onLogout() {
+import type { Icon } from '@wisemen/vue-core'
+import { AppIcon } from '@wisemen/vue-core'
+import type { RouteLocationRaw } from 'vue-router'
+
+import type { ButtonStyleProps } from './button.style'
+import { useButtonStyle } from './button.style'
+
+export interface AppButtonProps {
+ /**
+ * Whether the button is disabled.
+ * @default false
+ */
+ isDisabled?: boolean
+ /**
+ * Whether the button is in a loading state.
+ * @default false
+ */
+ isLoading?: boolean
+ /**
+ * The icon to display on the left side of the button.
+ * @default null
+ */
+ iconLeft?: Icon | null
+ /**
+ * The icon to display on the right side of the button.
+ * @default null
+ */
+ iconRight?: Icon | null
+ /**
+ * The size of the button.
+ * @default 'default'
+ */
+ size?: ButtonStyleProps['size']
+ to: RouteLocationRaw
+ /**
+ * The type of the button.
+ * @default 'button'
+ */
+ type?: 'button' | 'reset' | 'submit'
+ /**
+ * The variant of the button.
+ * @default 'default'
+ */
+ variant?: ButtonStyleProps['variant']
+}
+
+const props = withDefaults(defineProps(), {
+ // TODO: find out why defaulting these to `null` breaks the `Icon` prop type when using `declare module`.
+ // iconLeft: null,
+ // iconRight: null,
+ isDisabled: false,
+ isLoading: false,
+ size: 'default',
+ type: 'button',
+ variant: 'default',
+})
+
+const buttonStyle = useButtonStyle()
+
+const buttonClasses = computed(() =>
+ buttonStyle.button({
+ size: props.size,
+ variant: props.variant,
+ }))
+
+const buttonLeftIconClasses = computed(() =>
+ buttonStyle.buttonLeftIcon({
+ isLoading: props.isLoading,
+ size: props.size,
+ }))
+
+const buttonRightIconClasses = computed(() =>
+ buttonStyle.buttonRightIcon({
+ isLoading: props.isLoading,
+ size: props.size,
+ }))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layers/base/components/core/button/AppRouterLinkButton.vue b/layers/base/components/core/button/AppRouterLinkButton.vue
deleted file mode 100644
index 03a9c82..0000000
--- a/layers/base/components/core/button/AppRouterLinkButton.vue
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/layers/base/components/core/divider/AppDivider.vue b/layers/base/components/core/divider/AppDivider.vue
new file mode 100644
index 0000000..a971461
--- /dev/null
+++ b/layers/base/components/core/divider/AppDivider.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/layers/base/components/core/icon/AppIconCircle.vue b/layers/base/components/core/icon/AppIconCircle.vue
new file mode 100644
index 0000000..6413ad8
--- /dev/null
+++ b/layers/base/components/core/icon/AppIconCircle.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
diff --git a/layers/base/components/core/increment/AppIncrement.vue b/layers/base/components/core/increment/AppIncrement.vue
new file mode 100644
index 0000000..7dcc484
--- /dev/null
+++ b/layers/base/components/core/increment/AppIncrement.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
diff --git a/layers/base/components/core/increment/FormIncrement.vue b/layers/base/components/core/increment/FormIncrement.vue
new file mode 100644
index 0000000..e0f5c57
--- /dev/null
+++ b/layers/base/components/core/increment/FormIncrement.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
diff --git a/layers/base/components/seo/SeoWrapper.vue b/layers/base/components/seo/SeoWrapper.vue
index 8c0c71b..df7fd22 100644
--- a/layers/base/components/seo/SeoWrapper.vue
+++ b/layers/base/components/seo/SeoWrapper.vue
@@ -1,3 +1,4 @@
+
diff --git a/layers/base/icons/CartIcon.vue b/layers/base/icons/CartIcon.vue
new file mode 100644
index 0000000..ef9368d
--- /dev/null
+++ b/layers/base/icons/CartIcon.vue
@@ -0,0 +1,14 @@
+
+
+
diff --git a/layers/base/icons/PlusIcon.vue b/layers/base/icons/PlusIcon.vue
new file mode 100644
index 0000000..e9eb6fd
--- /dev/null
+++ b/layers/base/icons/PlusIcon.vue
@@ -0,0 +1,14 @@
+
+
+
diff --git a/layers/base/icons/TrashIcon.vue b/layers/base/icons/TrashIcon.vue
new file mode 100644
index 0000000..df83677
--- /dev/null
+++ b/layers/base/icons/TrashIcon.vue
@@ -0,0 +1,32 @@
+
+
+
diff --git a/layers/base/icons/icons.ts b/layers/base/icons/icons.ts
index a59741c..4285993 100644
--- a/layers/base/icons/icons.ts
+++ b/layers/base/icons/icons.ts
@@ -8,6 +8,7 @@ export const icons = {
arrowUp: import('@base/icons/ArrowUpIcon.vue'),
arrowUpDown: import('@base/icons/ArrowUpDownIcon.vue'),
calendar: import('@base/icons/CalendarIcon.vue'),
+ cart: import('@base/icons/CartIcon.vue'),
checkmark: import('@base/icons/CheckmarkIcon.vue'),
checkmarkCircle: import('@base/icons/CheckmarkCircleIcon.vue'),
chevronDown: import('@base/icons/ChevronDownIcon.vue'),
@@ -22,8 +23,10 @@ export const icons = {
instagram: import('@base/icons/InstagramIcon.vue'),
linkedIn: import('@base/icons/LinkedInIcon.vue'),
minus: import('@base/icons/MinusIcon.vue'),
+ plus: import('@base/icons/PlusIcon.vue'),
profile: import('@base/icons/ProfileIcon.vue'),
search: import('@base/icons/SearchIcon.vue'),
+ trash: import('@base/icons/TrashIcon.vue'),
twitter: import('@base/icons/TwitterIcon.vue'),
warning: import('@base/icons/WarningIcon.vue'),
} as const
diff --git a/layers/base/mocks/address.mock.ts b/layers/base/mocks/address.mock.ts
new file mode 100644
index 0000000..4f38576
--- /dev/null
+++ b/layers/base/mocks/address.mock.ts
@@ -0,0 +1,29 @@
+import {
+ createEmail,
+ createString,
+} from '@base/mocks/utils.mock'
+import type { Address } from '@base/models/address/address.model'
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+
+export function createAddress(overrides: Partial = {}): Address {
+ return {
+ id: generateUuid(),
+ box: createString(12),
+ city: createString(12),
+ country: createString(12),
+ email: createEmail(),
+ label: createString(12),
+ number: createString(12),
+ postalCode: createString(12),
+ street: createString(12),
+ types: [
+ 'delivery',
+ 'invoice',
+ ].splice(Math.floor(Math.random() * 2), 1),
+ ...overrides,
+ } as Address
+}
+
+export function createAddresses(count: number): Address[] {
+ return Array.from({ length: count }, () => createAddress())
+}
diff --git a/layers/base/mocks/api.mock.ts b/layers/base/mocks/api.mock.ts
new file mode 100644
index 0000000..53f628e
--- /dev/null
+++ b/layers/base/mocks/api.mock.ts
@@ -0,0 +1,3 @@
+export function createApiMock(data: T): Promise {
+ return Promise.resolve(data)
+}
diff --git a/layers/base/mocks/paginatedData.mock.ts b/layers/base/mocks/paginatedData.mock.ts
new file mode 100644
index 0000000..0cd37f9
--- /dev/null
+++ b/layers/base/mocks/paginatedData.mock.ts
@@ -0,0 +1,14 @@
+import type {
+ PaginatedApiData,
+} from '@base/models/paginated-data/paginatedApiData.model'
+
+export function createPaginatedData(data: T[]): PaginatedApiData {
+ return {
+ data,
+ pagination: {
+ count: data.length,
+ perPage: 20,
+ total: data.length,
+ },
+ } satisfies PaginatedApiData
+}
diff --git a/layers/base/mocks/utils.mock.ts b/layers/base/mocks/utils.mock.ts
new file mode 100644
index 0000000..64c9f5b
--- /dev/null
+++ b/layers/base/mocks/utils.mock.ts
@@ -0,0 +1,34 @@
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+
+export function createString(length: number = 12): string {
+ return Math.random().toString(36).substring(2, length + 2)
+}
+
+export function createNumber(min: number = 0, max: number = 1000): number {
+ // whole number
+ if (min % 1 === 0 && max % 1 === 0) {
+ return Math.floor(Math.random() * (max - min + 1) + min)
+ }
+
+ return Math.random() * (max - min) + min
+}
+
+export function createBoolean(): boolean {
+ return Math.random() < 0.5
+}
+
+export function createUuid(): string {
+ return generateUuid()
+}
+
+export function createDate(): Date {
+ const date = new Date()
+
+ date.setFullYear(date.getFullYear() - Math.floor(Math.random() * 10))
+
+ return date
+}
+
+export function createEmail(): string {
+ return `${createString(8)}@${createString(8)}.com`
+}
diff --git a/layers/base/models/paginated-data/paginatedData.model.ts b/layers/base/models/paginated-data/paginatedApiData.model.ts
similarity index 69%
rename from layers/base/models/paginated-data/paginatedData.model.ts
rename to layers/base/models/paginated-data/paginatedApiData.model.ts
index eeeabb7..209b93b 100644
--- a/layers/base/models/paginated-data/paginatedData.model.ts
+++ b/layers/base/models/paginated-data/paginatedApiData.model.ts
@@ -1,6 +1,6 @@
import { z } from 'zod'
-export function paginatedDataSchema(
+export function paginatedApiDataSchema(
schema: T,
) {
return z.object({
@@ -13,11 +13,11 @@ export function paginatedDataSchema(
})
}
-export interface PaginatedData {
+export interface PaginatedApiData {
data: TSchema[]
pagination: {
count: number
- per_page: number
+ perPage: number
total: number
}
}
diff --git a/layers/base/utils/uuid/generateUuid.util.ts b/layers/base/utils/uuid/generateUuid.util.ts
new file mode 100644
index 0000000..cfe3c2d
--- /dev/null
+++ b/layers/base/utils/uuid/generateUuid.util.ts
@@ -0,0 +1,9 @@
+export function generateUuid(): string {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
+ const r = (Math.random() * 16) | 0
+
+ const v = c === 'x' ? r : (r & 0x3) | 0x8
+
+ return v.toString(16)
+ })
+}
diff --git a/layers/cart/api/cart/services/cart.service.ts b/layers/cart/api/cart/services/cart.service.ts
index 13b8d5c..3c7fe56 100644
--- a/layers/cart/api/cart/services/cart.service.ts
+++ b/layers/cart/api/cart/services/cart.service.ts
@@ -1,63 +1,76 @@
-import { useApi } from '@base/composables/api/useApi'
+import { createApiMock } from '@base/mocks/api.mock'
+import { createCart } from '@cart/mocks/cart.mock'
import type { CartAddForm } from '@cart/models/cart/add/cartAddForm.model'
import type { CartAddBulkForm } from '@cart/models/cart/add-bulk/cartAddBulkForm.model'
-import { CartTransformer } from '@cart/models/cart/cart.transformer'
import type { Cart } from '@cart/models/cart/get/cart.model'
-import { cartDtoSchema } from '@cart/models/cart/get/cartDto.model'
import type { CartRemoveForm } from '@cart/models/cart/remove/cartRemoveForm.model'
import type { CartUpdateForm } from '@cart/models/cart/update/cartUpdateForm.model'
export class CartService {
- static async add(addForm: CartAddForm): Promise {
- const api = useApi()
- const data = await api.post({
- body: CartTransformer.toAddDto(addForm),
- responseSchema: cartDtoSchema,
- url: `/cart/${addForm.cartId}/items`,
- })
-
- return CartTransformer.toCart(data)
+ static async add(_addForm: CartAddForm): Promise {
+ // const api = useApi()
+ // const body = CartTransformer.toAddDto(addForm)
+ // return CartTransformer.toCart(response)
+ const response = await createApiMock(createCart())
+
+ return response
}
- static async addBulk(addForm: CartAddBulkForm): Promise {
- const api = useApi()
- const data = await api.post({
- body: CartTransformer.toAddBulkDto(addForm),
- responseSchema: cartDtoSchema,
- url: `/cart/${addForm.cartId}/items/bulk`,
- })
+ static async addBulk(_addForm: CartAddBulkForm): Promise {
+ // const api = useApi()
+ // const data = await api.post({
+ // body: CartTransformer.toAddBulkDto(addForm),
+ // responseSchema: cartDtoSchema,
+ // url: `/cart/${addForm.cartId}/items/bulk`,
+ // })
+
+ // return CartTransformer.toCart(data)
+
+ const response = await createApiMock(createCart())
- return CartTransformer.toCart(data)
+ return response
}
static async get(): Promise {
- const api = useApi()
- const data = await api.get({
- responseSchema: cartDtoSchema,
- url: `/cart`,
- })
+ // const api = useApi()
+ // const data = await api.get({
+ // responseSchema: cartDtoSchema,
+ // url: `/cart`,
+ // })
+
+ // return CartTransformer.toCart(data)
+
+ const response = await createApiMock(createCart())
- return CartTransformer.toCart(data)
+ return response
}
- static async remove(removeForm: CartRemoveForm): Promise {
- const api = useApi()
- const data = await api.delete({
- responseSchema: cartDtoSchema,
- url: `/cart/${removeForm.cartId}/items/${removeForm.orderProductId}`,
- })
+ static async remove(_removeForm: CartRemoveForm): Promise {
+ // const api = useApi()
+ // const data = await api.delete({
+ // responseSchema: cartDtoSchema,
+ // url: `/cart/${removeForm.cartId}/items/${removeForm.orderProductId}`,
+ // })
- return CartTransformer.toCart(data)
+ // return CartTransformer.toCart(data)
+
+ const response = await createApiMock(createCart())
+
+ return response
}
- static async update(updateForm: CartUpdateForm): Promise {
- const api = useApi()
- const data = await api.post({
- body: CartTransformer.toUpdateDto(updateForm),
- responseSchema: cartDtoSchema,
- url: `/cart/${updateForm.cartId}/items/${updateForm.orderProductId}`,
- })
+ static async update(_updateForm: CartUpdateForm): Promise {
+ // const api = useApi()
+ // const data = await api.post({
+ // body: CartTransformer.toUpdateDto(updateForm),
+ // responseSchema: cartDtoSchema,
+ // url: `/cart/${updateForm.cartId}/items/${updateForm.orderProductId}`,
+ // })
+
+ // return CartTransformer.toCart(data)
+
+ const response = await createApiMock(createCart())
- return CartTransformer.toCart(data)
+ return response
}
}
diff --git a/layers/cart/api/order/queries/useOrdersInfinite.ts b/layers/cart/api/order/queries/useOrdersInfinite.ts
index e8c9b68..cecfccd 100644
--- a/layers/cart/api/order/queries/useOrdersInfinite.ts
+++ b/layers/cart/api/order/queries/useOrdersInfinite.ts
@@ -1,4 +1,4 @@
-import type { PaginatedData } from '@base/models/paginated-data/paginatedData.model'
+import type { PaginatedApiData } from '@base/models/paginated-data/paginatedApiData.model'
import { orderKeys } from '@cart/api/order/keys/order.keys'
import { OrderService } from '@cart/api/order/services/order.service'
import type { OrderIndex } from '@cart/models/order/index/orderIndex.model'
@@ -8,8 +8,8 @@ export function useOrdersInfinite(search: Ref) {
const convertedSearch = computed(() => search.value ?? '')
return useInfiniteQuery({
- getNextPageParam: (lastPage: PaginatedData, _, lastPageParams) => {
- const perPage = lastPage.pagination.per_page
+ getNextPageParam: (lastPage: PaginatedApiData, _, lastPageParams) => {
+ const perPage = lastPage.pagination.perPage
const total = lastPage.pagination.total
if (perPage * lastPageParams < total) {
diff --git a/layers/cart/api/order/services/order.service.ts b/layers/cart/api/order/services/order.service.ts
index cd997a9..5655791 100644
--- a/layers/cart/api/order/services/order.service.ts
+++ b/layers/cart/api/order/services/order.service.ts
@@ -1,43 +1,48 @@
-import { useApi } from '@base/composables/api/useApi'
-import {
- type PaginatedData,
- paginatedDataSchema,
-} from '@base/models/paginated-data/paginatedData.model'
+import { createApiMock } from '@base/mocks/api.mock'
+import { createPaginatedData } from '@base/mocks/paginatedData.mock'
+import type {
+ PaginatedApiData,
+} from '@base/models/paginated-data/paginatedApiData.model'
+import { createOrder, createOrders } from '@cart/mocks/order.mock'
import type { Order } from '@cart/models/order/detail/order.model'
-import { orderDtoSchema } from '@cart/models/order/detail/orderDto.model'
import type { OrderIndex } from '@cart/models/order/index/orderIndex.model'
-import { orderIndexDtoSchema } from '@cart/models/order/index/orderIndexDto.model'
-import { OrderTransformer } from '@cart/models/order/order.transformer'
import type { OrderUuid } from '@cart/models/order/orderUuid.model'
export class OrderService {
- static async getAll(page: number, search?: null | string): Promise> {
- const api = useApi()
- const response = await api.get({
- config: {
- params: {
- page,
- per_page: 20,
- search: search == null || search === '' ? undefined : search,
- },
- },
- responseSchema: paginatedDataSchema(orderIndexDtoSchema),
- url: `/orders`,
- })
+ static async getAll(_page: number, _search?: null | string): Promise> {
+ // const api = useApi()
+ // const response = await api.get({
+ // config: {
+ // params: {
+ // page,
+ // per_page: 20,
+ // search: search == null || search === '' ? undefined : search,
+ // },
+ // },
+ // responseSchema: paginatedDataSchema(orderIndexDtoSchema),
+ // url: `/orders`,
+ // })
- return {
- ...response,
- data: response.data.map(OrderTransformer.toOrderIndex),
- }
+ // return {
+ // ...response,
+ // data: response.data.map(OrderTransformer.toOrderIndex),
+ // }
+
+ const response = await createApiMock(createPaginatedData(createOrders(20)))
+
+ return response
}
- static async getByUuid(uuid: OrderUuid): Promise {
- const api = useApi()
- const response = await api.get({
- responseSchema: orderDtoSchema,
- url: `/orders/${uuid}`,
- })
+ static async getByUuid(_uuid: OrderUuid): Promise {
+ // const api = useApi()
+ // const response = await api.get({
+ // responseSchema: orderDtoSchema,
+ // url: `/orders/${uuid}`,
+ // })
+
+ // return OrderTransformer.toOrder(response)
+ const response = await createApiMock(createOrder())
- return OrderTransformer.toOrder(response)
+ return response
}
}
diff --git a/layers/cart/components/header/CartHeader.vue b/layers/cart/components/header/CartHeader.vue
new file mode 100644
index 0000000..970bbc1
--- /dev/null
+++ b/layers/cart/components/header/CartHeader.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('cart.products_count', { count: amountOfProducts }) }}
+
+
+
+
+ {{ t('cart.total_to_pay') }}
+
+
+ {{ totalPrice ? formatPrice(totalPrice) : t('empty') }}
+
+
+
+
+ {{ t('order.finish_order') }}
+
+
+
+
+
+
+
diff --git a/layers/cart/components/header/CartHeaderActions.vue b/layers/cart/components/header/CartHeaderActions.vue
new file mode 100644
index 0000000..c0696d0
--- /dev/null
+++ b/layers/cart/components/header/CartHeaderActions.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
diff --git a/layers/cart/components/header/CartHeaderProduct.vue b/layers/cart/components/header/CartHeaderProduct.vue
new file mode 100644
index 0000000..0964b39
--- /dev/null
+++ b/layers/cart/components/header/CartHeaderProduct.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
diff --git a/layers/cart/locales/nl.json b/layers/cart/locales/nl.json
index 0db3279..da2f934 100644
--- a/layers/cart/locales/nl.json
+++ b/layers/cart/locales/nl.json
@@ -1,3 +1,9 @@
{
-
+ "cart.cart": "Winkelmand",
+ "cart.order": "Bestelling",
+ "cart.products_count": "Geen producten | Één product | {count} producten",
+ "cart.no_products": "Geen producten",
+ "cart.total_to_pay": "Totaal",
+ "order.finish_order": "Bestelling afronden",
+ "cart.remove": "Verwijderen"
}
diff --git a/layers/cart/mocks/cart.mock.ts b/layers/cart/mocks/cart.mock.ts
new file mode 100644
index 0000000..8f873f8
--- /dev/null
+++ b/layers/cart/mocks/cart.mock.ts
@@ -0,0 +1,32 @@
+import { createAddress } from '@base/mocks/address.mock'
+import {
+ createBoolean,
+ createDate,
+ createNumber,
+ createString,
+} from '@base/mocks/utils.mock'
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+import { createOrderProducts } from '@cart/mocks/orderProduct.mock'
+import type { CartUuid } from '@cart/models/cart/cartUuid.model'
+import type { Cart } from '@cart/models/cart/get/cart.model'
+
+export function createCart(overrides: Partial = {}): Cart {
+ return {
+ id: generateUuid() as CartUuid,
+ deliveryDate: createDate(),
+ orderDate: createDate(),
+ isDelivered: createBoolean(),
+ deliveryAddress: createAddress(),
+ invoiceAddress: createAddress(),
+ orderLineCount: createNumber(1, 14),
+ orderNumber: createString(12),
+ orderProducts: createOrderProducts(createNumber(1, 14)),
+ orderStatus: 'cart',
+ remarks: createString(12),
+ ...overrides,
+ } satisfies Cart
+}
+
+export function createCarts(count: number): Cart[] {
+ return Array.from({ length: count }, () => createCart())
+}
diff --git a/layers/cart/mocks/order.mock.ts b/layers/cart/mocks/order.mock.ts
new file mode 100644
index 0000000..e06c63d
--- /dev/null
+++ b/layers/cart/mocks/order.mock.ts
@@ -0,0 +1,38 @@
+import { createAddress } from '@base/mocks/address.mock'
+import {
+ createBoolean,
+ createDate,
+ createNumber,
+ createString,
+} from '@base/mocks/utils.mock'
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+import { createOrderProducts } from '@cart/mocks/orderProduct.mock'
+import type { Order } from '@cart/models/order/detail/order.model'
+import { orderStatusSchema } from '@cart/models/order/orderStatus.model'
+import type { OrderUuid } from '@cart/models/order/orderUuid.model'
+
+export function createRandomOrderStatus() {
+ const statuses = Object.values(orderStatusSchema.Values)
+
+ return statuses[Math.floor(Math.random() * statuses.length)] as Order['orderStatus']
+}
+export function createOrder(overrides: Partial = {}): Order {
+ return {
+ id: generateUuid() as OrderUuid,
+ deliveryDate: createDate(),
+ orderDate: createDate(),
+ isDelivered: createBoolean(),
+ deliveryAddress: createAddress(),
+ invoiceAddress: createAddress(),
+ orderLineCount: createNumber(0, 14),
+ orderNumber: createString(12),
+ orderProducts: createOrderProducts(createNumber(0, 14)),
+ orderStatus: createRandomOrderStatus(),
+ remarks: createString(12),
+ ...overrides,
+ } satisfies Order
+}
+
+export function createOrders(count: number): Order[] {
+ return Array.from({ length: count }, () => createOrder())
+}
diff --git a/layers/cart/mocks/orderProduct.mock.ts b/layers/cart/mocks/orderProduct.mock.ts
new file mode 100644
index 0000000..1a14887
--- /dev/null
+++ b/layers/cart/mocks/orderProduct.mock.ts
@@ -0,0 +1,25 @@
+import { createNumber } from '@base/mocks/utils.mock'
+import type { Price } from '@base/models/price/price.model'
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+import { createProduct } from '@cart/mocks/product.mock'
+import type { OrderProduct } from '@cart/models/order-product/orderProduct.model'
+import type { OrderProductUuid } from '@cart/models/order-product/orderProductUuid.model'
+
+export function createOrderProduct(overrides: Partial = {}): OrderProduct {
+ const product = createProduct({
+ isDetail: true,
+ })
+
+ return {
+ id: generateUuid() as OrderProductUuid,
+ productId: product.id,
+ price: createNumber(0, 100) as Price,
+ product,
+ quantity: createNumber(0, 8),
+ ...overrides,
+ } satisfies OrderProduct
+}
+
+export function createOrderProducts(count: number): OrderProduct[] {
+ return Array.from({ length: count }, () => createOrderProduct())
+}
diff --git a/layers/cart/mocks/product.mock.ts b/layers/cart/mocks/product.mock.ts
new file mode 100644
index 0000000..cc82d40
--- /dev/null
+++ b/layers/cart/mocks/product.mock.ts
@@ -0,0 +1,19 @@
+import { createNumber, createString } from '@base/mocks/utils.mock'
+import type { Price } from '@base/models/price/price.model'
+import { generateUuid } from '@base/utils/uuid/generateUuid.util'
+import type { Product } from '@cart/models/product/detail/product.model'
+import type { ProductUuid } from '@cart/models/product/productUuid.model'
+
+export function createProduct(overrides: Partial = {}): Product {
+ return {
+ id: generateUuid() as ProductUuid,
+ isDetail: true,
+ name: createString(12),
+ price: createNumber(0, 100) as Price,
+ ...overrides,
+ } satisfies Product
+}
+
+export function createProducts(count: number): Product[] {
+ return Array.from({ length: count }, () => createProduct())
+}
diff --git a/layers/cart/nuxt.config.ts b/layers/cart/nuxt.config.ts
index 20d2265..82391ea 100644
--- a/layers/cart/nuxt.config.ts
+++ b/layers/cart/nuxt.config.ts
@@ -4,16 +4,16 @@ export default defineNuxtConfig({
alias: {
'@auth': path.resolve(__dirname, '../auth'),
'@base': path.resolve(__dirname, '../base'),
- '@cart': path.resolve(__dirname, './cart'),
+ '@cart': path.resolve(__dirname, './'),
},
components: [
{
pathPrefix: false,
- path: '@auth/components',
+ path: '@cart/components',
},
{
pathPrefix: false,
- path: '@auth/views',
+ path: '@cart/views',
},
],