feat(admin): update order management and SMS rules settings UI with lint fixes
This commit is contained in:
parent
5e3e3958c5
commit
56e8029fff
@ -102,6 +102,9 @@ export interface Order {
|
||||
total?: number;
|
||||
isRefill?: boolean;
|
||||
shippingAddress?: string;
|
||||
refundStatus?: string;
|
||||
refundedAmount?: number;
|
||||
refundMethod?: string;
|
||||
}
|
||||
|
||||
export const ORDER_STATUS_MAP: Record<string, { label: string; color: string; icon: React.ElementType }> = {
|
||||
@ -242,8 +245,12 @@ export default function Orders() {
|
||||
setRefundModalOrder(order);
|
||||
const amt = Number(order.totalAmount || order.total || 0);
|
||||
setRefundAmount(String(amt));
|
||||
// If order was paid by wallet, default to wallet. If online, let admin choose.
|
||||
setRefundTarget(order.paymentMethod === 'wallet' ? 'wallet' : 'zibal');
|
||||
// If order was already refunded to wallet, default/force to gateway
|
||||
if (order.refundStatus === 'wallet') {
|
||||
setRefundTarget('zibal');
|
||||
} else {
|
||||
setRefundTarget(order.paymentMethod === 'wallet' ? 'wallet' : 'zibal');
|
||||
}
|
||||
setRefundReason(`استرداد سفارش #${order.trackingNumber || order.id.slice(0, 8)}`);
|
||||
updateUrlParams({ modal: 'refund', orderId: order.id });
|
||||
};
|
||||
@ -440,16 +447,15 @@ export default function Orders() {
|
||||
}
|
||||
|
||||
const res = await api.post('/payment/admin/refund', {
|
||||
orderId: refundModalOrder.id,
|
||||
trackId,
|
||||
amount: refundAmount ? Number(refundAmount) * 10 : undefined,
|
||||
tryReverse: true,
|
||||
description: refundReason || `استرداد وجه سفارش #${refundModalOrder.trackingNumber || refundModalOrder.id.slice(0, 8)}`,
|
||||
});
|
||||
|
||||
if (res.data?.result === 1 || res.data?.status === 1 || res.data?.success) {
|
||||
toast.success('درخواست استرداد وجه به درگاه زیبال با موفقیت ارسال شد.');
|
||||
// Also mark order as cancelled
|
||||
await api.put(`/admin/orders/${refundModalOrder.id}/status`, { status: 'cancelled' });
|
||||
if (res.data?.result === 1 || res.data?.status === 1 || res.data?.result === 100 || res.data?.success) {
|
||||
toast.success('درخواست استرداد وجه به درگاه زیبال با موفقیت ارسال شد و وضعیت سفارش بهروزرسانی شد.');
|
||||
setRefundModalOrder(null);
|
||||
await fetchOrders();
|
||||
} else {
|
||||
@ -790,6 +796,22 @@ export default function Orders() {
|
||||
<CreditCard className="w-3 h-3 shrink-0" />
|
||||
<span className="font-vazir">{payInfo.label}</span>
|
||||
</span>
|
||||
{order.refundStatus && (
|
||||
<span
|
||||
className={`text-[10px] font-bold font-vazir px-2 py-0.5 rounded-md border flex items-center gap-1 shadow-sm ${
|
||||
order.refundStatus === 'gateway'
|
||||
? 'bg-rose-50 text-rose-700 border-rose-200'
|
||||
: 'bg-amber-50 text-amber-700 border-amber-200'
|
||||
}`}
|
||||
>
|
||||
<Undo2 className="w-3 h-3 shrink-0" />
|
||||
<span className="font-vazir">
|
||||
{order.refundStatus === 'gateway'
|
||||
? 'مسترد به درگاه'
|
||||
: 'مسترد به کیفپول'}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{order.isRefill && (
|
||||
<span className="text-[10px] font-bold font-vazir px-2 py-0.5 rounded-md bg-emerald-50 text-emerald-700 border border-emerald-200 shadow-sm">
|
||||
تمدید ۵٪-
|
||||
@ -855,16 +877,16 @@ export default function Orders() {
|
||||
className="text-gray-600 hover:bg-gray-100"
|
||||
/>
|
||||
|
||||
{(order.status === 'cancelled' || order.status === 'pending_payment') && (
|
||||
{(order.status === 'cancelled' || order.status === 'pending_payment') && order.refundStatus !== 'gateway' && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Undo2}
|
||||
onClick={() => openOrderRefundModal(order)}
|
||||
disabled={isProcessing}
|
||||
className="text-rose-600 hover:bg-rose-50"
|
||||
className={`hover:bg-rose-50 ${order.refundStatus === 'wallet' ? 'text-amber-700 hover:bg-amber-50' : 'text-rose-600'}`}
|
||||
>
|
||||
استرداد
|
||||
{order.refundStatus === 'wallet' ? 'استرداد بانکی' : 'استرداد'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@ -1018,17 +1040,15 @@ export default function Orders() {
|
||||
{(() => {
|
||||
let addrText = selectedOrder.address?.fullAddress || selectedOrder.shippingAddress || 'ثبت نشده';
|
||||
let postCode = selectedOrder.address?.postalCode;
|
||||
let prov = selectedOrder.address?.province;
|
||||
let ct = selectedOrder.address?.city;
|
||||
|
||||
if (typeof selectedOrder.shippingAddress === 'string' && selectedOrder.shippingAddress.trim().startsWith('{')) {
|
||||
try {
|
||||
const parsed = JSON.parse(selectedOrder.shippingAddress);
|
||||
addrText = parsed.formatted || `${parsed.province || ''}، ${parsed.city || ''}، ${parsed.address || ''}`;
|
||||
if (parsed.postalCode) postCode = parsed.postalCode;
|
||||
if (parsed.province) prov = parsed.province;
|
||||
if (parsed.city) ct = parsed.city;
|
||||
} catch {}
|
||||
} catch {
|
||||
// ignore malformed json
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@ -1115,6 +1135,16 @@ export default function Orders() {
|
||||
<span>روش پرداخت:</span>
|
||||
<span className="text-white font-bold">{selectedOrder.paymentMethod === 'wallet' ? 'کیف پول الکترونیک' : 'درگاه پرداخت آنلاین'}</span>
|
||||
</div>
|
||||
{selectedOrder.refundStatus && (
|
||||
<div className="flex justify-between font-bold text-amber-300 pt-1 border-t border-gray-800/80">
|
||||
<span>وضعیت استرداد وجه:</span>
|
||||
<span>
|
||||
{selectedOrder.refundStatus === 'gateway'
|
||||
? `مسترد به درگاه بانکی (${toPersianDigits(Number(selectedOrder.refundedAmount || selectedOrder.totalAmount || 0).toLocaleString())} تومان)`
|
||||
: `مسترد به کیفپول (${toPersianDigits(Number(selectedOrder.refundedAmount || selectedOrder.totalAmount || 0).toLocaleString())} تومان)`}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between text-sm sm:text-base font-black text-amber-400 pt-2 border-t border-gray-800">
|
||||
<span>مبلغ نهایی پرداخت شده:</span>
|
||||
<span>{toPersianDigits(Number(selectedOrder.totalAmount || selectedOrder.total || 0).toLocaleString())} تومان</span>
|
||||
@ -1157,14 +1187,22 @@ export default function Orders() {
|
||||
{/* Destination selector */}
|
||||
<div>
|
||||
<label className="block font-bold text-gray-700 mb-2">روش عودت و بازگشت وجه:</label>
|
||||
{refundModalOrder.refundStatus === 'wallet' && (
|
||||
<div className="mb-3 p-3 bg-amber-50 border border-amber-200 rounded-xl text-amber-800 text-[11px] leading-relaxed">
|
||||
<strong>توجه:</strong> وجه این سفارش قبلاً به کیف پول کاربر عودت داده شده است. در صورت ثبت استرداد درگاه زیبال، مبلغ استرداد به صورت خودکار از موجودی کیف پول کاربر کسر خواهد شد تا از استرداد مضاعف جلوگیری شود.
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
disabled={refundModalOrder.refundStatus === 'wallet'}
|
||||
onClick={() => setRefundTarget('wallet')}
|
||||
className={`p-3.5 rounded-2xl border text-right transition-all cursor-pointer flex flex-col gap-1.5 ${
|
||||
refundTarget === 'wallet'
|
||||
? 'border-purple-600 bg-purple-50/60 ring-2 ring-purple-600/20'
|
||||
: 'border-gray-200 hover:border-gray-300'
|
||||
className={`p-3.5 rounded-2xl border text-right transition-all flex flex-col gap-1.5 ${
|
||||
refundModalOrder.refundStatus === 'wallet'
|
||||
? 'opacity-40 cursor-not-allowed bg-gray-50 border-gray-200'
|
||||
: refundTarget === 'wallet'
|
||||
? 'border-purple-600 bg-purple-50/60 ring-2 ring-purple-600/20 cursor-pointer'
|
||||
: 'border-gray-200 hover:border-gray-300 cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2 font-black text-gray-900">
|
||||
@ -1172,7 +1210,9 @@ export default function Orders() {
|
||||
<span>شارژ کیف پول کاربر</span>
|
||||
</div>
|
||||
<p className="text-[11px] text-gray-500 font-medium leading-relaxed">
|
||||
افزایش فوری اعتبار کیف پول جهت خریدهای بعدی مشتری
|
||||
{refundModalOrder.refundStatus === 'wallet'
|
||||
? 'قبلاً به کیف پول مسترد شده است'
|
||||
: 'افزایش فوری اعتبار کیف پول جهت خریدهای بعدی مشتری'}
|
||||
</p>
|
||||
</button>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user