Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/pages/game/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const Game = () => {
}, [gameMatchData, setHeaderTitle]);

return (
<div className="relative h-full flex-col gap-[1.2rem] px-[1.6rem] pt-[2rem]">
<div className="relative h-full flex-col gap-[1.2rem] bg-gray-100 px-[1.6rem] pt-[2rem]">
{gameMatchData?.result?.map((match) => (
// TODO: 매칭 현황 상태가 [그룹원 모집중]인 카드만 노출
<button
Expand Down
20 changes: 19 additions & 1 deletion src/pages/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Button from '@components/button/button/button';
import { WEEK_CALENDAR_START_OFFSET } from '@components/calendar/constants/CALENDAR';
import Dialog from '@components/dialog/dialog';
import { TAB_TYPES, type TabType } from '@components/tab/tab/constants/tab-type';
import { CREATE_MATCH_TOAST_MESSAGE } from '@constants/error-toast';
import useAuth from '@hooks/use-auth';
import { useTabState } from '@hooks/use-tab-state';
import { gaEvent } from '@libs/analytics';
Expand All @@ -19,8 +20,9 @@ import { ROUTES } from '@routes/routes-config';
import { useMutation } from '@tanstack/react-query';
import { addDays, format } from 'date-fns';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import { handleScrollLock } from '@/shared/utils/scroll-lock';
import { showErrorToast } from '@/shared/utils/show-error-toast';

// TODO: 선택 날짜 유지 로직 수정
// const getSelectedDateFromQuery = (searchParams: URLSearchParams, fallbackDate: Date): Date => {
Expand All @@ -32,6 +34,7 @@ import { handleScrollLock } from '@/shared/utils/scroll-lock';

const Home = () => {
const { activeType, changeTab } = useTabState();
const location = useLocation();
const navigate = useNavigate();
// const [searchParams, setSearchParams] = useSearchParams();
const entryDate = new Date();
Expand Down Expand Up @@ -68,6 +71,21 @@ const Home = () => {
gaEvent('home_enter', { from });
}, [needsMatchingSetup]);

useEffect(() => {
if (location.state?.shouldShowMatchCreatedToast) {
showErrorToast(CREATE_MATCH_TOAST_MESSAGE, {
offset: '8.8rem',
icon: false,
className: 'bg-sub-900 text-gray-black cap_14_sb',
});

navigate(location.pathname, {
replace: true,
state: {},
});
}
}, [location, navigate]);

// const syncSelectedDateToQuery = (date: Date) => {
// const nextParams = new URLSearchParams(searchParams);
// nextParams.set('date', format(date, 'yyyy-MM-dd'));
Expand Down
61 changes: 53 additions & 8 deletions src/pages/onboarding/components/complete-button-section.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
import { matchMutations } from '@apis/match/match-mutations';
import { matchQueries } from '@apis/match/match-queries';
import Button from '@components/button/button/button';
import { gaEvent } from '@libs/analytics';
import { ROUTES } from '@routes/routes-config';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import type { SelectedGame } from './date-select';

const CompleteButtonSection = () => {
interface CompleteButtonSectionProps {
pendingMatch: {
game: SelectedGame;
date: string;
type: 'single' | 'group';
};
}

const CompleteButtonSection = ({ pendingMatch }: CompleteButtonSectionProps) => {
const navigate = useNavigate();
const queryClient = useQueryClient();
const createMatchMutation = useMutation(matchMutations.CREATE_MATCH());

const handleGoToMate = () => {
Comment thread
bongtta marked this conversation as resolved.
navigate(ROUTES.HOME);
};

const handleCreate = () => {
const matchType = pendingMatch.type === 'single' ? 'DIRECT' : 'GROUP';
const gaMatchType = pendingMatch.type === 'single' ? 'one_to_one' : 'group';

gaEvent('match_create_click', {
match_type: gaMatchType,
role: 'creator',
});

createMatchMutation.mutate(
{
gameId: pendingMatch.game.id,
matchType,
},
{
onSuccess: () => {
if (matchType === 'DIRECT') {
queryClient.invalidateQueries({
queryKey: matchQueries.SINGLE_MATCH_LIST(pendingMatch.date).queryKey,
});
} else {
queryClient.invalidateQueries({
queryKey: matchQueries.GROUP_MATCH_LIST(pendingMatch.date).queryKey,
});
}

navigate(ROUTES.HOME, {
state: {
shouldShowMatchCreatedToast: true,
},
});
},
},
);
};

return (
<div className="w-full">
<section className="w-full flex-row-between gap-[0.8rem] p-[1.6rem]">
Expand All @@ -19,13 +70,7 @@ const CompleteButtonSection = () => {
className="w-full"
onClick={handleGoToMate}
/>
<Button
label="만들기"
size="M"
variant="blue"
className="w-full"
onClick={handleGoToMate}
/>
<Button label="만들기" size="M" variant="blue" className="w-full" onClick={handleCreate} />
</section>
</div>
);
Expand Down
14 changes: 11 additions & 3 deletions src/pages/onboarding/components/complete-group-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ const CompleteGroupCard = ({ matchId }: { matchId: number }) => {
const { data } = useSuspenseQuery(matchQueries.GROUP_MATCH_RESULT(matchId));

const cardProps: CardProps = {
...data,
type: 'group',
id: data.id,
type: 'game',
nickname: data.nickname,
count: data.count,
imgUrl: Array.isArray(data.imgUrl) ? data.imgUrl : [data.imgUrl],
awayTeam: data.awayTeam,
homeTeam: data.homeTeam,
stadium: data.stadium,
date: data.date,
isGroup: true,
className: 'w-full',
};

return <Card isCreated {...cardProps} />;
return <Card {...cardProps} />;
};

export default CompleteGroupCard;
16 changes: 11 additions & 5 deletions src/pages/onboarding/components/complete-single-card.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import { matchQueries } from '@apis/match/match-queries';
import Card from '@components/card/match-card/card';
import type { CardProps, ChipColor } from '@components/card/match-card/types/card';
import type { CardProps } from '@components/card/match-card/types/card';
import { useSuspenseQuery } from '@tanstack/react-query';

const CompleteSingleCard = ({ matchId }: { matchId: number }) => {
const { data } = useSuspenseQuery(matchQueries.SINGLE_MATCH_RESULT(matchId));

const cardProps: CardProps = {
...data,
type: 'single',
id: data.id,
type: 'game',
nickname: data.nickname,
count: 1,
imgUrl: [data.imgUrl],
chips: [data.team, data.style] as ChipColor[],
awayTeam: data.awayTeam,
homeTeam: data.homeTeam,
stadium: data.stadium,
date: data.date,
isGroup: false,
className: 'w-full',
};

return <Card isCreated {...cardProps} />;
return <Card {...cardProps} />;
};

export default CompleteSingleCard;
41 changes: 31 additions & 10 deletions src/pages/onboarding/components/complete.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
import { userQueries } from '@apis/user/user-queries';
import Card from '@components/card/match-card/card';
import type { CardProps } from '@components/card/match-card/types/card';
import { MATCHING_SUGGESTION_MESSAGE_TITLE } from '@pages/match/constants/matching';
import CompleteGroupCard from './complete-group-card';
import CompleteSingleCard from './complete-single-card';
import { useQuery } from '@tanstack/react-query';
import type { SelectedGame } from './date-select';

interface CompleteProps {
nickname: string;
matchId: number;
selectedGame: SelectedGame;
selectedDate: string;
type?: 'single' | 'group';
}

const Complete = ({ nickname, matchId, type }: CompleteProps) => {
const Complete = ({ selectedGame, selectedDate, type }: CompleteProps) => {
const { data } = useQuery({
...userQueries.USER_INFO(),
enabled: true,
});

const nickname = data?.nickname ?? '사용자';
const imgUrl = data?.imgUrl ?? '';

const cardProps: CardProps = {
id: selectedGame.id,
type: 'game',
nickname,
count: 1,
imgUrl: imgUrl ? [imgUrl] : [],
awayTeam: selectedGame.awayTeam,
homeTeam: selectedGame.homeTeam,
stadium: selectedGame.stadium,
date: selectedDate,
isGroup: type === 'group',
className: 'w-full',
};

return (
<div className="w-full flex-1 flex-col-between gap-[4rem] whitespace-pre-line pt-[6.45rem]">
<div className="w-full flex-col gap-[4rem] px-[1.6rem]">
<p className="title_24_sb text-center text-gray-black">
{MATCHING_SUGGESTION_MESSAGE_TITLE(nickname)}
</p>

{type === 'single' ? (
<CompleteSingleCard matchId={matchId} />
) : (
<CompleteGroupCard matchId={matchId} />
)}
<Card {...cardProps} />
</div>
</div>
);
Expand Down
12 changes: 10 additions & 2 deletions src/pages/onboarding/components/date-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ import { format } from 'date-fns';
import { useState } from 'react';
import { showErrorToast } from '@/shared/utils/show-error-toast';

export interface SelectedGame {
id: number;
awayTeam: string;
homeTeam: string;
gameTime: string;
stadium: string;
}

interface DateSelectProps {
onComplete: (matchId: number) => void;
onComplete: (selected: { game: SelectedGame; date: string }) => void;
activeType: TabType;
}

Expand Down Expand Up @@ -71,7 +79,7 @@ const DateSelect = ({ onComplete, activeType }: DateSelectProps) => {
date={format(selectedDate ?? new Date(), 'yyyy-MM-dd')}
gameSchedule={data ?? []}
activeType={activeType}
fromOnboarding={true}
fromOnboarding
onComplete={onComplete}
/>
</div>
Expand Down
43 changes: 17 additions & 26 deletions src/pages/onboarding/onboarding.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';

Expand All @@ -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);

Expand All @@ -44,7 +44,6 @@ const Onboarding = () => {
};

const navigate = useNavigate();

const { mutate } = useMutation(matchMutations.MATCH_CONDITION());

const handlePrev = () => {
Expand All @@ -60,11 +59,8 @@ const Onboarding = () => {
}
};

const { data: user } = useSuspenseQuery(userQueries.USER_INFO());
const nickname = user.nickname;

return (
<div className="h-full flex-col">
<div className="h-full flex-col bg-background">
<div className="sticky top-0 bg-background">
<OnboardingHeader onClick={handlePrev} />
{currentStep !== 'COMPLETE' && (
Expand Down Expand Up @@ -104,14 +100,6 @@ const Onboarding = () => {
/>
</Step>

{/* TODO: GENDER 단계 관련 전부 삭제 */}
{/* <Step name="GENDER">
<Gender
selectedOption={selections.GENDER}
onSelect={(option) => handleSelect('GENDER', option)}
/>
</Step> */}

<Step name="MATCHING_TYPE">
<MatchingType
selectedOption={selections.MATCHING_TYPE}
Expand All @@ -124,9 +112,10 @@ const Onboarding = () => {
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();
Expand All @@ -135,11 +124,11 @@ const Onboarding = () => {
</Step>

<Step name="COMPLETE">
{createdMatch && (
{pendingMatch && (
<Complete
nickname={nickname ?? ''}
matchId={createdMatch.matchId}
type={createdMatch.type}
selectedGame={pendingMatch.game}
selectedDate={pendingMatch.date}
type={pendingMatch.type}
/>
)}
</Step>
Expand All @@ -164,7 +153,9 @@ const Onboarding = () => {
/>
</div>
)}
{currentStep === 'COMPLETE' && <CompleteButtonSection />}
{currentStep === 'COMPLETE' && pendingMatch && (
<CompleteButtonSection pendingMatch={pendingMatch} />
)}
</div>
</div>
);
Expand Down
Loading
Loading