diff --git a/web/src/components/dex/InitializeUsdtModal.tsx b/web/src/components/dex/InitializeUsdtModal.tsx index 953addb9..dad7846a 100644 --- a/web/src/components/dex/InitializeUsdtModal.tsx +++ b/web/src/components/dex/InitializeUsdtModal.tsx @@ -8,7 +8,6 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { useToast } from '@/hooks/use-toast'; -import { ASSET_IDS, ASSET_CONFIGS } from '../../../shared/lib/wallet'; interface InitializeUsdtModalProps { isOpen: boolean; diff --git a/web/src/contexts/DashboardContext.tsx b/web/src/contexts/DashboardContext.tsx index 98cdd6db..6aaae5e7 100644 --- a/web/src/contexts/DashboardContext.tsx +++ b/web/src/contexts/DashboardContext.tsx @@ -1,4 +1,4 @@ -import { createContext, useContext, useState, useEffect, ReactNode } from 'react'; +import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'; import { useAuth } from '@/contexts/AuthContext'; import { usePolkadot } from '@/contexts/PolkadotContext'; import { supabase } from '@/lib/supabase'; @@ -27,15 +27,7 @@ export function DashboardProvider({ children }: { children: ReactNode }) { const [kycStatus, setKycStatus] = useState('NotStarted'); const [loading, setLoading] = useState(true); - useEffect(() => { - fetchProfile(); - if (selectedAccount && api && isApiReady) { - fetchScoresAndTikis(); - - } - }, [user, selectedAccount, api, isApiReady]); - - const fetchProfile = async () => { + const fetchProfile = useCallback(async () => { if (!user) { setLoading(false); return; @@ -59,9 +51,9 @@ export function DashboardProvider({ children }: { children: ReactNode }) { } finally { setLoading(false); } - }; + }, [user]); - const fetchScoresAndTikis = async () => { + const fetchScoresAndTikis = useCallback(async () => { if (!selectedAccount || !api) return; setLoading(true); @@ -76,7 +68,15 @@ export function DashboardProvider({ children }: { children: ReactNode }) { } finally { setLoading(false); } - }; + }, [selectedAccount, api]); + + useEffect(() => { + fetchProfile(); + if (selectedAccount && api && isApiReady) { + fetchScoresAndTikis(); + + } + }, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]); const citizenNumber = nftDetails.citizenNFT ? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId) diff --git a/web/src/contexts/PolkadotContext.tsx b/web/src/contexts/PolkadotContext.tsx index b4462ea6..adb8baa9 100644 --- a/web/src/contexts/PolkadotContext.tsx +++ b/web/src/contexts/PolkadotContext.tsx @@ -124,6 +124,7 @@ export const PolkadotProvider: React.FC = ({ api.disconnect(); } }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [endpoint]); // Auto-restore wallet on page load diff --git a/web/src/contexts/WalletContext.tsx b/web/src/contexts/WalletContext.tsx index bc682358..9f0ce870 100644 --- a/web/src/contexts/WalletContext.tsx +++ b/web/src/contexts/WalletContext.tsx @@ -239,7 +239,7 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr if (polkadot.selectedAccount && polkadot.isApiReady) { updateBalance(polkadot.selectedAccount.address); } - }, [polkadot.selectedAccount, polkadot.isApiReady]); + }, [polkadot.selectedAccount, polkadot.isApiReady, updateBalance]); // Sync error state with PolkadotContext useEffect(() => { diff --git a/web/src/contexts/WebSocketContext.tsx b/web/src/contexts/WebSocketContext.tsx index b5dbe407..2daa8954 100644 --- a/web/src/contexts/WebSocketContext.tsx +++ b/web/src/contexts/WebSocketContext.tsx @@ -17,6 +17,13 @@ interface WebSocketContextType { const WebSocketContext = createContext(null); +const ENDPOINTS = [ + 'ws://localhost:8082', // Local Vite dev server + 'ws://127.0.0.1:9944', // Local development node (primary) + 'ws://localhost:9944', // Local development node (alternative) + 'wss://ws.pezkuwichain.io', // Production WebSocket (fallback) +]; + export const useWebSocket = () => { const context = useContext(WebSocketContext); if (!context) { @@ -31,18 +38,11 @@ export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ chi const reconnectTimeout = useRef(); const eventListeners = useRef) => void>>>(new Map()); const { toast } = useToast(); - + // Connection state management const currentEndpoint = useRef(''); const hasShownFinalError = useRef(false); const connectionAttempts = useRef(0); - - const ENDPOINTS = [ - 'ws://localhost:8082', // Local Vite dev server - 'ws://127.0.0.1:9944', // Local development node (primary) - 'ws://localhost:9944', // Local development node (alternative) - 'wss://ws.pezkuwichain.io', // Production WebSocket (fallback) - ]; const connect = useCallback((endpointIndex: number = 0) => { // If we've tried all endpoints, show error once and stop diff --git a/web/src/hooks/useForum.ts b/web/src/hooks/useForum.ts index 5717f24e..af726ebb 100644 --- a/web/src/hooks/useForum.ts +++ b/web/src/hooks/useForum.ts @@ -95,6 +95,7 @@ export function useForum() { discussionsSubscription.unsubscribe(); announcementsSubscription.unsubscribe(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const fetchForumData = async () => { diff --git a/web/src/pages/Dashboard.tsx b/web/src/pages/Dashboard.tsx index a37086d4..481d9ecc 100644 --- a/web/src/pages/Dashboard.tsx +++ b/web/src/pages/Dashboard.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; @@ -40,17 +40,7 @@ export default function Dashboard() { totalNFTs: 0 }); - useEffect(() => { - fetchProfile(); - if (selectedAccount && api && isApiReady) { - fetchScoresAndTikis(); - - - } - }, [user, selectedAccount, api, isApiReady]); - - - const fetchProfile = async () => { + const fetchProfile = useCallback(async () => { if (!user) return; try { @@ -107,10 +97,10 @@ export default function Dashboard() { } finally { setLoading(false); } - }; + }, [user]); + + const fetchScoresAndTikis = useCallback(async () => { - const fetchScoresAndTikis = async () => { - if (!selectedAccount || !api) return; setLoadingScores(true); @@ -135,7 +125,16 @@ export default function Dashboard() { } finally { setLoadingScores(false); } - }; + }, [selectedAccount, api]); + + useEffect(() => { + fetchProfile(); + if (selectedAccount && api && isApiReady) { + fetchScoresAndTikis(); + + + } + }, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]); const sendVerificationEmail = async () => { if (!user?.email) { diff --git a/web/src/pages/ProfileSettings.tsx b/web/src/pages/ProfileSettings.tsx index e4f2c05c..7a689172 100644 --- a/web/src/pages/ProfileSettings.tsx +++ b/web/src/pages/ProfileSettings.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '@/contexts/AuthContext'; import { supabase } from '@/lib/supabase'; @@ -34,16 +34,9 @@ export default function ProfileSettings() { two_factor_enabled: false }); - useEffect(() => { - if (user) { - loadProfile(); - - } - }, [user]); - - const loadProfile = async () => { + const loadProfile = useCallback(async () => { try { - const { error } = await supabase + const { data, error } = await supabase .from('profiles') .select('*') .eq('id', user?.id) @@ -73,7 +66,14 @@ export default function ProfileSettings() { } catch (error) { if (import.meta.env.DEV) console.error('Error loading profile:', error); } - }; + }, [user]); + + useEffect(() => { + if (user) { + loadProfile(); + + } + }, [user, loadProfile]); const updateProfile = async () => { setLoading(true); diff --git a/web/src/pages/citizens/CitizensIssues.tsx b/web/src/pages/citizens/CitizensIssues.tsx index 583f5696..8787005a 100644 --- a/web/src/pages/citizens/CitizensIssues.tsx +++ b/web/src/pages/citizens/CitizensIssues.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; @@ -129,8 +129,9 @@ export default function CitizensIssues() { useEffect(() => { if (isApiReady && selectedAccount) { fetchAllData(); - + } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isApiReady, selectedAccount, activeTab]);