Files
boursecu_user/src/views/base/priceTrigger/components/Item.vue
T
safavimohadeseh78andCursor 9356a2ab5e Port modular price, product, and PWA fixes into boursecu
Sync live quote handling, SSE product images, store hours, file URL normalization, PWA icon cache, TV monitor, about software, SuperAdmin menu gates, price alerts, and related UX from modular while preserving boursecu branding and config constraints.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 08:26:52 -04:00

177 lines
5.5 KiB
Vue

<template>
<div v-if="variant === 'desktop'" class="dptr-card">
<p class="dptr-card__price">{{ usePrice(item.target_price) }}</p>
<div class="dptr-card__meta">
<div class="dptr-card__row">
<span class="dptr-card__label">محصول:</span>
<span class="dptr-card__value">{{ productTitle }}</span>
</div>
<div class="dptr-card__row">
<span class="dptr-card__label">جهت قیمت:</span>
<span class="dptr-card__value">{{ returnPriceCondition(item.price_condition) }}</span>
</div>
</div>
<div class="dptr-card__actions">
<button
type="button"
class="dptr-card__icon-btn dptr-card__icon-btn--edit"
@click.stop="emits('edit', item)"
>
<BasicIcon color="green" icon="vuesax-linear:edit" size="18" />
</button>
<button
type="button"
class="dptr-card__icon-btn dptr-card__icon-btn--danger"
@click.stop="deleteConfirmVisible = true"
>
<BasicIcon color="red" icon="vuesax-linear:trash" size="18" />
</button>
</div>
<div class="dptr-card__footer">
<span class="dptr-card__date">{{ toJalali(item.created_at) }}</span>
<a-switch
v-model:checked="isActive"
checked-children="فعال"
un-checked-children="غیر فعال"
@change="changeActive"
/>
</div>
<DialogVant v-model:show="deleteConfirmVisible" :closeOnClickOverlay="false" :timeOut="-1" teleport="body">
<template #title>
<div class="flex flex-col items-center">
<div class="p-5 text-sm">آیا از حذف هشدار اطمینان دارید؟</div>
</div>
</template>
<template #button>
<div class="text-center text-red flex items-center justify-center" @click="deleteItem">
<a-spin :spinning="deleteLoading" size="small">تایید</a-spin>
</div>
<div class="text-center" @click="deleteConfirmVisible = false">انصراف</div>
</template>
</DialogVant>
</div>
<div v-else @click="infoVisible = true" class="shadow mb-2 p-2 rounded-lg">
<div class="flex justify-between">
<div>
<div class="font-bold text-base mb-2">{{ usePrice(item.target_price) }}</div>
</div>
<div class="flex gap-2">
<BasicIcon
class="p-1"
color="red"
icon="vuesax-linear:trash"
@click.stop="deleteConfirmVisible = true"
/>
<BasicIcon
class="p-1"
color="green"
icon="vuesax-linear:edit"
@click.stop="emits('edit', item)"
/>
</div>
</div>
<div class="flex flex-col gap-2 mt-2">
<BasicInfoItem is-line title="محصول" :value="productTitle" />
<BasicInfoItem is-line title="جهت قیمت" :value="returnPriceCondition(item.price_condition)" />
</div>
<a-divider class="!my-3" />
<div class="flex justify-between mt-1">
<div class="mb-2">{{ toJalali(item.created_at) }}</div>
<a-switch
v-model:checked="isActive"
checked-children="فعال"
un-checked-children="غیر فعال"
@change="changeActive"
/>
</div>
<DialogVant v-model:show="deleteConfirmVisible" :closeOnClickOverlay="false" :timeOut="-1" teleport="body">
<template #title>
<div class="flex flex-col items-center">
<div class="p-5 text-sm">آیا از حذف هشدار اطمینان دارید؟</div>
</div>
</template>
<template #button>
<div class="text-center text-red flex items-center justify-center" @click="deleteItem">
<a-spin :spinning="deleteLoading" size="small">تایید</a-spin>
</div>
<div class="text-center" @click="deleteConfirmVisible = false">انصراف</div>
</template>
</DialogVant>
</div>
</template>
<script lang="ts" setup>
import { usePrice } from '../../../../utils/usePrice'
import { computed, onMounted, ref } from 'vue'
import { toJalali } from '../../../../utils/useDateTime'
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import type { PriceTrigger } from '@/models/PriceTrigger'
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
import DialogVant from '@/components/DialogVant.vue'
import { deletePriceTrigger, updatePriceTrigger } from '@/api/triggerPrice'
import { loading } from '@/utils'
const infoVisible = ref(false)
const isActive = ref(false)
const deleteLoading = ref(false)
const deleteConfirmVisible = ref(false)
const props = withDefaults(
defineProps<{
item: PriceTrigger
variant?: 'mobile' | 'desktop'
}>(),
{ variant: 'mobile' },
)
const emits = defineEmits(['edit', 'refresh'])
const productTitle = computed(() => props.item.product?.title || 'طلا')
onMounted(() => {
isActive.value = props.item.is_active
})
async function changeActive(val: boolean) {
try {
loading.value = true
await updatePriceTrigger(props?.item.id, { is_active: val })
} catch (e) {
console.log(e)
isActive.value = !isActive.value
} finally {
loading.value = false
}
}
function returnPriceCondition(val: string) {
switch (val) {
case '==':
return 'مساوی'
case '<':
return 'کوچکتر'
case '>':
return 'بزرگتر'
}
}
async function deleteItem() {
try {
deleteLoading.value = true
await deletePriceTrigger(props.item.id)
deleteConfirmVisible.value = false
emits('refresh')
} catch (e) {
console.log(e)
} finally {
deleteLoading.value = false
}
}
</script>