Skip to content

Commit

Permalink
Merge pull request #179 from KNU-HAEDAL/Feat/record-page-#148
Browse files Browse the repository at this point in the history
챌린지 인증/기록 페이지 #148
  • Loading branch information
joojjang authored Sep 30, 2024
2 parents 7873472 + 679ec2e commit e6fbf50
Show file tree
Hide file tree
Showing 22 changed files with 806 additions and 682 deletions.
64 changes: 42 additions & 22 deletions src/apis/challenge-record/challenge.record.api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AxiosError } from 'axios';

import { multiPartClient, axiosClient } from '../AxiosClient';
import {
ApiResponse,
Expand All @@ -9,35 +11,42 @@ import {

// POST: /api/challenges/{challengeId}/verification
export async function postVerification(
id: number,
image: File,
content: string
): Promise<{ data: ChallengeVerificationData; status: number }> {
const formData = new FormData();
formData.append(
challengeId: number,
content: string,
image: File
): Promise<void> {
const requestBody = new FormData();
requestBody.append(
'body',
new Blob([JSON.stringify({ content })], { type: 'application/json' })
);
formData.append('image', image);
requestBody.append('image', image);

const response = await multiPartClient.post<ChallengeVerificationData>(
`api/challenges/${id}/verifications`,
formData
`api/challenges/${challengeId}/verification`,
requestBody
);
console.log('postVerification response: ', response.data);
// return response.data;
return { data: response.data, status: response.status };
console.log('postVerification response: ', response.data); // test
}

// GET: /api/challenges/{challengeId}/record
export async function getChallengeRecord(
id: number
challengeId: number
): Promise<ChallengeRecordData> {
const response = await axiosClient.get<ApiResponse<ChallengeRecordData>>(
`api/challenges/${id}/record`
);
console.log('getChallengeRecord response: ', response.data);
return response.data.data;
try {
const response = await axiosClient.get(
`api/challenges/${challengeId}/record`
);
// console.log('getChallengeRecord response: ', response.data); // test
return response.data.data;
} catch (error) {
if (error instanceof AxiosError) {
throw new Error(
`getChallengeRecord error: ${error.response?.data.message || error.message}`
);
} else {
throw new Error('getChallengeRecord error: unexpected');
}
}
}

// GET: /api/challenges/record/{recordId}
Expand All @@ -51,11 +60,22 @@ export async function getChallengeRecordDetailorigin(
return response.data.data;
}

export async function getChallengeRecordDetail(
export async function getChallengeRecordDetails(
recordId: number
): Promise<ChallengeRecordDetailData> {
const response = await axiosClient.get(`api/challenges/record/${recordId}`);
return response.data;
try {
const response = await axiosClient.get(`api/challenges/record/${recordId}`);
// console.log('getChallengeRecordDetails response: ', response.data); // test
return response.data.data;
} catch (error) {
if (error instanceof AxiosError) {
throw new Error(
`getChallengeRecord error: ${error.response?.data.message || error.message}`
);
} else {
throw new Error('getChallengeRecord error: unexpected');
}
}
}

// GET: /api/user/challenges/completes
Expand Down
30 changes: 10 additions & 20 deletions src/apis/challenge-record/challenge.record.response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,19 @@ export type ApiResponse<T> = {
};

export type ChallengeRecordData = {
result: string;
data: {
title: string;
totalCount: number;
successCount: number;
startDate: string;
endDate: string;
recordIds: number[];
};
message: string;
errorCode: string;
title: string;
totalCount: number;
successCount: number;
startDate: string;
endDate: string;
recordIds: number[];
};

export type ChallengeRecordDetailData = {
result: string;
data: {
id: 0;
createdAt: string;
content: string;
imageUrl: string;
};
message: string;
errorCode: string;
id: 0;
createdAt: string;
content: string;
imageUrl: string;
};

export type CompleteChallengeData = {
Expand Down
27 changes: 27 additions & 0 deletions src/assets/stamp-active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/assets/stamp-inactive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions src/components/common/challenge-title/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Text } from '@chakra-ui/react';
import styled from '@emotion/styled';

type ChallengeTitleProps = {
category: string;
title: string;
};

const ChallengeTitle = ({ category, title }: ChallengeTitleProps) => {
return (
<Wrapper>
<Text fontSize='var(--font-size-xs)' color='var(--color-green-01)'>
{category}
</Text>
<Text fontSize='var(--font-size-xl)' fontWeight='700'>
{title}
</Text>
</Wrapper>
);
};

export default ChallengeTitle;

const Wrapper = styled.div`
margin: 16px;
display: flex;
flex-direction: column;
text-align: left;
`;
5 changes: 4 additions & 1 deletion src/components/common/cta/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const CTA = ({ label, disabled, onClick }: CTAProps) => {

export default CTA;

export const CTA_CONTAINER_HEIGHT = '4rem';

const StyledCTA = styled.button<{ disabled?: boolean }>`
width: calc(100% - 16px); // 부모 요소의 좌우 padding 빼고
border: none;
Expand Down Expand Up @@ -53,7 +55,8 @@ export const CTAContainer = styled.div`
bottom: 0;
display: flex;
width: 100%;
height: 4rem;
height: ${CTA_CONTAINER_HEIGHT};
padding: 8px 16px;
background-color: var(--color-white);
z-index: 1;
`;
37 changes: 29 additions & 8 deletions src/components/common/form/textarea/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
import { Text } from '@chakra-ui/react';
import styled from '@emotion/styled';

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

const Textarea = ({ placeholder, value, onChange, valid }: TextareaProps) => {
const Textarea = ({
placeholder,
value,
onChange,
minValueLength,
valid,
}: TextareaProps) => {
return (
<StyledTextarea
placeholder={placeholder}
value={value}
onChange={onChange}
valid={valid}
/>
<>
<StyledTextarea
placeholder={placeholder}
value={value}
onChange={onChange}
valid={valid}
/>
{/* 최소 길이 제한 있을 때만 보이기 */}
{minValueLength && (
<Text
fontSize='var(--font-size-xs)'
color={valid ? `var(--color-grey-01)` : `var(--color-class-05)`}
textAlign='right'
margin='8px 16px 0'
>
{value.length} / 최소 {minValueLength}
</Text>
)}
</>
);
};

Expand All @@ -29,10 +50,10 @@ const StyledTextarea = styled.textarea<{ valid?: boolean }>`
? 'var(--color-grey-02) 1px solid'
: 'var(--color-class-05) 1px solid'};
padding: 12px;
width: 100%;
height: 180px;
resize: none;
outline: none;
margin: 0 16px;
&::placeholder {
color: var(--color-grey-01);
Expand Down
9 changes: 5 additions & 4 deletions src/components/common/tabs/tab-panels/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,20 @@ export const TabPanel = ({ children, value, selectedIndex }: TabPanelProps) => {
};

export const StyledTabPanels = styled.div`
height: 100%;
width: 100%;
position: relative;
text-align: center;
display: flex;
flex-direction: column;
flex: 1;
`;

export const StyledTabPanel = styled.div<{
active: boolean;
}>`
display: ${(p) => (p.active ? 'flex' : 'none')};
font-size: 2rem;
flex-direction: column;
flex: 1;
width: 100%;
height: 100%;
justify-content: center;
font-size: 2rem;
`;
2 changes: 1 addition & 1 deletion src/components/features/layout/top-bar/page-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const PageBarLayout = styled(Box)<{
padding: 0.5rem;
gap: 1rem;
background-color: ${(props) => props.backgroundColor};
z-index: 1000;
z-index: 1;
position: sticky;
top: ${({ show }) => (show ? '0' : '-100px')};
transition: top 0.3s;
Expand Down
30 changes: 7 additions & 23 deletions src/pages/challenge-detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RankingSection } from './ranking-section/';
import { ReviewSection } from './review-section/';
import { type ChallengeDetailData } from '@/apis/challenge-detail/challenge.detail.response';
import DefaultImage from '@/assets/Default-Image.svg';
import ChallengeTitle from '@/components/common/challenge-title';
import { Tabs, Tab } from '@/components/common/tabs';
import { TabPanels, TabPanel } from '@/components/common/tabs/tab-panels';
import TopBar from '@/components/features/layout/top-bar';
Expand Down Expand Up @@ -79,12 +80,12 @@ const ChallengeDetailPage = () => {
</DefaultImageMask>
)}
</ImageList>

<ChallengeTitleWrapper>
<Category>{formatCategory(data?.category)}</Category>
<Title>{data?.title}</Title>
</ChallengeTitleWrapper>

{data && (
<ChallengeTitle
category={formatCategory(data.category)}
title={data.title}
/>
)}
<Tabs selectedTab={activeTab} onChange={handleSelectedTab}>
{tabsList.map((t, index) => (
<Tab key={t.label} label={t.label} value={index} />
Expand Down Expand Up @@ -140,20 +141,3 @@ export const StyledDefaultImage = styled.img`
object-fit: cover;
opacity: 50%;
`;

export const ChallengeTitleWrapper = styled.div`
margin: 16px;
display: flex;
flex-direction: column;
text-align: left;
`;

export const Category = styled.div`
font-size: var(--font-size-xs);
color: var(--color-green-01);
`;

export const Title = styled.div`
font-size: var(--font-size-xl);
font-weight: bold;
`;
Loading

0 comments on commit e6fbf50

Please sign in to comment.