diff --git a/src/pages/game/game.tsx b/src/pages/game/game.tsx index 29fd68fe..e745a6aa 100644 --- a/src/pages/game/game.tsx +++ b/src/pages/game/game.tsx @@ -120,7 +120,7 @@ const Game = () => { }, [gameMatchData, setHeaderTitle]); return ( -
+
{gameMatchData?.result?.map((match) => ( // TODO: 매칭 현황 상태가 [그룹원 모집중]인 카드만 노출
diff --git a/src/pages/onboarding/onboarding.tsx b/src/pages/onboarding/onboarding.tsx index 488cea0a..c071aca1 100644 --- a/src/pages/onboarding/onboarding.tsx +++ b/src/pages/onboarding/onboarding.tsx @@ -1,11 +1,10 @@ import { matchMutations } from '@apis/match/match-mutations'; -import { userQueries } from '@apis/user/user-queries'; import Button from '@components/button/button/button'; import { TAB_TYPES } from '@components/tab/tab/constants/tab-type'; import { useFunnel } from '@hooks/use-funnel'; import Complete from '@pages/onboarding/components/complete'; import CompleteButtonSection from '@pages/onboarding/components/complete-button-section'; -import DateSelect from '@pages/onboarding/components/date-select'; +import DateSelect, { type SelectedGame } from '@pages/onboarding/components/date-select'; import Frequency from '@pages/onboarding/components/frequency'; import MatchingType from '@pages/onboarding/components/matching-type'; import OnboardingHeader from '@pages/onboarding/components/onboarding-header'; @@ -16,7 +15,7 @@ import ViewingStyle from '@pages/onboarding/components/viewing-style'; import { FIRST_FUNNEL_STEPS, NO_TEAM_OPTION } from '@pages/onboarding/constants/onboarding'; import { handleButtonClick, isButtonDisabled } from '@pages/onboarding/utils/onboarding-button'; import { ROUTES } from '@routes/routes-config'; -import { useMutation, useSuspenseQuery } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -34,8 +33,9 @@ const Onboarding = () => { MATCHING_TYPE: null, }); - const [createdMatch, setCreatedMatch] = useState<{ - matchId: number; + const [pendingMatch, setPendingMatch] = useState<{ + game: SelectedGame; + date: string; type: 'single' | 'group'; } | null>(null); @@ -44,7 +44,6 @@ const Onboarding = () => { }; const navigate = useNavigate(); - const { mutate } = useMutation(matchMutations.MATCH_CONDITION()); const handlePrev = () => { @@ -60,11 +59,8 @@ const Onboarding = () => { } }; - const { data: user } = useSuspenseQuery(userQueries.USER_INFO()); - const nickname = user.nickname; - return ( -
+
{currentStep !== 'COMPLETE' && ( @@ -104,14 +100,6 @@ const Onboarding = () => { /> - {/* TODO: GENDER 단계 관련 전부 삭제 */} - {/* - handleSelect('GENDER', option)} - /> - */} - { activeType={ selections.MATCHING_TYPE === '1:1 매칭' ? TAB_TYPES.SINGLE : TAB_TYPES.GROUP } - onComplete={(matchId) => { - setCreatedMatch({ - matchId, + onComplete={({ game, date }) => { + setPendingMatch({ + game, + date, type: selections.MATCHING_TYPE === '1:1 매칭' ? 'single' : 'group', }); goNext(); @@ -135,11 +124,11 @@ const Onboarding = () => { - {createdMatch && ( + {pendingMatch && ( )} @@ -164,7 +153,9 @@ const Onboarding = () => { />
)} - {currentStep === 'COMPLETE' && } + {currentStep === 'COMPLETE' && pendingMatch && ( + + )}
); diff --git a/src/shared/components/bottom-sheet/game-match/game-match-bottom-sheet.tsx b/src/shared/components/bottom-sheet/game-match/game-match-bottom-sheet.tsx index 7a067d3e..cb91d6aa 100644 --- a/src/shared/components/bottom-sheet/game-match/game-match-bottom-sheet.tsx +++ b/src/shared/components/bottom-sheet/game-match/game-match-bottom-sheet.tsx @@ -5,33 +5,22 @@ import GameMatchFooter from '@components/bottom-sheet/game-match/game-match-foot import GameMatchList from '@components/bottom-sheet/game-match/game-match-list'; import { formatDateWeekday } from '@components/bottom-sheet/game-match/utils/format-date-weekday'; import { TAB_TYPES, type TabType } from '@components/tab/tab/constants/tab-type'; -import { MATCH_REQUEST_ERROR_MESSAGES } from '@constants/error-toast'; import { gaEvent } from '@libs/analytics'; +import type { SelectedGame } from '@pages/onboarding/components/date-select'; import { ROUTES } from '@routes/routes-config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import type { AxiosError } from 'axios'; import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { showErrorToast } from '@/shared/utils/show-error-toast'; - -interface GameScheduleItem { - id: number; - awayTeam: string; - homeTeam: string; - gameTime: string; - stadium: string; -} interface GameMatchBottomSheetProps { isOpen: boolean; onClose: () => void; date: string; - gameSchedule: GameScheduleItem[]; + gameSchedule: SelectedGame[]; onClick?: (selectedId: number | null) => void; activeType: TabType; fromOnboarding?: boolean; - // groupRole?: string | null; TODO: 추후 삭제 - onComplete?: (matchId: number) => void; + onComplete?: (selected: { game: SelectedGame; date: string }) => void; } const GameMatchBottomSheet = ({ @@ -41,7 +30,6 @@ const GameMatchBottomSheet = ({ gameSchedule, activeType, fromOnboarding = false, - // groupRole, onComplete, }: GameMatchBottomSheetProps) => { const [selectedIdx, setSelectedIdx] = useState(null); @@ -50,7 +38,7 @@ const GameMatchBottomSheet = ({ const createMatchMutation = useMutation(matchMutations.CREATE_MATCH()); const disabled = selectedIdx === null || createMatchMutation.isPending; - const matchType = activeType === TAB_TYPES.SINGLE ? 'direct' : 'group'; + const matchType = activeType === TAB_TYPES.SINGLE ? 'DIRECT' : 'GROUP'; const queryType = activeType === TAB_TYPES.SINGLE ? 'single' : 'group'; const handleClose = () => { @@ -58,11 +46,21 @@ const GameMatchBottomSheet = ({ onClose(); }; - const handleSubmit = async () => { + const handleSubmit = () => { if (selectedIdx === null) return; + const selectedGame = gameSchedule[selectedIdx]; if (!selectedGame) return; + if (fromOnboarding) { + handleClose(); + onComplete?.({ + game: selectedGame, + date, + }); + return; + } + const gaMatchType = activeType === TAB_TYPES.SINGLE ? 'one_to_one' : 'group'; gaEvent('match_create_click', { match_type: gaMatchType, @@ -78,7 +76,7 @@ const GameMatchBottomSheet = ({ onSuccess: (response) => { const createdMatchId = response.matchId.toString(); - if (matchType === 'direct') { + if (matchType === 'DIRECT') { queryClient.invalidateQueries({ queryKey: matchQueries.SINGLE_MATCH_LIST(date).queryKey, }); @@ -89,21 +87,7 @@ const GameMatchBottomSheet = ({ } handleClose(); - - if (fromOnboarding) { - onComplete?.(response.matchId); - } else { - navigate(`${ROUTES.MATCH_CREATE(createdMatchId.toString())}?type=${queryType}`); - } - }, - onError: (error) => { - const status = (error as AxiosError)?.response?.status; - - if (status === MATCH_REQUEST_ERROR_MESSAGES.TOO_MANY_REQUESTS.status) { - showErrorToast(MATCH_REQUEST_ERROR_MESSAGES.TOO_MANY_REQUESTS.message, '8.3rem'); - } else if (status === MATCH_REQUEST_ERROR_MESSAGES.DUPLICATE_MATCH.status) { - showErrorToast(MATCH_REQUEST_ERROR_MESSAGES.DUPLICATE_MATCH.message, '8.3rem'); - } + navigate(`${ROUTES.MATCH_CREATE(createdMatchId)}?type=${queryType}`); }, }, ); diff --git a/src/shared/constants/error-toast.ts b/src/shared/constants/error-toast.ts index 48906d1b..d3bf9a8a 100644 --- a/src/shared/constants/error-toast.ts +++ b/src/shared/constants/error-toast.ts @@ -21,3 +21,5 @@ export const NO_GAME_TOAST_MESSAGE = '해당 날짜에는 진행되는 경기가 export const HAS_DONE_TOAST_MESSAGE = '이미 매칭을 만든 경기예요.'; export const MY_MATCH_TOAST_MESSAGE = '내가 만든 매칭은 매칭현황에서 확인 가능해요.'; + +export const CREATE_MATCH_TOAST_MESSAGE = '방금 만든 카드를 매칭 현황에서 확인해 보세요! 🎉 '; diff --git a/src/shared/styles/global.css b/src/shared/styles/global.css index 6959a2bb..fa10790e 100644 --- a/src/shared/styles/global.css +++ b/src/shared/styles/global.css @@ -46,4 +46,8 @@ body::-webkit-scrollbar { display: none; /* Chrome, Safari */ } + + .toast-text { + max-width: none !important; + } } diff --git a/src/shared/utils/show-error-toast.tsx b/src/shared/utils/show-error-toast.tsx index 1dc99aae..f1a6d738 100644 --- a/src/shared/utils/show-error-toast.tsx +++ b/src/shared/utils/show-error-toast.tsx @@ -4,12 +4,13 @@ import { toast } from 'react-compact-toast'; type ShowErrorToastOptions = { icon?: boolean; offset?: string; + className?: string; }; const DEFAULT_AUTOCLOSE = 2000; const showErrorToastCore = (message: string, opts?: ShowErrorToastOptions) => { - const { icon = true } = opts ?? {}; + const { icon = true, className = '' } = opts ?? {}; toast({ text: message, @@ -17,8 +18,13 @@ const showErrorToastCore = (message: string, opts?: ShowErrorToastOptions) => { autoClose: DEFAULT_AUTOCLOSE, offset: opts?.offset, position: 'bottomCenter', - className: - '!min-h-[4.5rem] max-w-[calc(43rem-3.2rem)] w-[calc(100%-3.2rem)] cap_14_m text-gray-white rounded-[12px] bg-gray-700', + className: ` + !min-h-[4.5rem] + max-w-[calc(43rem-3.2rem)] + w-[calc(100%-3.2rem)] + rounded-[12px] + ${className || 'cap_14_m text-gray-white bg-gray-700'} + `, }); };