diff --git a/frontend/package.json b/frontend/package.json index 3186e62..02bce40 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,6 +2,7 @@ "name": "frontend", "version": "0.1.0", "private": true, + "proxy": "http://localhost:5000", "dependencies": { "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.4", @@ -13,6 +14,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.1.0", + "react-router-dom": "^6.22.3", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, diff --git a/frontend/src/App.js b/frontend/src/App.js index 41b8fd3..e4e5080 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,14 +1,25 @@ import * as React from "react"; import "./App.css"; +import { createBrowserRouter, RouterProvider } from "react-router-dom"; + import { ChakraProvider } from "@chakra-ui/react"; import Home from "./Pages/Home/Home"; import { theme } from "./Theme/theme"; +import Start from "./Pages/Game/Start"; + +const router = createBrowserRouter([ + { + path: "/", + element: , + }, + { path: "/game", element: }, +]); function App() { return ( - + ); } diff --git a/frontend/src/Components/ArtifactViewer.js b/frontend/src/Components/ArtifactViewer.js new file mode 100644 index 0000000..c2b1c83 --- /dev/null +++ b/frontend/src/Components/ArtifactViewer.js @@ -0,0 +1,38 @@ +import { useEffect, useState } from "react"; +import { HStack, VStack, Image, Spinner, Box } from "@chakra-ui/react"; + +export default function ArtifactViewer({ gameObjects, progression }) { + const [bigImgSrc, setBigImgSrc] = useState(gameObjects[0]["primaryImage"]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + setLoading(true); + setBigImgSrc(gameObjects[progression]["primaryImage"]); + setTimeout(() => { + setLoading(false); + }, 200); + }, [progression]); + + return ( + + {/* additional images */} + + {gameObjects[progression]["additionalImages"].length > 0 && + gameObjects[progression]["additionalImages"].map((url) => { + return ( + + + + ); + })} + + + {/* image */} + {loading ? ( + + ) : ( + + )} + + ); +} diff --git a/frontend/src/Pages/Game/Game.js b/frontend/src/Pages/Game/Game.js new file mode 100644 index 0000000..0c5b379 --- /dev/null +++ b/frontend/src/Pages/Game/Game.js @@ -0,0 +1,129 @@ +import { useEffect, useState } from "react"; +import { + VStack, + Center, + Text, + Spinner, + Image, + HStack, + Button, + Icon, + IconButton, +} from "@chakra-ui/react"; + +// import components +import FadeInUpBox from "../../Components/FadeUp"; +import ArtifactViewer from "../../Components/ArtifactViewer"; +import { + FiArrowLeftCircle, + FiArrowRightCircle, + FiChevronLeft, + FiChevronRight, +} from "react-icons/fi"; + +export default function Game({ setStage, gameState, setGameState }) { + // loading states + const [loading, setLoading] = useState(true); + const [loadingTextIndex, setLoadingTextIndex] = useState(0); + const loadingText = [ + "Creating Game...", + "Looking at Art...", + "Found over 488,048 Artifacts...", + "Nearly Done...", + ]; + + // game progression + // ranges 0 to 4 for each item + const [progression, setProgression] = useState(0); + + useEffect(() => { + const createGame = async () => { + fetch("/create-game") + .then((response) => { + if (!response.ok) throw new Error("Network response was not ok"); + return response.json(); + }) + .then((data) => { + console.log(data); // debug + + // update game state with objects + setGameState((prevState) => ({ + ...prevState, + gameObjects: data, + })); + + setLoading(false); + }) + .catch((error) => { + console.error("There was a problem with the fetch operation:", error); + }); + }; + + if (gameState["gameObjects"].length == 0) { + createGame(); + } + }, [gameState, loading]); + + // scroll through loading text + useEffect(() => { + setTimeout(() => { + if (loadingTextIndex == 3) setLoadingTextIndex(0); + else setLoadingTextIndex(loadingTextIndex + 1); + }, 2000); + }, [loadingTextIndex]); + + // show spinner if loading + if (loading) { + return ( +
+ + + + {loadingText[loadingTextIndex]} + + +
+ ); + } + + // return game content + return ( + + + {/* left arrow */} + + { + if (progression != 0) setProgression(progression - 1); + }} + icon={} + > + Last Item + + + + {/* main content */} + + + + + {/* right arrow */} + + { + if (progression != 4) setProgression(progression + 1); + }} + icon={} + > + + + + ); +} diff --git a/frontend/src/Pages/Game/Start.js b/frontend/src/Pages/Game/Start.js new file mode 100644 index 0000000..d2c328f --- /dev/null +++ b/frontend/src/Pages/Game/Start.js @@ -0,0 +1,57 @@ +import { useEffect, useState } from "react"; +import { VStack, Center, Text, Button } from "@chakra-ui/react"; +import { AnimatePresence } from "framer-motion"; + +// import components +import FadeInUpBox from "../../Components/FadeUp"; +import Game from "./Game"; + +export default function Start() { + /** + * stages: + * "start" - beginning screen with options + * "game" - game screen + */ + const [stage, setStage] = useState(""); + + // game state to be shared by all game pages + const [gameState, setGameState] = useState({ + gameObjects: [], + guesses: [1500, 1500, 1500, 1500, 1500], + }); + + return ( + +
+ + {stage == "" && } + {stage == "game" && ( + + )} + {stage == "postgame" && <>} + +
+
+ ); +} + +const Menu = ({ setStage }) => { + return ( + + + Start + + + + ); +}; diff --git a/frontend/src/Pages/Home/Landing.js b/frontend/src/Pages/Home/Landing.js index ecc586a..0d0d89e 100644 --- a/frontend/src/Pages/Home/Landing.js +++ b/frontend/src/Pages/Home/Landing.js @@ -2,8 +2,11 @@ import { VStack, Heading, Text, Button, Icon, HStack } from "@chakra-ui/react"; import { FiSmile } from "react-icons/fi"; import FadeInUpBox from "../../Components/FadeUp"; +import { useNavigate } from "react-router-dom"; + const Landing = ({ setStage }) => { const delay = 0.5; + const navigate = useNavigate(); return ( @@ -39,7 +42,10 @@ const Landing = ({ setStage }) => { transition: "0.2s", }} onClick={() => { - setStage("login"); + setStage("NA"); + setTimeout(() => { + navigate("/game"); + }, 1000); }} > Play as Guest diff --git a/frontend/src/index.js b/frontend/src/index.js index d563c0f..06f1991 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,15 +1,11 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - - - -); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 1f56d8d..97c9d7e 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2604,6 +2604,11 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@remix-run/router@1.15.3": + version "1.15.3" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.3.tgz#d2509048d69dbb72d5389a14945339f1430b2d3c" + integrity sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w== + "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -8918,11 +8923,6 @@ react-app-polyfill@^3.0.0: regenerator-runtime "^0.13.9" whatwg-fetch "^3.6.2" -react-apple-emojis@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-apple-emojis/-/react-apple-emojis-2.2.1.tgz#6462a32bff9d1d21dd1c893bb784ddb6eab2c1a9" - integrity sha512-tgq/+GUR6WsBkkkl0EYgVbaU803IF8GoELcG83cfircrEiyiiIbHqpBXIHyD8YIOecAGgN2ucEG6U/REDR7jvQ== - react-clientside-effect@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" @@ -9034,6 +9034,21 @@ react-remove-scroll@^2.5.6: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" +react-router-dom@^6.22.3: + version "6.22.3" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.22.3.tgz#9781415667fd1361a475146c5826d9f16752a691" + integrity sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw== + dependencies: + "@remix-run/router" "1.15.3" + react-router "6.22.3" + +react-router@6.22.3: + version "6.22.3" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.22.3.tgz#9d9142f35e08be08c736a2082db5f0c9540a885e" + integrity sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ== + dependencies: + "@remix-run/router" "1.15.3" + react-scripts@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003"