update origin link component
This commit is contained in:
parent
60e1abc941
commit
2249775e2a
3 changed files with 160 additions and 3 deletions
|
|
@ -41,10 +41,20 @@ export const useMerchApi = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateMerch = async (payload) => {
|
||||||
|
const response = await apiClient.put(`/merch/`, payload)
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response
|
||||||
|
} else {
|
||||||
|
console.log('Update merch error: ', response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addMerch,
|
addMerch,
|
||||||
getMerchDetails,
|
getMerchDetails,
|
||||||
getMerchList,
|
getMerchList,
|
||||||
deleteMerch,
|
deleteMerch,
|
||||||
|
updateMerch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import router from '@/router/index.js'
|
||||||
import PeriodSelector from '@/components/PeriodSelector.vue'
|
import PeriodSelector from '@/components/PeriodSelector.vue'
|
||||||
import ChartBlock from '@/components/ChartBlock.vue'
|
import ChartBlock from '@/components/ChartBlock.vue'
|
||||||
import { useChartsApi } from '@/api/charts.js'
|
import { useChartsApi } from '@/api/charts.js'
|
||||||
|
import EditLink from '@/views/DetailsView/EditLink.vue'
|
||||||
|
|
||||||
const { getMerchDetails, deleteMerch } = useMerchApi()
|
const { getMerchDetails, deleteMerch } = useMerchApi()
|
||||||
const { getDistinctPrices } = useChartsApi()
|
const { getDistinctPrices } = useChartsApi()
|
||||||
|
|
@ -102,11 +103,19 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-divider title-placement="left">Surugaya</n-divider>
|
<n-divider title-placement="left">Surugaya</n-divider>
|
||||||
<p><strong>Link:</strong> {{ merchDetails.origin_surugaya.link }}</p>
|
<EditLink
|
||||||
<p><strong>Cookie values:</strong> {{ merchDetails.origin_surugaya.cookie_values }}</p>
|
:merch-uuid="merch_uuid"
|
||||||
|
origin="surugaya"
|
||||||
|
:name="merchDetails.name"
|
||||||
|
v-model="merchDetails.origin_surugaya.link" />
|
||||||
|
|
||||||
<n-divider title-placement="left">Mandarake</n-divider>
|
<n-divider title-placement="left">Mandarake</n-divider>
|
||||||
<p><strong>Link</strong> {{ merchDetails.origin_mandarake.link }}</p>
|
<EditLink
|
||||||
|
:merch-uuid="merch_uuid"
|
||||||
|
origin="mandarake"
|
||||||
|
:name="merchDetails.name"
|
||||||
|
v-model="merchDetails.origin_mandarake.link" />
|
||||||
|
|
||||||
</n-card>
|
</n-card>
|
||||||
<div v-else>Not found</div>
|
<div v-else>Not found</div>
|
||||||
|
|
||||||
|
|
|
||||||
138
src/views/DetailsView/EditLink.vue
Normal file
138
src/views/DetailsView/EditLink.vue
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, nextTick, watch, computed } from 'vue'
|
||||||
|
import { useMerchApi } from '@/api/merch.js'
|
||||||
|
|
||||||
|
const { updateMerch } = useMerchApi()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
emptyText: {
|
||||||
|
type: String,
|
||||||
|
default: 'Add link'
|
||||||
|
},
|
||||||
|
merchUuid: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
origin: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const isEditing = ref(false)
|
||||||
|
const tempValue = ref('')
|
||||||
|
const inputRef = ref(null)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const displayValue = computed(() => {
|
||||||
|
const val = props.modelValue.trim()
|
||||||
|
return val === '' || val == null ? props.emptyText : props.modelValue
|
||||||
|
})
|
||||||
|
|
||||||
|
const startEditing = () => {
|
||||||
|
tempValue.value = props.modelValue
|
||||||
|
isEditing.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
inputRef.value?.focus?.()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
const newValue = tempValue.value.trim()
|
||||||
|
if (newValue !== props.modelValue) {
|
||||||
|
emit('update:modelValue', newValue)
|
||||||
|
}
|
||||||
|
isEditing.value = false
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
await updateMerch({
|
||||||
|
merch_uuid: props.merchUuid,
|
||||||
|
name: props.name,
|
||||||
|
origin: props.origin,
|
||||||
|
link: newValue
|
||||||
|
})
|
||||||
|
|
||||||
|
emit('update:modelValue', newValue)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Update link error:', error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
isEditing.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancel = () => {
|
||||||
|
isEditing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.modelValue, (newVal) => {
|
||||||
|
if (isEditing.value) {
|
||||||
|
tempValue.value = newVal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<span v-if="!isEditing" @click="startEditing" class="editable-text">
|
||||||
|
{{ displayValue }}
|
||||||
|
</span>
|
||||||
|
<div v-else class="editing-area">
|
||||||
|
<n-input
|
||||||
|
v-model:value="tempValue"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
ref="inputRef"
|
||||||
|
@keyup.enter="save"
|
||||||
|
@keyup.esc="cancel"
|
||||||
|
:placeholder="placeholder || 'Enter link here...'"
|
||||||
|
/>
|
||||||
|
<n-button size="small" type="primary" @click="save">✓</n-button>
|
||||||
|
<n-button size="small" @click="cancel">✕</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.editable-text {
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #18a058;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.2s;
|
||||||
|
min-height: 1.2em;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-text:hover {
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editing-area {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue