generated from antfu-collective/vitesse
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #49
- Loading branch information
Showing
8 changed files
with
276 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
<script setup lang='ts'> | ||
import { getCurrentInstance } from 'vue' | ||
import { type DataTableColumns, NButton, NIcon, NRate, NSpace, NText } from 'naive-ui/es/components' | ||
import type { RowData } from 'naive-ui/es/data-table/src/interface' | ||
import { | ||
Delete24Regular as DeleteIcon, | ||
} from '@vicons/fluent' | ||
import { storeToRefs } from 'pinia' | ||
import { useDialog, useMessage } from 'naive-ui' | ||
const { t } = useI18n() | ||
Check warning on line 11 in src/components/Review/ReviewManagement.vue GitHub Actions / lint
|
||
const store = useReviewStore() | ||
const { reviews, isLoading } = storeToRefs(store) | ||
const dialog = useDialog() | ||
const message = useMessage() | ||
const { proxy } = getCurrentInstance() | ||
onMounted(getItems) | ||
const columns: DataTableColumns<RowData> = [ | ||
{ | ||
title: 'RATE', | ||
key: 'rate', | ||
render(row) { | ||
return [ | ||
h(NRate, { color: 'gold', readonly: true, defaultValue: row.rate, allowHalf: true }), | ||
] | ||
}, | ||
}, | ||
{ | ||
title: 'COMMENT', | ||
key: 'comment', | ||
render(row) { | ||
return h(NText, | ||
{}, { | ||
default: () => row.comment.message, | ||
}) | ||
}, | ||
}, | ||
{ | ||
title: 'PRODUCT', | ||
key: 'name', | ||
render: row => | ||
h(NSpace, {}, { | ||
default: () => [ | ||
h(NText, {}, { default: () => `${row.product.name}` }), | ||
], | ||
}), | ||
}, | ||
{ | ||
title: 'CUSTOMER', | ||
key: 'phone', | ||
render(row) { | ||
return [ | ||
h(NText, {}, { default: () => `${row.customer.firstName} ${row.customer.lastName}` }), | ||
] | ||
}, | ||
}, | ||
{ | ||
title: 'DATE', | ||
key: 'date', | ||
render(row) { | ||
return h(NText, | ||
{}, { | ||
default: () => proxy.$filters.friendlyTime(row.date), | ||
}) | ||
}, | ||
}, | ||
{ | ||
title: 'Actions', | ||
key: 'actions', | ||
width: 110, | ||
render(row) { | ||
return [ | ||
h( | ||
NButton, | ||
{ | ||
size: 'medium', | ||
quaternary: true, | ||
circle: true, | ||
renderIcon: renderIcon(DeleteIcon), | ||
onClick: () => handleDeleteItem(row), | ||
}, | ||
), | ||
] | ||
}, | ||
}, | ||
] | ||
const { options } = storeToRefs(store) | ||
function renderIcon(icon: any) { | ||
return () => h(NIcon, null, { default: () => h(icon) }) | ||
} | ||
function handleDeleteItem(row: RowData) { | ||
dialog.error({ | ||
title: 'Confirm', | ||
content: 'Are you sure?', | ||
positiveText: 'Yes, Delete', | ||
negativeText: 'Cancel', | ||
onPositiveClick: () => { | ||
store.deleteProduct(row.id) | ||
message.success('Product was deleted!') | ||
}, | ||
}) | ||
} | ||
function rowKey(row: RowData) { | ||
return row.id | ||
} | ||
function getItems() { | ||
store.getReviews(options.value) | ||
} | ||
function handlePageChange(page: number) { | ||
options.value.page = page | ||
getItems() | ||
} | ||
function handleSorterChange() { | ||
getItems() | ||
} | ||
function handleFiltersChange() { | ||
getItems() | ||
} | ||
</script> | ||
|
||
<template> | ||
<n-layout> | ||
<n-layout-content> | ||
<div class="px-3"> | ||
<n-data-table | ||
remote :columns="columns" :data="reviews" :loading="isLoading" :pagination="options" | ||
selectable :row-key="rowKey" @update:sorter="handleSorterChange" @update:filters="handleFiltersChange" | ||
@update:page="handlePageChange" | ||
/> | ||
</div> | ||
</n-layout-content> | ||
</n-layout> | ||
</template> | ||
|
||
<style scoped lang='scss'></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { HttpResponse, http } from 'msw' | ||
import { faker } from '@faker-js/faker' | ||
import _ from 'lodash' | ||
import { CreatePagedResponse } from '../handlers.utility' | ||
import type { Review } from '~/models/Review' | ||
|
||
const reviews = _.times(65, createFakeReview) | ||
const handlers = [ | ||
http.get('/api/review/', ({ request }) => { | ||
const response = CreatePagedResponse<Review>(request, reviews) | ||
return HttpResponse.json(response, { status: 200 }) | ||
}), | ||
] | ||
|
||
function createFakeReview(): Review { | ||
return { | ||
id: faker.number.int().toString(), | ||
date: faker.date.past(), | ||
rate: faker.number.float({ max: 5 }), | ||
product: { | ||
name: faker.commerce.productName(), | ||
id: faker.number.int().toString(), | ||
}, | ||
comment: { | ||
id: faker.number.int().toString(), | ||
message: faker.commerce.productAdjective(), | ||
}, | ||
customer: { | ||
id: faker.number.int().toString(), | ||
firstName: faker.person.firstName(), | ||
lastName: faker.person.lastName(), | ||
address: [], | ||
mobile: faker.phone.number(), | ||
joinDate: faker.date.past(), | ||
birthDate: faker.date.birthdate(), | ||
email: faker.internet.email(), | ||
ordersCount: faker.number.int({ max: 50 }), | ||
}, | ||
} | ||
} | ||
|
||
export default handlers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { Customer } from './Customer' | ||
|
||
export interface Review { | ||
id: string | ||
customer: Customer | ||
product: ReviewProduct | ||
date: Date | ||
rate: number | ||
comment: Comment | ||
} | ||
|
||
export interface Comment { | ||
id: string | ||
message: string | ||
} | ||
|
||
export interface ReviewProduct { | ||
id: string | ||
name: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<script setup lang="ts"> | ||
</script> | ||
|
||
<route lang="yaml"> | ||
meta: | ||
title: Reviews | ||
</route> | ||
|
||
<template> | ||
<ReviewManagement /> | ||
</template> | ||
|
||
<style scoped></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ApiService } from '~/common/api/api-service' | ||
import type { PagedAndSortedRequest } from '~/models/PagedAndSortedRequest' | ||
import type { PagedListResult } from '~/models/PagedListResult' | ||
import type { Review } from '~/models/Review' | ||
|
||
const apiService = new ApiService('review') | ||
class ReviewService { | ||
constructor() { } | ||
async getReviewList(options: PagedAndSortedRequest): Promise<PagedListResult<Review>> { | ||
const response = await apiService.getPagedList<Review>('', options) | ||
return response | ||
} | ||
} | ||
export default new ReviewService() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { acceptHMRUpdate, defineStore } from 'pinia' | ||
import type { PagedAndSortedRequest } from '~/models/PagedAndSortedRequest' | ||
import type { Review } from '~/models/Review' | ||
import reviewService from '~/services/review.service' | ||
|
||
export interface ReviewState { | ||
|
||
} | ||
export const useReviewStore = defineStore('Review', () => { | ||
const reviews = ref<Review[]>([]) | ||
|
||
const reviewItem = ref<Review>() | ||
const isLoading = ref(false) | ||
const isSaving = ref(false) | ||
const { options } = useOptions() | ||
|
||
async function getReviews(options: PagedAndSortedRequest) { | ||
isLoading.value = true | ||
try { | ||
const response = await reviewService.getReviewList(options) | ||
reviews.value = response.items | ||
options.pageSize = Math.trunc(response.totalCount / options.itemsPerPage) | ||
} | ||
finally { | ||
isLoading.value = false | ||
} | ||
} | ||
return { | ||
reviews, | ||
isSaving, | ||
isLoading, | ||
getReviews, | ||
reviewItem, | ||
options, | ||
} | ||
}) | ||
if (import.meta.hot) | ||
import.meta.hot.accept(acceptHMRUpdate(useReviewStore, import.meta.hot)) |