Sfoglia il codice sorgente

Handle publish/unpublished game

Jeremie Pardou-Piquemal 3 anni fa
parent
commit
b1088e9974

+ 1 - 1
public/exec/saveGame.js

@@ -19,7 +19,7 @@ const main = async ({ store, id, userId, body }) => {
     console.log("Game not found");
   }
 
-  if (existingGame && existingGame.owner !== userId) {
+  if (existingGame && existingGame.owner && existingGame.owner !== userId) {
     console.log("Forbidden");
     throwError("Modification allowed only for owner", 403);
   }

+ 30 - 5
src/components/Account.js

@@ -39,10 +39,22 @@ const Account = (props) => {
       <Modal show={showLogin} setShow={setShowLogin} title={t("Login")}>
         {!emailSent && (
           <>
-            <input value={email} onChange={handleChange} />
-            <button onClick={handleSubmit} className="success">
-              {t("Ask authentication link")}
-            </button>
+            <input
+              value={email}
+              onChange={handleChange}
+              placeholder={t("Enter your email here")}
+            />
+            <div
+              style={{
+                display: "flex",
+                justifyContent: "center",
+                marginTop: "2em",
+              }}
+            >
+              <button onClick={handleSubmit} className="button primary">
+                {t("Ask authentication link")}
+              </button>
+            </div>
           </>
         )}
         {emailSent && (
@@ -50,7 +62,20 @@ const Account = (props) => {
             <p>
               {t("Mail sent, check your inbox and click the link to login.")}
             </p>
-            <button onClick={() => setShowLogin(false)}>Ok</button>
+            <div
+              style={{
+                display: "flex",
+                justifyContent: "center",
+                marginTop: "2em",
+              }}
+            >
+              <button
+                className="button primary"
+                onClick={() => setShowLogin(false)}
+              >
+                Ok
+              </button>
+            </div>
           </>
         )}
       </Modal>

+ 10 - 0
src/components/BoardConfig.js

@@ -59,6 +59,16 @@ const BoardConfig = () => {
               initialValue={boardConfig.info}
             />
           </Label>
+
+          <Label>
+            {t("Publish")}
+            <Field
+              name="published"
+              component="input"
+              type="checkbox"
+              initialValue={boardConfig.published}
+            />
+          </Label>
         </div>
       )}
     />

+ 4 - 4
src/utils/api.js

@@ -54,13 +54,14 @@ export const getGames = async () => {
       id: game._id,
       owner: game.owner,
       url: `${gameURI}/${game._id}`,
+      published: game.board.published,
     }));
   }
 
   if (!IS_PRODUCTION) {
     gameList = [
-      { name: "Test Game", data: testGame, id: "test" },
-      { name: "Perf Test", data: perfGame, id: "perf" },
+      { name: "Test Game", data: testGame, id: "test", published: true },
+      { name: "Perf Test", data: perfGame, id: "perf", published: true },
       ...gameList,
     ];
   }
@@ -89,8 +90,6 @@ export const getGame = async (gameId) => {
   } else {
     return data;
   }
-  /*const result = await fetch(`${gameURI}/${id}`);
-  return await result.json();*/
 };
 
 export const createGame = async (data) => {
@@ -130,6 +129,7 @@ export const sendAuthToken = async (email) => {
     headers: {
       Accept: "application/json",
       "Content-Type": "application/json",
+      "X-Auth-HOST": `${window.location.origin}`,
     },
     body: JSON.stringify({ userEmail: email }),
     credentials: "include",

+ 47 - 36
src/views/GameListView.js

@@ -2,14 +2,14 @@ import React from "react";
 import { Link, useLocation } from "react-router-dom";
 import { useTranslation } from "react-i18next";
 
-import { getGames, deleteGame } from "../utils/api";
+import { getGames } from "../utils/api";
 import Account from "../components/Account";
 import useAuth from "../hooks/useAuth";
 
-import { confirmAlert } from "react-confirm-alert";
 import "react-confirm-alert/src/react-confirm-alert.css";
 import logo from "../images/logo-mono.png";
 import header from "../images/header.jpg";
+import useLocalStorage from "../hooks/useLocalStorage";
 
 import styled from "styled-components";
 
@@ -116,14 +116,16 @@ const Game = styled.li`
   }
 `;
 
-function useQuery() {
+const useQuery = () => {
   return new URLSearchParams(useLocation().search);
-}
+};
 
 const GameListView = () => {
   const { t } = useTranslation();
+
+  const [isBeta, setIsBeta] = useLocalStorage("isBeta", false);
+
   let query = useQuery();
-  const beta = query.get("beta") === "true";
 
   const [gameList, setGameList] = React.useState([]);
   const { isAuthenticated, userId } = useAuth();
@@ -134,7 +136,15 @@ const GameListView = () => {
     });
   }, [isAuthenticated]);
 
-  const handleRemove = (idToRemove) => async () => {
+  const forceBeta = query.get("beta") === "true";
+
+  React.useEffect(() => {
+    if (forceBeta) {
+      setIsBeta(true);
+    }
+  }, [forceBeta, setIsBeta]);
+
+  /*const handleRemove = (idToRemove) => async () => {
     confirmAlert({
       title: t("Confirmation"),
       message: t("Do you really want to remove selected items ?"),
@@ -152,17 +162,17 @@ const GameListView = () => {
         },
       ],
     });
-  };
+  };*/
 
   return (
     <GameView>
       <Header>
-        {beta && isAuthenticated && (
+        {isBeta && isAuthenticated && (
           <Link to={`/game/`} className="button new-game">
             {t("Create new game")}
           </Link>
         )}
-        {beta && <Account className="login" />}
+        {isBeta && <Account className="login" />}
         <Brand className="brand">
           <a href="/">
             <img src={logo} alt="logo" />
@@ -174,33 +184,34 @@ const GameListView = () => {
         </h2>
       </Header>
       <GameList>
-        {gameList.map(({ name, id, owner }) => (
-          <Game key={id}>
-            <h2 className="game-name">{name}</h2>
-            <Link to={`/game/${id}/session/`} className="button play">
-              {t("Play")}
-            </Link>
-            {beta && (userId === owner || !owner) && (
-              <div className="extra-actions">
-                <Link to={`/game/${id}/edit`} className="button edit icon-only">
-                  <img
-                    src="https://icongr.am/feather/edit.svg?size=16&color=ffffff"
-                    alt={t("Edit")}
-                  />
-                </Link>
-                <button
-                  onClick={handleRemove(id)}
-                  className="button delete icon-only"
-                >
-                  <img
-                    src="https://icongr.am/feather/trash.svg?size=16&color=ffffff"
-                    alt={t("Remove")}
-                  />
-                </button>
-              </div>
-            )}
-          </Game>
-        ))}
+        {gameList
+          .filter(
+            ({ published, owner }) =>
+              published || (userId && (!owner || owner === userId))
+          )
+          .map(({ name, id, owner, published }) => (
+            <Game key={id}>
+              <h2 className="game-name">
+                {name} {!published && "(Private)"}
+              </h2>
+              <Link to={`/game/${id}/session/`} className="button play">
+                {t("Play")}
+              </Link>
+              {isBeta && userId && (userId === owner || !owner) && (
+                <div className="extra-actions">
+                  <Link
+                    to={`/game/${id}/edit`}
+                    className="button edit icon-only"
+                  >
+                    <img
+                      src="https://icongr.am/feather/edit.svg?size=16&color=ffffff"
+                      alt={t("Edit")}
+                    />
+                  </Link>
+                </div>
+              )}
+            </Game>
+          ))}
       </GameList>
     </GameView>
   );