diff --git a/src/api/zeroPrices.js b/src/api/zeroPrices.js index c69efd1..a7db41a 100644 --- a/src/api/zeroPrices.js +++ b/src/api/zeroPrices.js @@ -15,13 +15,26 @@ export const useZeroPrices = () => { await apiClient.delete('/merch/zeroprices', list) } catch (error) { - console.log('Delete zero prices error: ', error) + console.log('Delete target zero prices error: ', error) throw error } } + const deleteZeroPricesPeriod = async (start, end) => { + const params = new URLSearchParams({ start, end }).toString() + const url = `/merch/zeroprices/period${params ? `?${params}` : ''}` + const response = await apiClient.delete(url) + + if (response.status === 200) { + return response + } else { + console.log('Delete period select zero prices error: ', response) + } + } + return { getZeroPrices, deleteZeroPrices, + deleteZeroPricesPeriod, } } diff --git a/src/components/ChartBlock.vue b/src/components/ChartBlock.vue index 96a5243..11bd874 100644 --- a/src/components/ChartBlock.vue +++ b/src/components/ChartBlock.vue @@ -13,6 +13,7 @@ import { } from 'chart.js' import { Line } from 'vue-chartjs' import 'chartjs-adapter-date-fns' +import { originColors } from '@/services/colors.js' ChartJS.register( Title, @@ -33,11 +34,6 @@ const props = defineProps({ }, }) -const originColors = { - surugaya: '#2d3081', - mandarake: '#924646', -} - const chartData = ref({ datasets: [], }) diff --git a/src/services/apiClient.js b/src/services/apiClient.js index 082f10a..639fb84 100644 --- a/src/services/apiClient.js +++ b/src/services/apiClient.js @@ -7,8 +7,10 @@ let refreshPromise = null function createConfig(options = {}) { const token = localStorage.getItem('accessToken'); + const isFormData = options.body instanceof FormData; + const headers = { - 'Content-Type': 'application/json', + ...(isFormData ? {} : { 'Content-Type': 'application/json' }), ...options.headers, }; diff --git a/src/services/colors.js b/src/services/colors.js new file mode 100644 index 0000000..c337f2a --- /dev/null +++ b/src/services/colors.js @@ -0,0 +1,4 @@ +export const originColors = { + surugaya: '#2d3081', + mandarake: '#924646', +}; diff --git a/src/views/DetailsView/DetailsViewImages.vue b/src/views/DetailsView/DetailsViewImages.vue index 7284760..dc7a258 100644 --- a/src/views/DetailsView/DetailsViewImages.vue +++ b/src/views/DetailsView/DetailsViewImages.vue @@ -54,37 +54,21 @@ function onFileInputChange(event) { event.target.value = '' } -async function handleUpload({ fileList: newFileList }) { - const file = newFileList[newFileList.length - 1] +async function fetchImage(bustCache = false) { try { - await uploadImage(props.merchUuid, file.file) + let imgUrl = getImageUrl(props.merchUuid, 'full') - const { imgUrl } = await getImageUrl(props.merchUuid, 'full') - - message.success('Image uploaded successfully.') - - fileList.value = [ - { - name: file.name, - url: imgUrl, - status: 'finished', - }, - ] - } catch (error) { - message.error('Upload error: ' + (error.message || 'Unknown error.')) - } -} - -onMounted(async () => { - try { - const imgUrl = getImageUrl(props.merchUuid, 'full'); + if (bustCache) { + const separator = imgUrl.includes('?') ? '&' : '?' + imgUrl += `${separator}_t=${Date.now()}` + } await new Promise((resolve, reject) => { - const img = new Image(); - img.src = imgUrl; - img.onload = () => resolve(imgUrl); - img.onerror = () => reject(new Error('Image not found')); - }); + const img = new Image() + img.src = imgUrl + img.onload = () => resolve(imgUrl) + img.onerror = () => reject(new Error('Image not found')) + }) fileList.value = [ { @@ -92,13 +76,28 @@ onMounted(async () => { url: imgUrl, status: 'finished', }, - ]; + ] } catch (error) { - fileList.value = []; + fileList.value = [] if (!error.message.includes('404')) { - console.error('Error getting image: ', error); + console.error('Error getting image:', error) } } +} + +async function handleUpload({ fileList: newFileList }) { + const file = newFileList[newFileList.length - 1] + try { + await uploadImage(props.merchUuid, file.file) + message.success('Image uploaded successfully.') + await fetchImage(true) + } catch (error) { + message.error('Upload error: ' + (error.message || 'Unknown error.')) + } +} + +onMounted(async () => { + await fetchImage(false) }); const showConfirmDelete = ref(false) diff --git a/src/views/ZeroPricesView.vue b/src/views/ZeroPricesView.vue index adab776..82d41a5 100644 --- a/src/views/ZeroPricesView.vue +++ b/src/views/ZeroPricesView.vue @@ -1,54 +1,20 @@ - + diff --git a/src/views/ZeroPricesView/PeriodSelectTab.vue b/src/views/ZeroPricesView/PeriodSelectTab.vue new file mode 100644 index 0000000..4239f15 --- /dev/null +++ b/src/views/ZeroPricesView/PeriodSelectTab.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/views/ZeroPricesView/TargetZeroesTab.vue b/src/views/ZeroPricesView/TargetZeroesTab.vue new file mode 100644 index 0000000..ba71ba5 --- /dev/null +++ b/src/views/ZeroPricesView/TargetZeroesTab.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/views/ZeroPricesView/ZeroPriceCard.vue b/src/views/ZeroPricesView/ZeroPriceCard.vue index 10c80d7..32bd31f 100644 --- a/src/views/ZeroPricesView/ZeroPriceCard.vue +++ b/src/views/ZeroPricesView/ZeroPriceCard.vue @@ -1,36 +1,49 @@ @@ -48,4 +61,11 @@ const handleCheckboxChange = () => { gap: 12px; border: 1px solid #e0e0e0; } + +.bordered { + border: 1px solid; + border-radius: 4px; + padding: 2px; + margin: 3px; +} diff --git a/src/views/ZeroPricesView/ZeroPricesToolbar.vue b/src/views/ZeroPricesView/ZeroPricesToolbar.vue index 122e3d5..abe01cb 100644 --- a/src/views/ZeroPricesView/ZeroPricesToolbar.vue +++ b/src/views/ZeroPricesView/ZeroPricesToolbar.vue @@ -10,7 +10,7 @@ const props = defineProps({ const messages = useMessage() const { deleteZeroPrices } = useZeroPrices() -const emit = defineEmits(['deleted']) +const emit = defineEmits(['deleted', 'selectAll']) const handleDelete = async () => { try { @@ -22,6 +22,11 @@ const handleDelete = async () => { messages.error("Error deleting selected prices") } } + +const handleSelectAll = async () => { + emit('selectAll') +} +