adding validated services? patching forcad_local.py
This commit is contained in:
152
OmCTF-2025/services/block_game/frontend/src/App.tsx
Normal file
152
OmCTF-2025/services/block_game/frontend/src/App.tsx
Normal file
@@ -0,0 +1,152 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import Login from './components/Auth/Login';
|
||||
import Register from './components/Auth/Register';
|
||||
import LevelList from './components/Levels/LevelList';
|
||||
import LevelEditor from './components/Levels/LevelEditor';
|
||||
import GamePlayer from './components/Game/GamePlayer';
|
||||
import { authAPI } from './api';
|
||||
import { Level } from './types';
|
||||
import './App.css';
|
||||
|
||||
type AppState = 'login' | 'register' | 'levels' | 'playing' | 'editing';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [appState, setAppState] = useState<AppState>('login');
|
||||
const [currentLevelId, setCurrentLevelId] = useState<number | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [authStatusMessage, setAuthStatusMessage] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Check if user is already logged in via cookie
|
||||
validateAuth();
|
||||
}, []);
|
||||
|
||||
const validateAuth = async () => {
|
||||
try {
|
||||
await authAPI.whoami();
|
||||
setAppState('levels');
|
||||
setAuthStatusMessage(null);
|
||||
} catch (error: unknown) {
|
||||
const message = axios.isAxiosError(error) && error.response?.status === 400
|
||||
? (typeof error.response.data === 'string' ? error.response.data : error.response.data?.message || 'Bad Request')
|
||||
: null;
|
||||
setAuthStatusMessage(message ? `Auth check failed: ${message}` : null);
|
||||
setAppState('login');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAuthSuccess = () => {
|
||||
setAppState('levels');
|
||||
setAuthStatusMessage(null);
|
||||
};
|
||||
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await authAPI.logout();
|
||||
} catch (error) {
|
||||
console.error('Logout failed:', error);
|
||||
} finally {
|
||||
setAppState('login');
|
||||
setCurrentLevelId(null);
|
||||
setAuthStatusMessage(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePlayLevel = (levelId: number) => {
|
||||
setCurrentLevelId(levelId);
|
||||
setAppState('playing');
|
||||
};
|
||||
|
||||
const handleCreateLevel = () => {
|
||||
setAppState('editing');
|
||||
};
|
||||
|
||||
const handleCancelEditor = () => {
|
||||
setAppState('levels');
|
||||
};
|
||||
|
||||
const handleLevelSaved = (level: Level) => {
|
||||
console.log('Level saved:', level);
|
||||
setAppState('levels');
|
||||
};
|
||||
|
||||
const handleBackToLevels = () => {
|
||||
setCurrentLevelId(null);
|
||||
setAppState('levels');
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="app-loading">
|
||||
<div className="loading-spinner"></div>
|
||||
<p>Loading Block Game...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
switch (appState) {
|
||||
case 'login':
|
||||
return (
|
||||
<Login
|
||||
onLogin={handleAuthSuccess}
|
||||
authStatusMessage={authStatusMessage ?? undefined}
|
||||
onSwitchToRegister={() => {
|
||||
setAuthStatusMessage(null);
|
||||
setAppState('register');
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'register':
|
||||
return (
|
||||
<Register
|
||||
onRegister={handleAuthSuccess}
|
||||
onSwitchToLogin={() => setAppState('login')}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'levels':
|
||||
return (
|
||||
<LevelList
|
||||
onPlayLevel={handlePlayLevel}
|
||||
onCreateLevel={handleCreateLevel}
|
||||
onLogout={handleLogout}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'editing':
|
||||
return (
|
||||
<LevelEditor
|
||||
onCancel={handleCancelEditor}
|
||||
onSaved={handleLevelSaved}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'playing':
|
||||
if (!currentLevelId) {
|
||||
setAppState('levels');
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<GamePlayer
|
||||
levelId={currentLevelId}
|
||||
onBack={handleBackToLevels}
|
||||
/>
|
||||
);
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className="app-error">
|
||||
<h1>Something went wrong</h1>
|
||||
<button onClick={() => setAppState('login')}>
|
||||
Go to Login
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user