From 5bec4848a24aa2a24c514c356132318f77b3b251 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Fri, 3 Jul 2026 10:31:16 +0330 Subject: [PATCH] feat: unify currency display to toman across the application --- .../prompt/currency-toman-display-front.md | 93 +++++++++++++++++++ app/dashboard/page.js | 3 +- app/payment/[uuid]/page.js | 7 +- components/appointment/paying/index.js | 7 +- components/dashboard/userAccount/Head.js | 2 +- .../userAccount/sidebars/transactions/Card.js | 3 +- .../userAccount/sidebars/transactions/List.js | 5 +- lib/money.js | 8 ++ 8 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 .claude/prompt/currency-toman-display-front.md create mode 100644 lib/money.js diff --git a/.claude/prompt/currency-toman-display-front.md b/.claude/prompt/currency-toman-display-front.md new file mode 100644 index 0000000..a9962ff --- /dev/null +++ b/.claude/prompt/currency-toman-display-front.md @@ -0,0 +1,93 @@ +# واحد پول = تومان در سایت عمومی (نمایش ÷۱۰ / ورودی ×۱۰) — API ریال می‌ماند + +## پروژه + +`nobat724_front` (سایت عمومی). **cross-repo:** پرامپت همتا (ادمین): `clinicpro/.claude/prompt/currency-toman-display-admin.md`. API بک‌اند (`clinicpro`) واحدش **ریال** است و تغییر نمی‌کند؛ فیلدهای `*_rials` ریال برمی‌گردانند. + +## زمینه + +واحد نمایشِ سایت باید **تومان** باشد، اما API همهٔ مبالغ را **ریال** می‌دهد و می‌گیرد (`appointment_fee_rials`، `amount_rials`، …) و ارسال به درگاه هم ریال است (بک‌اند مدیریت می‌کند). پس فقط باید در **UI** مقدار ریال ÷۱۰ و با «تومان» نشان داده شود، و اگر جایی مبلغ از کاربر گرفته می‌شود ×۱۰ به ریال تبدیل شود. + +الان ناهماهنگ است: بعضی جاها عددِ `*_rials` خام با برچسب «ریال» نمایش داده می‌شود (`paying`, transactions, payment result, dashboard balance) و یک‌جا (`app/dashboard/page.js`) دستی `/10` شده. باید یکدست شود. + +## مشکل / هدف + +همهٔ مبالغِ نمایشی در سایت به **تومان** (÷۱۰ از مقدار ریالِ API) با برچسب «تومان» نشان داده شوند؛ منطق پرداخت/ارسال به درگاه (سمت بک‌اند، ریال) دست نخورد. + +## فایل‌های مرتبط + +| فایل | نقش | +|------|-----| +| `nobat724_front/lib/money.js` | **جدید** — helper تبدیل/فرمت مرکزی | +| `nobat724_front/components/appointment/paying/index.js` | مبلغ نوبت + دکمهٔ پرداخت (ریال→تومان) | +| `nobat724_front/components/dashboard/userAccount/sidebars/transactions/Card.js` | مبلغ تراکنش | +| `nobat724_front/components/dashboard/userAccount/sidebars/transactions/List.js` | مبلغ تراکنش | +| `nobat724_front/components/dashboard/userAccount/Head.js` | برچسب/موجودی | +| `nobat724_front/app/payment/[uuid]/page.js` | مبلغ نتیجهٔ پرداخت | +| `nobat724_front/app/dashboard/page.js` | جمع تراکنش‌ها (حذف `/10` دستی، استفاده از helper) | + +> با `grep -rn "ریال\|amount_rials\|_rials\|toLocaleString" components app` بقیهٔ نقاط مبلغ را هم پیدا و یکدست کن. + +## وضعیت فعلی + +### `components/appointment/paying/index.js` +```js +setFeeRials(Number(res?.data?.appointment_fee_rials) || 0); +// ... +const rials = feeRials != null ? feeRials.toLocaleString("fa-IR") : "—"; +// ... +{rials} ریال +// ... +{testMode ? "پرداخت آزمایشی" : `پرداخت ${rials} ریال`} +``` +مقدارِ ریالِ خام را با «ریال» نشان می‌دهد (باید تومان). + +### `app/dashboard/page.js` (تبدیل دستی ناهماهنگ) +```js +const totalTransactions = Math.round(totalRials / 10); // ریال → تومان +``` + +### `app/payment/[uuid]/page.js` +```js +{formatAmount(payment.amount_rials)} ریال +``` + +## وظایف + +### ۱. helper مرکزی `lib/money.js` + +```js +export const RIAL_PER_TOMAN = 10; +export const rialToToman = (rial) => Math.round((Number(rial) || 0) / RIAL_PER_TOMAN); +export const tomanToRial = (toman) => Math.round((Number(toman) || 0) * RIAL_PER_TOMAN); +// فرمت فارسیِ مبلغِ تومان از مقدار ریالِ API +export const formatToman = (rial) => rialToToman(rial).toLocaleString("fa-IR"); +``` + +### ۲. `paying/index.js` + +- نمایش مبلغ: `const toman = feeRials != null ? formatToman(feeRials) : "—";` +- جای «ریال» → «تومان»؛ دکمه: `پرداخت ${toman} تومان`. +- `feeRials` را همچنان از `appointment_fee_rials` بگیر (ریال)؛ فقط نمایش تبدیل شود. **مبلغی که برای شروع پرداخت به بک‌اند/درگاه می‌رود تغییر نکند** (بک‌اند ریال می‌فرستد). + +### ۳. تراکنش‌ها و موجودی داشبورد + +- `transactions/Card.js` و `List.js`: `Number(data.amount_rials)` خام + «ریال» → `formatToman(data.amount_rials)` + «تومان». +- `userAccount/Head.js`: موجودی/برچسب «ریال» → تومان (اگر عددی خام کنارش هست با `formatToman`). +- `app/dashboard/page.js`: به‌جای `Math.round(totalRials/10)` از `rialToToman(totalRials)` استفاده کن (همان نتیجه، یکدست). + +### ۴. صفحهٔ نتیجهٔ پرداخت + +- `app/payment/[uuid]/page.js`: `{formatAmount(payment.amount_rials)} ریال` → `{formatToman(payment.amount_rials)} تومان` (یا `formatAmount` را با `rialToToman` هماهنگ کن؛ اگر `formatAmount` جای دیگری هم استفاده می‌شود، دوباره‌تبدیل نشود). + +### ۵. جستجوی باقی‌ماندهٔ «ریال» + +`grep -rn "ریال" components app` → هر مبلغِ خام ریال را `formatToman` + «تومان» کن. برچسب‌های ثابت «ریال» به «تومان». + +## نکات مهم + +- **API/درگاه ریال می‌ماند:** هیچ فراخوانی `services/response.js` و هیچ مقدارِ ارسالی به بک‌اند تغییر نمی‌کند؛ فقط نمایش. مبلغ پرداخت را بک‌اند (ریال) مدیریت می‌کند. +- **ورودی پول (اگر هست):** اگر جایی کاربر مبلغ وارد می‌کند که به API می‌رود، با `tomanToRial` به ریال تبدیل کن (در این سایت معمولاً ورودی پول نیست؛ بیشتر نمایش است). +- **double-convert نکن:** جایی که قبلاً `/10` شده (dashboard/page.js) را با helper جایگزین کن، نه اضافه. +- **RTL/فونت/Jalali** مثل قبل؛ فقط عدد و برچسب واحد عوض می‌شود. +- تست: `npm run lint` و `npm run build` بدون خطا؛ سپس چشمی صفحهٔ پرداخت نوبت، داشبورد تراکنش‌ها، و نتیجهٔ پرداخت — اعداد باید ۱۰ برابر کوچک‌تر و با «تومان» باشند. diff --git a/app/dashboard/page.js b/app/dashboard/page.js index fedf132..202d9df 100644 --- a/app/dashboard/page.js +++ b/app/dashboard/page.js @@ -6,6 +6,7 @@ import { removeToken } from "@/utils"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { fetchReq } from "@/lib/req"; +import { rialToToman } from "@/lib/money"; import { safeJsonParse } from "@/lib/sanitize"; import { buildPatientUser } from "@/lib/representationAdapters"; import { getServerAccessToken } from "@/lib/serverToken"; @@ -44,7 +45,7 @@ export default async function Dashboard({ searchParams }) { const totalRials = payments .filter((p) => p.status === "success") .reduce((sum, p) => sum + (Number(p.amount_rials) || 0), 0); - const totalTransactions = Math.round(totalRials / 10); // ریال → تومان + const totalTransactions = rialToToman(totalRials); // ریال → تومان const extras = { mobile: userInfo?.mobile_number ?? "", diff --git a/app/payment/[uuid]/page.js b/app/payment/[uuid]/page.js index e6afa52..45d793e 100644 --- a/app/payment/[uuid]/page.js +++ b/app/payment/[uuid]/page.js @@ -3,6 +3,7 @@ import { useEffect, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { request } from "@/services/response"; +import { formatToman } from "@/lib/money"; import Cookies from "js-cookie"; import Layout from "@/components/layout"; @@ -95,9 +96,7 @@ export default function PaymentDetailsPage() { }).format(date); }; - const formatAmount = (rials) => { - return new Intl.NumberFormat("fa-IR").format(parseInt(rials)); - }; + const formatAmount = (rials) => formatToman(rials); if (loading) { return ( @@ -153,7 +152,7 @@ export default function PaymentDetailsPage() {
مبلغ: - {formatAmount(payment.amount_rials)} ریال + {formatAmount(payment.amount_rials)} تومان
diff --git a/components/appointment/paying/index.js b/components/appointment/paying/index.js index a2a4e30..a4c1b6c 100644 --- a/components/appointment/paying/index.js +++ b/components/appointment/paying/index.js @@ -4,6 +4,7 @@ import ArrowLeftB from "@/components/icons/ArrowLeftB"; import { Button, MenuItem, Select, FormControl, InputLabel } from "@mui/material"; import ButtonFixed from "./ButtonFixed"; import { request } from "@/services/response"; +import { formatToman } from "@/lib/money"; const PAYMENT_TTL = 900; @@ -44,7 +45,7 @@ function Paying({ setStep, appointmentId, expiresAt, doctor, data, isForAnother, return `${m}:${s.toString().padStart(2, "0")}`; }; - const rials = feeRials != null ? feeRials.toLocaleString("fa-IR") : "—"; + const toman = feeRials != null ? formatToman(feeRials) : "—"; const patientName = isForAnother ? [data?.name?.value, data?.family?.value].filter(Boolean).join(" ").trim() : data?.name?.value; @@ -105,7 +106,7 @@ function Paying({ setStep, appointmentId, expiresAt, doctor, data, isForAnother, مبلغ قابل پرداخت - {rials} ریال + {toman} تومان @@ -203,7 +204,7 @@ function Paying({ setStep, appointmentId, expiresAt, doctor, data, isForAnother, } > - {testMode ? "پرداخت آزمایشی" : `پرداخت ${rials} ریال`} + {testMode ? "پرداخت آزمایشی" : `پرداخت ${toman} تومان`} {!loading && } diff --git a/components/dashboard/userAccount/Head.js b/components/dashboard/userAccount/Head.js index 0cf009f..c470d21 100644 --- a/components/dashboard/userAccount/Head.js +++ b/components/dashboard/userAccount/Head.js @@ -48,7 +48,7 @@ function Head({ user }) {

{Number(user?.total_transactions || 0).toLocaleString("fa-IR")}{" "} - ریال + تومان

مجموع تراکنش ها diff --git a/components/dashboard/userAccount/sidebars/transactions/Card.js b/components/dashboard/userAccount/sidebars/transactions/Card.js index b075cfa..1e9db60 100644 --- a/components/dashboard/userAccount/sidebars/transactions/Card.js +++ b/components/dashboard/userAccount/sidebars/transactions/Card.js @@ -1,5 +1,6 @@ import TextLoading from "@/app/component/loading/Text"; import { convertTimestampToJalali } from "@/helper"; +import { formatToman } from "@/lib/money"; import Link from "next/link"; const PAYMENT_STATUS = { @@ -62,7 +63,7 @@ function Card({ data, loading }) {

- {data.amount_rials ? Number(data.amount_rials).toLocaleString("fa-IR") : "--"} ریال + {data.amount_rials ? formatToman(data.amount_rials) : "--"} تومان

diff --git a/components/dashboard/userAccount/sidebars/transactions/List.js b/components/dashboard/userAccount/sidebars/transactions/List.js index 7863d68..c68ba4c 100644 --- a/components/dashboard/userAccount/sidebars/transactions/List.js +++ b/components/dashboard/userAccount/sidebars/transactions/List.js @@ -6,6 +6,7 @@ import TextLoading from "@/app/component/loading/Text"; import CustomLoading from "@/app/component/loading/Custom"; import CircularLoading from "@/app/component/loading/Circular"; import { convertTimestampToJalali } from "@/helper"; +import { formatToman } from "@/lib/money"; import Pagination from "@/app/component/Pagination"; import Link from "next/link"; @@ -25,7 +26,7 @@ const TYPE_LABELS = { function List({ payments, loading, page, totalPages, onPageChange }) { const rows = Array.isArray(payments) ? payments : []; - const tableHead = ["ردیف", "شناسه پرداخت", "نوع", "تاریخ", "مبلغ (ریال)", "وضعیت"]; + const tableHead = ["ردیف", "شناسه پرداخت", "نوع", "تاریخ", "مبلغ (تومان)", "وضعیت"]; const centerTable = [0, 4, 5]; if (!loading && rows.length === 0) { @@ -80,7 +81,7 @@ function List({ payments, loading, page, totalPages, onPageChange }) { align="right" > - {row.amount_rials ? Number(row.amount_rials).toLocaleString("fa-IR") : "--"} + {row.amount_rials ? formatToman(row.amount_rials) : "--"} diff --git a/lib/money.js b/lib/money.js new file mode 100644 index 0000000..d016751 --- /dev/null +++ b/lib/money.js @@ -0,0 +1,8 @@ +// واحد API/درگاه ریال است؛ نمایش تومان (÷۱۰) و در صورت ورودی ×۱۰. +export const RIAL_PER_TOMAN = 10; + +export const rialToToman = (rial) => Math.round((Number(rial) || 0) / RIAL_PER_TOMAN); +export const tomanToRial = (toman) => Math.round((Number(toman) || 0) * RIAL_PER_TOMAN); + +// فرمت فارسیِ مبلغ تومان از مقدار ریالِ API. +export const formatToman = (rial) => rialToToman(rial).toLocaleString("fa-IR");