Skip to content

Commit

Permalink
Merge pull request #704 from woowacourse-teams/feature/#675
Browse files Browse the repository at this point in the history
안내면진다 디테일 페이지 구현
  • Loading branch information
ss0526100 authored Oct 23, 2024
2 parents e23c788 + 8103a24 commit 56fc3d1
Show file tree
Hide file tree
Showing 36 changed files with 1,186 additions and 452 deletions.
3 changes: 2 additions & 1 deletion frontend/src/apis/gets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '@_types/index';
import {
GetBet,
GetBetDetail,
GetBets,
GetChamyoAll,
GetChamyoMine,
Expand Down Expand Up @@ -233,6 +234,6 @@ export const getBetResult = async (betId: number) => {
`/bet/${betId}/result`,
);

const json = await response.json();
const json: GetBetDetail = await response.json();
return json.data.nickname;
};
6 changes: 6 additions & 0 deletions frontend/src/apis/responseTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ export interface GetBet {
data: BetDetail;
}

export interface GetBetDetail {
data: {
nickname: string;
};
}

export interface PostBet {
data: {
betId: number;
Expand Down
Binary file added frontend/src/common/assets/fonts/DNFBitBitTTF.ttf
Binary file not shown.
8 changes: 7 additions & 1 deletion frontend/src/common/font.style.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import bitbit from './assets/fonts/DNFBitBitTTF.ttf';
import { css } from '@emotion/react';
import partialSansKRRegular from './assets/fonts/PartialSansKR/PartialSansKR-Regular.woff2';
import pretendardBlackWoff2 from './assets/fonts/woff2-subset/Pretendard-Black.subset.woff2';
import pretendardBoldWoff2 from './assets/fonts/woff2-subset/Pretendard-Bold.subset.woff2';
import pretendardExtraBoldWoff2 from './assets/fonts/woff2-subset/Pretendard-ExtraBold.subset.woff2';
Expand All @@ -8,7 +10,6 @@ import pretendardMediumWoff2 from './assets/fonts/woff2-subset/Pretendard-Medium
import pretendardRegularWoff2 from './assets/fonts/woff2-subset/Pretendard-Regular.subset.woff2';
import pretendardSemiboldWoff2 from './assets/fonts/woff2-subset/Pretendard-SemiBold.subset.woff2';
import pretendardThinWoff2 from './assets/fonts/woff2-subset/Pretendard-Thin.subset.woff2';
import partialSansKRRegular from './assets/fonts/PartialSansKR/PartialSansKR-Regular.woff2';

const fonts = css`
@font-face {
Expand Down Expand Up @@ -83,6 +84,11 @@ const fonts = css`
font-display: swap;
src: url(${partialSansKRRegular}) format('woff2');
}
@font-face {
font-family: bitbit;
src: url(${bitbit});
}
`;

export default fonts;
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Meta, StoryObj } from '@storybook/react';
import ProfileFrame from './ProfileFrame';
import EmptyProfile from '@_common/assets/default_profile.svg';

import EmptyProfile from '@_common/assets/default_profile.svg?url';

import Plus from '@_common/assets/tabler_plus.svg?url';

const meta = {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ declare module '*.woff2' {
export default src;
}

declare module '*.ttf' {
const src: string;
export default src;
}

declare module '*.svg?url' {
const content: string;
export default content;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/hooks/queries/useBet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import QUERY_KEYS from '@_constants/queryKeys';
import { getBet } from '@_apis/gets';
import { getLastDarakbangId } from '@_common/lastDarakbangManager';
import QUERY_KEYS from '@_constants/queryKeys';
import { useQuery } from '@tanstack/react-query';

export default function useBet(betId: number) {
Expand Down
24 changes: 24 additions & 0 deletions frontend/src/hooks/queries/useBetRefetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import QUERY_KEYS from '@_constants/queryKeys';
import { getBet } from '@_apis/gets';
import { getLastDarakbangId } from '@_common/lastDarakbangManager';
import { useQuery } from '@tanstack/react-query';

export default function useBetRefetch(betId: number) {
const {
data: bet,
isLoading,
isFetching,
} = useQuery({
queryKey: [
QUERY_KEYS.darakbang,
getLastDarakbangId(),
QUERY_KEYS.bet,
betId,
],
queryFn: () => getBet(betId),
staleTime: 1000,
refetchInterval: 1000,
});

return { bet, isLoading, isFetching };
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import * as S from './StickyTriSectionHeader.style';

import { PropsWithChildren } from 'react';
import { MutableRefObject, PropsWithChildren, useEffect, useRef } from 'react';

import TriSectionHeader from '@_layouts/components/TriSectionHeader/TriSectionHeader';
import { useTheme } from '@emotion/react';

function StickyTriSectionHeader(props: PropsWithChildren) {
const { children } = props;
// TODO: ref를 외부에서 쓸 수 있게 되면 해당 인터페이스를 PropsWithChildren으로 대체
interface StickyTriSectionHeaderProps extends PropsWithChildren {
onEffect?: (ref: MutableRefObject<null | HTMLDivElement>) => void;
afterEffect?: (ref: MutableRefObject<null | HTMLDivElement>) => void;
}
function StickyTriSectionHeader(props: StickyTriSectionHeaderProps) {
const { children, onEffect, afterEffect } = props;
const theme = useTheme();
const headerRef = useRef(null);

useEffect(() => {
if (onEffect) onEffect(headerRef);
return () => afterEffect && afterEffect(headerRef);
}, [onEffect, afterEffect]);

return (
<div css={S.Header({ theme })}>
<TriSectionHeader>{children}</TriSectionHeader>
<div css={S.Header({ theme })} ref={headerRef}>
<TriSectionHeader onEffect={onEffect} afterEffect={afterEffect}>
{children}
</TriSectionHeader>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import * as S from './TriSectionHeader.style';

import { PropsWithChildren } from 'react';
import { MutableRefObject, PropsWithChildren, useEffect, useRef } from 'react';

import { useTheme } from '@emotion/react';

// TODO: ref를 외부에서 쓸 수 있게 되면 해당 인터페이스를 PropsWithChildren으로 대체
interface TriSectionHeaderProps extends PropsWithChildren {
borderBottomColor?: string;
onEffect?: (ref: MutableRefObject<null | HTMLDivElement>) => void;
afterEffect?: (ref: MutableRefObject<null | HTMLDivElement>) => void;
}
function TriSectionHeader(props: TriSectionHeaderProps) {
const { children, borderBottomColor } = props;
const { children, borderBottomColor, onEffect, afterEffect } = props;
const theme = useTheme();
const headerRef = useRef(null);

useEffect(() => {
if (onEffect) onEffect(headerRef);
return () => afterEffect && afterEffect(headerRef);
}, [onEffect, afterEffect]);

return (
<header css={S.getTriSectionHeaderStyle({ borderBottomColor, theme })}>
<header
css={S.getTriSectionHeaderStyle({ borderBottomColor, theme })}
ref={headerRef}
>
{children}
</header>
);
Expand Down
52 changes: 35 additions & 17 deletions frontend/src/mocks/handler/betHandler.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { API_URL } from '@_apis/endPoints';
import { GetBet, GetBetDetail, PostBet } from '@_apis/responseTypes';
import { HttpResponse, http } from 'msw';

import { API_URL } from '@_apis/endPoints';
import { BetDetail } from '@_types/index';

const BET_ID = 10;
// 더미 데이터 생성
const dummyBets = [
{
id: 1,
id: BET_ID,
title: '첫 번째 배팅',
currentParticipants: 10,
deadline: '2024-09-26 12:30',
deadline: '2024-09-26T12:30',
isAnnounced: false,
},
{
id: 2,
id: BET_ID,
title: '두 번째 배팅',
currentParticipants: 5,
deadline: '2024-09-26 13:00',
isAnnounced: true,
deadline: '2024-10-26T13:00',
isAnnounced: false,
},
];

const dummyBetDetail = {
const deadLine = '2024-10-21T21:14:00';
const dummyBetDetail: BetDetail = {
title: '상세 배팅',
currentParticipants: 10,
deadline: '2024-09-26 12:30',
isAnnounced: false,
deadline: deadLine,
isAnnounced: true,
participants: [
{
nickname: '사용자1',
Expand All @@ -35,6 +40,16 @@ const dummyBetDetail = {
id: 102,
profileUrl: 'https://example.com/profile2.jpg',
},
{
nickname: '사용자2',
id: 103,
profileUrl: 'https://example.com/profile2.jpg',
},
{
nickname: '사용자2',
id: 104,
profileUrl: 'https://example.com/profile2.jpg',
},
],
myRole: 'MOIMEE',
chatroomId: null,
Expand All @@ -49,16 +64,19 @@ export const betHandler = [
}),

// 2. 배팅 상세 조회 API
http.get(API_URL.bet.detail(1), () => {
return HttpResponse.json(dummyBetDetail);
http.get(API_URL.bet.detail(BET_ID), () => {
return HttpResponse.json<GetBet>({
data: { ...dummyBetDetail, isAnnounced: new Date(deadLine) < new Date() },
});
}),

// 3. 배팅 생성 API
http.post(API_URL.bet.create, async ({ request }) => {
await request.json();
return HttpResponse.json({
betId: 3,
message: '배팅이 생성되었습니다.',
return HttpResponse.json<PostBet>({
data: {
betId: BET_ID,
},
});
}),

Expand All @@ -71,9 +89,9 @@ export const betHandler = [
}),

// 5. 배팅 결과 조회 API
http.get(API_URL.bet.result(1), () => {
return HttpResponse.json({
nickname: '우승자 닉네임',
http.get(API_URL.bet.result(10), () => {
return HttpResponse.json<GetBetDetail>({
data: { nickname: '사용자1' },
});
}),
];
4 changes: 2 additions & 2 deletions frontend/src/pages/Bet/BetCreationPage/BetCreationPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import FunnelStepIndicator from '@_components/Funnel/FunnelStepIndicator/FunnelStepIndicator';
import BackArrowButton from '@_components/Button/BackArrowButton/BackArrowButton';
import useFunnel from '@_hooks/useFunnel';
import FunnelLayout from '@_layouts/FunnelLayout/FunnelLayout';
import FunnelStepIndicator from '@_components/Funnel/FunnelStepIndicator/FunnelStepIndicator';
import TitleStep from './components/Steps/TitleStep';
import WaitingMinutesStep from './components/Steps/WaitingMinutesStep';
import useBetCreationForm from './hooks/useBetCreationForm';
import useFunnel from '@_hooks/useFunnel';

export type BetCreationStep = '제목' | '추첨시간';

Expand Down
5 changes: 3 additions & 2 deletions frontend/src/pages/Bet/BetDetailPage/BetDetailPage.style.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { css, Theme } from '@emotion/react';
import { Theme, css } from '@emotion/react';

export const containerStyle = css`
display: flex;
flex-direction: column;
gap: 16px;
gap: 4rem;
padding: 0 0 2rem;
`;

export const titleBox = () => css`
Expand Down
Loading

0 comments on commit 56fc3d1

Please sign in to comment.