Skip to content

Commit

Permalink
fix: 팀 정보가 없을 시 임시 이미지 보이게 처리
Browse files Browse the repository at this point in the history
  • Loading branch information
seongminn committed Nov 28, 2023
1 parent faa13e0 commit 3255844
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 42 deletions.
5 changes: 3 additions & 2 deletions src/app/match/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function Match({ params }: { params: { id: string } }) {
</AsyncBoundary>
<AsyncBoundary
errorFallback={props => <Cheer.ErrorFallback {...props} />}
loadingFallback={<div>응원 로딩중...</div>}
loadingFallback={<Loader />}
>
<MatchCheerByIdFetcher matchId={params.id}>
{data => <Cheer cheers={data} />}
Expand Down Expand Up @@ -113,7 +113,7 @@ export default function Match({ params }: { params: { id: string } }) {
loadingFallback={<Loader />}
>
<MatchCommentFetcher matchId={params.id}>
{({ commentList, ...data }) => (
{({ commentList, matchTeams, ...data }) => (
<div className="max-h-[450px] overflow-y-auto p-5">
<ul className="pb-8">
<CommentList
Expand All @@ -125,6 +125,7 @@ export default function Match({ params }: { params: { id: string } }) {
<li ref={scrollRef}></li>
</ul>
<CommentForm
matchTeams={matchTeams}
matchId={params.id}
mutate={mutate}
scrollToBottom={scrollToBottom}
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/MatchCard/pieces/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function Label({ className }: LabelProps) {
parseTimeString(startTime);

return (
<div className={$('flex items-center justify-between', className)}>
<div className={$('flex items-center justify-between text-sm', className)}>
<time>
{month}. {date}. {weekday}요일 {period} {hours}:{minutes}
</time>
Expand Down
5 changes: 5 additions & 0 deletions src/components/common/MatchCard/pieces/Score.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ type ScoreProps = {

export default function Score({ teamIndex, className }: ScoreProps) {
const { gameTeams } = useMatchCardContext();

if (gameTeams.length === 0) {
return <span className={$('text-3xl', className)}>-</span>;
}

const targetTeam = gameTeams[teamIndex - 1];

return <span className={$('text-3xl', className)}>{targetTeam.score}</span>;
Expand Down
16 changes: 16 additions & 0 deletions src/components/common/MatchCard/pieces/Team.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ type TeamProps = {
export default function Team({ teamIndex, className }: TeamProps) {
const { gameTeams } = useMatchCardContext();

if (gameTeams.length === 0) {
return (
<div className={$(className)}>
<svg
className="me-4 h-16 w-16 text-gray-200 dark:text-gray-700"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M10 0a10 10 0 1 0 10 10A10.011 10.011 0 0 0 10 0Zm0 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Zm0 13a8.949 8.949 0 0 1-4.951-1.488A3.987 3.987 0 0 1 9 13h2a3.987 3.987 0 0 1 3.951 3.512A8.949 8.949 0 0 1 10 18Z" />
</svg>
</div>
);
}

const targetTeamInfo = gameTeams[teamIndex - 1];

return (
Expand Down
16 changes: 12 additions & 4 deletions src/components/match/Banner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { MatchCard } from '@/components/common/MatchCard';
import { MatchType } from '@/types/match';

export default function MatchBanner(props: MatchType) {
const [firstTeam, secondTeam] = props.gameTeams;

return (
<MatchCard {...props} className="flex flex-col">
<MatchCard.Label className="absolute top-2 flex w-full justify-between px-2" />
Expand All @@ -13,11 +15,17 @@ export default function MatchBanner(props: MatchType) {
height={200}
className="h-[200px]"
/>
<MatchCard.Team teamIndex={1} className="flex flex-col items-center" />
<MatchCard.Score teamIndex={1} />
<MatchCard.Team
teamIndex={firstTeam.order}
className="flex flex-col items-center"
/>
<MatchCard.Score teamIndex={firstTeam.order} />
<MatchCard.Status />
<MatchCard.Score teamIndex={2} />
<MatchCard.Team teamIndex={2} className="flex flex-col items-center" />
<MatchCard.Score teamIndex={secondTeam.order} />
<MatchCard.Team
teamIndex={secondTeam.order}
className="flex flex-col items-center"
/>
</div>
</MatchCard>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/match/CheerTeam/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export default function CheerTeam({
)}
{...props}
>
<div className="flex w-full items-center justify-center text-white">
<button className="flex w-full items-center justify-center text-white">
{children}
</div>
</button>
</div>
);
}
81 changes: 55 additions & 26 deletions src/components/match/CommentForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,83 @@
import { UseMutateFunction } from '@tanstack/react-query';
import { FormEvent, useState } from 'react';
import { ChangeEvent, FormEvent, useState } from 'react';

import { MatchCommentPayload } from '@/types/match';
import { MatchCommentPayload, MatchTeamType } from '@/types/match';

type CommentFormProps = {
matchId: string;
matchTeams: MatchTeamType[];
mutate: UseMutateFunction<void, Error, MatchCommentPayload, unknown>;
scrollToBottom: () => void;
};

export default function CommentForm({
matchId,
matchTeams,
mutate,
scrollToBottom,
}: CommentFormProps) {
const [inputValue, setInputValue] = useState('');
const [selectedTeamId, setSelectedTeamId] = useState<number>(1);
const [isOpen, toggleOpen] = useState(false);

const handleCommentSubmit = (
e: FormEvent<HTMLFormElement>,
payload: MatchCommentPayload,
) => {
e.preventDefault();
mutate(payload);
mutate({ ...payload, gameTeamId: selectedTeamId });
setInputValue('');
scrollToBottom();
};

const handleRadioClick = (e: ChangeEvent<HTMLInputElement>) => {
setSelectedTeamId(Number(e.target.value));
};

return (
<form
className="h-70px absolute -bottom-1 left-0 w-full"
onSubmit={e =>
handleCommentSubmit(e, {
gameTeamId: Number(matchId),
content: inputValue,
})
}
>
<div
className="grid items-center rounded-lg bg-gray-2"
style={{ gridTemplateColumns: '1fr auto' }}
<>
<form
className="h-70px absolute -bottom-1 left-0 w-full"
onSubmit={e =>
handleCommentSubmit(e, {
gameTeamId: Number(matchId),
content: inputValue,
})
}
>
<input
className="bg-inherit px-5 text-gray-5 outline-none"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
placeholder="응원하는 팀에 댓글을 남겨보세요!"
/>
<button className="rounded-xl bg-primary px-5 py-3 text-white">
댓글
</button>
</div>
</form>
{isOpen && (
<fieldset className="absolute top-0 flex w-full -translate-y-full items-center justify-start gap-2 rounded-lg bg-white px-5 py-3 shadow-md">
{matchTeams.map(team => (
<label key={team.gameTeamId} className="flex items-center">
<input
type="radio"
checked={selectedTeamId === team.gameTeamId}
value={team.gameTeamId}
onChange={handleRadioClick}
className="dark:border-gray-6 dark:bg-gray-6 h-4 w-4 border-gray-3 bg-gray-1 text-primary focus:ring-2 focus:ring-primary dark:ring-offset-black dark:focus:ring-primary"
/>
{team.gameTeamName}
</label>
))}
</fieldset>
)}

<div
className="z-10 grid items-center rounded-lg bg-gray-2"
style={{ gridTemplateColumns: '1fr auto' }}
>
<input
className="bg-inherit px-5 text-gray-5 outline-none"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
placeholder="응원하는 팀에 댓글을 남겨보세요!"
onFocus={() => toggleOpen(true)}
/>
<button className="rounded-xl bg-primary px-5 py-3 text-white">
댓글
</button>
</div>
</form>
</>
);
}
22 changes: 18 additions & 4 deletions src/queries/useMatchCommentById/Fetcher.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { InfiniteData } from '@tanstack/react-query';
import { ReactNode } from 'react';

import { MatchCommentType } from '@/types/match';
import { MatchCommentType, MatchTeamType } from '@/types/match';

import useMatchCommentById from './query';

type MatchCommentFetcherProps = {
matchId: string;
children: ({
commentList,
matchTeams,
fetchNextPage,
hasNextPage,
isFetching,
}: {
commentList: InfiniteData<MatchCommentType[]>;
matchTeams: MatchTeamType[];
fetchNextPage: () => void;
hasNextPage: boolean;
isFetching: boolean;
Expand All @@ -24,10 +26,22 @@ export default function MatchCommentFetcher({
matchId,
children,
}: MatchCommentFetcherProps) {
const { commentList, error, fetchNextPage, hasNextPage, isFetching } =
useMatchCommentById(matchId);
const {
commentList,
matchTeams,
error,
fetchNextPage,
hasNextPage,
isFetching,
} = useMatchCommentById(matchId);

if (error) throw error;

return children({ commentList, fetchNextPage, hasNextPage, isFetching });
return children({
commentList,
matchTeams,
fetchNextPage,
hasNextPage,
isFetching,
});
}
16 changes: 14 additions & 2 deletions src/queries/useMatchCommentById/query.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
import {
useSuspenseInfiniteQuery,
useSuspenseQuery,
} from '@tanstack/react-query';

import { getMatchById, getMatchCommentById } from '@/api/match';

import { getMatchCommentById } from '@/api/match';
export default function useMatchCommentById(matchId: string) {
const { data, error, fetchNextPage, hasNextPage, isFetching } =
useSuspenseInfiniteQuery({
Expand All @@ -14,11 +18,19 @@ export default function useMatchCommentById(matchId: string) {
}),
});

const { data: matchTeams, error: matchError } = useSuspenseQuery({
queryKey: ['match-detail', 'for-comment', matchId],
queryFn: () => getMatchById(matchId),
select: data => data.gameTeams,
});

return {
commentList: data,
matchTeams,
fetchNextPage,
hasNextPage,
isFetching,
error,
matchError,
};
}
2 changes: 1 addition & 1 deletion src/queries/useMatchList/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const useMatchList = ({
cursor: pageParam,
}),
initialPageParam: 0,
getNextPageParam: lastPage => lastPage[0]?.id || null,
getNextPageParam: lastPage => lastPage.at(-1)?.id || null,
});

return {
Expand Down
2 changes: 2 additions & 0 deletions src/types/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type MatchTeamType = {
gameTeamName: string;
logoImageUrl: string;
score: number;
order: number;
};

export type MatchCheerType = {
Expand Down Expand Up @@ -52,6 +53,7 @@ export type MatchCommentType = {
gameTeamId: number;
createdAt: string;
isBlocked: boolean;
order: number;
};

export type MatchCommentPayload = Pick<
Expand Down

0 comments on commit 3255844

Please sign in to comment.