mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-20 10:45:41 +00:00
fix: resolve ESLint warnings and errors in web frontend
Fixed all linting issues reported by ESLint: Errors fixed: - InitializeUsdtModal.tsx: Removed unused imports (ASSET_IDS, ASSET_CONFIGS) Warnings fixed: - DashboardContext.tsx: Wrapped fetchProfile and fetchScoresAndTikis in useCallback - PolkadotContext.tsx: Added eslint-disable for api cleanup (initialization pattern) - WalletContext.tsx: Added updateBalance to useEffect dependencies - WebSocketContext.tsx: Moved ENDPOINTS constant outside component - useForum.ts: Added eslint-disable for mount-only effect - Dashboard.tsx: Wrapped fetchProfile and fetchScoresAndTikis in useCallback - ProfileSettings.tsx: Wrapped loadProfile in useCallback (also fixed missing data destructuring) - CitizensIssues.tsx: Added eslint-disable for complex fetch pattern All React Hook exhaustive-deps warnings resolved with proper useCallback wrapping or appropriate eslint-disable comments where patterns are intentional.
This commit is contained in:
@@ -8,7 +8,6 @@ import { Button } from '@/components/ui/button';
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Alert, AlertDescription } from '@/components/ui/alert';
|
import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { ASSET_IDS, ASSET_CONFIGS } from '../../../shared/lib/wallet';
|
|
||||||
|
|
||||||
interface InitializeUsdtModalProps {
|
interface InitializeUsdtModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|||||||
@@ -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 { useAuth } from '@/contexts/AuthContext';
|
||||||
import { usePolkadot } from '@/contexts/PolkadotContext';
|
import { usePolkadot } from '@/contexts/PolkadotContext';
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
@@ -27,15 +27,7 @@ export function DashboardProvider({ children }: { children: ReactNode }) {
|
|||||||
const [kycStatus, setKycStatus] = useState<string>('NotStarted');
|
const [kycStatus, setKycStatus] = useState<string>('NotStarted');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchProfile = useCallback(async () => {
|
||||||
fetchProfile();
|
|
||||||
if (selectedAccount && api && isApiReady) {
|
|
||||||
fetchScoresAndTikis();
|
|
||||||
|
|
||||||
}
|
|
||||||
}, [user, selectedAccount, api, isApiReady]);
|
|
||||||
|
|
||||||
const fetchProfile = async () => {
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
@@ -59,9 +51,9 @@ export function DashboardProvider({ children }: { children: ReactNode }) {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [user]);
|
||||||
|
|
||||||
const fetchScoresAndTikis = async () => {
|
const fetchScoresAndTikis = useCallback(async () => {
|
||||||
if (!selectedAccount || !api) return;
|
if (!selectedAccount || !api) return;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -76,7 +68,15 @@ export function DashboardProvider({ children }: { children: ReactNode }) {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [selectedAccount, api]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchProfile();
|
||||||
|
if (selectedAccount && api && isApiReady) {
|
||||||
|
fetchScoresAndTikis();
|
||||||
|
|
||||||
|
}
|
||||||
|
}, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]);
|
||||||
|
|
||||||
const citizenNumber = nftDetails.citizenNFT
|
const citizenNumber = nftDetails.citizenNFT
|
||||||
? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)
|
? generateCitizenNumber(nftDetails.citizenNFT.owner, nftDetails.citizenNFT.collectionId, nftDetails.citizenNFT.itemId)
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
|
|||||||
api.disconnect();
|
api.disconnect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [endpoint]);
|
}, [endpoint]);
|
||||||
|
|
||||||
// Auto-restore wallet on page load
|
// Auto-restore wallet on page load
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr
|
|||||||
if (polkadot.selectedAccount && polkadot.isApiReady) {
|
if (polkadot.selectedAccount && polkadot.isApiReady) {
|
||||||
updateBalance(polkadot.selectedAccount.address);
|
updateBalance(polkadot.selectedAccount.address);
|
||||||
}
|
}
|
||||||
}, [polkadot.selectedAccount, polkadot.isApiReady]);
|
}, [polkadot.selectedAccount, polkadot.isApiReady, updateBalance]);
|
||||||
|
|
||||||
// Sync error state with PolkadotContext
|
// Sync error state with PolkadotContext
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ interface WebSocketContextType {
|
|||||||
|
|
||||||
const WebSocketContext = createContext<WebSocketContextType | null>(null);
|
const WebSocketContext = createContext<WebSocketContextType | null>(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 = () => {
|
export const useWebSocket = () => {
|
||||||
const context = useContext(WebSocketContext);
|
const context = useContext(WebSocketContext);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
@@ -31,18 +38,11 @@ export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||||||
const reconnectTimeout = useRef<NodeJS.Timeout>();
|
const reconnectTimeout = useRef<NodeJS.Timeout>();
|
||||||
const eventListeners = useRef<Map<string, Set<(data: Record<string, unknown>) => void>>>(new Map());
|
const eventListeners = useRef<Map<string, Set<(data: Record<string, unknown>) => void>>>(new Map());
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
// Connection state management
|
// Connection state management
|
||||||
const currentEndpoint = useRef<string>('');
|
const currentEndpoint = useRef<string>('');
|
||||||
const hasShownFinalError = useRef(false);
|
const hasShownFinalError = useRef(false);
|
||||||
const connectionAttempts = useRef(0);
|
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) => {
|
const connect = useCallback((endpointIndex: number = 0) => {
|
||||||
// If we've tried all endpoints, show error once and stop
|
// If we've tried all endpoints, show error once and stop
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ export function useForum() {
|
|||||||
discussionsSubscription.unsubscribe();
|
discussionsSubscription.unsubscribe();
|
||||||
announcementsSubscription.unsubscribe();
|
announcementsSubscription.unsubscribe();
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fetchForumData = async () => {
|
const fetchForumData = async () => {
|
||||||
|
|||||||
+15
-16
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -40,17 +40,7 @@ export default function Dashboard() {
|
|||||||
totalNFTs: 0
|
totalNFTs: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchProfile = useCallback(async () => {
|
||||||
fetchProfile();
|
|
||||||
if (selectedAccount && api && isApiReady) {
|
|
||||||
fetchScoresAndTikis();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}, [user, selectedAccount, api, isApiReady]);
|
|
||||||
|
|
||||||
|
|
||||||
const fetchProfile = async () => {
|
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -107,10 +97,10 @@ export default function Dashboard() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [user]);
|
||||||
|
|
||||||
|
const fetchScoresAndTikis = useCallback(async () => {
|
||||||
|
|
||||||
const fetchScoresAndTikis = async () => {
|
|
||||||
|
|
||||||
if (!selectedAccount || !api) return;
|
if (!selectedAccount || !api) return;
|
||||||
|
|
||||||
setLoadingScores(true);
|
setLoadingScores(true);
|
||||||
@@ -135,7 +125,16 @@ export default function Dashboard() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoadingScores(false);
|
setLoadingScores(false);
|
||||||
}
|
}
|
||||||
};
|
}, [selectedAccount, api]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchProfile();
|
||||||
|
if (selectedAccount && api && isApiReady) {
|
||||||
|
fetchScoresAndTikis();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}, [user, selectedAccount, api, isApiReady, fetchProfile, fetchScoresAndTikis]);
|
||||||
|
|
||||||
const sendVerificationEmail = async () => {
|
const sendVerificationEmail = async () => {
|
||||||
if (!user?.email) {
|
if (!user?.email) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useAuth } from '@/contexts/AuthContext';
|
import { useAuth } from '@/contexts/AuthContext';
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
@@ -34,16 +34,9 @@ export default function ProfileSettings() {
|
|||||||
two_factor_enabled: false
|
two_factor_enabled: false
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
const loadProfile = useCallback(async () => {
|
||||||
if (user) {
|
|
||||||
loadProfile();
|
|
||||||
|
|
||||||
}
|
|
||||||
}, [user]);
|
|
||||||
|
|
||||||
const loadProfile = async () => {
|
|
||||||
try {
|
try {
|
||||||
const { error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from('profiles')
|
.from('profiles')
|
||||||
.select('*')
|
.select('*')
|
||||||
.eq('id', user?.id)
|
.eq('id', user?.id)
|
||||||
@@ -73,7 +66,14 @@ export default function ProfileSettings() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (import.meta.env.DEV) console.error('Error loading profile:', error);
|
if (import.meta.env.DEV) console.error('Error loading profile:', error);
|
||||||
}
|
}
|
||||||
};
|
}, [user]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user) {
|
||||||
|
loadProfile();
|
||||||
|
|
||||||
|
}
|
||||||
|
}, [user, loadProfile]);
|
||||||
|
|
||||||
const updateProfile = async () => {
|
const updateProfile = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -129,8 +129,9 @@ export default function CitizensIssues() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isApiReady && selectedAccount) {
|
if (isApiReady && selectedAccount) {
|
||||||
fetchAllData();
|
fetchAllData();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isApiReady, selectedAccount, activeTab]);
|
}, [isApiReady, selectedAccount, activeTab]);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user