add analytics

This commit is contained in:
2026-06-05 00:11:45 -03:00
parent a2947b3bf2
commit fd8e9049bf
35 changed files with 1540 additions and 30 deletions

View File

@@ -16,6 +16,8 @@ import React, {
import PropTypes from "prop-types";
import { gameEventBus } from "../utils/gameEvents";
import { GameProgressProvider, useGameProgress } from "./GameProgressContext";
import { useGameActivityTracking } from "../services/analytics/useGameActivityTracking";
import { getAnalytics } from "../services/analytics/AnalyticsManager";
export const GAME_STATES = {
PARADO: "parado",
@@ -83,16 +85,53 @@ function GameStateInnerProvider({ children, gameConfig }) {
const [codeEditorContent, setCodeEditorContent] = useState("");
const [failureMessage, setFailureMessage] = useState("");
const [isDebugMode, setIsDebugMode] = useState(() => {
const urlParams = new URLSearchParams(window.location.search);
const debugKey = Array.from(urlParams.keys()).find(
// Try both window.location.search and hash-based query params (for HashRouter)
let urlParams = new URLSearchParams(window.location.search);
let debugKey = Array.from(urlParams.keys()).find(
(k) => k.toLowerCase() === "debug",
);
return urlParams.get(debugKey)?.toLowerCase() === "true";
// If not found in search, try hash (for HashRouter with ?debug=true after hash)
if (!debugKey && window.location.hash.includes('?')) {
const hashSearch = window.location.hash.split('?')[1];
urlParams = new URLSearchParams(hashSearch);
debugKey = Array.from(urlParams.keys()).find(
(k) => k.toLowerCase() === "debug",
);
}
const isDebug = urlParams.get(debugKey)?.toLowerCase() === "true";
return isDebug;
});
const getCodeFromWorkspace = useRef(null);
const getCodeFromEditor = useRef(null);
// Rastrear atividade do jogo (analytics)
useGameActivityTracking(gameConfig, {
executionState,
currentPhase,
currentBlockCount,
editorType,
});
const trackGenericEvent = useCallback(
(eventName, extraData = {}) => {
if (!gameConfig?.gameId) return;
const analytics = getAnalytics();
analytics.trackEvent(eventName, {
atividade_id: gameConfig.gameId,
atividade_nome: gameConfig.gameName || gameConfig.gameId,
fase_numero: currentPhase,
editor_tipo: editorType,
blocos_atuais: currentBlockCount,
...extraData,
});
},
[gameConfig?.gameId, gameConfig?.gameName, currentPhase, editorType, currentBlockCount],
);
/**
* Executa o código/workspace do editor de forma síncrona.
* Registra o código gerado e muda estado para EXECUTANDO.
@@ -103,6 +142,14 @@ function GameStateInnerProvider({ children, gameConfig }) {
* @throws {console.error} Se editor não registrou a função de execução
*/
const execute = () => {
trackGenericEvent("tentativa_execucao", {
origem_acao: "botao_executar",
});
trackGenericEvent("blocos_usados", {
origem_acao: "execucao",
});
if (editorType === "code") {
if (getCodeFromEditor.current) {
const codigo = getCodeFromEditor.current();
@@ -192,7 +239,15 @@ function GameStateInnerProvider({ children, gameConfig }) {
* @param {number} numeroFase - Número da fase para navegar (1-indexed)
* @returns {void}
*/
const changePhase = (numeroFase) => {
const changePhase = (numeroFase, source = "unknown") => {
if (source === "manual_selector") {
trackGenericEvent("troca_fase_manual", {
fase_origem: currentPhase,
fase_destino: numeroFase,
origem_acao: source,
});
}
progressChangePhase(numeroFase);
setExecutionState(GAME_STATES.PARADO);
setGeneratedCode("");