Design, develop, and organize a full-stack web application with complete creative freedom. Choose your project concept, select from a wide range of technical modules, and make key architectural decisions. This highly flexible project allows you to explore modern web development while demonstrating your technical skills and creativity through a modular approach.
# Conflicts:
# frontend/src/pages/ttt/ttt.ts
diff --git c/frontend/src/pages/ttt/ttt.html i/frontend/src/pages/ttt/ttt.html
index 82b0f8f..0ea49e1 100644
--- c/frontend/src/pages/ttt/ttt.html
+++ i/frontend/src/pages/ttt/ttt.html
@@ -1,6 +1,6 @@
<div class="displaybox">
- <div id="mainbox" class="mainboxDisplay">
- <button id="JoinQueueBtn" class="btn-style absolute top-4 right-6">Join Queue</button>
+ <div class="mainboxDisplay" id="mainbox">
+ <button class="btn-style absolute top-4 right-6" id="JoinQueueBtn">Join Queue</button>
<h1 class="text-3xl font-bold text-gray-800">
Tic-tac-toe Box<span id="t-username"></span>
</h1><br>
@@ -14,7 +14,7 @@
</div>
<div class="text-center text-sm text-gray-800 px-4 whitespace-nowrap">
- <div id="currentPlayer" class='text-7xl font-bold'></div>
+ <div class='text-7xl font-bold' id="currentPlayer"></div>
<div id="currentPlayerTimer">Waiting for match...</div>
</div>
@@ -27,17 +27,21 @@
</div>
</div>
<div class="grid-box mt-2">
- <div class="grid-layout">
- <div id="cell1" class="ttt-cell"></div>
- <div id="cell2" class="ttt-cell"></div>
- <div id="cell3" class="ttt-cell"></div>
- <div id="cell4" class="ttt-cell"></div>
- <div id="cell5" class="ttt-cell"></div>
- <div id="cell6" class="ttt-cell"></div>
- <div id="cell7" class="ttt-cell"></div>
- <div id="cell8" class="ttt-cell"></div>
- <div id="cell9" class="ttt-cell"></div>
+ <div class="grid-layout relative rounded-lg overflow-hidden">
+ <div class="absolute inset-0 flex flex-col items-center justify-center z-10 bg-gray-900/85 text-white hidden"
+ id="ttt-end-screen">
+ outcome
+ </div>
+ <div class="ttt-cell" id="cell1"></div>
+ <div class="ttt-cell" id="cell2"></div>
+ <div class="ttt-cell" id="cell3"></div>
+ <div class="ttt-cell" id="cell4"></div>
+ <div class="ttt-cell" id="cell5"></div>
+ <div class="ttt-cell" id="cell6"></div>
+ <div class="ttt-cell" id="cell7"></div>
+ <div class="ttt-cell" id="cell8"></div>
+ <div class="ttt-cell" id="cell9"></div>
</div>
- </div>
+ </div>
</div>
</div>
\ No newline at end of file
diff --git c/frontend/src/pages/ttt/ttt.ts i/frontend/src/pages/ttt/ttt.ts
index 2c22add..a111624 100644
--- c/frontend/src/pages/ttt/ttt.ts
+++ i/frontend/src/pages/ttt/ttt.ts
@@ -1,7 +1,7 @@
import "./ttt.css"
import {addRoute, type RouteHandlerReturn} from "@app/routing";
import tttPage from "./ttt.html?raw";
-import {showError, showInfo, showSuccess, showWarn} from "@app/toast";
+import {showError, showInfo} from "@app/toast";
import {io} from "socket.io-client";
import type {CSocket as Socket, GameUpdate} from "./socket";
import {updateUser} from "@app/auth";
@@ -57,7 +57,8 @@ async function handleTTT(): Promise<RouteHandlerReturn> {
const currentPlayerIndicator = document.getElementById("currentPlayer");
const joinQueueBtn = document.getElementById("JoinQueueBtn");
const currentPlayerTimer = document.getElementById("currentPlayerTimer")
- if (!userXString || !userOString || !currentPlayerIndicator || !joinQueueBtn || !currentPlayerTimer) {
+ const result_message = document.getElementById("ttt-end-screen");
+ if (!userXString || !userOString || !currentPlayerIndicator || !joinQueueBtn || !currentPlayerTimer || !result_message) {
return showError('fatal error');
}
@@ -128,9 +129,12 @@ async function handleTTT(): Promise<RouteHandlerReturn> {
};
const makeEnd = (type: 'win' | 'conceded' | 'draw', player: 'X' | 'O') => {
- // TODO: Enhance the draw notification
if (type === 'draw') {
- showWarn('It\'s a draw !')
+ result_message.innerText = "It's a draw! :/";
+ result_message.classList.remove("hidden");
+ setTimeout(() => {
+ result_message.classList.add("hidden");
+ }, 3 * 1000);
}
if (type === 'win') {
@@ -145,11 +149,19 @@ async function handleTTT(): Promise<RouteHandlerReturn> {
default:
return;
}
- // TODO: Enhance the win/loss notification
- if (youWin)
- showSuccess('You won the game !');
- else
- showError('You lost the game :(');
+ if (youWin) {
+ result_message.innerText = "You won the game! :)";
+ result_message.classList.remove("hidden");
+ setTimeout(() => {
+ result_message.classList.add("hidden");
+ }, 3 * 1000);
+ } else {
+ result_message.innerText = "You lost the game! :(";
+ result_message.classList.remove("hidden");
+ setTimeout(() => {
+ result_message.classList.add("hidden");
+ }, 3 * 1000);
+ }
}
};
|
||
|---|---|---|
| .github/workflows | ||
| .husky | ||
| frontend | ||
| logs | ||
| monitoring | ||
| nginx | ||
| nginx-dev | ||
| openapi-template | ||
| src | ||
| .gitignore | ||
| docker-compose.yml | ||
| Docker.mk | ||
| env.example | ||
| flake.nix | ||
| Makefile | ||
| package.json | ||
| pnpm-workspace.yaml | ||
| README.MD | ||
Modules ft_transcendence
| Type de module | Titre du module | Technologie | Description |
|---|---|---|---|
| Mandatory | Base Website | Technologies imposées | Créer un site web avec TypeScript, SPA, backend PHP (optionnel), Docker, sécurité (HTTPS, validation, hash, etc.) |
| Major | Backend Framework | Fastify (Node.js) | Créer un backend avec Fastify/Node.js |
| Major | Blockchain Score | Avalanche + Solidity | Enregistrer les scores de tournoi sur Avalanche via des smart contracts |
| Major | Standard User Management | Technos libres (features imposées) | Auth, profil, avatar, amis, stats, historique... |
| Major | Remote Auth | Google Sign-in | Authentification via Google |
| Major | Remote Players | Technos libres | Permettre à deux joueurs de jouer à distance |
| Major | Multiplayer Game | Technos libres | Mode de jeu à plus de 2 joueurs |
| Major | Add Another Game | Technos libres | Ajouter un second jeu avec matchmaking et historique |
| Major | Live Chat | Technos libres | MP, block, invite à jouer, profils depuis le chat |
| Major | AI Opponent | Technos libres (A* interdit) | IA qui simule un joueur humain (refresh 1s, entrées clavier simulées) |
| Major | WAF & Vault | WAF + ModSecurity + Vault | Sécuriser via WAF, ModSecurity, Vault pour les secrets |
| Major | 2FA + JWT | 2FA + JWT | Authentification double facteur avec tokens JWT sécurisés |
| Major | ELK Stack Logging | Elasticsearch + Logstash + Kibana | Stack ELK pour logs, analyse et visualisation |
| Major | Microservices Backend | Technos libres | Refactor backend en microservices |
| Major | Advanced 3D | Babylon.js | Pong en 3D avec Babylon.js |
| Major | Server-Side Pong | Technos libres | Pong serveur + API |
| Major | CLI vs Web Pong | Technos libres | Jouer depuis le CLI contre un joueur Web via API |
| Minor | Frontend Toolkit | Tailwind CSS (avec TypeScript) | Utiliser Tailwind CSS avec TypeScript pour le frontend |
| Minor | Database | SQLite | Ajouter un backend utilisant SQLite comme base de données |
| Minor | Game Customization | Technos libres | Options de jeu : powerups, maps, etc. |
| Minor | Stats Dashboards | Technos libres | Dashboards utilisateurs + parties |
| Minor | GDPR & Anonymization | Technos libres | Suppression de compte, anonymisation, gestion des données personnelles |
| Minor | Monitoring | Prometheus + Grafana | Supervision avec Prometheus et visualisation avec Grafana |
| Minor | Support All Devices | Technos libres | Responsive + support tactile, clavier, souris |
| Minor | Browser Compatibility | Technos libres | Support d’un navigateur supplémentaire |
| Minor | Multilingual | Technos libres | Site multilingue avec au moins 3 langues |
| Minor | Visual Impairment | Technos libres | Accessibilité visuelle : contrastes, navigation clavier, etc. |
| Minor | SSR | Technos libres | Server Side Rendering pour perf + SEO |