diff options
author | Julien Dessaux | 2022-11-21 21:39:17 +0100 |
---|---|---|
committer | Julien Dessaux | 2022-11-21 21:39:17 +0100 |
commit | 8ac636186cf5f704264e7473864c54b3edaf4049 (patch) | |
tree | 6f575d5b4dc5afc0c087e0467c4dd7d6e4a6dd6b | |
parent | cleaned up the distinction between routes and controllers (diff) | |
download | jeux-de-mots-8ac636186cf5f704264e7473864c54b3edaf4049.tar.gz jeux-de-mots-8ac636186cf5f704264e7473864c54b3edaf4049.tar.bz2 jeux-de-mots-8ac636186cf5f704264e7473864c54b3edaf4049.zip |
Added basic games handling
-rw-r--r-- | controllers/games/gameId.js | 17 | ||||
-rw-r--r-- | controllers/games/root.js | 13 | ||||
-rw-r--r-- | controllers/play.js | 9 | ||||
-rw-r--r-- | database/001_games.sql | 12 | ||||
-rw-r--r-- | database/db.js | 1 | ||||
-rw-r--r-- | database/games.js | 29 | ||||
-rw-r--r-- | main.js | 4 | ||||
-rw-r--r-- | middlewares/sessions.js | 2 | ||||
-rw-r--r-- | routes/games.js | 15 | ||||
-rw-r--r-- | routes/play.js | 35 | ||||
-rw-r--r-- | static/index.css | 62 | ||||
-rw-r--r-- | views/game.ejs (renamed from views/play.ejs) | 18 | ||||
-rw-r--r-- | views/games.ejs | 17 |
13 files changed, 157 insertions, 77 deletions
diff --git a/controllers/games/gameId.js b/controllers/games/gameId.js new file mode 100644 index 0000000..c87a857 --- /dev/null +++ b/controllers/games/gameId.js @@ -0,0 +1,17 @@ +import { getGame } from "../../database/games.js"; + +function makePageData(user, cwdata) { + return { + title: "Jouer", + user: user, + CWDATA: cwdata, + }; +} + +export function gameId_get(req, res) { + const game = getGame(req.params.gameId); + // TODO redirect if null + let cwdata = game; // TODO reformat this object + console.log(cwdata); + return res.render("game", makePageData(req.session.user, cwdata)); +} diff --git a/controllers/games/root.js b/controllers/games/root.js new file mode 100644 index 0000000..ece7b74 --- /dev/null +++ b/controllers/games/root.js @@ -0,0 +1,13 @@ +import { listGames } from "../../database/games.js"; + +export function root_get(req, res) { + const data = { + title: "Liste des parties", + user: req.session.user, + games: listGames(req.session.user.id), + }; + for (let i=0; i<data.games.length; i++) { + data.games[i].data = JSON.parse(data.games[i].data); + } + return res.render("games", data); +} diff --git a/controllers/play.js b/controllers/play.js deleted file mode 100644 index c00d15d..0000000 --- a/controllers/play.js +++ /dev/null @@ -1,9 +0,0 @@ -function makeController(req, cwdata) { - return { - title: "Jouer", - user: req.session.user, - CWDATA: cwdata, - }; -} - -export default makeController; diff --git a/database/001_games.sql b/database/001_games.sql new file mode 100644 index 0000000..be45084 --- /dev/null +++ b/database/001_games.sql @@ -0,0 +1,12 @@ +CREATE TABLE games ( + id INTEGER PRIMARY KEY, + player1 INTEGER NOT NULL, + player2 INTEGER NOT NULL, + data TEXT NOT NULL, + created_at DATE DEFAULT (datetime('now')), + last_move_at DATE DEFAULT NULL, + FOREIGN KEY (player1) REFERENCES users(id) ON DELETE CASCADE, + FOREIGN KEY (player2) REFERENCES users(id) ON DELETE CASCADE +); +CREATE INDEX idx_games_player1 ON games(player1); +CREATE INDEX idx_games_player2 ON games(player2); diff --git a/database/db.js b/database/db.js index 259ab58..a360e9b 100644 --- a/database/db.js +++ b/database/db.js @@ -3,6 +3,7 @@ import Database from "better-sqlite3"; const allMigrations = [ "database/000_init.sql", + "database/001_games.sql", ]; const db = new Database("jdm.db"); diff --git a/database/games.js b/database/games.js new file mode 100644 index 0000000..b378eb2 --- /dev/null +++ b/database/games.js @@ -0,0 +1,29 @@ +import db from "./db.js"; + +const createGameStatement = db.prepare("INSERT INTO games (player1, player2, data) VALUES (?, ?, ?);"); +const getGameStatement = db.prepare("SELECT * from games where id = ?;"); +const listGamesStatement = db.prepare("SELECT * from games where player1 = ?1 OR player2 = ?1 ORDER BY last_move_at;"); + +export function createGame(player1, player2, data) { + try { + return createGameStatement.run(player1, player2, data).lastInsertRowId; + } catch { + return null; + } +} + +export function getGame(id) { + try { + return getGameStatement.get(id); + } catch { + return null; + } +} + +export function listGames(userId) { + try { + return listGamesStatement.all({ 1: userId }); + } catch { + return []; + } +} @@ -1,7 +1,7 @@ import express from "express"; import helmet from "./middlewares/helmet.js"; -import playRouter from "./routes/play.js"; +import gamesRouter from "./routes/games.js"; import rootRouter from "./routes/root.js"; const app = express(); @@ -11,7 +11,7 @@ app.use(helmet); app.set("views", "./views"); app.set("view engine", "ejs"); -app.use("/play", playRouter); +app.use("/games", gamesRouter); app.use("/static", express.static("static")); app.use("/", rootRouter); diff --git a/middlewares/sessions.js b/middlewares/sessions.js index 6112a8c..8697ae0 100644 --- a/middlewares/sessions.js +++ b/middlewares/sessions.js @@ -3,7 +3,7 @@ import sqlite from "better-sqlite3"; import sqliteStore from "better-sqlite3-session-store"; const SqliteStore = sqliteStore(expressSession); -const db = new sqlite("sessions.db", { verbose: console.log }); +const db = new sqlite("sessions.db", process.env.NODE_ENV === "production" ? null : { verbose: console.log }); const secret = process.env.SESSION_SECRET || "secret"; const session = expressSession({ cookie: { diff --git a/routes/games.js b/routes/games.js new file mode 100644 index 0000000..67d105d --- /dev/null +++ b/routes/games.js @@ -0,0 +1,15 @@ +import express from "express"; + +import { gameId_get } from "../controllers/games/gameId.js"; +import { root_get } from "../controllers/games/root.js"; +import requireAuth from "../middlewares/requireAuth.js"; +import session from "../middlewares/sessions.js"; + +const router = express.Router(); +router.use(session); +router.use(requireAuth); + +router.get("/", root_get); +router.get("/:gameId(\\d+)", gameId_get); + +export default router; diff --git a/routes/play.js b/routes/play.js deleted file mode 100644 index 4db9acd..0000000 --- a/routes/play.js +++ /dev/null @@ -1,35 +0,0 @@ -import express from "express"; - -import makePlayController from "../controllers/play.js"; -import requireAuth from "../middlewares/requireAuth.js"; -import session from "../middlewares/sessions.js"; - -const router = express.Router(); -router.use(session); -router.use(requireAuth); - -router.get("/", (req, res) => { - const cwdata = { - board: [ - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ], - [ "", "", "", "", "","", "", "", "", "", "", "", "", "", "" ] - ], - letters: [ "A", "B", "C", "D", "E", "F", "JOKER" ] - }; - return res.render("play", makePlayController(req, cwdata)); -}); - -export default router; diff --git a/static/index.css b/static/index.css index f5ef0b9..afb1c33 100644 --- a/static/index.css +++ b/static/index.css @@ -8,7 +8,7 @@ aside { } body { - background: #126623; + background: #358a46; display: grid; grid-template-rows: auto 1fr auto; font-family: -apple-system, BlinkMacSystemFont, @@ -50,11 +50,12 @@ header nav ul li { text-decoration: none; } header nav ul li a { - color: #b58900; + color: black; display: block; text-decoration: none; } header nav ul li.nav-menu-title { + background: #126623; float: left; text-transform: uppercase; font-weight: 700; @@ -68,50 +69,69 @@ form input { } main { - margin-left: auto; - margin-right: auto; + background: #126623; + padding-left: 1em; + padding-right: 1em; } -td { - background: #47b75e; - border: 1px solid #d4fcdb; - min-width: 27px; - height: 27px; - text-align: center; +#games { + border-collapse: collapse; +} +#games tr:nth-child(even){background-color: #f2f2f2;} +#games tr:hover {background-color: #ddd;} +#games td, #games th { + border: 1px solid #ddd; + padding: 8px; +} +#games th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #04AA6D; + color: white; } -#board { - border-collapse: collapse; - font-weight: bold; +#remaining_letters { max-width: 405px; } +#rack-area { + max-width: 405px; +} #rack { display:inline-block; font-weight: bold; } - -#remaining_letters { +#board { + border-collapse: collapse; + font-weight: bold; max-width: 405px; } +#board tr td, #rack tr td { + background: #47b75e; + border: 1px solid #d4fcdb; + min-width: 27px; + height: 27px; + text-align: center; +} -.tw { +#board tr td.tw { background:#E60000; } -.dw { +#board tr td.dw { background:#F86969; } -.tl { +#board tr td.tl { background:#3675FA; } -.dl { +#board tr td.dl { background:#22ACD8; } -.start { +#board tr td.start { background:#ff5500; } -.letter { +#board tr td.letter, #rack tr td.letter { background:#f3e797; } .placed { diff --git a/views/play.ejs b/views/game.ejs index bc98c94..e1fab41 100644 --- a/views/play.ejs +++ b/views/game.ejs @@ -17,20 +17,20 @@ <tr><td id="s13_0"><td id="s13_1" class="dw" title="double word"><td id="s13_2"><td id="s13_3"><td id="s13_4"><td id="s13_5" class="tl" title="triple letter"><td id="s13_6"><td id="s13_7"><td id="s13_8"><td id="s13_9" class="tl" title="triple letter"><td id="s13_10"><td id="s13_11"><td id="s13_12"><td id="s13_13" class="dw" title="double word"><td id="s13_14"></tr> <tr><td id="s14_0" class="tw" title="triple word"><td id="s14_1"><td id="s14_2"><td id="s14_3" class="dl" title="double letter"><td id="s14_4"><td id="s14_5"><td id="s14_6"><td id="s14_7" class="tw" title="triple word"><td id="s14_8"><td id="s14_9"><td id="s14_10"><td id="s14_11" class="dl" title="double letter"><td id="s14_12"><td id="s14_13"><td id="s14_14" class="tw" title="triple word"></tr> </table> -<p> -<table id="rack"> - <tr><td id="l0"><td id="l1"><td id="l2"><td id="l3"><td id="l4"><td id="l5"><td id="l6"></tr> -</table> -<aside> - <button title="validate your move" onclick="onvalidatemoveclick()" id="validate" disabled>0 - Validate</button> - <button onclick="onSelectSwapTilesClicked()" id="pass">Pass</button> -</aside> +<p id="rack-area"> + <table id="rack"> + <tr><td id="l0"><td id="l1"><td id="l2"><td id="l3"><td id="l4"><td id="l5"><td id="l6"></tr> + </table> + <aside> + <button title="validate your move" onclick="onvalidatemoveclick()" id="validate" disabled>0 - Validate</button> + <button onclick="onSelectSwapTilesClicked()" id="pass">Pass</button> + </aside> </p> <p> <span id="player_1_name">player one name</span>: <span class="player_name" id="player_1_points">0</span><br> <span id="player_2_name">player two name</span>: <span class="player_name" id="player_2_points">0</span> </p> <p id="remaining_letters"></p> -<script>var CWDATA = <%- JSON.stringify(CWDATA) %></script> +<script>var CWDATA = <%- CWDATA.data %></script> <script type="module" src="/static/index.js"></script> <%- include("footer") %> diff --git a/views/games.ejs b/views/games.ejs new file mode 100644 index 0000000..3189be8 --- /dev/null +++ b/views/games.ejs @@ -0,0 +1,17 @@ +<%- include("header") %> +<% if (Object.keys(games).length === 0) { %> +<h2>Aucune partie en cours</h2> +<% } else { %> +<h2>Liste des parties en cours</h2> +<table id="games"> + <tr><th>Partie</th><th>Joueur 1</th><th>Joueur 2</th></tr> + <% games.forEach((game) => { %> + <tr> + <td><a href="/games/<%= game.id %>"><%= game.data.title %></a></td> + <td><a href="/users/<%= game.player1 %>"><%= game.data.player1.name %></a></td> + <td><a href="/users/<%= game.player2 %>"><%= game.data.player2.name %></a></td> + </tr> + <% }) %> +</table> +<% } %> +<%- include("footer") %> |