admin/src/pages/wallet/wallet-list/WalletListPage.tsx

154 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { Wallet, Loader2 } from 'lucide-react';
import { PageContainer, PageTitle } from '@/components/ui/Typography';
import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
import { useWalletStatus, useUpdateWalletStatus } from '../core/_hooks';
import { WalletStatus, WALLET_LABELS } from '../core/_models';
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString('fa-IR', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
};
const ToggleSwitch = ({
checked,
onChange,
disabled,
}: {
checked: boolean;
onChange: (checked: boolean) => void;
disabled?: boolean;
}) => {
return (
<label className="flex items-center cursor-pointer">
<input
type="checkbox"
checked={checked}
onChange={(e) => onChange(e.target.checked)}
disabled={disabled}
className="sr-only"
/>
<div
className={`relative w-11 h-6 rounded-full transition-colors ${
checked
? 'bg-primary-600'
: 'bg-gray-300 dark:bg-gray-600'
} ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
>
<div
className={`absolute top-0.5 left-0.5 bg-white rounded-full h-5 w-5 transition-transform ${
checked ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</div>
</label>
);
};
const WalletListPage = () => {
const { data, isLoading, error } = useWalletStatus();
const { mutate: updateStatus, isPending } = useUpdateWalletStatus();
const handleToggle = (wallet: WalletStatus, newStatus: boolean) => {
updateStatus({
wallet_type: wallet.wallet_type,
status: newStatus,
});
};
if (isLoading) {
return (
<PageContainer>
<div className="flex justify-center items-center h-64">
<LoadingSpinner />
</div>
</PageContainer>
);
}
if (error) {
return (
<PageContainer>
<div className="text-center py-12">
<p className="text-red-600 dark:text-red-400">
خطا در بارگذاری وضعیت کیفهای پول
</p>
</div>
</PageContainer>
);
}
const statuses = data?.statuses || [];
return (
<PageContainer>
<div className="flex flex-col space-y-3 sm:flex-row sm:items-center sm:justify-between sm:space-y-0">
<div>
<PageTitle className="flex items-center gap-2">
<Wallet className="h-6 w-6" />
مدیریت کیف پول
</PageTitle>
<p className="text-gray-600 dark:text-gray-400 mt-1">
فعال یا غیرفعال کردن کیفهای پول
</p>
</div>
</div>
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden">
<div className="p-6">
<div className="space-y-4">
{statuses.map((wallet) => (
<div
key={wallet.wallet_type}
className="flex items-center justify-between p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
<div className="flex-1">
<div className="flex items-center gap-3">
<h3 className="text-lg font-medium text-gray-900 dark:text-gray-100">
{WALLET_LABELS[wallet.wallet_type]}
</h3>
<span
className={`px-2 py-1 rounded-md text-xs font-medium ${
wallet.is_active
? 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-200'
: 'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-200'
}`}
>
{wallet.is_active ? 'فعال' : 'غیرفعال'}
</span>
</div>
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
آخرین بهروزرسانی: {formatDate(wallet.updated_at)}
</p>
</div>
<div className="flex items-center gap-4">
{isPending ? (
<Loader2 className="h-5 w-5 animate-spin text-gray-400" />
) : (
<ToggleSwitch
checked={wallet.is_active}
onChange={(checked) => handleToggle(wallet, checked)}
/>
)}
</div>
</div>
))}
</div>
</div>
</div>
</PageContainer>
);
};
export default WalletListPage;