fix(finance): shared treasury layout so tab switches stop jumping

Keep title and nav mounted in TreasuryLayout with stable header height, and finish Ant form chrome (MoneyInput, Jalali) on finance pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-21 21:47:00 +03:30
co-authored by Cursor
parent 23ae273232
commit cb5944e767
15 changed files with 907 additions and 476 deletions
@@ -1,10 +1,20 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import {
Alert as AAlert,
Card as ACard,
Empty as AEmpty,
Flex as AFlex,
List as AList,
Typography,
} from 'ant-design-vue';
import { api } from '@/lib/api';
import { UiPageHeader } from '@/components/ui';
import TreasuryNav from '@/components/treasury/TreasuryNav.vue';
import { formatJalaliNumeric } from '@/lib/jalali';
const { Paragraph: ATypographyParagraph } = Typography;
const AListItem = AList.Item;
const AListItemMeta = AList.Item.Meta;
type Row = {
id: string;
action: string;
@@ -32,26 +42,31 @@ onMounted(async () => {
</script>
<template>
<section class="page">
<UiPageHeader title="سوابق تغییرات مالی" description="تسویه سند و نشستن وجه در صندوق، با مقدار ثبت‌شده." />
<TreasuryNav />
<p v-if="error" class="err">{{ error }}</p>
<p v-if="!error && !rows.length" class="muted">سابقه‌ای نیست.</p>
<article v-for="row in rows" :key="row.id">
<header>
<strong>{{ actionLabel[row.action] ?? row.action }}</strong>
<time>{{ formatJalaliNumeric(new Date(row.createdAt)) }}</time>
</header>
<pre>{{ JSON.stringify(row.after ?? row.before, null, 2) }}</pre>
</article>
</section>
</template>
<a-flex vertical :gap="16">
<a-alert v-if="error" type="error" show-icon :message="error" />
<style scoped>
.page { display: grid; gap: 0.8rem; }
article { background: #fff; border: 1px solid #e7eef2; border-radius: 14px; padding: 0.8rem 1rem; }
header { display: flex; justify-content: space-between; gap: 0.75rem; }
time, .muted { color: #64748b; }
pre { margin: 0.45rem 0 0; white-space: pre-wrap; font: inherit; color: #334155; }
.err { color: #b91c1c; font-weight: 700; }
</style>
<a-card :bordered="false">
<a-empty v-if="!error && !rows.length" description="سابقه‌ای نیست." />
<a-list v-else item-layout="vertical" :data-source="rows">
<template #renderItem="{ item }">
<a-list-item>
<a-list-item-meta>
<template #title>
{{ actionLabel[item.action] ?? item.action }}
</template>
<template #description>
{{ formatJalaliNumeric(new Date(item.createdAt)) }}
</template>
</a-list-item-meta>
<a-typography-paragraph
:copyable="true"
:style="{ marginBottom: 0, whiteSpace: 'pre-wrap', fontFamily: 'inherit' }"
>
{{ JSON.stringify(item.after ?? item.before, null, 2) }}
</a-typography-paragraph>
</a-list-item>
</template>
</a-list>
</a-card>
</a-flex>
</template>