changes of boursecu

This commit is contained in:
2026-06-29 11:20:02 +02:00
parent 809bd69068
commit 2583becda7
21 changed files with 748 additions and 261 deletions
@@ -2,103 +2,64 @@
<div class="boursecu-transactions pb-[calc(var(--app-bottom-chrome-height)+1rem)]">
<MobilePageHeader title="تراکنش ها" />
<div class="mpage-content">
<div class="boursecu-transactions__tabs px-4">
<div class="flex gap-5 overflow-x-auto whitespace-nowrap pb-1">
<button
v-for="tab in BOURSECU_TRANSACTION_TABS"
:key="tab.id"
type="button"
class="boursecu-transactions__tab shrink-0"
:class="{ 'boursecu-transactions__tab--active': activeTabId === tab.id }"
@click="setActiveTab(tab.id)"
>
{{ tab.label }}
</button>
</div>
</div>
<div v-if="activeTab.showTradeToggle" class="px-4 mt-4 flex justify-end">
<div class="boursecu-transactions__trade-toggle">
<button
type="button"
class="boursecu-transactions__trade-toggle-item"
:class="{ 'boursecu-transactions__trade-toggle-item--active': tradeSide === 'buy' }"
@click="setTradeSide('buy')"
>
خرید
</button>
<button
type="button"
class="boursecu-transactions__trade-toggle-item"
:class="{ 'boursecu-transactions__trade-toggle-item--active': tradeSide === 'sell' }"
@click="setTradeSide('sell')"
>
فروش
</button>
</div>
</div>
<div v-if="activeTab.showAdvancedFilters" class="boursecu-transactions__filters px-4 mt-4">
<div class="boursecu-transactions__filters-label">
<BasicIcon icon="vuesax-linear:filter" size="16" />
<span>فیلترها:</span>
</div>
<a-select
v-model:value="statusFilter"
allow-clear
class="boursecu-transactions__filter-select"
placeholder="وضعیت"
size="large"
@change="applyInlineFilters"
>
<a-select-option
v-for="option in statusOptions"
:key="option.value"
:value="option.value"
>
{{ option.label }}
</a-select-option>
</a-select>
<div class="boursecu-transactions__filter-dates">
<BaseDatePicker
v-model:value="dateFromFilter"
class="boursecu-transactions__filter-date"
placeholder="تاریخ از"
size="large"
@onchange="applyInlineFilters"
/>
<BaseDatePicker
v-model:value="dateToFilter"
class="boursecu-transactions__filter-date"
placeholder="تاریخ تا"
size="large"
@onchange="applyInlineFilters"
/>
</div>
</div>
<div ref="listRef" :class="loading ? 'min-h-[50vh]' : ''" class="px-4 mt-5">
<list-anim v-if="!loading">
<Item v-for="item in items" :key="item.id" :item="item" />
<div :ref="bindMobileObserver" class="w-full opacity-0 relative">
در حال بارگذاری
<div class="mpage-content px-4">
<div class="dtxn-toolbar boursecu-transactions__toolbar">
<div class="dtxn-tabs">
<button
v-for="tab in BOURSECU_TRANSACTION_TABS"
:key="tab.id"
type="button"
class="dtxn-tabs__btn"
:class="{ 'dtxn-tabs__btn--active': activeTabId === tab.id }"
@click="setActiveTab(tab.id)"
>
{{ tab.label }}
</button>
</div>
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
</list-anim>
<template v-else>
<TransactionSkeleton v-for="i in 8" :key="i" class="mt-1" />
</template>
<div
v-if="!loading && items.length === 0"
class="boursecu-transactions__empty"
>
<img :src="emptyImage" alt="" class="boursecu-transactions__empty-image" />
<p class="boursecu-transactions__empty-text">{{ emptyText }}</p>
<div v-if="activeTab.showTradeToggle" class="dtxn-toggle">
<button
type="button"
class="dtxn-toggle__btn"
:class="{ 'dtxn-toggle__btn--active': tradeSide === 'buy' }"
@click="setTradeSide('buy')"
>
خرید
</button>
<button
type="button"
class="dtxn-toggle__btn"
:class="{ 'dtxn-toggle__btn--active': tradeSide === 'sell' }"
@click="setTradeSide('sell')"
>
فروش
</button>
</div>
</div>
<BoursecuTransactionFilters
v-if="activeTab.showAdvancedFilters"
mobile-layout
/>
<div ref="listRef" :class="loading ? 'min-h-[50vh]' : ''" class="mt-5">
<list-anim v-if="!loading">
<Item v-for="item in items" :key="item.id" :item="item" />
<div :ref="bindMobileObserver" class="w-full opacity-0 relative">
در حال بارگذاری
</div>
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
</list-anim>
<template v-else>
<TransactionSkeleton v-for="i in 8" :key="i" class="mt-1" />
</template>
<div v-if="!loading && items.length === 0" class="dtxn-empty">
<img :src="emptyImage" alt="" class="dtxn-empty__image" />
<p class="dtxn-empty__text">{{ emptyText }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
@@ -106,13 +67,12 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { loading, loadingMore } from '@/utils'
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
import ListAnim from '@/components/ListAnim.vue'
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
import emptyImage from '@/assets/img/cash_empty.svg'
import Item from './components/Item.vue'
import BoursecuTransactionFilters from './components/BoursecuTransactionFilters.vue'
import { BOURSECU_TRANSACTION_TABS } from './config/boursecuTabs'
import { useTransactionsPageContext } from './composables/useTransactionsPage'
@@ -120,123 +80,45 @@ const listRef = ref<HTMLElement | null>(null)
const {
items,
dateFromFilter,
dateToFilter,
statusFilter,
statusOptions,
activeTabId,
tradeSide,
activeTab,
emptyText,
setActiveTab,
setTradeSide,
applyInlineFilters,
bindMobileObserver,
} = useTransactionsPageContext()
</script>
<style scoped lang="less">
<style lang="less">
@import './desktop/styles/desktop-transactions.less';
.boursecu-transactions {
background: #fff;
min-height: 100%;
}
.boursecu-transactions__tab {
appearance: none;
cursor: pointer;
border: none;
background: transparent;
padding: 0 0 0.5rem;
font-size: 0.875rem;
font-weight: 600;
color: #8b9490;
border-bottom: 2px solid transparent;
transition: color 0.2s ease, border-color 0.2s ease;
}
.boursecu-transactions__tab--active {
color: #1f2937;
border-bottom-color: #e8b923;
}
.boursecu-transactions__trade-toggle {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 3px;
border-radius: 10px;
background: #eceff1;
}
.boursecu-transactions__trade-toggle-item {
appearance: none;
cursor: pointer;
min-width: 5.5rem;
padding: 0.45rem 1rem;
border: 1px solid transparent;
border-radius: 8px;
background: transparent;
color: #6b7280;
font-size: 0.875rem;
font-weight: 600;
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.boursecu-transactions__trade-toggle-item--active {
background: #fff;
border-color: #d4e3de;
color: #1f2937;
.boursecu-transactions__toolbar {
margin-top: 4px;
margin-bottom: 16px;
}
.boursecu-transactions__filters {
display: flex;
flex-direction: column;
gap: 10px;
}
align-items: stretch;
.boursecu-transactions__filters-label {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.875rem;
color: #6b7280;
}
.boursecu-transactions__filter-select {
width: 100%;
}
.boursecu-transactions__filter-dates {
display: flex;
gap: 10px;
width: 100%;
.dtxn-filters__product {
max-width: none;
}
}
.boursecu-transactions__filter-select,
.boursecu-transactions__filter-date {
flex: 1;
width: 100%;
min-width: 0;
}
.boursecu-transactions__empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem 1rem 4rem;
text-align: center;
}
.boursecu-transactions__empty-image {
width: 11rem;
max-width: 60vw;
height: auto;
object-fit: contain;
}
.boursecu-transactions__empty-text {
margin-top: 1rem;
font-size: 0.95rem;
font-weight: 600;
color: #6b7280;
.boursecu-transactions__filter-dates {
width: 100%;
}
</style>