diff --git a/app/(route)/alarm/_components/re-request-alarm.tsx b/app/(route)/alarm/_components/re-request-alarm.tsx new file mode 100644 index 0000000..0a242a7 --- /dev/null +++ b/app/(route)/alarm/_components/re-request-alarm.tsx @@ -0,0 +1,19 @@ +import AlertIcon from '@/app/_components/icons/AlertIcon' +import { type Alarm } from '@/app/_service/alarm/alarm.types' + +interface ReRequestAlarmProps { + alarm: Alarm +} + +export default function ReRequestAlarm({ alarm }: ReRequestAlarmProps) { + return ( +
+
+ + + {alarm.name} 인증 요청이 도착했어요! + +
+
+ ) +} diff --git a/app/(route)/alarm/_components/request-alarm.tsx b/app/(route)/alarm/_components/request-alarm.tsx new file mode 100644 index 0000000..f14b1bc --- /dev/null +++ b/app/(route)/alarm/_components/request-alarm.tsx @@ -0,0 +1,82 @@ +'use client' + +import Image from 'next/image' + +import { useQueryClient } from '@tanstack/react-query' + +import { type Alarm } from '@/app/_service/alarm/alarm.types' + +import { QUERY_KEY, useApproveCertificationAlarmMutation, useRejectCertificationAlarmMutation } from '../queries' + +interface RequestAlarmProps { + alarm: Alarm +} + +export default function RequestAlarm({ alarm }: RequestAlarmProps) { + const approveCertificationAlarmMutation = useApproveCertificationAlarmMutation() + const rejectCertificationAlarmMutation = useRejectCertificationAlarmMutation() + + const queryClient = useQueryClient() + + return ( +
+
+ + + + + + {alarm.name} 인증 요청이 도착했어요! + +
+
+
+ +
+
+
+ + +
+
+ ) +} diff --git a/app/(route)/alarm/_components/requestAlarm.tsx b/app/(route)/alarm/_components/success-alarm.tsx similarity index 79% rename from app/(route)/alarm/_components/requestAlarm.tsx rename to app/(route)/alarm/_components/success-alarm.tsx index 0204dc1..d42ecd7 100644 --- a/app/(route)/alarm/_components/requestAlarm.tsx +++ b/app/(route)/alarm/_components/success-alarm.tsx @@ -1,6 +1,10 @@ -import Image from 'next/image' +import { type Alarm } from '@/app/_service/alarm/alarm.types' -export default function RequestAlarm() { +interface SuccessAlarmProps { + alarm: Alarm +} + +export default function SuccessAlarm({ alarm }: SuccessAlarmProps) { return (
@@ -12,14 +16,10 @@ export default function RequestAlarm() { /> - 매일 일기쓰기 인증 요청이 도착했어요! + 업로드한 + {alarm.name} 인증 완료!
-
-
- -
-
) } diff --git a/app/(route)/alarm/page.tsx b/app/(route)/alarm/page.tsx index d553f23..6aaee99 100644 --- a/app/(route)/alarm/page.tsx +++ b/app/(route)/alarm/page.tsx @@ -1,9 +1,20 @@ +'use client' + import { UserContextProvider } from '@/app/_components/providers/UserProvider' import BackButton from './_components/BackButton' -import RequestAlarm from './_components/requestAlarm' +import ReRequestAlarm from './_components/re-request-alarm' +import RequestAlarm from './_components/request-alarm' +import SuccessAlarm from './_components/success-alarm' +import { useAlarmQuery } from './queries' export default function AlarmPage() { + const alarmQuery = useAlarmQuery() + + if (!alarmQuery.isSuccess) { + return null + } + return (
@@ -14,9 +25,21 @@ export default function AlarmPage() {
- - - + {alarmQuery.data.data.alarms.map((alarm) => { + if (alarm.alarm_type === 'REQUEST') { + return + } + + if (alarm.alarm_type === 'SUCCESS') { + return + } + + if (alarm.alarm_type === 'RE-REQUEST') { + return + } + + return null + })}
diff --git a/app/(route)/alarm/queries.ts b/app/(route)/alarm/queries.ts new file mode 100644 index 0000000..1ce24ef --- /dev/null +++ b/app/(route)/alarm/queries.ts @@ -0,0 +1,32 @@ +import { useMutation, useQuery } from '@tanstack/react-query' + +import { approveCertificationAlarm, getAlarms } from '@/app/_service/alarm' + +export const QUERY_KEY = { + ALARM: ['alarm'], +} + +export const useAlarmQuery = () => { + return useQuery({ + queryKey: QUERY_KEY.ALARM, + queryFn: () => { + return getAlarms() + }, + }) +} + +export const useApproveCertificationAlarmMutation = () => { + return useMutation({ + mutationFn: ({ challengeCertificationId }: { challengeCertificationId: number }) => { + return approveCertificationAlarm({ challengeCertificationId }) + }, + }) +} + +export const useRejectCertificationAlarmMutation = () => { + return useMutation({ + mutationFn: ({ challengeCertificationId }: { challengeCertificationId: number }) => { + return approveCertificationAlarm({ challengeCertificationId }) + }, + }) +} diff --git a/app/(route)/challenge/[id]/page.tsx b/app/(route)/challenge/[id]/page.tsx index dd7c026..1253fa1 100644 --- a/app/(route)/challenge/[id]/page.tsx +++ b/app/(route)/challenge/[id]/page.tsx @@ -5,6 +5,7 @@ import Image from 'next/image' import { useState } from 'react' import CertificationDialog from './_components/certification-dialog' +import { useChallengeDetailQuery } from './queries' export default function ChallengeDetailPage({ params, @@ -14,6 +15,15 @@ export default function ChallengeDetailPage({ } }) { const [isOpenCertificationDialog, setIsOpenCertificationDialog] = useState(false) + const challengeDetailQuery = useChallengeDetailQuery({ challengeId: params.id }) + + if (!challengeDetailQuery.isSuccess) { + return null + } + + const result = challengeDetailQuery.data.data + + console.log(result) return (
diff --git a/app/(route)/challenge/[id]/queries.ts b/app/(route)/challenge/[id]/queries.ts index c7a3b8f..7626a54 100644 --- a/app/(route)/challenge/[id]/queries.ts +++ b/app/(route)/challenge/[id]/queries.ts @@ -1,9 +1,22 @@ -import { useMutation } from '@tanstack/react-query' +import { useMutation, useQuery } from '@tanstack/react-query' -import { submitCertification } from '@/app/_service/challenge' +import { getChallengeDetail, submitCertification } from '@/app/_service/challenge' + +const QUERY_KEY = { + CHALLENGE_DETAIL: (id: number) => ['challengeDetail', id], +} export const useSubmitCertificationMutation = () => { return useMutation({ mutationFn: submitCertification, }) } + +export const useChallengeDetailQuery = ({ challengeId }: { challengeId: number }) => { + return useQuery({ + queryKey: QUERY_KEY.CHALLENGE_DETAIL(challengeId), + queryFn: () => { + return getChallengeDetail({ challengeId }) + }, + }) +} diff --git a/app/(route)/me/page.tsx b/app/(route)/me/page.tsx index 72164da..67d48e3 100644 --- a/app/(route)/me/page.tsx +++ b/app/(route)/me/page.tsx @@ -1,37 +1,52 @@ +'use client' + import Image from 'next/image' import RightArrowCircleIcon from '@/app/_components/icons/RightArrowCircleIcon' +import { useUserContext } from '@/app/_components/providers/UserProvider' + +import { CHAMPION } from '../sign-up/page' import BadgeCard from './_components/badge-card' +import { useUserStatusQuery } from './queries' export default function MePage() { + const userStatusQuery = useUserStatusQuery() + const { user } = useUserContext() + + if (!userStatusQuery.isSuccess) { + return null + } + + const { completedCount, startedCount, friendCount } = userStatusQuery.data.data + return (
- 달다구리 + {user.nickname}
🚀 - 235개 + {startedCount}개 의 달을 여행했어요
🌕 - 175개 + {completedCount}개 의 달에 도착했어요
👩‍🚀 - 175명 + {friendCount}명 의 친구들과 여행했어요
diff --git a/app/(route)/me/queries.ts b/app/(route)/me/queries.ts new file mode 100644 index 0000000..61a60f1 --- /dev/null +++ b/app/(route)/me/queries.ts @@ -0,0 +1,16 @@ +import { useQuery } from '@tanstack/react-query' + +import { getUserStatus } from '@/app/_service/auth' + +const QUERY_KEY = { + USER_STATUS: ['userStatus'], +} + +export const useUserStatusQuery = () => { + return useQuery({ + queryKey: QUERY_KEY.USER_STATUS, + queryFn: () => { + return getUserStatus() + }, + }) +} diff --git a/app/(route)/sign-up/page.tsx b/app/(route)/sign-up/page.tsx index 9408d56..893456a 100644 --- a/app/(route)/sign-up/page.tsx +++ b/app/(route)/sign-up/page.tsx @@ -13,7 +13,7 @@ import { getKakaoAccessToken, removeKakaoAccessToken, setAccessToken } from '@/a import { useLoginQuery, useSignUpMutation } from './queries' -const CHAMPION = { +export const CHAMPION = { DEFAULT: { RED: 'https://dodals3.s3.ap-northeast-2.amazonaws.com/asset/profile_red.png', YELLOW: 'https://dodals3.s3.ap-northeast-2.amazonaws.com/asset/profile_yellow.png', diff --git a/app/_service/alarm/alarm.types.ts b/app/_service/alarm/alarm.types.ts new file mode 100644 index 0000000..37c3950 --- /dev/null +++ b/app/_service/alarm/alarm.types.ts @@ -0,0 +1,8 @@ +export interface Alarm { + id: number + member_id: number + challenge_certification_id: number + alarm_type: 'REQUEST' | 'RE-REQUEST' | 'SUCCESS' + authenticateImageUrl: 'https://dodals3.s3.ap-northeast-2.amazonaws.com/1702758664871' + name: string +} diff --git a/app/_service/alarm/index.ts b/app/_service/alarm/index.ts new file mode 100644 index 0000000..e24bbf9 --- /dev/null +++ b/app/_service/alarm/index.ts @@ -0,0 +1,15 @@ +import api from '../core/api' + +import { type Alarm } from './alarm.types' + +export const getAlarms = () => { + return api.get<{ alarms: Alarm[] }>('/alarms') +} + +export const approveCertificationAlarm = ({ challengeCertificationId }: { challengeCertificationId: number }) => { + return api.post('/alarms/approve', { challengeCertificationId }) +} + +export const rejectCertificationAlarm = ({ challengeCertificationId }: { challengeCertificationId: number }) => { + return api.post('/alarms/reject', { challengeCertificationId }) +} diff --git a/app/_service/auth/auth.types.ts b/app/_service/auth/auth.types.ts index 89cab79..550f537 100644 --- a/app/_service/auth/auth.types.ts +++ b/app/_service/auth/auth.types.ts @@ -21,3 +21,9 @@ export interface SignUpParams { nickname: string champion: Champion } + +export interface UserStatus { + completedCount: number + friendCount: number + startedCount: number +} diff --git a/app/_service/auth/index.ts b/app/_service/auth/index.ts index 157d946..6db04c7 100644 --- a/app/_service/auth/index.ts +++ b/app/_service/auth/index.ts @@ -9,6 +9,7 @@ import { type GetTokenFromKakaoParams, type GetTokenFromKakaoResponse, type SignUpParams, + type UserStatus, } from './auth.types' export const getTokenByAuthorizationCode = async ({ code }: GetTokenFromKakaoParams) => { @@ -26,3 +27,7 @@ export const login = ({ accessToken }: { accessToken: string }) => { export const signUp = ({ accessToken, nickname, champion }: SignUpParams) => { return api.post('/users/signUp', { accessToken, nickname, champion }) } + +export const getUserStatus = () => { + return api.get('/users/status') +} diff --git a/app/_service/challenge/challenge.types.ts b/app/_service/challenge/challenge.types.ts index 598b752..4f5cc22 100644 --- a/app/_service/challenge/challenge.types.ts +++ b/app/_service/challenge/challenge.types.ts @@ -39,3 +39,17 @@ export interface Challenge { } export type GetChallengesResponse = Challenge[] + +export interface ChallengeDetail { + id: number + nickname: string + champion: Champion + participation_count: number + challenge_name: string + category: Category + reward: string +} + +export type GetChallengeDetail = ChallengeDetail[] & { + myId: number +} diff --git a/app/_service/challenge/index.ts b/app/_service/challenge/index.ts index e00ba7b..ae84469 100644 --- a/app/_service/challenge/index.ts +++ b/app/_service/challenge/index.ts @@ -7,6 +7,7 @@ import { type GetUpcomingChallengeParams, type GetUpcomingChallengeResponse, type GetChallengesResponse, + type GetChallengeDetail, } from './challenge.types' export const getTodayStatus = () => { @@ -47,3 +48,7 @@ export const submitCertification = ({ image, challengeId }: { image: File; chall }, }) } + +export const getChallengeDetail = ({ challengeId }: { challengeId: number }) => { + return api.get(`/challenges/in-progress/${challengeId}`) +}