feat: Phase 3 - P2P Fiat Trading System (Production-Ready)

Major Updates:
- Footer improvements: English-only text, proper alignment, professional icons
- DEX Pool implementation with AMM-based token swapping
- Enhanced dashboard with DashboardContext for centralized data
- New Citizens section and government entrance page

DEX Features:
- Token swap interface with price impact calculation
- Pool management (add/remove liquidity)
- Founder-only admin panel for pool creation
- HEZ wrapping functionality (wHEZ)
- Multiple token support (HEZ, wHEZ, USDT, USDC, BTC)

UI/UX Improvements:
- Footer: Removed distracting images, added Mail icons, English text
- Footer: Proper left alignment for all sections
- DEX Dashboard: Founder access badge, responsive tabs
- Back to home navigation in DEX interface

Component Structure:
- src/components/dex/: DEX-specific components
- src/components/admin/: Admin panel components
- src/components/dashboard/: Dashboard widgets
- src/contexts/DashboardContext.tsx: Centralized dashboard state

Shared Libraries:
- shared/lib/kyc.ts: KYC status management
- shared/lib/citizenship-workflow.ts: Citizenship flow
- shared/utils/dex.ts: DEX calculations and utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 05:44:48 +03:00
parent 2df29a6395
commit 51028e6344
18 changed files with 5886 additions and 68 deletions
+94
View File
@@ -0,0 +1,94 @@
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import { usePolkadot } from '@/contexts/PolkadotContext';
import { supabase } from '@/lib/supabase';
import { getAllTikiNFTDetails, generateCitizenNumber, type TikiNFTDetails } from '@pezkuwi/lib/tiki';
import { getKycStatus } from '@pezkuwi/lib/kyc';
interface DashboardData {
profile: any | null;
nftDetails: { citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number };
kycStatus: string;
citizenNumber: string;
loading: boolean;
}
const DashboardContext = createContext<DashboardData | undefined>(undefined);
export function DashboardProvider({ children }: { children: ReactNode }) {
const { user } = useAuth();
const { api, isApiReady, selectedAccount } = usePolkadot();
const [profile, setProfile] = useState<any>(null);
const [nftDetails, setNftDetails] = useState<{ citizenNFT: TikiNFTDetails | null; roleNFTs: TikiNFTDetails[]; totalNFTs: number }>({
citizenNFT: null,
roleNFTs: [],
totalNFTs: 0
});
const [kycStatus, setKycStatus] = useState<string>('NotStarted');
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchProfile();
if (selectedAccount && api && isApiReady) {
fetchScoresAndTikis();
}
}, [user, selectedAccount, api, isApiReady]);
const fetchProfile = async () => {
if (!user) return;
try {
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', user.id)
.maybeSingle();
if (error) {
console.error('Profile fetch error:', error);
return;
}
setProfile(data);
} catch (error) {
console.error('Error fetching profile:', error);
} finally {
setLoading(false);
}
};
const fetchScoresAndTikis = async () => {
if (!selectedAccount || !api) return;
setLoading(true);
try {
const status = await getKycStatus(api, selectedAccount.address);
setKycStatus(status);
const details = await getAllTikiNFTDetails(api, selectedAccount.address);
setNftDetails(details);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
const citizenNumber = nftDetails.citizenNFT
? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)
: 'N/A';
return (
<DashboardContext.Provider value={{ profile, nftDetails, kycStatus, citizenNumber, loading }}>
{children}
</DashboardContext.Provider>
);
}
export function useDashboard() {
const context = useContext(DashboardContext);
if (context === undefined) {
throw new Error('useDashboard must be used within a DashboardProvider');
}
return context;
}