From 970c40fadd9ae4f314472f9e5c40567fddc8517d Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 17:38:31 +0900 Subject: [PATCH 1/8] =?UTF-8?q?[feat]=20=E3=83=AD=E3=82=B0=E3=82=A2?= =?UTF-8?q?=E3=82=A6=E3=83=88=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=A8=E3=83=A1?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E9=80=9A=E7=9F=A5=E3=81=AE=E5=88=87=E3=82=8A?= =?UTF-8?q?=E6=9B=BF=E3=81=88=E3=83=9C=E3=82=BF=E3=83=B3=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/app/user/page.tsx | 87 +++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/app/src/app/user/page.tsx b/app/src/app/user/page.tsx index f659fdf..b640671 100644 --- a/app/src/app/user/page.tsx +++ b/app/src/app/user/page.tsx @@ -7,6 +7,7 @@ import PlayerRankCard from "@/components/view/user/PlayerRankCard"; import StatusChangeDialog from "@/components/view/user/StatusChangeDialog"; import StatusList from "@/components/view/user/StatusList"; import { useStatusChangeDialog } from "@/lib/atom"; +import { signOut } from "@/lib/signOut"; import type { MyScoreDetail, DBUser as User } from "@/types"; import { useEffect, useState } from "react"; import { FiEdit2 } from "react-icons/fi"; @@ -17,6 +18,7 @@ const UserPage = () => { const [userData, setUserData] = useState(); const [myScore, setMyScore] = useState([]); const [isEditing, setIsEditing] = useState(false); + const [isSubscribed, setIsSubscribed] = useState(true); const [isOpen, setIsOpen] = useStatusChangeDialog(); useEffect(() => { @@ -46,10 +48,14 @@ const UserPage = () => { fetchData(); }, []); + const handleUnsubscribe = async () => {}; + + const handleResubscribe = async () => {}; + if (!userData) return null; return (
-
+
{userData.photoUrl ? ( { {isEditing ? (
-
+
- +

過去のチャレンジ

- {myScore.length === 0 ? ( -
-

まだチャレンジの記録がありません

-

- 新しいチャレンジに挑戦してみましょう! -

-
- ) : ( - myScore.map((score) => ( -
- チャレンジ画像 -
-
-

{score.assignment}

-
- -

{score.answerTime}

+
+ {myScore.length === 0 ? ( +
+

まだチャレンジの記録がありません

+

+ 新しいチャレンジに挑戦してみましょう! +

+
+ ) : ( + myScore.map((score) => ( +
+ チャレンジ画像 +
+
+

{score.assignment}

+
+ +

{score.answerTime}

+
+

{score.point}点

-

{score.point}点

-
- )) + )) + )} +
+ + + + {isSubscribed ? ( + + ) : ( + )}
From d457438a120165206bb72a9fc3422af1993b482e Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 19:04:15 +0900 Subject: [PATCH 2/8] =?UTF-8?q?[fix]=20=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/prisma/schema.prisma | 1 - 1 file changed, 1 deletion(-) diff --git a/app/prisma/schema.prisma b/app/prisma/schema.prisma index 75887b1..514b292 100755 --- a/app/prisma/schema.prisma +++ b/app/prisma/schema.prisma @@ -22,7 +22,6 @@ model User { experiencePoint ExperiencePoint? @relation() rateId Int @default(1) ratePoint Int - // todo メール受信のフラグを追記。APIは別で作成する isReceivedMail Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt From c2198762f0b9c499c539220ceb17448f3bf9e3d8 Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 19:04:28 +0900 Subject: [PATCH 3/8] =?UTF-8?q?[fix]=20=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0=E3=81=AE?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/lib/signInAndUp.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/lib/signInAndUp.ts b/app/src/lib/signInAndUp.ts index 56b7dcd..6d60edb 100644 --- a/app/src/lib/signInAndUp.ts +++ b/app/src/lib/signInAndUp.ts @@ -14,18 +14,22 @@ export const signInOrUp = async (firebaseUser: FirebaseUser) => { }, }); - const userData = await res.json(); + if (res.status === 200) { + const userData = await res.json(); - const user: DBUser = { ...userData }; + const user: DBUser = { ...userData }; - if (userData) { - storeStorageUser(user); - if (!userData.experiencePoint) { - await createExp(userData.id); + if (userData) { + storeStorageUser(user); + if (!userData.experiencePoint) { + await createExp(userData.id); + } + toRoot(); } - toRoot(); - } else { + } else if (res.status === 404) { await signUp(firebaseUser); + } else { + console.error(`Unexpected status code: ${res.status}`); } } catch (error) { console.error("エラーが発生しました:", error); From 807f6c34169fa508eb4bed20bb9503de1f234828 Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 19:04:58 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[feat]=20api=E3=81=AE=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=81=A8=E3=83=A1=E3=83=BC=E3=83=AB=E9=80=81=E4=BF=A1=E3=81=AE?= =?UTF-8?q?=E5=AF=BE=E8=B1=A1=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/app/api/mailer/route.ts | 1 + .../api/user/updateEmailPreference/route.ts | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 app/src/app/api/user/updateEmailPreference/route.ts diff --git a/app/src/app/api/mailer/route.ts b/app/src/app/api/mailer/route.ts index 98fd12e..8328ac6 100644 --- a/app/src/app/api/mailer/route.ts +++ b/app/src/app/api/mailer/route.ts @@ -25,6 +25,7 @@ export async function POST() { try { const usersEmails = ( await prisma.user.findMany({ + where: { isReceivedMail: true }, select: { email: true, }, diff --git a/app/src/app/api/user/updateEmailPreference/route.ts b/app/src/app/api/user/updateEmailPreference/route.ts new file mode 100644 index 0000000..63d3e49 --- /dev/null +++ b/app/src/app/api/user/updateEmailPreference/route.ts @@ -0,0 +1,27 @@ +import { prisma } from "@lib/prisma"; +import type { NextRequest } from "next/server"; + +export async function POST(req: NextRequest) { + try { + const { uid, isReceivedMail } = await req.json(); + + await prisma.user.update({ + where: { uid }, + data: { isReceivedMail }, + }); + + return new Response(JSON.stringify({ message: "設定を更新しました" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (error) { + console.error("設定更新エラー:", error); + return new Response( + JSON.stringify({ error: "設定の更新に失敗しました。" }), + { + status: 500, + headers: { "Content-Type": "application/json" }, + }, + ); + } +} From bb137b70817712e4d07ff57c6bcc25caac56eb3d Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 19:05:25 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[feat]=20api=E3=81=8B=E3=82=89=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E3=81=A8=E5=A4=89=E6=9B=B4=E3=81=AE=E3=83=AD=E3=82=B8?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/app/user/page.tsx | 90 ++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/app/src/app/user/page.tsx b/app/src/app/user/page.tsx index b640671..3fd8e89 100644 --- a/app/src/app/user/page.tsx +++ b/app/src/app/user/page.tsx @@ -4,8 +4,6 @@ import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import PlayerRankCard from "@/components/view/user/PlayerRankCard"; -import StatusChangeDialog from "@/components/view/user/StatusChangeDialog"; -import StatusList from "@/components/view/user/StatusList"; import { useStatusChangeDialog } from "@/lib/atom"; import { signOut } from "@/lib/signOut"; import type { MyScoreDetail, DBUser as User } from "@/types"; @@ -15,44 +13,75 @@ import { LuClock, LuFlame, LuTrophy } from "react-icons/lu"; import { VscAccount } from "react-icons/vsc"; const UserPage = () => { - const [userData, setUserData] = useState(); + const [userData, setUserData] = useState(null); const [myScore, setMyScore] = useState([]); const [isEditing, setIsEditing] = useState(false); - const [isSubscribed, setIsSubscribed] = useState(true); + const [isSubscribed, setIsSubscribed] = useState(true); const [isOpen, setIsOpen] = useStatusChangeDialog(); useEffect(() => { - const fetchData = async () => { - const userIdString = localStorage.getItem("userID"); - if (!userIdString) { - window.location.href = "/login"; - return; - } + const userIdString = localStorage.getItem("userID"); + if (!userIdString) { + window.location.href = "/login"; + return; + } + + const userData: User = JSON.parse(userIdString); + setUserData(userData); + const fetchUserData = async () => { try { - const userData = JSON.parse(userIdString); - setUserData(userData); // LocalStorageのユーザー情報を状態として保存 + const [userResponse, scoreResponse] = await Promise.all([ + fetch(`/api/user?uid=${userData.uid}`), + fetch(`/api/score/me/${userData.uid}?all=true`), + ]); - const response = await fetch(`/api/score/me/${userData.uid}?all=true`); - if (!response.ok) { - throw new Error("データの取得に失敗しました"); + if (!userResponse.ok) { + throw new Error("ユーザー情報の取得に失敗しました"); } + const userDetails = await userResponse.json(); + setIsSubscribed(userDetails.isReceivedMail); - const data = await response.json(); + if (!scoreResponse.ok) { + throw new Error("データの取得に失敗しました"); + } + const data = await scoreResponse.json(); setMyScore(data); } catch (error) { console.error("エラーが発生しました:", error); } }; - fetchData(); + fetchUserData(); }, []); - const handleUnsubscribe = async () => {}; + const handleToggleEmailSubscription = async () => { + if (!userData) return; + + try { + const response = await fetch("/api/user/updateEmailPreference", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + uid: userData.uid, + isReceivedMail: !isSubscribed, + }), + }); - const handleResubscribe = async () => {}; + if (!response.ok) { + throw new Error("設定の更新に失敗しました"); + } + + setIsSubscribed((prev) => !prev); + } catch (error) { + console.error("エラーが発生しました:", error); + } + }; if (!userData) return null; + return (
@@ -71,13 +100,10 @@ const UserPage = () => {
- -
@@ -88,7 +114,7 @@ const UserPage = () => { {userData.name || "user@example.com"} - {isSubscribed ? ( - - ) : ( - - )} +
); From 7e8ab3fd01ae0b689439dc2307966b2a2e2ca0c8 Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 19:16:22 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[fix]=20=E3=82=A4=E3=83=B3=E3=83=9D?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/app/user/page.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/app/user/page.tsx b/app/src/app/user/page.tsx index 5e9f9cb..89236ee 100644 --- a/app/src/app/user/page.tsx +++ b/app/src/app/user/page.tsx @@ -5,6 +5,8 @@ import { Card } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { LoadingSpinner } from "@/components/view/LoadingSpinner"; import PlayerRankCard from "@/components/view/user/PlayerRankCard"; +import { StatusChangeDialog } from "@/components/view/user/StatusChangeDialog"; +import { StatusList } from "@/components/view/user/StatusList"; import { useStatusChangeDialog } from "@/lib/atom"; import { signOut } from "@/lib/signOut"; import type { From e9c25037057c0fe8bf60bc4a8833f57223324e8a Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 21:01:28 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[fix]=20api=E3=82=92POST=E3=81=8B=E3=82=89P?= =?UTF-8?q?UT=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/{updateEmailPreference => updateReceivedMail}/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename app/src/app/api/user/{updateEmailPreference => updateReceivedMail}/route.ts (93%) diff --git a/app/src/app/api/user/updateEmailPreference/route.ts b/app/src/app/api/user/updateReceivedMail/route.ts similarity index 93% rename from app/src/app/api/user/updateEmailPreference/route.ts rename to app/src/app/api/user/updateReceivedMail/route.ts index 63d3e49..9012347 100644 --- a/app/src/app/api/user/updateEmailPreference/route.ts +++ b/app/src/app/api/user/updateReceivedMail/route.ts @@ -1,7 +1,7 @@ import { prisma } from "@lib/prisma"; import type { NextRequest } from "next/server"; -export async function POST(req: NextRequest) { +export async function PUT(req: NextRequest) { try { const { uid, isReceivedMail } = await req.json(); From b21fdcfc941900392564b16ee1f576b16490c87a Mon Sep 17 00:00:00 2001 From: TkymHrt <23.h.takayama.nutfes@gmail.com> Date: Sat, 16 Nov 2024 21:01:52 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[fix]=20API=E3=81=AE=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E3=82=92=E9=81=A9=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/app/user/page.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/app/user/page.tsx b/app/src/app/user/page.tsx index 89236ee..74a4e96 100644 --- a/app/src/app/user/page.tsx +++ b/app/src/app/user/page.tsx @@ -88,10 +88,10 @@ const UserPage = () => { const handleToggleEmailSubscription = async () => { if (!userData) return; - + try { - const response = await fetch("/api/user/updateEmailPreference", { - method: "POST", + const response = await fetch("/api/user/updateReceivedMail", { + method: "PUT", headers: { "Content-Type": "application/json", }, @@ -100,16 +100,16 @@ const UserPage = () => { isReceivedMail: !isSubscribed, }), }); - + if (!response.ok) { throw new Error("設定の更新に失敗しました"); } - + setIsSubscribed((prev) => !prev); } catch (error) { console.error("エラーが発生しました:", error); } - }; + } if (!userData) return null; if (isLoading) {