const AccountRow: React.FC<{ account: Account, onDelete: (id: string) => void, onSwitch: (login: string) => void, onAuth: () => void }> = ({ account, onDelete, onSwitch, onAuth }) => { const { shareAccountWithUser, revokeAccountAccess, revokeAllAccountAccess, getServerUsers, serverConfig } = useAccounts(); const [timeLeft, setTimeLeft] = useState(null); const [isShareOpen, setIsShareOpen] = useState(false); const [targetUserId, setTargetUserId] = useState(''); const [isSharing, setIsSharing] = useState(false); const [serverUsers, setServerUsers] = useState([]); const cooldownDate = account?.cooldownExpiresAt ? new Date(account.cooldownExpiresAt) : null; const isCooldownActive = cooldownDate && !isNaN(cooldownDate.getTime()) && cooldownDate.getTime() > Date.now(); useEffect(() => { if (!isCooldownActive || !cooldownDate) { setTimeLeft(null); return; } const targetTime = cooldownDate.getTime(); const timer = setInterval(() => { const diff = targetTime - Date.now(); if (diff <= 0) { setTimeLeft(null); clearInterval(timer); return; } const hours = Math.floor(diff / 3600000); const mins = Math.floor((diff % 3600000) / 60000); const secs = Math.floor((diff % 60000) / 1000); setTimeLeft(`${hours}h ${mins}m ${secs}s`); }, 1000); return () => clearInterval(timer); }, [account?.cooldownExpiresAt, isCooldownActive]); const avatarSrc = account?.localAvatar ? `steam-resource://${account.localAvatar}` : (account?.avatar || ''); const [imgSrc, setImgSrc] = useState(avatarSrc); useEffect(() => { setImgSrc(avatarSrc); }, [avatarSrc]); const handleOpenShare = async () => { setIsShareOpen(true); try { const [users, selfInfo] = await Promise.all([ getServerUsers(), (window as any).electronAPI.getServerUserInfo() ]); const filtered = (Array.isArray(users) ? users : []).filter(u => u.steamId !== selfInfo.steamId && u.steamId !== account.steamId ); setServerUsers(filtered); } catch (e) {} }; const handleShare = async () => { if (!targetUserId) return; setIsSharing(true); try { await shareAccountWithUser(account.steamId, targetUserId); setTargetUserId(''); } catch (e: any) { alert(e.message || "Failed to share account"); } finally { setIsSharing(false); } }; const handleRevoke = async (targetSteamId: string) => { if (!window.confirm("Revoke access for this user?")) return; try { await revokeAccountAccess(account.steamId, targetSteamId); } catch (e: any) { alert(e.message); } }; const handleRevokeAll = async () => { if (!window.confirm("Completely stop sharing this account with the community?")) return; try { await revokeAllAccountAccess(account.steamId); setIsShareOpen(false); } catch (e: any) { alert(e.message); } }; const isBanned = account?.vacBanned || (account?.gameBans && account.gameBans > 0); const isShared = account?._id.startsWith('shared_'); return ( {isShared && ( )} {account?.personaName || 'Unknown'} {account?.steamId} {isBanned ? ( ACCOUNT BANNED {account?.vacBanned && ( )} {account?.gameBans ? account.gameBans > 0 && ( ) : null} ) : ( SECURE )} {account?.authError ? ( Needs Re-auth ) : isCooldownActive ? ( {timeLeft} ) : ( Available )} {account.loginName && ( )} {account.steamLoginSecure && !account.authError ? : (account.authError ? : )} {account.steamLoginSecure && !account.authError && ( TRACKING )} (window as any).electronAPI.openExternal(account?.profileUrl || '')}> onDelete(account?._id || '')}> setIsShareOpen(false)} maxWidth="xs" fullWidth> Account Permissions GRANT ACCESS Select User CURRENT ACCESS {(account as any).sharedWith?.map((sw: any) => ( handleRevoke(sw.steamId)}> ))} {(!(account as any).sharedWith || (account as any).sharedWith.length === 0) && ( Not shared with anyone yet. )} {(account as any).sharedWith?.length > 0 && ( )} ); };