Skip to content

Commit 4354626

Browse files
committed
回答をDBに記録するようにした
1 parent 99e1002 commit 4354626

File tree

5 files changed

+101
-21
lines changed

5 files changed

+101
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
Warnings:
3+
4+
- The primary key for the `JGeoGLUEAnswer` table will be changed. If it partially fails, the table could be left without primary key constraint.
5+
- You are about to drop the column `id` on the `JGeoGLUEAnswer` table. All the data in the column will be lost.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "JGeoGLUEAnswer" DROP CONSTRAINT "JGeoGLUEAnswer_pkey",
10+
DROP COLUMN "id",
11+
ADD CONSTRAINT "JGeoGLUEAnswer_pkey" PRIMARY KEY ("taskId", "userId");

prisma/schema.prisma

+5-5
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ model JGeoGLUETask {
7272
}
7373

7474
model JGeoGLUEAnswer {
75-
id String @id @default(cuid())
7675
taskId String
7776
userId String
7877
answer String
7978
isCorrect Boolean
80-
createdAt DateTime @default(now())
81-
updatedAt DateTime @updatedAt
79+
createdAt DateTime @default(now())
80+
updatedAt DateTime @updatedAt
81+
task JGeoGLUETask @relation(fields: [taskId], references: [id], onDelete: Cascade)
82+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
8283
83-
task JGeoGLUETask @relation(fields: [taskId], references: [id], onDelete: Cascade)
84-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
84+
@@id([taskId, userId])
8585
}

src/app/api/tasks/answer/route.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { auth } from "@/app/auth";
2+
import { prisma } from "@/app/prisma";
3+
import { NextRequest, NextResponse } from "next/server";
4+
5+
export async function POST(req: NextRequest) {
6+
try {
7+
const session = await auth();
8+
9+
if (!session?.user) {
10+
return NextResponse.json(
11+
{ error: "Please log in to anser to tasks" },
12+
{ status: 403 }
13+
);
14+
}
15+
if (session.user.id === undefined) {
16+
return NextResponse.json(
17+
{ error: "Please log in to anser to tasks" },
18+
{ status: 403 }
19+
);
20+
}
21+
22+
const body = await req.json();
23+
const { answer } = body;
24+
const createdAnswer = await prisma.jGeoGLUEAnswer.upsert({
25+
where: {
26+
taskId_userId: {
27+
taskId: answer.taskId,
28+
userId: session.user.id,
29+
},
30+
},
31+
update: {
32+
answer: answer.answer,
33+
isCorrect: answer.isCorrect,
34+
},
35+
create: {
36+
userId: session.user.id,
37+
taskId: answer.taskId,
38+
answer: answer.answer,
39+
isCorrect: answer.isCorrect,
40+
},
41+
});
42+
43+
return NextResponse.json(createdAnswer, { status: 201 });
44+
} catch (error) {
45+
console.error("Error creating JGeoGLUE task:", error);
46+
return NextResponse.json(
47+
{ error: "Failed to create task" },
48+
{ status: 500 }
49+
);
50+
}
51+
}

src/app/q/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default function Page() {
5858
</div>
5959
)}
6060
{session === null && <RequireLoginCard />}
61-
{session?.user && (
61+
{session?.user && currentTask && (
6262
<>
6363
<div
6464
style={{

src/components/GeoGLUETaskCard/index.tsx

+33-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,45 @@
1-
import { GeoEAGTask, GeoETATask } from "@/types/JGeoGLUE";
1+
import { JGeoGLUETask } from "@prisma/client";
22
import { useState } from "react";
33

4-
const GeoEAGOptions = ["✅ 全く同じ", "🟡 部分的に一致", "❌️ 全く違う"];
4+
const GeoEAGOptions = [
5+
{ label: "✅ 全く同じ", value: "全く同じ" },
6+
{ label: "🟡 部分的に一致", value: "部分的に一致" },
7+
{ label: "❌️ 全く違う", value: "全く違う" },
8+
];
59

610
const GeoETAOptions = [
7-
"🏞️ 都道府県",
8-
"🏙️ 市区町村",
9-
"🏘️ 町名",
10-
"🏠 番地",
11-
"🏢 施設名",
12-
"🏗️ その他",
11+
{ label: "🏞️ 都道府県", value: "都道府県" },
12+
{ label: "🏙️ 市区町村", value: "市区町村" },
13+
{ label: "🏘️ 町名", value: "町名" },
14+
{ label: "🏠 番地", value: "番地" },
15+
{ label: "🏢 施設名", value: "施設名" },
16+
{ label: "🏗️ その他", value: "その他" },
1317
];
1418

1519
export const GeoGLUETaskCard: React.FC<{
16-
task: GeoEAGTask | GeoETATask;
20+
task: JGeoGLUETask;
1721
onNext: () => void;
1822
}> = ({ task, onNext }) => {
1923
const [answerIsCorrect, setAnswerIsCorrect] = useState<boolean | null>(null);
2024

2125
const options = task.type === "GeoEAG" ? GeoEAGOptions : GeoETAOptions;
2226

23-
const handleAnswer = (option: string) => {
24-
setAnswerIsCorrect(option.includes(task.correctAnswer));
27+
const handleAnswer = (optionValue: string) => {
28+
const isCorrect = task.correctAnswer === optionValue;
29+
setAnswerIsCorrect(isCorrect);
30+
fetch("/api/tasks/answer", {
31+
method: "POST",
32+
headers: {
33+
"Content-Type": "application/json",
34+
},
35+
body: JSON.stringify({
36+
answer: {
37+
taskId: task.id,
38+
answer: optionValue,
39+
isCorrect,
40+
},
41+
}),
42+
});
2543
};
2644

2745
const handleNext = () => {
@@ -56,19 +74,19 @@ export const GeoGLUETaskCard: React.FC<{
5674
{options.map((option) => {
5775
return (
5876
<button
59-
key={option}
60-
onClick={() => handleAnswer(option)}
77+
key={option.value}
78+
onClick={() => handleAnswer(option.value)}
6179
style={{
6280
border: "none",
6381
borderRadius: "0.375rem",
6482
display: "block",
6583
padding: "10px",
6684
}}
6785
disabled={
68-
answerIsCorrect !== null && option !== task.correctAnswer
86+
answerIsCorrect !== null && option.value !== task.correctAnswer
6987
}
7088
>
71-
{option}
89+
{option.label}
7290
</button>
7391
);
7492
})}

0 commit comments

Comments
 (0)