Skip to content

Commit

Permalink
Merge pull request #168 from KNU-HAEDAL/develop
Browse files Browse the repository at this point in the history
변경사항 병합
  • Loading branch information
Dobbymin authored Sep 29, 2024
2 parents 91feded + 3f20b0b commit 0208289
Show file tree
Hide file tree
Showing 20 changed files with 459 additions and 280 deletions.
27 changes: 27 additions & 0 deletions src/apis/my-challenge-record/getReview.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ChallengeResponse } from './getReview.response';
import { axiosClient } from '@/apis/AxiosClient';
import { useQuery } from '@tanstack/react-query';

const getReviewPath = () => '/api/challengeGroups/reviews';

const ReviewQueryKey = [getReviewPath()];

const getReview = async (
page: number,
size: number
): Promise<ChallengeResponse> => {
const response = await axiosClient.get(getReviewPath(), {
params: {
page,
size,
},
});
return response.data;
};

export const useGetReview = (page: number, size: number) => {
return useQuery<ChallengeResponse, Error>({
queryKey: [ReviewQueryKey, page, size],
queryFn: () => getReview(page, size),
});
};
28 changes: 28 additions & 0 deletions src/apis/my-challenge-record/getReview.response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import ApiResponse from '@/apis/ApiResponse';

export type ChallengeUser = {
id: number;
nickname: string;
profileImageUrl: string;
tierInfo: {
tier: string;
totalExp: number;
currentExp: number;
};
};

export type ChallengeData = {
challengeId: number;
challengeTitle: string;
user: ChallengeUser;
content: string;
rating: number;
};

export type ChallengeResponseData = {
totalPage: number;
hasNext: boolean;
data: ChallengeData[];
};

export type ChallengeResponse = ApiResponse<ChallengeResponseData>;
59 changes: 59 additions & 0 deletions src/components/common/cta/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import styled from '@emotion/styled';

type CTAProps = {
label: string;
disabled?: boolean;
onClick: () => void;
};

const CTA = ({ label, disabled, onClick }: CTAProps) => {
return (
<StyledCTA disabled={disabled} onClick={onClick}>
{label}
</StyledCTA>
);
};

export default CTA;

const StyledCTA = styled.button<{ disabled?: boolean }>`
width: calc(100% - 16px); // 부모 요소의 좌우 padding 빼고
border: none;
border-radius: 10px;
background-color: var(--color-green-01);
color: var(--color-white);
font-size: var(--font-size-md);
font-weight: bold;
outline: none;
padding: 10px 8px;
margin: 0 auto;
&:disabled {
cursor: not-allowed;
color: var(--color-grey-01);
background-color: var(--color-grey-02);
}
/* &:hover와 &:focus는 disabled === false일 때만 적용 */
&:hover,
&:focus {
${({ disabled }) =>
!disabled &&
`
opacity: 0.8 !important;
background-color: var(--color-green-01) !important;
color: var(--color-white) !important;
`}
}
`;

// 컨테이너 필요할 때 따로 임포트하여 사용
export const CTAContainer = styled.div`
position: sticky;
bottom: 0;
display: flex;
width: 100%;
height: 4rem;
padding: 8px 16px;
background-color: var(--color-white);
`;
48 changes: 48 additions & 0 deletions src/components/common/form/textarea/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from '@emotion/styled';

type TextareaProps = {
placeholder?: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
valid?: boolean;
};

const Textarea = ({ placeholder, value, onChange, valid }: TextareaProps) => {
return (
<StyledTextarea
placeholder={placeholder}
value={value}
onChange={onChange}
valid={valid}
/>
);
};

export default Textarea;

const StyledTextarea = styled.textarea<{ valid?: boolean }>`
font-size: var(--font-size-sm);
color: var(--color-black);
border-radius: 20px;
border: ${({ valid }) =>
valid
? 'var(--color-grey-02) 1px solid'
: 'var(--color-class-05) 1px solid'};
padding: 12px;
width: 100%;
height: 180px;
resize: none;
outline: none;
&::placeholder {
color: var(--color-grey-01);
opacity: 1; /* Firefox에서 placeholder 색상을 명시적으로 설정하기 위해 추가 */
}
&:focus {
border: ${({ valid }) =>
valid
? 'var(--color-green-01) 1px solid'
: 'var(--color-class-05) 1px solid'};
}
`;
17 changes: 17 additions & 0 deletions src/components/features/layout/nav-bar-layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import NavBar, { NAVBAR_HEIGHT } from '@/components/features/layout/nav-bar';
import { Box } from '@chakra-ui/react';

type NavBarLayoutTypes = {
children: React.ReactNode;
};

const NavBarLayout = ({ children }: NavBarLayoutTypes) => {
return (
<Box>
<Box minHeight={`calc(100vh - ${NAVBAR_HEIGHT})`}>{children}</Box>
<NavBar />
</Box>
);
};

export default NavBarLayout;
46 changes: 0 additions & 46 deletions src/components/features/layout/nav-bar/buttons.tsx

This file was deleted.

73 changes: 56 additions & 17 deletions src/components/features/layout/nav-bar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,63 @@
import NavBarButtons from './buttons.tsx';
import { useNavigate } from 'react-router-dom';

import { navBarData } from '@/constants/nav-bar';
import { Box } from '@chakra-ui/react';
import styled from '@emotion/styled';

type NavBarTypes = {
children: React.ReactNode;
};
export const NAVBAR_HEIGHT = '3.44rem';

const NavBar = () => {
const navigate = useNavigate();

const handleNav = (page: string) => {
navigate(page);
};

const Index = ({ children }: NavBarTypes) => {
return (
<>
<Box
display='flex'
flexDirection='column'
height='100%'
paddingBottom='3.44'
>
<Box flex={1}>{children}</Box>
<NavBarButtons />
</Box>
</>
<Wrapper>
{navBarData.map((item) => (
<Tab key={item.title}>
<Icon
src={item.icon}
// alt={item.title}
onClick={() => handleNav(item.path)}
/>
</Tab>
))}
</Wrapper>
);
};

export default Index;
export default NavBar;

const Wrapper = styled(Box)`
display: flex;
flex-direction: row;
width: 100%;
height: ${NAVBAR_HEIGHT};
position: sticky;
bottom: 0;
left: 0;
border-top: 0.5px solid #bdc5cd;
background-color: #fafafa;
`;

const Tab = styled.div`
width: 50%;
height: 100%;
display: inline-flex;
justify-content: center;
align-items: center;
`;

const Icon = styled.button<{ src: string }>`
width: 2rem;
height: 2rem;
outline: none;
background-image: url(${({ src }) => src});
background-size: cover;
background-position: center;
background-repeat: no-repeat;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import * as S from './styles';
import { joinChallenge } from '@/apis/challenge-detail/challenge.detail.api';
import { type Challenge } from '@/apis/challenge-detail/challenge.detail.response';
import { Chip } from '@/components/common/chip';
import CTA from '@/components/common/cta';
import { getDynamicPath } from '@/routes/protected-route';
import { Box } from '@chakra-ui/react';

type Props = {
challenge: Challenge;
Expand Down Expand Up @@ -71,7 +73,8 @@ const ChallengeItem = ({ challenge, maxDifficulty }: Props) => {
</Chip>
</S.ContentGrid>

<S.CTA onClick={handleJoinChallenge}>참여하기</S.CTA>
<Box margin='0 0 16px 0' />
<CTA label='참여하기' onClick={handleJoinChallenge} />
</S.Wrapper>
);
};
Expand Down
13 changes: 0 additions & 13 deletions src/pages/challenge-detail/components/challenge-item/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,3 @@ export const Bar = styled(MaxBar)<{ width: number }>`
export const TimesPeriodContent = styled(Text)`
margin: 0 0 0 auto;
`;

export const CTA = styled.button`
width: calc(100% - 16px); // 부모 요소의 좌우 padding 빼고
padding: 10px 8px;
margin: auto;
border-radius: 10px;
background-color: var(--color-green-01);
color: var(--color-white);
font-weight: bold;
font-size: var(--font-size-md);
margin-top: 16px;
`;
1 change: 0 additions & 1 deletion src/pages/challenge-detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ export default ChallengeDetailPage;

export const Wrapper = styled.div`
width: 100%;
margin-bottom: 3.44rem; // 하단 내브 바 높이
`;

export const ImageList = styled.div`
Expand Down
2 changes: 1 addition & 1 deletion src/pages/challenge-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
import Contents from './components/contents';
import { useGetChallengeList } from '@/apis/challenge-list/getChallengeList.api';
import { Tab, Tabs } from '@/components/common/tabs';
import { TabPanel } from '@/components/common/tabs/tap-panels';
import { TabPanel } from '@/components/common/tabs/tab-panels';
import TopBar from '@/components/features/layout/top-bar';
import { Box, Spinner } from '@chakra-ui/react';
import styled from '@emotion/styled';
Expand Down
10 changes: 5 additions & 5 deletions src/pages/main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import Category from './components/category';
import Review from './components/review';
import Strick from './components/strick';
import Tier from './components/tier';
import TopBar from '@/components/features/layout/top-bar';
import TopBar, { HEADER_HEIGHT } from '@/components/features/layout/top-bar';
import styled from '@emotion/styled';

const MainPage = () => {
return (
<>
<TopBar type='Main' backgroundColor='#fff' title={''} />
<LoginPageLayout>
<Wrapper>
<Category />
<Tier />
<Strick />
<Review />
</LoginPageLayout>
</Wrapper>
</>
);
};

export default MainPage;

const LoginPageLayout = styled.div`
min-height: 100vh;
const Wrapper = styled.div`
min-height: calc(100vh - ${HEADER_HEIGHT});
`;
Loading

0 comments on commit 0208289

Please sign in to comment.