Update frontend/src/App.jsx

This commit is contained in:
Zac Gaetano 2026-04-04 22:51:39 -04:00
parent a4094f13cf
commit 11e72ebeec

View file

@ -15,6 +15,7 @@ const App = () => {
});
const [systemInfo, setSystemInfo] = useState(null);
const [usageStats, setUsageStats] = useState(null);
const [authStatus, setAuthStatus] = useState(null);
const [loading, setLoading] = useState(false);
const [activeView, setActiveView] = useState('tasks'); // 'tasks' | 'dashboard'
@ -23,10 +24,12 @@ const App = () => {
fetchTasks();
fetchSystemInfo();
fetchUsageStats();
fetchAuthStatus();
const interval = setInterval(() => {
fetchTasks();
fetchSystemInfo();
fetchUsageStats();
fetchAuthStatus();
}, 10000);
return () => clearInterval(interval);
}, []);
@ -61,6 +64,38 @@ const App = () => {
}
};
const fetchAuthStatus = async () => {
try {
const response = await fetch('/api/auth/status');
const data = await response.json();
setAuthStatus(data);
} catch (error) {
console.error('Error fetching auth status:', error);
}
};
const handleLogin = async () => {
try {
const response = await fetch('/api/auth/login', { method: 'POST' });
const data = await response.json();
setAuthStatus(prev => ({ ...prev, ...data }));
if (data.auth_url) {
window.open(data.auth_url, '_blank');
}
} catch (error) {
console.error('Error initiating login:', error);
}
};
const handleLogout = async () => {
try {
await fetch('/api/auth/logout', { method: 'POST' });
fetchAuthStatus();
} catch (error) {
console.error('Error logging out:', error);
}
};
const handleCreateTask = async (e) => {
e.preventDefault();
setLoading(true);
@ -137,6 +172,15 @@ const App = () => {
<button className={`nav-btn ${activeView === 'tasks' ? 'active' : ''}`} onClick={() => setActiveView('tasks')}>Tasks</button>
<button className={`nav-btn ${activeView === 'dashboard' ? 'active' : ''}`} onClick={() => setActiveView('dashboard')}>Dashboard</button>
</nav>
<div className="auth-badge">
{authStatus?.status === 'logged_in' ? (
<span className="auth-ok" title={authStatus.account}> {authStatus.account || 'Logged in'}</span>
) : authStatus?.status === 'pending' ? (
<span className="auth-pending"> Awaiting login</span>
) : (
<button className="auth-login-btn" onClick={handleLogin}>🔐 Login with Claude Max</button>
)}
</div>
{systemInfo && (
<div className="system-status">
<span className={`status-indicator ${systemInfo.scheduler_running ? 'running' : 'stopped'}`}></span>
@ -187,6 +231,43 @@ const App = () => {
)}
</div>
<div className="dashboard-section">
<h3>Claude Authentication</h3>
<div className="auth-panel">
{authStatus?.status === 'logged_in' ? (
<div className="auth-connected">
<span className="auth-icon"></span>
<div>
<div className="auth-title">Connected to Claude Max</div>
<div className="auth-sub">{authStatus.account}</div>
</div>
<button className="btn btn-secondary btn-sm" onClick={handleLogout}>Log Out</button>
</div>
) : authStatus?.status === 'pending' ? (
<div className="auth-pending-panel">
<span className="auth-icon"></span>
<div>
<div className="auth-title">Waiting for browser login</div>
{authStatus.auth_url && (
<a className="auth-url-link" href={authStatus.auth_url} target="_blank" rel="noreferrer">
Open login page
</a>
)}
</div>
</div>
) : (
<div className="auth-disconnected">
<span className="auth-icon">🔐</span>
<div>
<div className="auth-title">Not logged in</div>
<div className="auth-sub">Log in with your Claude Max account to run tasks</div>
</div>
<button className="btn btn-primary btn-sm" onClick={handleLogin}>Login with Claude Max</button>
</div>
)}
</div>
</div>
<div className="dashboard-section">
<h3>Claude API Usage</h3>
<div className="usage-grid">