Files
boursecu_user/src/views/base/transactions/desktop/DesktopBoursecuTransactionsView.vue
T
safavimohadeseh78andCursor a5e458ed25 Split desktop and mobile layouts with shared page data so APIs fetch once per context.
Add layout shells, desktop views, module-level page caches, and UI fixes for auth, home, wallet, transactions, address, and related pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 10:08:46 +03:30

127 lines
3.8 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="dtxn">
<div class="dtxn__container">
<header class="dtxn-topbar">
<p class="dtxn-topbar__eyebrow">گزارش‌ها</p>
<h1 class="dtxn-topbar__title">تراکنش‌ها</h1>
</header>
<div class="dtxn-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>
<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>
<div class="dtxn-filters">
<div class="dtxn-filters__label">
<BasicIcon icon="vuesax-linear:filter" size="16" />
<span>فیلترها:</span>
</div>
<a-select
v-model:value="statusFilter"
allow-clear
class="dtxn-filters__select"
placeholder="وضعیت"
size="large"
@change="applyInlineFilters"
>
<a-select-option value="active">فعال</a-select-option>
<a-select-option value="inactive">غیرفعال</a-select-option>
</a-select>
<BaseDatePicker
v-model:value="dateFilter"
class="dtxn-filters__date"
placeholder="تاریخ"
size="large"
@onchange="applyInlineFilters"
/>
</div>
<div ref="listRef" :class="loading ? 'min-h-[40vh]' : ''" class="mt-5">
<div v-if="!loading" class="dtxn-list">
<list-anim>
<Item
v-for="item in items"
:key="item.id"
:item="item"
variant="desktop"
/>
</list-anim>
<div :ref="bindDesktopObserver" class="w-full opacity-0 relative">
در حال بارگذاری
</div>
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
</div>
<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>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { loading, loadingMore } from '@/utils'
import BasicIcon from '@/components/BasicPacks/BasicIcon.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 { BOURSECU_TRANSACTION_TABS } from '../config/boursecuTabs'
import { useTransactionsPageContext } from '../composables/useTransactionsPage'
const listRef = ref<HTMLElement | null>(null)
const {
items,
dateFilter,
statusFilter,
activeTabId,
tradeSide,
activeTab,
emptyText,
setActiveTab,
setTradeSide,
applyInlineFilters,
bindDesktopObserver,
} = useTransactionsPageContext()
</script>
<style lang="less" src="./styles/desktop-transactions.less"></style>