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
+
+
+
+
+
+
+ >)
+}
+
+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
+
+
+
+
+
+ >)
+}
+
+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}
+
+ )
+ })}
+
+
+
+
+ >
);
};
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.
-
+ <>
+ go right
+
+ This is select game page.
+ {showGameTitle(gameName)}
+
+ go left
+ >
);
};
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