Remove user-app v1 and ship pending order, auth, and app fixes.

Drop the duplicate customer app from the monorepo and keep user-app-v2 as the only app; include order pricing, admin cart, OTP/SMS, and dashboard cache updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
mahmood
2026-10-28 16:22:32 +03:30
co-authored by Cursor
parent bc881a0a8a
commit 520454481b
367 changed files with 335 additions and 28536 deletions
@@ -128,6 +128,9 @@
/>
<a-tag v-else color="orange">{{ item.qty }}</a-tag>
</a-descriptions-item>
<a-descriptions-item v-if="Number(item.flatRialCharge) > 0" label="اجرت ریالی">
<a-tag>{{ Number(item.flatRialCharge).toLocaleString('fa-IR') }} ریال</a-tag>
</a-descriptions-item>
<a-descriptions-item label="توضیحات">
<div>{{ item.note }}</div>
</a-descriptions-item>
@@ -121,6 +121,9 @@
<a-descriptions-item label="تعداد">
<a-tag color="orange">{{ item.qty }}</a-tag>
</a-descriptions-item>
<a-descriptions-item v-if="Number(item.flatRialCharge) > 0" label="اجرت ریالی">
<a-tag>{{ Number(item.flatRialCharge).toLocaleString('fa-IR') }} ریال</a-tag>
</a-descriptions-item>
</a-descriptions>
<a-divider v-if="index < tempRow.items.length - 1" />
</div>
@@ -108,6 +108,9 @@
<a-descriptions-item label="تعداد">
<a-tag color="orange">{{ item.qty }}</a-tag>
</a-descriptions-item>
<a-descriptions-item v-if="Number(item.flatRialCharge) > 0" label="اجرت ریالی">
<a-tag>{{ Number(item.flatRialCharge).toLocaleString('fa-IR') }} ریال</a-tag>
</a-descriptions-item>
</a-descriptions>
<a-divider v-if="index < tempRow.items.length - 1" />
</div>
+35 -2
View File
@@ -9,8 +9,9 @@
Price columns: legacy read `price` and `price_with_discount` off each variant,
which the redesigned catalog does not store (gold price is quoted live and
wage is a percentage). Those cells show the gram weight and wage instead of
inventing a Rial figure — see docs/ADMIN-PORT-PLAN.md.
wage is a percentage). Those cells show the gram weight and percent wage.
The fixed rial making charge (rial_pay) is its own editable column and is
sent as rial_input.
-->
<a-spin v-if="hasPermission('order.create')" :spinning="loading">
<a-card title="لیست محصولات" class="page-card">
@@ -67,6 +68,18 @@
{{ getVariant(record).percentage_pay }}٪
</template>
<template v-else-if="column.dataIndex === 'rial'">
<a-input-number
:value="lineRial(record)"
:min="0"
:step="50000"
style="width: 140px"
:formatter="rialFormatter"
:parser="rialParser"
@change="onRialChange(index, $event)"
/>
</template>
<template v-else-if="column.dataIndex === 'qty'">
<!--
legacy capped quantity at the variant's stock, falling back to
@@ -262,11 +275,16 @@ const columns = [
{ title: 'کد محصول', dataIndex: 'pid', align: 'center', width: 90 },
{ title: 'محصول', dataIndex: 'product' },
{ title: 'اجرت', dataIndex: 'wage', align: 'center' },
{ title: 'اجرت ریالی', dataIndex: 'rial', align: 'center', width: 160 },
{ title: 'تعداد', dataIndex: 'qty', align: 'center', width: 140 },
{ title: 'وزن', dataIndex: 'weight', align: 'center', width: 90 },
{ title: 'مجموع', dataIndex: 'total', align: 'center' },
];
const rialFormatter = (val: string | number | undefined) =>
val ? `${val}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '';
const rialParser = (val: string | undefined) => (val ? val.replace(/,/g, '') : '');
// ── inline weight editor
const variant = reactive<{ id?: string; grams?: number }>({});
@@ -303,6 +321,20 @@ function onQtyChange(index: number, value: unknown) {
cart.updateItemQuantity({ index, quantity: Number(value) });
}
/** Unset on the line means the variant's rial_pay; 0 means the operator cleared it. */
function lineRial(item: CartItem): number {
if (item.rial_input != null) {
const n = Number(item.rial_input);
return Number.isFinite(n) ? n : 0;
}
const n = Number(getVariant(item).rial_pay ?? 0);
return Number.isFinite(n) ? n : 0;
}
function onRialChange(index: number, value: number | string | null) {
cart.updateItemRial({ index, rial: value == null || value === '' ? 0 : Number(value) });
}
function onVariantPick(record: Record<string, any>, e: { key: string | number }) {
addToCart(record, String(e.key));
}
@@ -374,6 +406,7 @@ async function submitOrder() {
qty: x.qty,
percent: v.percentage_pay,
promotion_id: x.promotion_id,
rial_input: lineRial(x),
};
});