Files
ultimate-ban-tracker/frontend/src/hooks/useAccounts.tsx

218 lines
7.2 KiB
TypeScript

import React, { createContext, useContext, useState, useEffect } from 'react';
export interface Account {
_id: string;
steamId: string;
personaName: string;
loginName?: string;
steamLoginSecure?: string;
loginConfig?: any;
sessionUpdatedAt?: string;
autoCheckCooldown: boolean;
avatar: string;
localAvatar?: string;
profileUrl: string;
status: string;
vacBanned: boolean;
gameBans: number;
lastBanCheck: string;
lastScrapeTime?: string;
cooldownExpiresAt?: string;
authError?: boolean;
notes?: string;
}
export interface ServerConfig {
url: string;
token?: string;
serverSteamId?: string;
enabled: boolean;
isAdmin?: boolean;
}
interface AccountsContextType {
accounts: Account[];
serverConfig: ServerConfig | null;
isLoading: boolean;
isSyncing: boolean;
addAccount: (data: { identifier: string }) => Promise<void>;
updateAccount: (id: string, data: Partial<Account>) => Promise<void>;
deleteAccount: (id: string) => Promise<void>;
switchAccount: (loginName: string) => Promise<void>;
openSteamAppLogin: () => Promise<void>;
openSteamLogin: (steamId: string) => Promise<void>;
shareAccountWithUser: (steamId: string, targetSteamId: string) => Promise<any>;
revokeAccountAccess: (steamId: string, targetSteamId: string) => Promise<any>;
revokeAllAccountAccess: (steamId: string) => Promise<any>;
// Server Methods
updateServerConfig: (config: Partial<ServerConfig>) => Promise<void>;
loginToServer: () => Promise<void>;
syncNow: () => Promise<void>;
scrapeAccount: (steamId: string) => Promise<boolean>;
getCommunityAccounts: () => Promise<any[]>;
getServerUsers: () => Promise<any[]>;
refreshAccounts: (showLoading?: boolean) => Promise<void>;
// Admin Methods
adminGetStats: () => Promise<any>;
adminGetUsers: () => Promise<any[]>;
adminDeleteUser: (userId: string) => Promise<void>;
adminGetAccounts: () => Promise<any[]>;
adminRemoveAccount: (steamId: string) => Promise<void>;
}
const AccountsContext = createContext<AccountsContextType | undefined>(undefined);
export const AccountsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [accounts, setAccounts] = useState<Account[]>([]);
const [serverConfig, setServerConfig] = useState<ServerConfig | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [isSyncing, setIsSyncing] = useState(false);
const refreshAccounts = async (showLoading = false) => {
if (showLoading) setIsLoading(true);
try {
const api = (window as any).electronAPI;
if (!api) {
console.warn("[useAccounts] electronAPI not found in window");
return;
}
console.log("[useAccounts] Fetching data from main process...");
const accData = await api.getAccounts();
const configData = await api.getServerConfig();
setAccounts(Array.isArray(accData) ? accData : []);
setServerConfig(configData || null);
} catch (error) {
console.error("[useAccounts] Error loading accounts:", error);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
refreshAccounts(true);
const api = (window as any).electronAPI;
if (api?.onAccountsUpdated) {
const cleanup = api.onAccountsUpdated((updatedAccounts: Account[]) => {
setAccounts(Array.isArray(updatedAccounts) ? updatedAccounts : []);
});
return typeof cleanup === 'function' ? cleanup : undefined;
}
}, []);
const syncNow = async () => {
setIsSyncing(true);
try {
await (window as any).electronAPI.syncNow();
await refreshAccounts();
} catch (e) {
console.error("[useAccounts] Sync failed", e);
} finally {
setIsSyncing(false);
}
};
const scrapeAccount = async (steamId: string) => {
const success = await (window as any).electronAPI.scrapeAccount(steamId);
if (success) await syncNow();
return success;
};
const addAccount = async (data: { identifier: string }) => {
await (window as any).electronAPI.addAccount(data);
await refreshAccounts();
await syncNow();
};
const updateAccount = async (id: string, data: Partial<Account>) => {
await (window as any).electronAPI.updateAccount(id, data);
await refreshAccounts();
};
const deleteAccount = async (id: string) => {
if (!window.confirm("Are you sure you want to remove this account?")) return;
await (window as any).electronAPI.deleteAccount(id);
await refreshAccounts();
};
const switchAccount = async (loginName: string) => {
if (!loginName) return;
await (window as any).electronAPI.switchAccount(loginName);
};
const openSteamAppLogin = async () => {
await (window as any).electronAPI.openSteamAppLogin();
};
const openSteamLogin = async (steamId: string) => {
await (window as any).electronAPI.openSteamLogin(steamId);
await syncNow();
};
const shareAccountWithUser = async (steamId: string, targetSteamId: string) => {
const res = await (window as any).electronAPI.shareAccountWithUser(steamId, targetSteamId);
await syncNow();
return res;
};
const revokeAccountAccess = async (steamId: string, targetSteamId: string) => {
const res = await (window as any).electronAPI.revokeAccountAccess(steamId, targetSteamId);
await syncNow();
return res;
};
const revokeAllAccountAccess = async (steamId: string) => {
const res = await (window as any).electronAPI.revokeAllAccountAccess(steamId);
await syncNow();
return res;
};
const updateServerConfig = async (config: Partial<ServerConfig>) => {
const updated = await (window as any).electronAPI.updateServerConfig(config);
setServerConfig(updated);
};
const loginToServer = async () => {
await (window as any).electronAPI.loginToServer();
await refreshAccounts();
await syncNow();
};
const getCommunityAccounts = async () => {
return await (window as any).electronAPI.getCommunityAccounts();
};
const getServerUsers = async () => {
return await (window as any).electronAPI.getServerUsers();
};
// --- Admin Methods ---
const adminGetStats = async () => (window as any).electronAPI.adminGetStats();
const adminGetUsers = async () => (window as any).electronAPI.adminGetUsers();
const adminDeleteUser = async (userId: string) => (window as any).electronAPI.adminDeleteUser(userId);
const adminGetAccounts = async () => (window as any).electronAPI.adminGetAccounts();
const adminRemoveAccount = async (steamId: string) => (window as any).electronAPI.adminRemoveAccount(steamId);
return (
<AccountsContext.Provider value={{
accounts, serverConfig, isLoading, isSyncing, addAccount, updateAccount, deleteAccount,
switchAccount, openSteamAppLogin, openSteamLogin, updateServerConfig, loginToServer,
getCommunityAccounts, getServerUsers, shareAccountWithUser, revokeAccountAccess, revokeAllAccountAccess, syncNow, refreshAccounts,
scrapeAccount, adminGetStats, adminGetUsers, adminDeleteUser, adminGetAccounts, adminRemoveAccount
}}>
{children}
</AccountsContext.Provider>
);
};
export const useAccounts = () => {
const context = useContext(AccountsContext);
if (context === undefined) {
throw new Error('useAccounts must be used within an AccountsProvider');
}
return context;
};