154 lines
4.7 KiB
TypeScript
154 lines
4.7 KiB
TypeScript
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;
|
||
|
||
|
||
|
||
|
||
|