import React, { useState, useEffect } from 'react'; import { useForm } from 'react-hook-form'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Checkbox } from '@/components/ui/checkbox'; import { Loader2, AlertTriangle, CheckCircle, User, Users as UsersIcon, MapPin, Briefcase, Mail, Check, X, AlertCircle } from 'lucide-react'; import { usePezkuwi } from '@/contexts/PezkuwiContext'; import type { CitizenshipData, Region, MaritalStatus } from '@pezkuwi/lib/citizenship-workflow'; import { FOUNDER_ADDRESS, submitKycApplication, subscribeToKycApproval, getKycStatus } from '@pezkuwi/lib/citizenship-workflow'; import { generateCommitmentHash, generateNullifierHash, encryptData, saveLocalCitizenshipData, uploadToIPFS } from '@pezkuwi/lib/citizenship-workflow'; interface NewCitizenApplicationProps { onClose: () => void; referrerAddress?: string | null; } type FormData = Omit; export const NewCitizenApplication: React.FC = ({ onClose, referrerAddress }) => { // identityKyc pallet is on People Chain const { api, isApiReady, peopleApi, isPeopleReady, selectedAccount, connectWallet } = usePezkuwi(); const { register, handleSubmit, watch, setValue, formState: { errors } } = useForm(); const [submitting, setSubmitting] = useState(false); const [submitted, setSubmitted] = useState(false); const [waitingForApproval, setWaitingForApproval] = useState(false); const [kycApproved, setKycApproved] = useState(false); const [error, setError] = useState(null); const [agreed, setAgreed] = useState(false); const [confirming, setConfirming] = useState(false); const [applicationHash, setApplicationHash] = useState(''); const [checkingStatus, setCheckingStatus] = useState(false); const maritalStatus = watch('maritalStatus'); const childrenCount = watch('childrenCount'); const handleApprove = async () => { // identityKyc pallet is on People Chain if (!peopleApi || !isPeopleReady || !selectedAccount) { setError('Please connect your wallet and wait for People Chain connection'); return; } setConfirming(true); try { const { web3FromAddress } = await import('@pezkuwi/extension-dapp'); const injector = await web3FromAddress(selectedAccount.address); if (import.meta.env.DEV) console.log('Confirming citizenship application on People Chain (self-confirmation)...'); // Call confirm_citizenship() extrinsic on People Chain - self-confirmation for Welati Tiki const tx = peopleApi.tx.identityKyc.confirmCitizenship(); await tx.signAndSend(selectedAccount.address, { signer: injector.signer }, ({ status, events, dispatchError }) => { if (dispatchError) { if (dispatchError.isModule) { const decoded = peopleApi.registry.findMetaError(dispatchError.asModule); if (import.meta.env.DEV) console.error(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`); setError(`${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`); } else { if (import.meta.env.DEV) console.error(dispatchError.toString()); setError(dispatchError.toString()); } setConfirming(false); return; } if (status.isInBlock || status.isFinalized) { if (import.meta.env.DEV) console.log('✅ Citizenship confirmed successfully on People Chain!'); if (import.meta.env.DEV) console.log('Block hash:', status.asInBlock || status.asFinalized); // Check for CitizenshipConfirmed event events.forEach(({ event }) => { if (event.section === 'identityKyc' && event.method === 'CitizenshipConfirmed') { if (import.meta.env.DEV) console.log('📢 CitizenshipConfirmed event detected'); setKycApproved(true); setWaitingForApproval(false); // Redirect to citizen dashboard after 2 seconds setTimeout(() => { onClose(); window.location.href = '/dashboard'; }, 2000); } }); setConfirming(false); } }); } catch (err) { if (import.meta.env.DEV) console.error('Approval error:', err); setError((err as Error).message || 'Failed to approve application'); setConfirming(false); } }; const handleReject = async () => { // Cancel/withdraw the application - simply close modal and go back // No blockchain interaction needed - application will remain Pending until confirmed or admin-rejected if (import.meta.env.DEV) console.log('Canceling citizenship application (no blockchain interaction)'); onClose(); window.location.href = '/'; }; // Check KYC status on mount (identityKyc pallet is on People Chain) useEffect(() => { const checkKycStatus = async () => { if (!peopleApi || !isPeopleReady || !selectedAccount) { return; } setCheckingStatus(true); try { const status = await getKycStatus(peopleApi, selectedAccount.address); if (import.meta.env.DEV) console.log('Current KYC Status from People Chain:', status); if (status === 'Approved') { if (import.meta.env.DEV) console.log('KYC already approved! Redirecting to dashboard...'); setKycApproved(true); // Redirect to dashboard after 2 seconds setTimeout(() => { onClose(); window.location.href = '/dashboard'; }, 2000); } else if (status === 'Pending') { // If pending, show the waiting screen setWaitingForApproval(true); } } catch (err) { if (import.meta.env.DEV) console.error('Error checking KYC status:', err); } finally { setCheckingStatus(false); } }; checkKycStatus(); }, [peopleApi, isPeopleReady, selectedAccount, onClose]); // Subscribe to KYC approval events on People Chain useEffect(() => { if (!peopleApi || !isPeopleReady || !selectedAccount || !waitingForApproval) { return; } if (import.meta.env.DEV) console.log('Setting up KYC approval listener on People Chain for:', selectedAccount.address); const unsubscribe = subscribeToKycApproval( peopleApi, selectedAccount.address, () => { if (import.meta.env.DEV) console.log('KYC Approved on People Chain! Redirecting to dashboard...'); setKycApproved(true); setWaitingForApproval(false); // Redirect to citizen dashboard after 2 seconds setTimeout(() => { onClose(); window.location.href = '/dashboard'; }, 2000); }, (error) => { if (import.meta.env.DEV) console.error('KYC approval subscription error:', error); setError(`Failed to monitor approval status: ${error}`); } ); return () => { if (unsubscribe) { unsubscribe(); } }; }, [peopleApi, isPeopleReady, selectedAccount, waitingForApproval, onClose]); const onSubmit = async (data: FormData) => { // identityKyc pallet is on People Chain if (!peopleApi || !isPeopleReady || !selectedAccount) { setError('Please connect your wallet and wait for People Chain connection'); return; } if (!agreed) { setError('Please agree to the terms'); return; } setError(null); setSubmitting(true); try { // Check KYC status before submitting (from People Chain) const currentStatus = await getKycStatus(peopleApi, selectedAccount.address); if (currentStatus === 'Approved') { setError('Your KYC has already been approved! Redirecting to dashboard...'); setKycApproved(true); setTimeout(() => { onClose(); window.location.href = '/dashboard'; }, 2000); return; } if (currentStatus === 'Pending') { setError('You already have a pending KYC application. Please wait for admin approval.'); setWaitingForApproval(true); return; } // Note: Referral initiation must be done by the REFERRER before the referee does KYC // The referrer calls api.tx.referral.initiateReferral(refereeAddress) from InviteUserModal // Here we just use the referrerAddress in the citizenship data if provided if (referrerAddress) { if (import.meta.env.DEV) console.log(`KYC application with referrer: ${referrerAddress}`); } // Prepare complete citizenship data const citizenshipData: CitizenshipData = { ...data, walletAddress: selectedAccount.address, timestamp: Date.now(), referralCode: data.referralCode || FOUNDER_ADDRESS // Auto-assign to founder if empty }; // Generate commitment and nullifier hashes const commitmentHash = await generateCommitmentHash(citizenshipData); const nullifierHash = await generateNullifierHash(selectedAccount.address, citizenshipData.timestamp); if (import.meta.env.DEV) console.log('Commitment Hash:', commitmentHash); if (import.meta.env.DEV) console.log('Nullifier Hash:', nullifierHash); // Encrypt data const encryptedData = await encryptData(citizenshipData, selectedAccount.address); // Save to local storage (backup) await saveLocalCitizenshipData(citizenshipData, selectedAccount.address); // Upload to IPFS const ipfsCid = await uploadToIPFS(encryptedData); if (import.meta.env.DEV) console.log('IPFS CID:', ipfsCid); if (import.meta.env.DEV) console.log('IPFS CID type:', typeof ipfsCid); if (import.meta.env.DEV) console.log('IPFS CID value:', JSON.stringify(ipfsCid)); // Ensure ipfsCid is a string const cidString = String(ipfsCid); if (!cidString || cidString === 'undefined' || cidString === '[object Object]') { throw new Error(`Invalid IPFS CID: ${cidString}`); } // Submit to blockchain (identityKyc pallet is on People Chain) if (import.meta.env.DEV) console.log('Submitting KYC application to People Chain...'); const result = await submitKycApplication( peopleApi, selectedAccount, citizenshipData.fullName, citizenshipData.email, cidString, `Citizenship application for ${citizenshipData.fullName}` ); if (!result.success) { setError(result.error || 'Failed to submit KYC application to blockchain'); setSubmitting(false); return; } if (import.meta.env.DEV) console.log('✅ KYC application submitted to blockchain'); if (import.meta.env.DEV) console.log('Block hash:', result.blockHash); // Save block hash for display if (result.blockHash) { setApplicationHash(result.blockHash.slice(0, 16) + '...'); } // Move to waiting for approval state setSubmitted(true); setSubmitting(false); setWaitingForApproval(true); } catch (err) { if (import.meta.env.DEV) console.error('Submission error:', err); setError('Failed to submit citizenship application'); setSubmitting(false); } }; if (!selectedAccount) { return ( Connect Wallet Required You need to connect your wallet to apply for citizenship ); } // KYC Approved - Success state if (kycApproved) { return (

KYC Approved!

Congratulations! Your citizenship application has been approved. Redirecting to citizen dashboard...

); } // Waiting for self-confirmation if (waitingForApproval) { return ( {/* Icon */}

Confirm Your Citizenship Application

Your application has been submitted to the blockchain. Please review and confirm your identity to mint your Citizen NFT (Welati Tiki).

{/* Status steps */}

Data Encrypted

Your KYC data has been encrypted and stored on IPFS

Blockchain Submitted

Transaction hash: {applicationHash || 'Processing...'}

Awaiting Your Confirmation

Confirm or reject your application below

{/* Action buttons */}
{error && ( {error} )}
); } // Initial submission success (before blockchain confirmation) if (submitted && !waitingForApproval) { return (

Processing Application...

Encrypting your data and submitting to the blockchain. Please wait...

); } return (
{/* Personal Identity Section */} Nasnameya Kesane (Personal Identity)
{errors.fullName &&

Required

}
{errors.fatherName &&

Required

}
{errors.grandfatherName &&

Required

}
{errors.motherName &&

Required

}
{/* Tribal Affiliation */} Eşîra Te (Tribal Affiliation)
{errors.tribe &&

Required

}
{/* Family Status */} Rewşa Malbatê (Family Status)
setValue('maritalStatus', value as MaritalStatus)} defaultValue="nezewici" >
{maritalStatus === 'zewici' && ( <>
{childrenCount && childrenCount > 0 && (
{Array.from({ length: childrenCount }).map((_, i) => (
))}
)} )}
{/* Geographic Origin */} Herêma Te (Your Region)
{errors.region &&

Required

}
{/* Contact & Profession */} Têkilî û Pîşe (Contact & Profession)
{errors.email &&

Valid email required

}
{errors.profession &&

Required

}
{/* Referral */} Koda Referral (Referral Code - Optional) If you were invited by another citizen, enter their referral code

If empty, you will be automatically linked to the Founder (Satoshi Qazi Muhammed)

{/* Terms Agreement */}
setAgreed(checked as boolean)} />
{error && ( {error} )}
); };