Merge remote-tracking branch 'origin/modular' into modular

This commit is contained in:
2026-06-04 22:33:41 +03:30
9 changed files with 123 additions and 30 deletions
@@ -3,22 +3,23 @@
<template #default="{ item: row }">
<MobileSheetHeader :title="row.name || '-'" :show-title="isMobile">
<template #actions>
<MobileIconButton plain icon="vuesax-linear:archive-tick" color="#e3bf00" :size="22" @click="$emit('archive', row)" />
<MobileIconButton plain icon="vuesax-linear:archive-tick" color="#e3bf00" :size="22" @click="closeAndEmit('archive', row)" />
<MobileIconButton
plain
:icon="row.active ? 'vuesax-linear:user-tick' : 'vuesax-linear:user-remove'"
:color="row.active ? '#54AD06' : '#ad0627'"
:size="22"
@click="$emit('toggleActive', row)"
@click="confirmToggleActive(row)"
/>
<MobileIconButton plain icon="vuesax-linear:wallet-add" color="#9333ea" :size="22" @click="$emit('chargeMoney', row)" />
<MobileIconButton plain icon="vuesax-linear:wallet-money" color="#ea580c" :size="22" @click="$emit('chargeGold', row)" />
<MobileIconButton plain icon="vuesax-linear:wallet-add" color="#9333ea" :size="22" @click="closeAndEmit('chargeMoney', row)" />
<MobileIconButton plain icon="vuesax-linear:wallet-money" color="#ea580c" :size="22" @click="closeAndEmit('chargeGold', row)" />
<MobileIconButton plain icon="vuesax-linear:stickynote" color="#10913A" :size="22" @click="closeAndEmit('info', row)" />
<MobileIconButton
plain
:icon="row.trade_active ? 'vuesax-linear:box-tick' : 'vuesax-linear:box-remove'"
:color="row.trade_active ? '#54AD06' : '#ad0627'"
:size="22"
@click="$emit('toggleTrade', row)"
@click="confirmToggleTrade(row)"
/>
<MobileIconButton
v-if="!(row as any).is_legal"
@@ -26,7 +27,7 @@
icon="vuesax-linear:user-search"
color="#0d9488"
:size="22"
@click="$emit('confirmUser', row)"
@click="closeAndEmit('confirmUser', row)"
/>
</template>
</MobileSheetHeader>
@@ -72,7 +73,9 @@
</template>
<script setup lang="ts">
import { Modal } from 'ant-design-vue'
import type { Customer } from '@/model/customer'
import { MODAL_ABOVE_ACTION_SHEET_Z_INDEX } from '@/constants/overlayZIndex'
import MobileDetailRow from '@/components/mobile/MobileDetailRow.vue'
import MobileStatCard from '@/components/mobile/MobileStatCard.vue'
import MobileDetailSheet from '@/components/mobile/MobileDetailSheet.vue'
@@ -116,4 +119,40 @@ function goldBalance(row: Customer) {
function lastSeen(row: Customer) {
return row.last_seen_at ? toJalali(row.last_seen_at) : '-'
}
type SheetEmit =
| 'archive'
| 'chargeMoney'
| 'chargeGold'
| 'info'
| 'confirmUser'
function closeAndEmit(event: SheetEmit, row: Customer) {
visibleProxy.value = false
emit(event, row)
}
function confirmToggleActive(row: Customer) {
Modal.confirm({
title: row.active ? 'آیا حساب کاربری را غیرفعال می‌کنید؟' : 'آیا حساب کاربری را فعال می‌کنید؟',
okText: 'تایید',
cancelText: 'رد',
centered: true,
zIndex: MODAL_ABOVE_ACTION_SHEET_Z_INDEX,
onOk: () => emit('toggleActive', row)
})
}
function confirmToggleTrade(row: Customer) {
Modal.confirm({
title: row.trade_active
? 'آیا سفارش دهی را غیرمجاز می‌کنید؟'
: 'آیا سفارش دهی را مجاز می‌کنید؟',
okText: 'تایید',
cancelText: 'رد',
centered: true,
zIndex: MODAL_ABOVE_ACTION_SHEET_Z_INDEX,
onOk: () => emit('toggleTrade', row)
})
}
</script>
@@ -69,7 +69,7 @@
<a-form-item v-if="getConfigApp('name') === 'boursecu'" label="دسته بندی" name="group_type" :rules="inputRules()">
<BasicSelect v-model:value="form.group_type" :items="boursemesCategoryItems" valueName="value" keyName="value" />
</a-form-item>
<a-form-item v-if="getConfigApp('name') === 'garoosi'" label="دسته بندی" name="group_type" :rules="inputRules()">
<a-form-item v-else-if="getConfigApp('name') === 'garoosi'" label="دسته بندی" name="group_type" :rules="inputRules()">
<BasicSelect v-model:value="form.group_type" :items="garoosiCategoryItems" valueName="value" keyName="value" />
</a-form-item>
<a-form-item v-else label="دسته بندی" name="group_type" :rules="inputRules()">
@@ -1,26 +1,37 @@
<template>
<div class="flex h-full min-h-0 min-w-0 max-w-full flex-col overflow-hidden">
<div class="shrink-0 pr-3 md:flex">
<div class="content-center">فعال سازی محصولات:</div>
<div class="ml-2 content-center mt-1 md:mt-unset md:mr-4">زمان شروع</div>
<div>
<TimePicker
v-model:value="startTime"
:locale="customLocale"
placeholder="انتخاب زمان"
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
/>
</div>
<div class="md:mr-4 ml-2 mt-2 md:mt-unset content-center">زمان پایان</div>
<div>
<TimePicker
v-model:value="endTime"
:locale="customLocale"
placeholder="انتخاب زمان"
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
/>
</div>
<BaseButton class="mt-2 md:mt-unset md:mr-2" @click="setTimeActive(startTime, endTime)">ثبت</BaseButton>
<div class="shrink-0">
<Collapse
class="product-activation-collapse"
:activeKey="activationActiveKey"
@update:activeKey="activationActiveKey = $event as (string | number)[]"
>
<BaseCollapse title="فعال سازی محصولات" active-key="activation" :actives="activationActiveKey">
<template #content>
<div class="flex flex-col gap-2 md:flex-row md:flex-wrap md:items-center">
<div class="content-center md:mr-4">زمان شروع</div>
<div>
<TimePicker
v-model:value="startTime"
:locale="customLocale"
placeholder="انتخاب زمان"
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
/>
</div>
<div class="content-center md:mr-4">زمان پایان</div>
<div>
<TimePicker
v-model:value="endTime"
:locale="customLocale"
placeholder="انتخاب زمان"
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
/>
</div>
<BaseButton class="md:mr-2" @click="setTimeActive(startTime, endTime)">ثبت</BaseButton>
</div>
</template>
</BaseCollapse>
</Collapse>
</div>
<BasicShowContext title="لیست محصولات" class="min-h-0 flex-1">
@@ -97,7 +108,8 @@
</template>
<script setup lang="ts">
import { message, Modal, TimePicker } from 'ant-design-vue'
import { Collapse, message, Modal, TimePicker } from 'ant-design-vue'
import BaseCollapse from '@/components/BaseCollapse.vue'
import locale from 'ant-design-vue/es/date-picker/locale/fa_IR'
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
@@ -122,6 +134,7 @@ const [submit, reload] = useBaseTable()
const emits = defineEmits(['edit', 'add'])
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
const activationActiveKey = ref<(string | number)[]>(isMobile.value ? [] : ['activation'])
const startTime = ref(dayjs('00:00:00', 'HH:mm:ss'))
const endTime = ref(dayjs('00:00:00', 'HH:mm:ss'))
@@ -195,4 +208,18 @@ async function setTimeActive(start: dayjs.Dayjs | string, end: dayjs.Dayjs | str
.ant-tooltip {
z-index: 1001 !important;
}
.product-activation-collapse.ant-collapse {
:deep(> .ant-collapse-item > .ant-collapse-header) {
padding: 0 !important;
}
:deep(.ant-collapse-content-box) {
padding: 0 !important;
}
:deep(.ant-collapse-header .mb-3) {
margin-bottom: 0 !important;
}
}
</style>