From 60f46dfe5cb82ab245a918e063144239ec182c84 Mon Sep 17 00:00:00 2001 From: G-hoon Date: Fri, 27 Sep 2024 22:29:33 +0900 Subject: [PATCH] =?UTF-8?q?[feat/#58]=20=ED=8C=9D=EC=97=85=20=EC=B0=BD?= =?UTF-8?q?=EC=9D=B4=20=EC=B4=88=EA=B8=B0=EC=97=90=EB=A7=8C=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=ED=81=AC=EB=A3=A8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8F=89?= =?UTF-8?q?=EA=B7=A0=20=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/group.ts | 1 + src/components/Crew/CrewList.tsx | 2 ++ src/components/PoseDetector.tsx | 20 ++++++++----- src/hooks/useMyGroup.ts | 5 ++-- src/hooks/useSnapshotMutation.ts | 24 +--------------- src/pages/AuthPage.tsx | 11 ++++---- src/pages/MonitoringPage.tsx | 48 +++++++++++++++----------------- src/pages/MyCrew.tsx | 24 ++++++++++++++-- src/store/SnapshotStore.ts | 5 +++- 9 files changed, 74 insertions(+), 66 deletions(-) diff --git a/src/api/group.ts b/src/api/group.ts index 4128458..b9bdd0c 100644 --- a/src/api/group.ts +++ b/src/api/group.ts @@ -33,6 +33,7 @@ export interface groupUserRank { export interface GroupUserRankData { groupId: number + avgScore: number ranks: groupUserRank[] } diff --git a/src/components/Crew/CrewList.tsx b/src/components/Crew/CrewList.tsx index 4f9a5ab..ade6972 100644 --- a/src/components/Crew/CrewList.tsx +++ b/src/components/Crew/CrewList.tsx @@ -158,6 +158,8 @@ const CrewList = (): ReactElement => { } }, [openJoinCrewModal, searchParams, setSearchParams]) + console.log("ranks: ", ranks) + return (
{myGroupData && Object.keys(myGroupData).length > 0 && ( diff --git a/src/components/PoseDetector.tsx b/src/components/PoseDetector.tsx index 1f3ac05..f43c7be 100644 --- a/src/components/PoseDetector.tsx +++ b/src/components/PoseDetector.tsx @@ -2,7 +2,6 @@ import { position } from "@/api" import { duration } from "@/api/notification" import { poseType } from "@/api/pose" import { useCameraPermission } from "@/hooks/useCameraPermission" -import { useGuidePopup } from "@/hooks/useGuidePopup" import { useModals } from "@/hooks/useModals" import useNotification from "@/hooks/useNotification" import { useSendPose } from "@/hooks/usePoseMutation" @@ -29,12 +28,11 @@ const PoseDetector: React.FC = () => { const [isTailboneSit, setIsTailboneSit] = useState(null) const [isHandOnChin, setIsHandOnChin] = useState(null) const [isModelLoaded, setIsModelLoaded] = useState(false) + const [isClosedInitialGuidePopup, setIsClosedInitialGuidePopup] = useState(false) // const [isSnapShotSaved, setIsSnapSaved] = useState(false) const { showNotification, hasPermission: hasNotiPermisson } = usePushNotification() - const { isPopupOpen, handleClosePopup } = useGuidePopup() - const { openModal, isModalOpen } = useModals() const modelRef = useRef(null) @@ -53,7 +51,7 @@ const PoseDetector: React.FC = () => { const isShowImmediNotiRef = useRef(false) const canvasRef = useRef(null) - const { isSnapShotSaved, snapshot, setSnapShot } = useSnapShotStore() + const { isSnapShotSaved, snapshot, setSnapShot, isInitialSnapShotExist } = useSnapShotStore() const createSnapMutation = useCreateSnaphot() const sendPoseMutation = useSendPose() @@ -195,7 +193,7 @@ const PoseDetector: React.FC = () => { if (modelRef && modelRef.current) { snapRef.current = resultRef.current if (snapshot === null) { - if (snapRef.current) { + if (snapRef.current && snapRef.current.length > 0) { const req = snapRef.current[0].keypoints.map((p) => ({ position: p.name.toUpperCase() as position, x: p.x, @@ -212,6 +210,8 @@ const PoseDetector: React.FC = () => { }, } ) + } else { + alert("브라우저의 카메라 혹은 인공지능 모델에 문제가 발생했습니다. 새로고침 후 다시 시도해주시기 바랍니다.") } } } @@ -336,6 +336,10 @@ const PoseDetector: React.FC = () => { console.log(notification) }, [notification]) + const handleCloseInitialGuidePopup = () => { + setIsClosedInitialGuidePopup(true) + } + return ( <> {isScriptError ? ( @@ -347,7 +351,7 @@ const PoseDetector: React.FC = () => { {isModelLoaded && ( <> - {!isPopupOpen && !isModalOpen && ( + {isInitialSnapShotExist && !isModalOpen && ( { )} )} - {!isSnapShotSaved && isPopupOpen && } + {!isClosedInitialGuidePopup && !isInitialSnapShotExist && ( + + )}
)} diff --git a/src/hooks/useMyGroup.ts b/src/hooks/useMyGroup.ts index 712fbf7..7998352 100644 --- a/src/hooks/useMyGroup.ts +++ b/src/hooks/useMyGroup.ts @@ -1,4 +1,4 @@ -import { getGroupScores, getMyGroup, groupUserRank, MyGroupData, withdrawMyGroup } from "@/api" +import { getGroupScores, getMyGroup, groupUserRank, GroupUserRankData, MyGroupData, withdrawMyGroup } from "@/api" import { useAuthStore } from "@/store" import { useMyGroupStore } from "@/store/MyGroup" import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" @@ -18,7 +18,7 @@ export default function useMyGroup() { }) // Fetch group scores - const myGroupScoresQuery = useQuery<{ data: { ranks: groupUserRank[] } }, Error>({ + const myGroupScoresQuery = useQuery<{ data: GroupUserRankData }, Error>({ queryKey: ["groupScores", myGroupData?.id], queryFn: () => getGroupScores(myGroupData!.id), enabled: !!myGroupData?.id, @@ -67,6 +67,7 @@ export default function useMyGroup() { return { myGroupData: myGroupData ?? data?.data, ranks: myGroupScoresQuery.data?.data.ranks ?? [], + avgScore: myGroupScoresQuery.data?.data.avgScore, myRank, isLoading: isLoading || myGroupScoresQuery.isLoading, error: error || myGroupScoresQuery.error, diff --git a/src/hooks/useSnapshotMutation.ts b/src/hooks/useSnapshotMutation.ts index 4a2a9b2..65e8824 100644 --- a/src/hooks/useSnapshotMutation.ts +++ b/src/hooks/useSnapshotMutation.ts @@ -1,4 +1,4 @@ -import { createSnapshot, createSnapshotRes, getRecentSnapshot, getSnapshots, snapshot } from "@/api" +import { createSnapshot, createSnapshotRes, snapshot } from "@/api" import { useMutation, UseMutationResult } from "@tanstack/react-query" export const useCreateSnaphot = (): UseMutationResult => { @@ -11,25 +11,3 @@ export const useCreateSnaphot = (): UseMutationResult => { - return useMutation({ - mutationFn: (id: string) => { - return getSnapshots(id) - }, - onSuccess: (data) => { - console.log(data) - }, - }) -} - -export const useGetRecentSnapshot = (): UseMutationResult => { - return useMutation({ - mutationFn: () => { - return getRecentSnapshot() - }, - onSuccess: (data) => { - console.log(data) - }, - }) -} diff --git a/src/pages/AuthPage.tsx b/src/pages/AuthPage.tsx index 0ae53e3..5c5cd6b 100644 --- a/src/pages/AuthPage.tsx +++ b/src/pages/AuthPage.tsx @@ -5,7 +5,7 @@ import { useOauth, useSignUp, useSignIn, useGetIsSignUp } from "@/hooks/useAuthM import RoutePath from "@/constants/routes.json" import { useAuthStore } from "@/store/AuthStore" import { useSnapShotStore } from "@/store/SnapshotStore" -import { useGetRecentSnapshot } from "@/hooks/useSnapshotMutation" +import { getRecentSnapshot } from "@/api" // import { useGetNoti } from "@/hooks/useNotiMutation" // import { useNotificationStore } from "@/store/NotificationStore" @@ -16,13 +16,12 @@ const AuthPage: React.FC = () => { const getIsSignUpMutation = useGetIsSignUp() const signUpMutation = useSignUp() const signInMutation = useSignIn() - const getRecentSnapMutation = useGetRecentSnapshot() // const getNotiMutation = useGetNoti() const [isLoading, setIsLoading] = useState(true) const [isError, setIsError] = useState(false) const setUser = useAuthStore((state) => state.setUser) - const setSnap = useSnapShotStore((state) => state.setSnapShot) + const { setSnapShot } = useSnapShotStore() // const setNoti = useNotificationStore((state) => state.setNotification) useEffect(() => { @@ -49,11 +48,13 @@ const AuthPage: React.FC = () => { setUser({ uid, nickname }, accessToken) // 최근 스냅샷을 가져오기 - const userSnap = await getRecentSnapMutation.mutateAsync() + const userSnap = await getRecentSnapshot() // 스냅샷이 있으면 store에 저장 if (userSnap.id !== -1) { - setSnap(userSnap.points.map((p) => ({ name: p.position.toLocaleLowerCase(), x: p.x, y: p.y, confidence: 1 }))) + setSnapShot( + userSnap.points.map((p) => ({ name: p.position.toLocaleLowerCase(), x: p.x, y: p.y, confidence: 1 })) + ) } // const notification = await getNotiMutation.mutateAsync() diff --git a/src/pages/MonitoringPage.tsx b/src/pages/MonitoringPage.tsx index a7f5ff5..885cdbb 100644 --- a/src/pages/MonitoringPage.tsx +++ b/src/pages/MonitoringPage.tsx @@ -1,47 +1,45 @@ +import { getRecentSnapshot } from "@/api" import { PoseDetector } from "@/components" import PostrueCrew from "@/components/Posture/PostrueCrew" +import usePushNotification from "@/hooks/usePushNotification" +import { useSnapShotStore } from "@/store/SnapshotStore" import GroupSideIcon from "@assets/icons/group-side-nav-button.svg?react" import React, { useEffect, useState } from "react" -import { useGetRecentSnapshot } from "@/hooks/useSnapshotMutation" -import { useSnapShotStore } from "@/store/SnapshotStore" -import usePushNotification from "@/hooks/usePushNotification" -import { useGuidePopup } from "@/hooks/useGuidePopup" const MonitoringPage: React.FC = () => { const { hasPermission } = usePushNotification() - const getRecentSnapMutation = useGetRecentSnapshot() - - const { isPopupOpen } = useGuidePopup() - const { snapshot, setSnapShot } = useSnapShotStore() - + const { snapshot, setSnapShot, isInitialSnapShotExist } = useSnapShotStore() const [isSidebarOpen, setIsSidebarOpen] = useState(true) const toggleSidebar = (): void => { setIsSidebarOpen((prev) => !prev) } - const init = async (): Promise => { - // 최근 스냅샷을 가져오기 - if (!snapshot) { - const userSnap = await getRecentSnapMutation.mutateAsync() + useEffect(() => { + const init = async (): Promise => { + // 최근 스냅샷을 가져오기 + if (!snapshot) { + const userSnap = await getRecentSnapshot() - // 스냅샷이 있으면 store에 저장 - if (userSnap.id !== -1) { - setSnapShot( - userSnap.points.map((p) => ({ name: p.position.toLocaleLowerCase(), x: p.x, y: p.y, confidence: 1 })) - ) + // 스냅샷이 있으면 store에 저장 + if (userSnap.id !== -1) { + setSnapShot( + userSnap.points.map((p) => ({ name: p.position.toLocaleLowerCase(), x: p.x, y: p.y, confidence: 1 })) + ) + } } } - } - - useEffect(() => { init() }, []) return (
{/* Main content area */} -
+
@@ -57,14 +55,14 @@ const MonitoringPage: React.FC = () => { {/* 사이드바 */}
- {isSidebarOpen && !isPopupOpen && } + {isSidebarOpen && isInitialSnapShotExist && }
{/* 토글 버튼 */} - {!isSidebarOpen && !isPopupOpen && ( + {!isSidebarOpen && isInitialSnapShotExist && ( diff --git a/src/pages/MyCrew.tsx b/src/pages/MyCrew.tsx index 52240ce..f839f83 100644 --- a/src/pages/MyCrew.tsx +++ b/src/pages/MyCrew.tsx @@ -13,7 +13,7 @@ import { useNavigate } from "react-router-dom" import { useCallback, useEffect } from "react" export default function MyCrew() { - const { myGroupData, ranks, myRank, withdrawFromGroup, isLoading } = useMyGroup() + const { myGroupData, ranks, myRank, withdrawFromGroup, isLoading, avgScore } = useMyGroup() const { openModal } = useModals() const naviagte = useNavigate() @@ -54,6 +54,8 @@ export default function MyCrew() { }) }, [myGroupData, openModal]) + console.log("my crew: ", myRank, " / ", avgScore) + return ( <> @@ -137,8 +139,24 @@ export default function MyCrew() { {/* footer */}
- 나는 우리 크루 평균보다 틀어짐이  6회 더 -  감지되었어요. + {(!myRank || !myRank.score) && + (avgScore !== undefined || avgScore !== null) && + `우리 크루 평균 자세 경고 횟수는 ${avgScore}회 입니다.`} + {myRank && + myRank.score && + (avgScore !== undefined || avgScore !== null) && + `지난 한 시간 동안 나의 자세 경고 횟수는 ${myRank.score}회 입니다.`} + {myRank && myRank.score && avgScore && ( + <> + 나는 우리 크루 평균보다 자세 경고를{" "} + Number(myRank.score) ? "text-[#1A75FF]" : "text-red-500"} `} + > + {Math.abs(avgScore - myRank?.score)}회 {Number(avgScore) > Number(myRank?.score) ? "덜" : "더"} + +  받았어요. + + )}
) diff --git a/src/store/SnapshotStore.ts b/src/store/SnapshotStore.ts index 1a3984e..f5b749c 100644 --- a/src/store/SnapshotStore.ts +++ b/src/store/SnapshotStore.ts @@ -3,6 +3,7 @@ import { create } from "zustand" import { persist } from "zustand/middleware" interface SnapShotState { + isInitialSnapShotExist: boolean isSnapShotSaved: boolean snapshot: keypoint[] | null setSnapShot: (snapshot: keypoint[] | null) => void @@ -13,8 +14,10 @@ export const useSnapShotStore = create( persist( (set) => ({ isSnapShotSaved: false, + isInitialSnapShotExist: false, snapshot: null, - setSnapShot: (snapshot: keypoint[] | null) => set({ snapshot, isSnapShotSaved: true }), + setSnapShot: (snapshot: keypoint[] | null) => + set({ snapshot, isSnapShotSaved: true, isInitialSnapShotExist: true }), resetSnapShot: () => set({ snapshot: null, isSnapShotSaved: false }), }), { name: "snapshotStorage" }