Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Backend API Configuration
VITE_API_URL=http://localhost:4000/api
VITE_BASE_URL=http://localhost:4000

# Frontend Configuration
VITE_APP_NAME=WordIT
VITE_APP_VERSION=1.0.0
1 change: 1 addition & 0 deletions game-page-upgrade
Submodule game-page-upgrade added at d53667
120 changes: 56 additions & 64 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"framer-motion": "^12.23.26",
"lint-staged": "^16.2.6",
"lucide-react": "^0.553.0",
"react": "^19.1.1",
Expand All @@ -51,7 +50,6 @@
"react-hook-form": "^7.68.0",
"react-hot-toast": "^2.6.0",
"react-router-dom": "^7.9.5",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.17",
"yet-another-react-lightbox": "^3.25.0",
Expand All @@ -64,7 +62,9 @@
"@types/node": "^24.10.1",
"@types/react": "^19.1.16",
"@types/react-dom": "^19.1.9",
"@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react": "^5.0.4",
"bun-types": "^1.3.4",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
Expand Down
10 changes: 10 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ import CreateCrossword from "./pages/crosswords/create";
import PlayCrossword from "./pages/crosswords/index";
import EditCrossword from "./pages/crosswords/edit";

import WatchAndMemorizeGame from "./pages/watch-and-memorize/play";

import React from "react";

function App() {
return (
<>
Expand Down Expand Up @@ -97,6 +101,12 @@ function App() {
/>
<Route path="/airplane/play/:id" element={<AirplaneGeneralGame />} />

{/* ⭐️ ADD WATCH & MEMORIZE ROUTE */}
<Route
path="/watch-and-memorize/play/:projectId"
element={<WatchAndMemorizeGame />}
/>

<Route element={<ProtectedRoute />}>
<Route path="/profile" element={<ProfilePage />} />
<Route path="/my-projects" element={<MyProjectsPage />} />
Expand Down
2 changes: 1 addition & 1 deletion src/api/quiz/useCreateQuiz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const useCreateQuiz = async (payload: QuizPayload) => {

formData.append("questions", JSON.stringify(questionsPayload));

const res = await api.post("/api/game/game-type/quiz", formData, {
const res = await api.post("/game/game-type/quiz", formData, {
headers: { "Content-Type": "multipart/form-data" },
});

Expand Down
93 changes: 93 additions & 0 deletions src/api/watchAndMemorizeApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import api from "@/api/axios";
import { GAME_TEMPLATE_ID } from "@/pages/watch-and-memorize/gameConfig";

export interface GameData {
id?: string;
name: string;
description?: string;
thumbnail_image: string;
game_template_id: string;
is_published: boolean;
game_json: {
images: Array<{ id: string; src: string; label: string }>;
showCount: number;
showDurationMs: number;
totalTimeSec: number;
};
}

export interface LeaderboardEntry {
id: string;
score: number;
time_taken?: number;
difficulty?: string;
user?: {
username: string;
profile_picture?: string;
};
created_at: string;
}

export interface GamePlayData {
game_id: string;
score: number;
time_taken: number;
difficulty?: string;
}

// Get all games for watch-and-memorize template
export const getWatchAndMemorizeGames = async () => {
const response = await api.get("/game", {
params: {
game_template_id: GAME_TEMPLATE_ID,
limit: 100,
},
});
return response.data;
};

// Get specific game by ID
export const getGameById = async (gameId: string) => {
const response = await api.get(`/game/game-type/${gameId}`);
return response.data;
};

// Create a new watch-and-memorize game
export const createWatchAndMemorizeGame = async (gameData: GameData) => {
const response = await api.post("/game/game-type", {
...gameData,
game_template_id: GAME_TEMPLATE_ID,
});
return response.data;
};

// Update game play count
export const updateGamePlayCount = async (gameId: string) => {
const response = await api.post("/game/play-count", {
game_id: gameId,
});
return response.data;
};

// Submit score to leaderboard
export const submitScore = async (gamePlayData: GamePlayData) => {
const response = await api.post("/leaderboard", gamePlayData);
return response.data;
};

// Get leaderboard for a specific game
export const getGameLeaderboard = async (gameId: string, limit = 10) => {
const response = await api.get(`/leaderboard/${gameId}`, {
params: { limit },
});
return response.data;
};

// Like/unlike a game
export const toggleGameLike = async (gameId: string, isLike: boolean) => {
const response = await api.post("/game/like", {
game_id: gameId,
is_like: isLike,
});
return response.data;
};
Loading
Loading