import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { useToast } from '@/hooks/use-toast'; import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { Loader2, Plus, CheckCircle, AlertTriangle, Shield } from 'lucide-react'; import { COMMISSIONS } from '@/config/commissions'; import { Alert, AlertDescription } from '@/components/ui/alert'; export function CommissionSetupTab() { const { t } = useTranslation(); const { api, isApiReady, selectedAccount, walletSource } = usePezkuwi(); const { toast } = useToast(); const [loading, setLoading] = useState(true); const [commissionMembers, setCommissionMembers] = useState([]); const [setupComplete, setSetupComplete] = useState(false); const [processing, setProcessing] = useState(false); const [newMemberAddress, setNewMemberAddress] = useState(''); useEffect(() => { if (!api || !isApiReady) return; checkSetup(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [api, isApiReady]); const checkSetup = async () => { if (!api) return; setLoading(true); try { // Check DynamicCommissionCollective members const members = await api.query.dynamicCommissionCollective.members(); const memberList = members.toJSON() as string[]; setCommissionMembers(memberList); // Commission is initialized if there's at least one member setSetupComplete(memberList.length > 0); if (import.meta.env.DEV) console.log('Commission members:', memberList); if (import.meta.env.DEV) console.log('Setup complete:', memberList.length > 0); } catch (error) { if (import.meta.env.DEV) console.error('Error checking setup:', error); } finally { setLoading(false); } }; const handleAddMember = async () => { if (!api || !selectedAccount) { toast({ title: t('commission.setup.walletNotConnected'), description: t('commission.setup.connectWallet'), variant: 'destructive', }); return; } if (!newMemberAddress) { toast({ title: t('commission.setup.noAddresses'), description: t('commission.setup.enterAtLeastOne'), variant: 'destructive', }); return; } setProcessing(true); try { const { getSigner } = await import('@/lib/get-signer'); const injector = await getSigner(selectedAccount.address, walletSource, api); // Parse addresses (one per line, trim whitespace) const newAddresses = newMemberAddress .split('\n') .map(addr => addr.trim()) .filter(addr => addr.length > 0); if (newAddresses.length === 0) { toast({ title: t('commission.setup.noValidAddresses'), description: t('commission.setup.enterValidAddress'), variant: 'destructive', }); setProcessing(false); return; } // Get current members const currentMembers = await api.query.dynamicCommissionCollective.members(); const memberList = (currentMembers.toJSON() as string[]) || []; // Filter out already existing members const newMembers = newAddresses.filter(addr => !memberList.includes(addr)); if (newMembers.length === 0) { toast({ title: t('commission.setup.alreadyInitialized'), description: t('commission.setup.alreadyInitialized'), variant: 'destructive', }); setProcessing(false); return; } // Add new members const updatedList = [...memberList, ...newMembers]; if (import.meta.env.DEV) console.log('Adding new members:', newMembers); if (import.meta.env.DEV) console.log('Updated member list:', updatedList); const tx = api.tx.sudo.sudo( api.tx.dynamicCommissionCollective.setMembers( updatedList, null, updatedList.length ) ); await new Promise((resolve, reject) => { tx.signAndSend( selectedAccount.address, { signer: injector.signer }, ({ status, dispatchError }) => { if (status.isInBlock || status.isFinalized) { if (dispatchError) { let errorMessage = t('commission.setup.addMemberFailed'); if (dispatchError.isModule) { const decoded = api.registry.findMetaError(dispatchError.asModule); errorMessage = `${decoded.section}.${decoded.name}`; } toast({ title: t('commission.setup.addMemberFailed'), description: errorMessage, variant: 'destructive', }); reject(new Error(errorMessage)); } else { toast({ title: t('commission.setup.addMemberSuccess', { count: newMembers.length }), }); setNewMemberAddress(''); setTimeout(() => checkSetup(), 2000); resolve(); } } } ); }); } catch (error) { if (import.meta.env.DEV) console.error('Error adding member:', error); toast({ title: t('commission.setup.addMemberFailed'), description: error instanceof Error ? error.message : t('commission.setup.addMemberFailed'), variant: 'destructive', }); } finally { setProcessing(false); } }; const handleInitializeCommission = async () => { if (!api || !selectedAccount) { toast({ title: t('commission.setup.walletNotConnected'), description: t('commission.setup.connectWallet'), variant: 'destructive', }); return; } setProcessing(true); try { const { getSigner } = await import('@/lib/get-signer'); const injector = await getSigner(selectedAccount.address, walletSource, api); if (import.meta.env.DEV) console.log('Initializing KYC Commission...'); if (import.meta.env.DEV) console.log('Proxy account:', COMMISSIONS.KYC.proxyAccount); // Initialize DynamicCommissionCollective with Alice as first member // Other members can be added later const tx = api.tx.sudo.sudo( api.tx.dynamicCommissionCollective.setMembers( [selectedAccount.address], // Add caller as first member null, 1 ) ); await new Promise((resolve, reject) => { tx.signAndSend( selectedAccount.address, { signer: injector.signer }, ({ status, dispatchError, events }) => { if (import.meta.env.DEV) console.log('Transaction status:', status.type); if (status.isInBlock || status.isFinalized) { if (dispatchError) { let errorMessage = 'Transaction failed'; if (dispatchError.isModule) { const decoded = api.registry.findMetaError(dispatchError.asModule); errorMessage = `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`; } else { errorMessage = dispatchError.toString(); } if (import.meta.env.DEV) console.error('Setup error:', errorMessage); toast({ title: t('commission.setup.setupFailed'), description: errorMessage, variant: 'destructive', }); reject(new Error(errorMessage)); return; } // Check for Sudid event const sudidEvent = events.find(({ event }) => event.section === 'sudo' && event.method === 'Sudid' ); if (sudidEvent) { if (import.meta.env.DEV) console.log('✅ KYC Commission initialized'); toast({ title: t('commission.setup.kycInitialized'), }); resolve(); } else { if (import.meta.env.DEV) console.warn('Transaction included but no Sudid event'); resolve(); } } } ).catch((error) => { if (import.meta.env.DEV) console.error('Failed to sign and send:', error); toast({ title: t('commission.setup.transactionError'), description: error instanceof Error ? error.message : t('commission.setup.failedToSubmit'), variant: 'destructive', }); reject(error); }); }); // Reload setup status setTimeout(() => checkSetup(), 2000); } catch (error) { if (import.meta.env.DEV) console.error('Error initializing commission:', error); toast({ title: t('commission.setup.setupFailed'), description: error instanceof Error ? error.message : t('commission.setup.failedToInitialize'), variant: 'destructive', }); } finally { setProcessing(false); } }; if (!isApiReady) { return (
{t('commission.setup.connecting')}
); } if (!selectedAccount) { return ( {t('commission.setup.connectWalletAlert')} ); } return (
{/* Setup Status */} {t('commission.setup.statusLabel')} {loading ? (
) : ( <>

{t('commission.setup.statusLabel')}

{setupComplete ? t('commission.setup.initialized') : t('commission.setup.notInitialized')}

{setupComplete ? ( {t('commission.setup.ready')} ) : ( {t('commission.setup.notInitializedBadge')} )}

{t('commission.setup.proxyAccount')}

{COMMISSIONS.KYC.proxyAccount}

{t('commission.setup.membersLabel')} ({commissionMembers.length})

{commissionMembers.length === 0 ? (
{t('commission.setup.noMembers')}
) : (
{commissionMembers.map((member, index) => (

{member}

{member === COMMISSIONS.KYC.proxyAccount && ( {t('commission.setup.kycProxy')} )}
))}
)}
{!setupComplete && ( {t('commission.setup.initRequired')} )} {setupComplete && (

{t('commission.setup.addMembersTitle')}