diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts index 8d80de6..b542033 100644 --- a/src/auto-imports.d.ts +++ b/src/auto-imports.d.ts @@ -224,6 +224,7 @@ declare global { const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] const useOnline: typeof import('@vueuse/core')['useOnline'] const useOptions: typeof import('./composables/options')['useOptions'] + const useOrderStore: typeof import('./store/order')['useOrderStore'] const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] const useParallax: typeof import('@vueuse/core')['useParallax'] const useParentElement: typeof import('@vueuse/core')['useParentElement'] @@ -542,6 +543,7 @@ declare module 'vue' { readonly useOffsetPagination: UnwrapRef readonly useOnline: UnwrapRef readonly useOptions: UnwrapRef + readonly useOrderStore: UnwrapRef readonly usePageLeave: UnwrapRef readonly useParallax: UnwrapRef readonly useParentElement: UnwrapRef @@ -853,6 +855,7 @@ declare module '@vue/runtime-core' { readonly useOffsetPagination: UnwrapRef readonly useOnline: UnwrapRef readonly useOptions: UnwrapRef + readonly useOrderStore: UnwrapRef readonly usePageLeave: UnwrapRef readonly useParallax: UnwrapRef readonly useParentElement: UnwrapRef diff --git a/src/components.d.ts b/src/components.d.ts index 1840dcb..94eb764 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -26,9 +26,15 @@ declare module 'vue' { Navbar: typeof import('./components/Navbar.vue')['default'] NBadge: typeof import('naive-ui')['NBadge'] NButton: typeof import('naive-ui')['NButton'] + NCard: typeof import('naive-ui')['NCard'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NDataTable: typeof import('naive-ui')['NDataTable'] NDialogProvider: typeof import('naive-ui')['NDialogProvider'] + NDrawer: typeof import('naive-ui')['NDrawer'] + NDrawerContent: typeof import('naive-ui')['NDrawerContent'] + NDynamicTags: typeof import('naive-ui')['NDynamicTags'] + NForm: typeof import('naive-ui')['NForm'] + NFormItem: typeof import('naive-ui')['NFormItem'] NIcon: typeof import('naive-ui')['NIcon'] NInput: typeof import('naive-ui')['NInput'] NLayout: typeof import('naive-ui')['NLayout'] @@ -36,9 +42,16 @@ declare module 'vue' { NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] NMessageProvider: typeof import('naive-ui')['NMessageProvider'] + NModal: typeof import('naive-ui')['NModal'] NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] NPageHeader: typeof import('naive-ui')['NPageHeader'] NPopselect: typeof import('naive-ui')['NPopselect'] + NSelect: typeof import('naive-ui')['NSelect'] + NSpace: typeof import('naive-ui')['NSpace'] + NSwitch: typeof import('naive-ui')['NSwitch'] + NTreeSelect: typeof import('naive-ui')['NTreeSelect'] + NUpload: typeof import('naive-ui')['NUpload'] + OrderManagement: typeof import('./components/Orders/OrderManagement.vue')['default'] ProductsManagement: typeof import('./components/Products/ProductsManagement.vue')['default'] ReviewManagement: typeof import('./components/Review/ReviewManagement.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/src/components/Orders/OrderManagement.vue b/src/components/Orders/OrderManagement.vue new file mode 100644 index 0000000..7096125 --- /dev/null +++ b/src/components/Orders/OrderManagement.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/components/Products/ProductsManagement.vue b/src/components/Products/ProductsManagement.vue index e8da66a..f015080 100644 --- a/src/components/Products/ProductsManagement.vue +++ b/src/components/Products/ProductsManagement.vue @@ -3,7 +3,6 @@ import { type DataTableColumns, NButton, NIcon, NImage, NSpace, NSwitch, NTag, N import type { RowData } from 'naive-ui/es/data-table/src/interface' import { Delete24Regular as DeleteIcon, - Edit24Regular as EditIcon, Add24Filled as PlusIcon, Star20Filled as StarIcon, } from '@vicons/fluent' @@ -76,17 +75,7 @@ const columns: DataTableColumns = [ width: 110, render(row) { return [ - h( - NButton, - { - size: 'medium', - renderIcon: renderIcon(EditIcon), - quaternary: true, - circle: true, - class: 'mr-2', - onClick: () => { }, - }, - ), + h( NButton, { diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 701f04e..d16df79 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -1,5 +1,5 @@ @@ -177,6 +180,7 @@ function renderIcon(icon: any) { align-items: center; padding: 1.5rem 1.1rem 0.5rem 1.1rem; transition: all 100ms; + .logo { width: 33px; margin-right: 0.8rem; diff --git a/src/main.ts b/src/main.ts index e18a585..0ce5b8d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,7 +20,9 @@ async function enableMocking() { return const { worker } = await import('~/mocks/browser') - return worker.start() + return worker.start({ + onUnhandledRequest: 'bypass', + }) } const router = createRouter({ diff --git a/src/mocks/handlers/order.handler.ts b/src/mocks/handlers/order.handler.ts new file mode 100644 index 0000000..98e954a --- /dev/null +++ b/src/mocks/handlers/order.handler.ts @@ -0,0 +1,39 @@ +import { HttpResponse, http } from 'msw' +import _ from 'lodash' +import { faker } from '@faker-js/faker' +import { CreatePagedResponse } from '../handlers.utility' +import { OrderStatus } from '~/models/Order' +import type { OrderItem, OrderList } from '~/models/Order' + +const orders = _.times(100, createFakeOrder) +const handlers = [ + http.get('/api/order', ({ request }) => { + const response = CreatePagedResponse(request, orders) + return HttpResponse.json(response, { status: 200 }) + }), +] + +function createFakeOrder(): OrderList { + return { + id: faker.number.int().toString(), + status: faker.helpers.enumValue(OrderStatus), + address: { + city: { name: 'Tehran', provinceId: faker.number.int().toString(), id: faker.number.int().toString() }, + province: { name: 'Tehran', id: faker.number.int().toString() }, + id: faker.number.int().toString(), + text: '30, Shams Ave, Ghasrodasht St', + }, + itemsCount: faker.number.int({ max: 10 }), + createdDate: faker.date.past(), + customer: `${faker.person.firstName()} ${faker.person.lastName()}`, + customerId: faker.number.int().toString(), + totalPrice: faker.number.int({ min: 20000, max: 10000000 }), + } +} + +function createFakeOrderItems(): OrderItem { + return { + id: faker.number.int().toString(), + } +} +export default handlers diff --git a/src/models/Customer.ts b/src/models/Customer.ts index 0da5af9..997b278 100644 --- a/src/models/Customer.ts +++ b/src/models/Customer.ts @@ -11,7 +11,21 @@ export interface Customer { } export interface Address { + id: string + province: Province + city: City + text: string +} + +export interface City { + id: string + provinceId: string + name: string +} +export interface Province { + id: string + name: string } export interface CustomerCreateModel extends Customer { diff --git a/src/models/Order.ts b/src/models/Order.ts new file mode 100644 index 0000000..769255c --- /dev/null +++ b/src/models/Order.ts @@ -0,0 +1,34 @@ +import type { Address, Customer } from './Customer' + +export interface OrderList { + id: string + customer: string + customerId: string + address: Address + status: OrderStatus + createdDate: Date + totalPrice: number + itemsCount: number +} + +export interface Order { + id: string + customer: Customer + items: OrderItem[] + address: Address + status: OrderStatus + createdDate: Date + totalPrice: number +} + +export interface OrderItem { + id: string +} + +export enum OrderStatus { + Submitted, + Processing, + ReadyToSend, + Sent, + Delivered, +} diff --git a/src/pages/Orders/index.vue b/src/pages/Orders/index.vue new file mode 100644 index 0000000..954fe21 --- /dev/null +++ b/src/pages/Orders/index.vue @@ -0,0 +1,14 @@ + + + +meta: + title: Orders + + + + + diff --git a/src/services/order.service.ts b/src/services/order.service.ts new file mode 100644 index 0000000..f69f521 --- /dev/null +++ b/src/services/order.service.ts @@ -0,0 +1,23 @@ +import { ApiService } from '~/common/api/api-service' +import type { Order, OrderList } from '~/models/Order' +import type { PagedAndSortedRequest } from '~/models/PagedAndSortedRequest' +import type { PagedListResult } from '~/models/PagedListResult' + +const apiService = new ApiService('order') +class OrderService { + constructor() { } + async getOrderList(options: PagedAndSortedRequest): Promise> { + const response = await apiService.getPagedList('', options) + return response + } + + async getOrder(id: string): Promise { + const response = await apiService.get(id) + return response + } + + async deleteOrder(id: string): Promise { + return await apiService.delete(id) + } +} +export default new OrderService() diff --git a/src/store/order.store.ts b/src/store/order.store.ts new file mode 100644 index 0000000..623ce64 --- /dev/null +++ b/src/store/order.store.ts @@ -0,0 +1,37 @@ +import { acceptHMRUpdate, defineStore } from 'pinia' +import type { Order, OrderList } from '~/models/Order' +import type { PagedAndSortedRequest } from '~/models/PagedAndSortedRequest' +import orderService from '~/services/order.service' + +export const useOrderStore = defineStore('Order', () => { + const orders = ref([]) + const isLoading = ref(false) + const isSaving = ref(false) + const { options } = useOptions() + + async function getOrders(options: PagedAndSortedRequest) { + isLoading.value = true + try { + const response = await orderService.getOrderList(options) + orders.value = response.items + options.pageSize = Math.trunc(response.totalCount / options.itemsPerPage) + } + finally { + isLoading.value = false + } + } + + async function getOrderDetail(order: Order) { + const response = await orderService.getOrder(order.id) + } + + return { + options, + orders, + getOrders, + getOrderDetail, + isSaving, + } +}) +if (import.meta.hot) + import.meta.hot.accept(acceptHMRUpdate(useOrderStore, import.meta.hot))