diff --git a/README.md b/README.md index 9763360..38ec603 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ https://www.figma.com/design/8NGJOCtcVqLFtTrS3P0ht7/Nihongo-Alley---copied-with-new-games?node-id=0-88&node-type=CANVAS&t=FZORUYPPwlmsROs0-0 ## Folder structure -There is two ways in Nextjs. We adopt pages directory structure.
+There is two ways in Nextjs for routing. We adopt pages routing, not app routing.
https://medium.com/@CraftedX/should-you-use-next-js-pages-or-app-directory-38e803fe5cb4 Folder structure is related to routing.
@@ -17,10 +17,10 @@ The basic behavior of Next.js by naming for file/folders.
There are some part which is defferent in between page router and app router.
https://nextjs.org/docs/app/building-your-application/routing/colocation
-The _app.tsx file is used for every page.
+The _app.tsx file is used for rendering every page.
https://nextjs.org/docs/pages/building-your-application/routing/custom-app -Page name is case-sensitive. +Page name is case-sensitive. URL is case-sensitive as well. * Commponents
React components used in each page. For example, flash card, card to show score, ...
@@ -39,15 +39,14 @@ https://next-auth.js.org/getting-started/example
* install
npm install
※For development of only frontend, we don't need docker run.
-※EbisuG haven't checked running app with docker yet. * run local
npm run dev
## Route ### Protected route +Use middleware.ts for protected route. https://www.freecodecamp.org/news/secure-routes-in-next-js/
-※EbisuG haven't implemented protecton for some route yet. ## Authentication We use Nextauth.js. @@ -55,6 +54,10 @@ Detail logic. https://refine.dev/blog/nextauth-google-github-authentication-nextjs/#for-githubprovider-you-will-need-a-github-account +## Errors +* App doesn't run after successful build. +Make sure you use the latest things. Delete your image, container, and volume. Run docker compose commands again. + ### Reference Using google auth.
https://blog.stackademic.com/building-a-custom-google-authentication-system-with-django-rest-framework-and-reactjs-ii-794fa8592782 diff --git a/components/game/findPairGame/start.tsx b/components/game/findPairGame/start.tsx new file mode 100644 index 0000000..e69de29 diff --git a/components/game/newExpression/mainCard.tsx b/components/game/newExpression/mainCard.tsx new file mode 100644 index 0000000..c0c0a32 --- /dev/null +++ b/components/game/newExpression/mainCard.tsx @@ -0,0 +1,27 @@ +import { useContext } from "react" +import { SelectedMaterial } from "../../../pages/game/learning" + +// +const getPhrase = async (id: number) => { + const result = "test string" + // const fetched = await fetch("endopinturl") + // const result: phraseType = fetched.json() + return result +} + +const MainCard = () => { + const selectedMaterial = useContext(SelectedMaterial) + + return ( + <> +
+ {selectedMaterial?.phrase!==undefined?(<>{selectedMaterial.phrase.japanese}):<>null}

+ {selectedMaterial?.phrase!==undefined?(<>{selectedMaterial.phrase.english}):<>null}

+ {selectedMaterial?.phrase!==undefined?(<>{selectedMaterial.phrase.description}):<>null}

+
+ + ) +} + +export default MainCard \ No newline at end of file diff --git a/components/game/newExpression/phraseList.tsx b/components/game/newExpression/phraseList.tsx new file mode 100644 index 0000000..ab07fba --- /dev/null +++ b/components/game/newExpression/phraseList.tsx @@ -0,0 +1,50 @@ +import { useContext } from "react" +import { SelectedMaterial } from "../../../pages/game/learning" + +//get all phrase based on topic +const getAllPhrase = async (id: number) => { + const result = "test string" + // const fetched = await fetch("endopinturl") + // const result: phraseType = fetched.json() + return result +} + +const PhraseList = () => { + const selectedMaterial = useContext(SelectedMaterial) + + return ( + <> +
{selectedMaterial?.selectPhrase({id:2, japanese:"よっす"})}} + > + topic is :{selectedMaterial?.topic} + よっす +
+
{selectedMaterial?.selectPhrase({id:3, japanese:"おっす", english:"hi", description:"short version of おはようございます"})}} + > + topic is :{selectedMaterial?.topic} + おっす +
+
+ topic is :{selectedMaterial?.topic} + うっす +
+
+ topic is :{selectedMaterial?.topic} + はいよ +
+
+ topic is :{selectedMaterial?.topic} + わかった! +
+ + ) +} + +export default PhraseList \ No newline at end of file diff --git a/components/game/newExpression/start.tsx b/components/game/newExpression/start.tsx new file mode 100644 index 0000000..142f9b5 --- /dev/null +++ b/components/game/newExpression/start.tsx @@ -0,0 +1,27 @@ +import Image, { ImageLoader } from 'next/image' +import gamePic from "./../../../public/new-expression-fox.png" +import Link from 'next/link' + +const baseUrl = process.env.NEXTAUTH_URL + +const imageLoader: ImageLoader = ({ src, width, quality }) => { + return `${baseUrl}/${src}?w=${width}&q=${quality || 75}` +} + +const LearningStart: React.FC = () => { + return (<> +
+
+ New Expression

+ + Learning Mode + +
+
+ Fox picture +
+
+ ) +} + +export default LearningStart \ No newline at end of file diff --git a/components/game/practice/start.tsx b/components/game/practice/start.tsx new file mode 100644 index 0000000..6341331 --- /dev/null +++ b/components/game/practice/start.tsx @@ -0,0 +1,24 @@ +import Image, { ImageLoader } from 'next/image' +import gamePic from "./../../../public/practice-nife.png" + +const baseUrl = process.env.NEXTAUTH_URL + +const imageLoader: ImageLoader = ({ src, width, quality }) => { + return `${baseUrl}/${src}?w=${width}&q=${quality || 75}` +} + +const PracticeStart: React.FC = () => { + return (<> +
+
+ Practice

+ Practice Mode +
+
+ Cross nife picture +
+
+ ) +} + +export default PracticeStart \ No newline at end of file diff --git a/components/header.tsx b/components/header.tsx index e50be49..c5661de 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -1,4 +1,4 @@ -import { useSession, signIn, signOut } from "next-auth/react"; +import { useSession, signOut } from "next-auth/react"; import Link from "next/link"; import { useRouter } from "next/router"; @@ -9,7 +9,11 @@ export const Header: React.FC = () => { return ( <>
-
To Homepage
+
+ + To Homepage + +
This is empty space
{session ? <> diff --git a/next.config.mjs b/next.config.mjs index 4678774..cfea52d 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,8 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + experimental: { + optimizePackageImports: ["next-auth"], + }, +}; export default nextConfig; diff --git a/pages/404.tsx b/pages/404.tsx index 31b987e..c1f473c 100644 --- a/pages/404.tsx +++ b/pages/404.tsx @@ -1,7 +1,5 @@ //User can play quick answer game. -import React, { useState, useEffect } from "react"; - const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL; const Error404 = () => { diff --git a/pages/_app.tsx b/pages/_app.tsx index 29d764b..0f729da 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { AppProps } from "next/app"; import "../styles/globals.css"; import { Layout } from "../components/layouts"; diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 457a2b4..3663641 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -8,6 +8,11 @@ let googleClientSecret = process.env.GOOGLE_CLIENT_SECRET if (googleClientId === undefined) googleClientId = "" if (googleClientSecret === undefined) googleClientSecret = "" +interface urlSets { + url: string + baseUrl: string +} + export const authOptions = { // Configure one or more authentication providers providers: [ @@ -18,6 +23,7 @@ export const authOptions = { // ...add more providers here ], secret: process.env.NEXTAUTH_SECRET, + //add calbacks here. } export default NextAuth(authOptions) \ No newline at end of file diff --git a/pages/game/learning.tsx b/pages/game/learning.tsx index 6b66378..98877b4 100644 --- a/pages/game/learning.tsx +++ b/pages/game/learning.tsx @@ -1,16 +1,60 @@ //User can play learning page. -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, createContext } from "react"; +import MainCard from "../../components/game/newExpression/mainCard"; +import { phraseType, learningContextType } from "../../types/types"; +import PhraseList from "../../components/game/newExpression/phraseList"; const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL; +const TOPICS = ["First Contact", "Playing together", "Drinking"] +export const SelectedMaterial = createContext(null) const Learning = () => { + const [selectedTopic, setSelectedTopic] = useState(TOPICS[0]) + const [selectedPhrase, setSelectedPhrase] = useState({ + id: 0, + japanese: "loading...", + }) + //Just test for appearence, put useEffect here. + useEffect(() => { + setSelectedPhrase({ + id: 1, + japanese: "よっす", + english: "Hi", + description: "よっす is shorter version of おはようございます" + }) + }, []) return ( -
-This is Learning. -
+ <> + +
+
+ Main card component + +
+
+ Choose topic + {TOPICS.map((elem, ind) => { + return ( +
{ + setSelectedTopic(elem) + }}> + {elem} +
+ ) + })} +
+
+ Each pharese list + +
+
+
+ ); }; diff --git a/pages/index.tsx b/pages/index.tsx index 4034d3c..110d158 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,4 +1,5 @@ -import React, { useState, useEffect } from "react"; +import Link from "next/link"; +import { useState, useEffect } from "react"; const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL; @@ -19,6 +20,7 @@ const HomePage = () => {

With Django, React, Postgres, and Docker

{data ? data : "Loading data..."}

{" "} {/* Display data or loading message */} + Play game!
); }; diff --git a/pages/login.tsx b/pages/login.tsx index 5e823e6..9e21dab 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -1,10 +1,10 @@ //This page is for login page. //User can login and sign up. -import React, { useState, useEffect, FormEvent } from "react"; -import SelectGame from "./selectGame"; +import { useState, FormEvent } from "react"; import { useRouter } from "next/router"; import { useSession, signIn, signOut } from "next-auth/react"; +import Link from "next/link"; const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL; @@ -40,6 +40,7 @@ const Login = () => { ) : ( <> Alredy logged in. + Play games! )) } diff --git a/pages/selectGame.tsx b/pages/selectGame.tsx index 9358dbc..563394d 100644 --- a/pages/selectGame.tsx +++ b/pages/selectGame.tsx @@ -1,16 +1,44 @@ //User can select game. -import React, { useState, useEffect } from "react"; +import React, { useState } from "react"; +import NewExpressionStart from "../components/game/newExpression/start"; +import PracticeStart from "../components/game/practice/start"; -const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL; +const gameFileNames = ["newExpression", "practice"] const SelectGame = () => { + const [gameName, setGameName] = useState(gameFileNames[0]) + + const goRightGame = () => { + setGameName(gameFileNames[(gameFileNames.indexOf(gameName) + 1) % gameFileNames.length]) + } + const goLeftGame = () => { + setGameName(gameFileNames[(gameFileNames.indexOf(gameName) + gameFileNames.length - 1) % gameFileNames.length]) + } + + const showGameTitle = (gameFileName: string) => { + switch (gameFileName) { + case "newExpression": + return + case "practice": + return + default: + return ( + <>Sorry, there is no game. + ) + } + } return ( -
-This is select game page. -
+ <> + +
+ This is select game page.
+ {showGameTitle(gameName)} +
+ + ); }; diff --git a/public/new-expression-fox.png b/public/new-expression-fox.png new file mode 100644 index 0000000..6ab0566 Binary files /dev/null and b/public/new-expression-fox.png differ diff --git a/public/practice-nife.png b/public/practice-nife.png new file mode 100644 index 0000000..879cd76 Binary files /dev/null and b/public/practice-nife.png differ diff --git a/types/types.ts b/types/types.ts new file mode 100644 index 0000000..eaa0e31 --- /dev/null +++ b/types/types.ts @@ -0,0 +1,17 @@ +interface learningContextType { + topic: string + phrase: phraseType + selectPhrase:React.Dispatch> +} + +interface phraseType { + id: number + japanese: string + english?: string + description?: string +} + + +export type { + learningContextType, phraseType +} \ No newline at end of file