kashkool ver 1
This commit is contained in:
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASlider: typeof import('ant-design-vue/es')['Slider']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
BaseDatePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue')['default']
|
||||
Basic: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/basic.vue')['default']
|
||||
BasicActionSheet: typeof import('./src/components/BasicPacks/BasicActionSheet.vue')['default']
|
||||
BasicButton: typeof import('./src/components/BasicPacks/BasicButton.vue')['default']
|
||||
BasicDraggableFileUpload: typeof import('./src/components/BasicPacks/BasicUploads/BasicDraggableFileUpload.vue')['default']
|
||||
BasicIcon: typeof import('./src/components/BasicPacks/BasicIcon.vue')['default']
|
||||
BasicInfoItem: typeof import('./src/components/BasicPacks/BasicInfoItem.vue')['default']
|
||||
BasicInput: typeof import('./src/components/BasicPacks/BasicInput.vue')['default']
|
||||
BasicModal: typeof import('./src/components/BasicPacks/BasicModal.vue')['default']
|
||||
BasicPriceInput: typeof import('./src/components/BasicPacks/BasicPriceInput/src/BasicPriceInput.vue')['default']
|
||||
BasicSelect: typeof import('./src/components/BasicPacks/BasicSelect.vue')['default']
|
||||
BasicTags: typeof import('./src/components/BasicPacks/BasicTags/index.vue')['default']
|
||||
BasicTextArea: typeof import('./src/components/BasicPacks/BasicTextArea.vue')['default']
|
||||
BasicToggleTwoItem: typeof import('./src/components/BasicPacks/BasicToggleTwoItem.vue')['default']
|
||||
Bg_main: typeof import('./src/components/bg_main.vue')['default']
|
||||
Bordered: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/bordered.vue')['default']
|
||||
DateRender: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/date-render.vue')['default']
|
||||
Demo: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/index.vue')['default']
|
||||
DialogVant: typeof import('./src/components/DialogVant.vue')['default']
|
||||
DialogVantOneButton: typeof import('./src/components/DialogVantOneButton.vue')['default']
|
||||
Disabled: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/disabled.vue')['default']
|
||||
DisabledDate: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/disabled-date.vue')['default']
|
||||
Empty: typeof import('./src/components/empty.vue')['default']
|
||||
ExtraFooter: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/extra-footer.vue')['default']
|
||||
Format: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/format.vue')['default']
|
||||
GoldLoading: typeof import('./src/components/GoldLoading.vue')['default']
|
||||
ListAnim: typeof import('./src/components/ListAnim.vue')['default']
|
||||
Mode: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/mode.vue')['default']
|
||||
PresettedRanges: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/presetted-ranges.vue')['default']
|
||||
ProductImage: typeof import('./src/components/ProductImage.vue')['default']
|
||||
RangePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/range-picker.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SelectInRange: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/select-in-range.vue')['default']
|
||||
Size: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/size.vue')['default']
|
||||
StartEnd: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/start-end.vue')['default']
|
||||
Suffix: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/suffix.vue')['default']
|
||||
Switchable: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/switchable.vue')['default']
|
||||
Text: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/text.vue')['default']
|
||||
Time: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/time.vue')['default']
|
||||
TransactionSkeleton: typeof import('./src/components/TransactionSkeleton.vue')['default']
|
||||
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
||||
VanDialog: typeof import('vant/es')['Dialog']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -23,16 +23,27 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
cursor: pointer;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#whatsapp-button:hover {
|
||||
#whatsapp-button:hover:not(.is-dragging) {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 6px 14px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#whatsapp-button.is-dragging {
|
||||
cursor: grabbing;
|
||||
transform: none;
|
||||
box-shadow: 0 8px 18px rgba(0,0,0,0.22);
|
||||
}
|
||||
|
||||
#whatsapp-button img {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#whatsapp-button:hover + #whatsapp-tooltip {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
|
||||
@@ -100,7 +100,6 @@ const indicator = h(LoadingOutlined, {
|
||||
})
|
||||
const showSplash = ref(true)
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
checkVersion()
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import useAxios from '@/utils/useAxios'
|
||||
|
||||
export async function getSettings() {
|
||||
return await useAxios.get(`api/get_settings`)
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import VueLazyLoad from 'vue3-lazyload'
|
||||
import { getMe } from '@/api/me'
|
||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
|
||||
import { useAuthStore } from '@/store/useAuthStore'
|
||||
import { initWhatsappButtonDrag } from '@/utils/initWhatsappButtonDrag'
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(createPinia())
|
||||
@@ -181,6 +182,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
})
|
||||
|
||||
app.mount('#app')
|
||||
initWhatsappButtonDrag()
|
||||
// if (currentRoute.value !== '/') {
|
||||
// await start()
|
||||
// }
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
import {
|
||||
buildSupportMessengerUrl,
|
||||
loadSupportMessengerFromSettings,
|
||||
supportMessengerSettings,
|
||||
} from '@/utils/supportMessenger'
|
||||
|
||||
const STORAGE_KEY = 'ghatreh_whatsapp_button_position'
|
||||
const DRAG_THRESHOLD = 6
|
||||
const WIDTH = 60
|
||||
const HEIGHT = 60
|
||||
const DEFAULT_BOTTOM_OFFSET = 90
|
||||
const DEFAULT_RIGHT_OFFSET = 20
|
||||
|
||||
type FabPosition = { x: number; y: number }
|
||||
|
||||
function getViewportWidth() {
|
||||
return Math.min(window.innerWidth, 426)
|
||||
}
|
||||
|
||||
function getHorizontalOffset() {
|
||||
const vw = window.innerWidth
|
||||
const contentWidth = getViewportWidth()
|
||||
return Math.max(0, (vw - contentWidth) / 2)
|
||||
}
|
||||
|
||||
function getDefaultPosition(): FabPosition {
|
||||
const vh = window.innerHeight
|
||||
const offsetX = getHorizontalOffset()
|
||||
const contentWidth = getViewportWidth()
|
||||
|
||||
return {
|
||||
x: offsetX + contentWidth - WIDTH - DEFAULT_RIGHT_OFFSET,
|
||||
y: vh - DEFAULT_BOTTOM_OFFSET - HEIGHT,
|
||||
}
|
||||
}
|
||||
|
||||
function loadPosition(): FabPosition | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
if (!raw) return null
|
||||
const parsed = JSON.parse(raw) as FabPosition
|
||||
if (typeof parsed?.x === 'number' && typeof parsed?.y === 'number') {
|
||||
return parsed
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function savePosition(pos: FabPosition) {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(pos))
|
||||
}
|
||||
|
||||
function clampPosition(pos: FabPosition): FabPosition {
|
||||
const vw = window.innerWidth
|
||||
const vh = window.innerHeight
|
||||
|
||||
return {
|
||||
x: Math.max(0, Math.min(vw - WIDTH, pos.x)),
|
||||
y: Math.max(0, Math.min(vh - HEIGHT, pos.y)),
|
||||
}
|
||||
}
|
||||
|
||||
function applyPosition(button: HTMLElement, pos: FabPosition) {
|
||||
button.style.position = 'fixed'
|
||||
button.style.bottom = 'auto'
|
||||
button.style.right = 'auto'
|
||||
button.style.left = `${pos.x}px`
|
||||
button.style.top = `${pos.y}px`
|
||||
button.style.touchAction = 'none'
|
||||
}
|
||||
|
||||
function updateWhatsappHref(button: HTMLAnchorElement) {
|
||||
const link = buildSupportMessengerUrl(
|
||||
supportMessengerSettings.value.messenger,
|
||||
supportMessengerSettings.value.messengerId
|
||||
)
|
||||
|
||||
button.href = link || '#'
|
||||
button.style.display = 'flex'
|
||||
}
|
||||
|
||||
export function initWhatsappButtonDrag() {
|
||||
const button = document.getElementById('whatsapp-button') as HTMLAnchorElement | null
|
||||
if (!button) return
|
||||
|
||||
let pos = clampPosition(loadPosition() ?? getDefaultPosition())
|
||||
applyPosition(button, pos)
|
||||
|
||||
let pointerId: number | null = null
|
||||
let startX = 0
|
||||
let startY = 0
|
||||
let originX = 0
|
||||
let originY = 0
|
||||
let hasMoved = false
|
||||
let dragging = false
|
||||
|
||||
function onResize() {
|
||||
pos = clampPosition(pos)
|
||||
applyPosition(button!, pos)
|
||||
savePosition(pos)
|
||||
}
|
||||
|
||||
function onPointerDown(event: PointerEvent) {
|
||||
dragging = true
|
||||
hasMoved = false
|
||||
pointerId = event.pointerId
|
||||
startX = event.clientX
|
||||
startY = event.clientY
|
||||
originX = pos.x
|
||||
originY = pos.y
|
||||
button!.classList.add('is-dragging')
|
||||
button!.setPointerCapture(event.pointerId)
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
function onPointerMove(event: PointerEvent) {
|
||||
if (!dragging || pointerId !== event.pointerId) return
|
||||
|
||||
const dx = event.clientX - startX
|
||||
const dy = event.clientY - startY
|
||||
|
||||
if (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD) {
|
||||
hasMoved = true
|
||||
}
|
||||
|
||||
pos = clampPosition({ x: originX + dx, y: originY + dy })
|
||||
applyPosition(button!, pos)
|
||||
}
|
||||
|
||||
function finishPointer(event: PointerEvent) {
|
||||
if (!dragging || pointerId !== event.pointerId) return
|
||||
|
||||
dragging = false
|
||||
pointerId = null
|
||||
button!.classList.remove('is-dragging')
|
||||
savePosition(pos)
|
||||
|
||||
const clicked = !hasMoved
|
||||
hasMoved = false
|
||||
|
||||
if (clicked && button!.href && button!.href !== '#') {
|
||||
window.open(button!.href, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
}
|
||||
|
||||
button.addEventListener('pointerdown', onPointerDown)
|
||||
button.addEventListener('pointermove', onPointerMove)
|
||||
button.addEventListener('pointerup', finishPointer)
|
||||
button.addEventListener('pointercancel', finishPointer)
|
||||
button.addEventListener('click', (event) => event.preventDefault())
|
||||
window.addEventListener('resize', onResize)
|
||||
|
||||
void loadSupportMessengerFromSettings().then(() => {
|
||||
updateWhatsappHref(button)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { ref } from 'vue'
|
||||
import { getSettings } from '@/api/configuration'
|
||||
|
||||
export type SupportMessengerType =
|
||||
| 'bale'
|
||||
| 'telegram'
|
||||
| 'whatsapp'
|
||||
| 'rubika'
|
||||
| 'eitaa'
|
||||
| 'soroush'
|
||||
|
||||
export interface SupportMessengerSettings {
|
||||
messenger?: SupportMessengerType | string
|
||||
messengerId?: string
|
||||
messengerText?: string
|
||||
}
|
||||
|
||||
export const supportMessengerSettings = ref<SupportMessengerSettings>({})
|
||||
|
||||
function getActiveSettingValue(settings: Array<{ key?: string; is_active?: boolean; value?: unknown }>, key: string) {
|
||||
const setting = settings.find((item) => item?.key === key && item?.is_active === true)
|
||||
const value = setting?.value
|
||||
if (value === undefined || value === null) return ''
|
||||
return String(value).trim()
|
||||
}
|
||||
|
||||
export function buildSupportMessengerUrl(messenger?: string, messengerId?: string) {
|
||||
const id = (messengerId ?? '').trim()
|
||||
if (!id) return ''
|
||||
|
||||
if (/^https?:\/\//i.test(id)) return id
|
||||
|
||||
const type = (messenger ?? '').trim().toLowerCase()
|
||||
const username = id.replace(/^@/, '')
|
||||
|
||||
switch (type) {
|
||||
case 'bale':
|
||||
if (id.includes('ble.ir')) {
|
||||
return id.startsWith('http') ? id : `https://${id.replace(/^\/\//, '')}`
|
||||
}
|
||||
return `https://ble.ir/${username}`
|
||||
case 'telegram':
|
||||
return `https://t.me/${username}`
|
||||
case 'whatsapp':
|
||||
return `https://wa.me/${username.replace(/\D/g, '')}`
|
||||
case 'rubika':
|
||||
return `https://rubika.ir/${username}`
|
||||
case 'eitaa':
|
||||
return `https://eitaa.com/${username}`
|
||||
case 'soroush':
|
||||
return `https://splus.ir/splus/${username}`
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadSupportMessengerFromSettings() {
|
||||
try {
|
||||
const settings = await getSettings()
|
||||
if (!settings || !Array.isArray(settings)) return
|
||||
|
||||
supportMessengerSettings.value = {
|
||||
messenger: getActiveSettingValue(settings, 'support_messenger'),
|
||||
messengerId: getActiveSettingValue(settings, 'support_messenger_id'),
|
||||
messengerText: getActiveSettingValue(settings, 'support_messenger_text'),
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const DRAG_THRESHOLD = 6
|
||||
|
||||
type FabPosition = { x: number; y: number }
|
||||
|
||||
type DraggableFloatingOptions = {
|
||||
width?: number
|
||||
height?: number
|
||||
defaultBottomOffset?: number
|
||||
defaultRightOffset?: number
|
||||
}
|
||||
|
||||
export function useDraggableFloatingButton(
|
||||
storageKey: string,
|
||||
options: DraggableFloatingOptions = {}
|
||||
) {
|
||||
const width = options.width ?? 96
|
||||
const height = options.height ?? 44
|
||||
const defaultBottomOffset = options.defaultBottomOffset ?? 92
|
||||
const defaultRightOffset = options.defaultRightOffset ?? 20
|
||||
|
||||
const pos = ref<FabPosition>({ x: 0, y: 0 })
|
||||
const dragging = ref(false)
|
||||
|
||||
let pointerId: number | null = null
|
||||
let startX = 0
|
||||
let startY = 0
|
||||
let originX = 0
|
||||
let originY = 0
|
||||
let hasMoved = false
|
||||
|
||||
const fabStyle = computed(() => ({
|
||||
left: `${pos.value.x}px`,
|
||||
top: `${pos.value.y}px`,
|
||||
width: `${width}px`,
|
||||
touchAction: 'none'
|
||||
}))
|
||||
|
||||
function getViewportWidth() {
|
||||
return Math.min(window.innerWidth, 426)
|
||||
}
|
||||
|
||||
function getHorizontalOffset() {
|
||||
const vw = window.innerWidth
|
||||
const contentWidth = getViewportWidth()
|
||||
return Math.max(0, (vw - contentWidth) / 2)
|
||||
}
|
||||
|
||||
function resetToDefault() {
|
||||
const vh = window.innerHeight
|
||||
const offsetX = getHorizontalOffset()
|
||||
const contentWidth = getViewportWidth()
|
||||
|
||||
pos.value = {
|
||||
x: offsetX + contentWidth - width - defaultRightOffset,
|
||||
y: vh - defaultBottomOffset - height
|
||||
}
|
||||
}
|
||||
|
||||
function clampToViewport() {
|
||||
const vw = window.innerWidth
|
||||
const vh = window.innerHeight
|
||||
|
||||
pos.value = {
|
||||
x: Math.max(0, Math.min(vw - width, pos.value.x)),
|
||||
y: Math.max(0, Math.min(vh - height, pos.value.y))
|
||||
}
|
||||
}
|
||||
|
||||
function loadPosition() {
|
||||
try {
|
||||
const raw = localStorage.getItem(storageKey)
|
||||
if (!raw) return false
|
||||
const parsed = JSON.parse(raw) as FabPosition
|
||||
if (typeof parsed?.x === 'number' && typeof parsed?.y === 'number') {
|
||||
pos.value = parsed
|
||||
clampToViewport()
|
||||
return true
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function savePosition() {
|
||||
localStorage.setItem(storageKey, JSON.stringify(pos.value))
|
||||
}
|
||||
|
||||
function handleResize() {
|
||||
clampToViewport()
|
||||
savePosition()
|
||||
}
|
||||
|
||||
function handlePointerDown(event: PointerEvent) {
|
||||
dragging.value = true
|
||||
hasMoved = false
|
||||
pointerId = event.pointerId
|
||||
startX = event.clientX
|
||||
startY = event.clientY
|
||||
originX = pos.value.x
|
||||
originY = pos.value.y
|
||||
;(event.currentTarget as HTMLElement)?.setPointerCapture?.(event.pointerId)
|
||||
}
|
||||
|
||||
function handlePointerMove(event: PointerEvent) {
|
||||
if (!dragging.value || pointerId !== event.pointerId) return
|
||||
|
||||
const dx = event.clientX - startX
|
||||
const dy = event.clientY - startY
|
||||
|
||||
if (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD) {
|
||||
hasMoved = true
|
||||
}
|
||||
|
||||
pos.value = {
|
||||
x: originX + dx,
|
||||
y: originY + dy
|
||||
}
|
||||
clampToViewport()
|
||||
}
|
||||
|
||||
function finishPointer(event: PointerEvent) {
|
||||
if (!dragging.value || pointerId !== event.pointerId) return false
|
||||
|
||||
dragging.value = false
|
||||
pointerId = null
|
||||
savePosition()
|
||||
|
||||
const clicked = !hasMoved
|
||||
hasMoved = false
|
||||
return clicked
|
||||
}
|
||||
|
||||
function handlePointerUp(event: PointerEvent) {
|
||||
return finishPointer(event)
|
||||
}
|
||||
|
||||
function handlePointerCancel(event: PointerEvent) {
|
||||
finishPointer(event)
|
||||
return false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!loadPosition()) {
|
||||
resetToDefault()
|
||||
}
|
||||
window.addEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
return {
|
||||
dragging,
|
||||
fabStyle,
|
||||
handlePointerDown,
|
||||
handlePointerMove,
|
||||
handlePointerUp,
|
||||
handlePointerCancel,
|
||||
resetToDefault
|
||||
}
|
||||
}
|
||||
@@ -80,27 +80,56 @@
|
||||
<!-- Total and Checkout -->
|
||||
<div class=" flex justify-center fixed bottom-20 left-0 right-0 z-1">
|
||||
<div class="md:w-[426px] w-full bg-white border-t border-gray-200 p-4 shadow-lg">
|
||||
<div
|
||||
v-if="discountInfo?.amount > 0"
|
||||
class="mb-3 flex items-center justify-between rounded-lg bg-purple-50 px-3 py-2"
|
||||
>
|
||||
<div class="flex flex-col gap-0.5 text-sm">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-gray-600">کد تخفیف:</span>
|
||||
<span class="font-semibold">{{ discountInfo.code }}</span>
|
||||
</div>
|
||||
<div class="text-xs text-green-600">
|
||||
{{ discountPercentLabel }} تخفیف اعمال شد
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center gap-1 text-xs text-red-500"
|
||||
@click="removeDiscount"
|
||||
>
|
||||
<BasicIcon icon="vuesax-linear:close-circle" size="18" />
|
||||
<span>حذف</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div class="text-lg font-semibold">مجموع:</div>
|
||||
<div class="flex flex-col gap-2 ">
|
||||
<div class="flex flex-col items-end gap-1">
|
||||
<div class="text-primary font-bold text-xl">
|
||||
{{ usePrice(displaytotalPrice) }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="discountInfo?.amount > 0"
|
||||
class="text-xs text-gray-400 line-through"
|
||||
>
|
||||
{{ usePrice(totalPrice) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="!text-primary font-bold text-xs line-through cursor-pointer "
|
||||
v-if="discountInfo?.amount>0"
|
||||
@click="showDiscountModal=true">
|
||||
{{ usePrice(totalPrice) }}
|
||||
</div>
|
||||
<div v-else
|
||||
class="!text-primary font-bold text-xs underline-solid underline cursor-pointer"
|
||||
@click="showDiscountModal=true">
|
||||
کد تخفیف دارم
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="!discountInfo?.amount"
|
||||
class="mb-3 text-center"
|
||||
>
|
||||
<span
|
||||
class="text-xs text-primary underline cursor-pointer"
|
||||
@click="showDiscountModal = true"
|
||||
>
|
||||
کد تخفیف دارم
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<BasicButton
|
||||
class="w-full py-3"
|
||||
type="primary"
|
||||
@@ -186,6 +215,18 @@ const displaytotalPrice = computed(() => {
|
||||
return totalPrice.value
|
||||
})
|
||||
|
||||
const discountPercentLabel = computed(() => {
|
||||
const amount = Number(discountInfo.value?.amount ?? 0)
|
||||
if (amount <= 0) return ''
|
||||
return `${Math.round(amount * 100)}٪`
|
||||
})
|
||||
|
||||
function removeDiscount() {
|
||||
discountInfo.value = undefined
|
||||
discountCode.value = ''
|
||||
message.success('کد تخفیف حذف شد')
|
||||
}
|
||||
|
||||
async function submitDiscount() {
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
@@ -127,8 +127,6 @@
|
||||
src="@/assets/img/logo.png"
|
||||
/>
|
||||
</div>
|
||||
<!-- <div class="flex justify-center">خرید </div>
|
||||
<div class="flex justify-center">محصول </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div :class="setNavColor('buyProduct')" class="tab" @click="setRoute('buyProduct')">
|
||||
@@ -166,16 +164,14 @@
|
||||
<div class="text-xs mt-1 font-bold">درباره ما</div>
|
||||
</div>
|
||||
<div class="main_in">
|
||||
<div class="text-white circle_in">
|
||||
<div class="circle_into " @click="popVisible = !popVisible">
|
||||
<img
|
||||
class="p-2"
|
||||
src="@/assets/img/logo.png"
|
||||
/>
|
||||
</div>
|
||||
<!-- <div class="flex justify-center">خرید </div>
|
||||
<div class="flex justify-center">محصول </div>-->
|
||||
</div>
|
||||
<div class="text-white circle_in">
|
||||
<div class="circle_into " @click="popVisible = !popVisible">
|
||||
<img
|
||||
class="p-2"
|
||||
src="@/assets/img/logo.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div :class="setNavColor('buyProduct')" class="tab" @click="setRoute('buyProduct')">
|
||||
<Icon icon="vuesax-linear:coin" />
|
||||
|
||||
Reference in New Issue
Block a user