209 lines
7.7 KiB
JavaScript
209 lines
7.7 KiB
JavaScript
// Import our custom CSS
|
|
import '../scss/styles.scss'
|
|
// Import all of Bootstrap's JS
|
|
import * as bootstrap from 'bootstrap'
|
|
|
|
import Alpine from 'alpinejs'
|
|
|
|
window.Alpine = Alpine
|
|
|
|
// Define an Alpine component to manage the game state
|
|
Alpine.data('gameManager', () => ({
|
|
// --- Component State ---
|
|
isLoading: false,
|
|
error: null,
|
|
gameData: null,
|
|
// --- Document State (add properties for each document type) ---
|
|
passportSrc: null, // For PNG data URL
|
|
accountSrc: null, // For PDF data URL
|
|
profileSrc: null, // For DOCX data URL (download link)
|
|
descriptionText: null, // For decoded TXT content
|
|
|
|
init() {
|
|
console.log('Game manager initializing...');
|
|
this.startNewGame();
|
|
},
|
|
|
|
// --- Helper Function to Process Document Data ---
|
|
processClientData(clientData) {
|
|
if (!clientData) {
|
|
console.log('No client data to process.');
|
|
this.passportSrc = null;
|
|
this.accountSrc = null;
|
|
this.profileSrc = null;
|
|
this.descriptionText = null;
|
|
return;
|
|
}
|
|
|
|
console.log('Processing client data for documents:', clientData);
|
|
|
|
// --- Passport (PNG) ---
|
|
if (clientData.passport) {
|
|
this.passportSrc = `data:image/png;base64,${clientData.passport}`;
|
|
} else {
|
|
this.passportSrc = null; // Reset if not provided
|
|
console.log('Passport base64 data not found.');
|
|
}
|
|
|
|
// --- Account (PDF) ---
|
|
if (clientData.account) {
|
|
this.accountSrc = `data:application/pdf;base64,${clientData.account}`;
|
|
} else {
|
|
this.accountSrc = null; // Reset if not provided
|
|
console.log('Account base64 data not found.');
|
|
}
|
|
|
|
// --- Profile (DOCX) - Create download link ---
|
|
if (clientData.profile) {
|
|
this.profileSrc = `data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,${clientData.profile}`;
|
|
} else {
|
|
this.profileSrc = null; // Reset if not provided
|
|
console.log('Profile base64 data not found.');
|
|
}
|
|
|
|
// --- Description (TXT) - Decode base64 ---
|
|
if (clientData.description) {
|
|
try {
|
|
this.descriptionText = atob(clientData.description);
|
|
} catch (e) {
|
|
console.error('Error decoding description base64:', e);
|
|
this.descriptionText = 'Error decoding document content.';
|
|
}
|
|
} else {
|
|
this.descriptionText = null; // Reset if not provided
|
|
console.log('Description base64 data not found.');
|
|
}
|
|
},
|
|
|
|
startNewGame() {
|
|
this.isLoading = true;
|
|
this.error = null;
|
|
this.gameData = null;
|
|
// Reset document states
|
|
this.processClientData(null);
|
|
|
|
// Use the browser's fetch API
|
|
fetch('http://127.0.0.1:5000/new-game', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
return response.json().then(errData => {
|
|
throw new Error(errData.detail || `HTTP error! status: ${response.status}`);
|
|
}).catch(() => {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
});
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('New game data received:', data);
|
|
this.gameData = data;
|
|
// Process documents from the new game data
|
|
this.processClientData(this.gameData.client_data);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error starting new game:', error);
|
|
this.error = error.message || 'Failed to start game. Check console/backend.';
|
|
})
|
|
.finally(() => {
|
|
this.isLoading = false;
|
|
});
|
|
},
|
|
|
|
submitDecision(decision) {
|
|
if (!decision || (decision !== 'Accept' && decision !== 'Reject')) {
|
|
this.error = 'Invalid decision provided.';
|
|
console.error('Invalid decision:', decision);
|
|
return;
|
|
}
|
|
if (!this.gameData || !this.gameData.session_id || !this.gameData.client_id) {
|
|
this.error = 'Missing game data (session or client ID). Cannot submit decision.';
|
|
console.error('Missing game data for decision:', this.gameData);
|
|
return;
|
|
}
|
|
if (this.isLoading) {
|
|
console.warn('Already processing a request.');
|
|
return;
|
|
}
|
|
if (this.gameData.status === 'gameover') {
|
|
console.warn('Game is already over.');
|
|
return;
|
|
}
|
|
|
|
console.log(`Submitting decision: ${decision} for client: ${this.gameData.client_id}`);
|
|
this.isLoading = true;
|
|
this.error = null;
|
|
// Reset document states before fetching new data
|
|
this.processClientData(null);
|
|
|
|
const requestBody = {
|
|
decision: decision,
|
|
session_id: this.gameData.session_id,
|
|
client_id: this.gameData.client_id
|
|
};
|
|
|
|
fetch('http://127.0.0.1:5000/next', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(requestBody)
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
return response.text().then(text => {
|
|
try {
|
|
const errData = JSON.parse(text);
|
|
throw new Error(errData.detail || `HTTP error! status: ${response.status}`);
|
|
} catch (e) {
|
|
throw new Error(text || `HTTP error! status: ${response.status}`);
|
|
}
|
|
});
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Decision response received:', data);
|
|
// Update core game data
|
|
this.gameData.score = data.score;
|
|
this.gameData.status = data.status;
|
|
this.gameData.decision = data.decision;
|
|
this.gameData.bot_reason = data.bot_reason;
|
|
|
|
// Update client_id and client_data only if present and game not over
|
|
if (data.status !== 'gameover') {
|
|
if (data.client_id) {
|
|
this.gameData.client_id = data.client_id;
|
|
} else {
|
|
console.warn("Game continues but no new client ID received from /next endpoint.");
|
|
}
|
|
|
|
if (data.client_data) {
|
|
this.gameData.client_data = data.client_data;
|
|
// Process documents from the new client data
|
|
this.processClientData(this.gameData.client_data);
|
|
} else {
|
|
console.warn("Game continues but no new client data received from /next endpoint.");
|
|
this.gameData.client_data = null; // Clear old client data if none received
|
|
this.processClientData(null); // Ensure docs are cleared
|
|
}
|
|
} else {
|
|
console.log('Game Over! Final score:', this.gameData.score);
|
|
// Optionally clear client_id and client_data on gameover
|
|
// this.gameData.client_id = null;
|
|
// this.gameData.client_data = null;
|
|
// this.processClientData(null); // Clear docs on game over
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error submitting decision:', error);
|
|
this.error = error.message || 'Failed to submit decision.';
|
|
})
|
|
.finally(() => {
|
|
this.isLoading = false;
|
|
});
|
|
}
|
|
}));
|
|
|
|
|
|
Alpine.start() |