Compare commits

...

3 Commits

Author SHA1 Message Date
parsa aghaei
97cd1c72aa fix: declare isUpdatingModalStatus and handleSaveModalStatus in Orders
All checks were successful
Deploy Canina / deploy (push) Successful in 30s
2026-08-23 11:17:56 +03:30
parsa aghaei
26a992c030 fix: clean unused variables and refine modal parameter binding
Some checks failed
Deploy Canina / deploy (push) Has been cancelled
2026-08-23 11:16:32 +03:30
parsa aghaei
7848232452 fix: destructure setMultipleParams in Transactions 2026-08-23 11:13:44 +03:30
2 changed files with 33 additions and 17 deletions

View File

@ -115,7 +115,7 @@ export const ORDER_STATUS_MAP: Record<string, { label: string; color: string; ic
cancelled: { label: 'لغو شده', color: 'bg-red-50 text-red-700 border-red-200', icon: XCircle }, cancelled: { label: 'لغو شده', color: 'bg-red-50 text-red-700 border-red-200', icon: XCircle },
}; };
export const getPaymentStatusBadge = (status: string) => { const getPaymentStatusBadge = (status: string) => {
switch (status?.toLowerCase()) { switch (status?.toLowerCase()) {
case 'success': case 'success':
case 'paid': case 'paid':
@ -132,7 +132,7 @@ export const getPaymentStatusBadge = (status: string) => {
} }
}; };
export const getShippingMethodLabel = (method?: string) => { const getShippingMethodLabel = (method?: string) => {
switch (method?.toLowerCase()) { switch (method?.toLowerCase()) {
case 'express': case 'express':
case 'tipax': return { label: 'تیپاکس (اکسپرس)', color: 'bg-purple-50 text-purple-700 border-purple-200' }; case 'tipax': return { label: 'تیپاکس (اکسپرس)', color: 'bg-purple-50 text-purple-700 border-purple-200' };
@ -144,7 +144,8 @@ export const getShippingMethodLabel = (method?: string) => {
} }
}; };
export const getPaymentMethodLabel = (method?: string) => {
const getPaymentMethodLabel = (method?: string) => {
switch (method?.toLowerCase()) { switch (method?.toLowerCase()) {
case 'online': case 'online':
case 'zibal': case 'zibal':
@ -158,6 +159,7 @@ export const getPaymentMethodLabel = (method?: string) => {
} }
}; };
const toPersianDigits = (n: string | number): string => { const toPersianDigits = (n: string | number): string => {
if (n === null || n === undefined) return ''; if (n === null || n === undefined) return '';
const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
@ -329,6 +331,27 @@ export default function Orders() {
} }
}; };
const [isUpdatingModalStatus, setIsUpdatingModalStatus] = useState(false);
const handleSaveModalStatus = async (newStatus: string) => {
if (!selectedOrder) return;
try {
setIsUpdatingModalStatus(true);
setModalStatus(newStatus);
await api.put(`/admin/orders/${selectedOrder.id}/status`, {
status: newStatus,
trackingNumber: modalTrackingCode || undefined,
});
await fetchOrders();
toast.success('وضعیت سفارش با موفقیت بروزرسانی شد');
} catch (err) {
console.error('Failed to update modal status', err);
toast.error('خطا در بروزرسانی وضعیت سفارش');
} finally {
setIsUpdatingModalStatus(false);
}
};
const handleSaveModalChanges = async () => { const handleSaveModalChanges = async () => {
if (!selectedOrder) return; if (!selectedOrder) return;
try { try {
@ -349,6 +372,7 @@ export default function Orders() {
const handleExecuteOrderRefund = async () => { const handleExecuteOrderRefund = async () => {
if (!refundModalOrder) return; if (!refundModalOrder) return;
try { try {

View File

@ -2,28 +2,17 @@ import React, { useState, useEffect, useCallback } from 'react';
import { import {
CreditCard, CreditCard,
Search, Search,
RefreshCw,
Eye, Eye,
Copy, Copy,
CheckCircle2, CheckCircle2,
XCircle, XCircle,
Clock, Clock,
Filter,
DollarSign, DollarSign,
TrendingUp, TrendingUp,
AlertTriangle,
Receipt, Receipt,
User,
ShoppingBag,
ArrowUpDown,
ExternalLink,
ShieldCheck, ShieldCheck,
RotateCcw, RotateCcw,
Activity, Activity,
Globe,
Monitor,
Code,
Send,
Undo2, Undo2,
Printer, Printer,
Wallet, Wallet,
@ -36,10 +25,10 @@ import Button from '../components/ui/Button';
import Badge from '../components/ui/Badge'; import Badge from '../components/ui/Badge';
import ThSort from '../components/ui/ThSort'; import ThSort from '../components/ui/ThSort';
import Modal from '../components/ui/Modal'; import Modal from '../components/ui/Modal';
import MaskableField from '../components/ui/MaskableField';
import TransactionReceiptModal, { type TransactionReceiptData } from '../components/TransactionReceiptModal'; import TransactionReceiptModal, { type TransactionReceiptData } from '../components/TransactionReceiptModal';
import { useTableParams } from '../utils/useTableParams'; import { useTableParams } from '../utils/useTableParams';
interface Transaction { interface Transaction {
id: string; id: string;
userId: string; userId: string;
@ -110,6 +99,7 @@ export default function Transactions() {
sortOrder, sortOrder,
page, page,
setParam, setParam,
setMultipleParams,
handleSort, handleSort,
clearFilters, clearFilters,
} = useTableParams({ } = useTableParams({
@ -119,6 +109,7 @@ export default function Transactions() {
defaultLimit: 15, defaultLimit: 15,
}); });
const [transactions, setTransactions] = useState<Transaction[]>([]); const [transactions, setTransactions] = useState<Transaction[]>([]);
const [stats, setStats] = useState<Stats | null>(null); const [stats, setStats] = useState<Stats | null>(null);
const [health, setHealth] = useState<GatewayHealth | null>(null); const [health, setHealth] = useState<GatewayHealth | null>(null);
@ -951,15 +942,16 @@ export default function Transactions() {
{refundModalTx && ( {refundModalTx && (
<Modal <Modal
isOpen={!!refundModalTx} isOpen={!!refundModalTx}
onClose={() => setRefundModalTx(null)} onClose={closeRefundModal}
title={`استرداد وجه تراکنش #${refundModalTx.trackId || refundModalTx.id.slice(0, 8)}`} title={`استرداد وجه تراکنش #${refundModalTx.trackId || refundModalTx.id.slice(0, 8)}`}
icon={Undo2} icon={Undo2}
maxWidth="lg" maxWidth="lg"
footer={ footer={
<div className="flex items-center justify-end gap-2 w-full"> <div className="flex items-center justify-end gap-2 w-full">
<Button variant="outline" size="sm" onClick={() => setRefundModalTx(null)}> <Button variant="outline" size="sm" onClick={closeRefundModal}>
انصراف انصراف
</Button> </Button>
<Button <Button
variant={refundTarget === 'wallet' ? 'primary' : 'danger'} variant={refundTarget === 'wallet' ? 'primary' : 'danger'}
size="sm" size="sm"