feat(admin): comma-grouped Latin amounts on the session payment step
Add an opt-in latin prop to PriceInput (en-US grouping, English digits) and use it for the discount-value and payment-amount fields on PaymentStep, which were raw number inputs. Amounts now show 3-digit comma grouping and Persian digits typed are converted to English (via PriceInput's toEnglishDigits). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import type { DiscountSuggestion } from '../../types';
|
||||
import type { SessionCardData } from '../SessionServiceCard';
|
||||
import SearchableSelect from '../ui/SearchableSelect';
|
||||
import PersianDateInput from '../ui/PersianDateInput';
|
||||
import PriceInput from '../ui/PriceInput';
|
||||
import { Step2PaymentCard, FilesServiceBalanceWallet, TrashRed } from '../icons/FilesServiceIcons';
|
||||
|
||||
/** روشهای پرداخت — همان چهار گزینهی آکاردئون tauri Step2Payment. */
|
||||
@@ -48,10 +49,10 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
const sessionUuid = session.uuid;
|
||||
|
||||
const [discountType, setDiscountType] = useState('');
|
||||
const [discountValue, setDiscountValue] = useState('');
|
||||
const [discountValue, setDiscountValue] = useState(0);
|
||||
const [paymentDate, setPaymentDate] = useState(todayISO());
|
||||
const [expanded, setExpanded] = useState<string | null>(null);
|
||||
const [amount, setAmount] = useState('');
|
||||
const [amount, setAmount] = useState(0);
|
||||
|
||||
const invalidate = () => {
|
||||
qc.invalidateQueries({ queryKey: ['patient-sessions', recordUuid] });
|
||||
@@ -67,7 +68,7 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
|
||||
const payMut = useMutation({
|
||||
mutationFn: (body: object) => api.post(`/api/v1/session/${sessionUuid}/payments`, body),
|
||||
onSuccess: () => { invalidate(); setAmount(''); toast.success('پرداخت ثبت شد'); },
|
||||
onSuccess: () => { invalidate(); setAmount(0); toast.success('پرداخت ثبت شد'); },
|
||||
onError: (e: Error) => toast.error(e.message),
|
||||
});
|
||||
|
||||
@@ -78,19 +79,19 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
const suggestions: DiscountSuggestion[] = (suggestionsQ.data?.data as any)?.data ?? (suggestionsQ.data?.data as any) ?? [];
|
||||
|
||||
const applyDiscount = () => {
|
||||
if (!discountType || !discountValue) return;
|
||||
discountMut.mutate({ discount_type: discountType, discount_value: Number(discountValue) });
|
||||
if (!discountType || discountValue <= 0) return;
|
||||
discountMut.mutate({ discount_type: discountType, discount_value: discountValue });
|
||||
};
|
||||
const applyRule = (ruleUuid: string) => {
|
||||
discountMut.mutate({ discount_rule_uuid: ruleUuid });
|
||||
};
|
||||
const removeDiscount = () => {
|
||||
setDiscountType(''); setDiscountValue('');
|
||||
setDiscountType(''); setDiscountValue(0);
|
||||
discountMut.mutate({ discount_rule_uuid: null });
|
||||
};
|
||||
const submitPayment = (method: string) => {
|
||||
if (!amount) return;
|
||||
payMut.mutate({ method, amount_rials: Number(amount), paid_at: isoToUnix(paymentDate) });
|
||||
if (amount <= 0) return;
|
||||
payMut.mutate({ method, amount_rials: amount, paid_at: isoToUnix(paymentDate) });
|
||||
};
|
||||
|
||||
const finalPrice = session.final_price_rials ?? 0;
|
||||
@@ -146,19 +147,17 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
placeholder="مبلغ تخفیف"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
min={0}
|
||||
dir="ltr"
|
||||
placeholder="مقدار تخفیف را وارد نمایید"
|
||||
<PriceInput
|
||||
latin
|
||||
value={discountValue}
|
||||
onChange={(e) => setDiscountValue(e.target.value)}
|
||||
onChange={setDiscountValue}
|
||||
placeholder="مقدار تخفیف را وارد نمایید"
|
||||
style={{ flex: 1, minWidth: 0, height: 40, padding: '0 12px', fontSize: 13, border: 'none', outline: 'none', background: 'transparent', color: 'inherit' }}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={applyDiscount}
|
||||
disabled={discountMut.isPending || !discountType || !discountValue}
|
||||
disabled={discountMut.isPending || !discountType || discountValue <= 0}
|
||||
style={{ height: 40, minWidth: 72, border: 'none', borderRadius: '0 4px 4px 0', background: '#E8EBFF', color: '#3B3F9F', fontSize: 13, fontWeight: 600, cursor: 'pointer' }}
|
||||
>
|
||||
ثبت
|
||||
@@ -212,7 +211,7 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
<button
|
||||
type="button"
|
||||
aria-expanded={open}
|
||||
onClick={() => { setExpanded(open ? null : m.key); setAmount(''); }}
|
||||
onClick={() => { setExpanded(open ? null : m.key); setAmount(0); }}
|
||||
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%', padding: '14px 4px', background: 'transparent', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
<span className="dark:text-[#D7D8ED]" style={{ fontSize: 14, fontWeight: 600, color: '#111827' }}>{m.label}</span>
|
||||
@@ -220,20 +219,18 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
|
||||
</button>
|
||||
{open && (
|
||||
<div style={{ display: 'flex', gap: 8, padding: '0 4px 14px' }}>
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
dir="ltr"
|
||||
<PriceInput
|
||||
latin
|
||||
className="input"
|
||||
placeholder="مبلغ (تومان)"
|
||||
value={amount}
|
||||
onChange={(e) => setAmount(e.target.value)}
|
||||
onChange={setAmount}
|
||||
style={{ flex: 1, height: 40 }}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => submitPayment(m.key)}
|
||||
disabled={payMut.isPending || !amount}
|
||||
disabled={payMut.isPending || amount <= 0}
|
||||
style={{ ...primaryBtn, height: 40, padding: '0 20px', borderRadius: 8 }}
|
||||
>
|
||||
ثبت پرداخت
|
||||
|
||||
Reference in New Issue
Block a user