diff --git a/hooks/answer.ts b/hooks/answer.ts index ae52ba7..1f7b2c8 100644 --- a/hooks/answer.ts +++ b/hooks/answer.ts @@ -15,8 +15,13 @@ export const useAnswers = (id: string) => { const {data, mutate} = useSWR(`problems/${id}/answers`, fetcher) + const getAnswer = (id: string): Answer | null => { + return data?.data?.answers.find((answer) => answer.id === id) ?? null + } + return { answers: data?.data?.answers ?? [], + getAnswer, mutate } } \ No newline at end of file diff --git a/package.json b/package.json index b82a724..4f8821f 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "eslint": "8.28.0", "eslint-config-next": "^13.1.1", "ky": "^0.33.0", + "luxon": "^3.2.0", "next": "^13.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -29,6 +30,7 @@ "zenn-markdown-html": "^0.1.132" }, "devDependencies": { + "@types/luxon": "^3.2.0", "autoprefixer": "^10.4.13", "postcss": "^8.4.19", "tailwindcss": "^3.2.4" diff --git a/pages/problems/[problemId].tsx b/pages/problems/[problemId].tsx index c5dd191..2ce4d73 100644 --- a/pages/problems/[problemId].tsx +++ b/pages/problems/[problemId].tsx @@ -4,6 +4,7 @@ import {useRouter} from "next/router"; import Error from "next/error"; import {useForm, Controller, SubmitHandler} from "react-hook-form"; +import {DateTime} from "luxon"; import ICTSCNavBar from "../../components/Navbar"; import ICTSCCard from "../../components/Card"; @@ -13,6 +14,7 @@ import LoadingPage from "../../components/LoadingPage"; import {useApi} from "../../hooks/api"; import {useAuth} from "../../hooks/auth"; import {useProblems} from "../../hooks/problem"; +import {useAnswers} from "../../hooks/answer"; type Inputs = { answer: string; @@ -20,6 +22,7 @@ type Inputs = { const ProblemPage = () => { const router = useRouter(); + const {problemId} = router.query; const {handleSubmit, control, watch, formState: {errors}} = useForm() // answer のフォームを監視 @@ -30,12 +33,14 @@ const ProblemPage = () => { const {getProblem, isLoading} = useProblems(); const [isPreview, setIsPreview] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); + const [selectedAnswerId, setSelectedAnswerId] = useState(null); const [status, setStatus] = useState(null); - - const {problemId} = router.query; const problem = getProblem(problemId as string); + const {answers, getAnswer, mutate} = useAnswers(problem?.id as string); + const selectedAnswer = getAnswer(selectedAnswerId as string); + // モーダルを表示しバリデーションを行う const onModal: SubmitHandler = async () => { setIsModalOpen(true) @@ -51,6 +56,10 @@ const ProblemPage = () => { }) setStatus(response.status) + + if (response.ok) { + await mutate() + } } @@ -68,6 +77,8 @@ const ProblemPage = () => { ); } + console.log(answers) + return ( <> @@ -144,6 +155,78 @@ const ProblemPage = () => {
※ 回答は20分に1度のみです
+
+
+ 定期的に自動更新されます +
+
+ + + + + + + + + + + + + {answers + .sort((a, b) => { + if (a.created_at < b.created_at) { + return 1; + } + if (a.created_at > b.created_at) { + return -1; + } + return 0; + }) + .map((answer) => { + const createdAt = DateTime.fromISO(answer.created_at) + + return ( + + + + + + + + + ); + })} + + + +
提出日時問題コード問題得点チェック済み
{createdAt.toFormat('yyyy-MM-dd HH:mm:ss')}{problem?.code}{problem?.title}{answer?.point ?? '--'} pt{answer.point != null ? '○' : '採点中'} + setSelectedAnswerId(answer.id)}>投稿内容 +
+
+ {selectedAnswer != null && ( +
+ +
+
+ {selectedAnswer.point !== null && ( +
+ + + +
+ )} + チーム: {selectedAnswer.user_group.name}({selectedAnswer.user_group.organization}) +
+
+ {DateTime.fromISO(selectedAnswer.created_at).toFormat('yyyy-MM-dd HH:mm:ss')} +
+
+ +
+
+ )}
) diff --git a/yarn.lock b/yarn.lock index 3a2d2a6..039293b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -188,6 +188,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/luxon@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.2.0.tgz#99901b4ab29a5fdffc88fff59b3b47fbfbe0557b" + integrity sha512-lGmaGFoaXHuOLXFvuju2bfvZRqxAqkHPx9Y9IQdQABrinJJshJwfNCKV+u7rR3kJbiqfTF/NhOkcxxAFrObyaA== + "@types/node@18.11.9": version "18.11.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" @@ -1626,6 +1631,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +luxon@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.0.tgz#7962c5dafcd3623e70e222882be49b381e7a8718" + integrity sha512-Namj3XqoJjFekq/JHQEaaAv4zyE/fyyDBrMEBnIL2s/X54SC8W5Ea0uej1TRXUArWec8OojsAVsGBYhNRjpMVw== + markdown-it-anchor@^8.4.1: version "8.6.5" resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz#30c4bc5bbff327f15ce3c429010ec7ba75e7b5f8"