Skip to content

Commit dac5e62

Browse files
authored
[FE] 코드잽 프로덕션 v1.1.5 배포
[FE] 코드잽 프로덕션 v1.1.5 배포
2 parents 5800317 + 421ecbc commit dac5e62

File tree

70 files changed

+1098
-187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1098
-187
lines changed

frontend/package-lock.json

Lines changed: 88 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "code-zap",
3-
"version": "1.1.4",
3+
"version": "1.1.5",
44
"description": "",
55
"main": "index.js",
66
"scripts": {
@@ -22,6 +22,7 @@
2222
],
2323
"license": "ISC",
2424
"dependencies": {
25+
"@amplitude/analytics-browser": "^2.11.7",
2526
"@emotion/react": "^11.11.4",
2627
"@emotion/styled": "^11.11.5",
2728
"@sentry/react": "^8.22.0",

frontend/src/api/categories.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ import type {
99
CustomError,
1010
Category,
1111
} from '@/types';
12-
import { MemberInfo } from '@/types';
1312

1413
import { customFetch } from './customFetch';
1514

1615
const API_URL = process.env.REACT_APP_API_URL ?? '';
1716

1817
export const CATEGORY_API_URL = `${API_URL}${END_POINTS.CATEGORIES}`;
1918

20-
export const getCategoryList = async ({ memberId }: Pick<MemberInfo, 'memberId'>) => {
19+
export const getCategoryList = async (memberId: number) => {
2120
const url = `${CATEGORY_API_URL}?memberId=${memberId}`;
2221

2322
const response = await customFetch<CategoryListResponse>({

frontend/src/api/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ export {
2727
checkName,
2828
} from './authentication';
2929
export { LIKE_API_URL, postLike, deleteLike } from './like';
30+
export { getMemberName } from './members';

frontend/src/api/members.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { END_POINTS } from '@/routes';
2+
import { GetMemberNameResponse } from '@/types';
3+
4+
import { customFetch } from './customFetch';
5+
6+
const API_URL = process.env.REACT_APP_API_URL;
7+
8+
export const MEMBER_API_URL = `${API_URL}${END_POINTS.MEMBERS}`;
9+
10+
export const getMemberName = async (memberId: number) => {
11+
const url = `${MEMBER_API_URL}/${memberId}/name`;
12+
13+
const response = await customFetch<GetMemberNameResponse>({
14+
url,
15+
});
16+
17+
if ('name' in response) {
18+
return response;
19+
}
20+
21+
throw new Error(response.detail);
22+
};

frontend/src/api/queryKeys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const QUERY_KEY = {
22
CATEGORY_LIST: 'categoryList',
33
CHECK_NAME: 'checkName',
44
LOGIN_STATE: 'loginState',
5+
MEMBER_NAME: 'memberName',
56
TAG_LIST: 'tagList',
67
TEMPLATE: 'template',
78
TEMPLATE_LIST: 'templateList',

frontend/src/api/tags.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { END_POINTS } from '@/routes';
2-
import { MemberInfo } from '@/types';
32
import { TagListResponse } from '@/types/api';
43

54
import { customFetch } from './customFetch';
@@ -8,7 +7,7 @@ const API_URL = process.env.REACT_APP_API_URL ?? '';
87

98
export const TAG_API_URL = `${API_URL}${END_POINTS.TAGS}`;
109

11-
export const getTagList = async ({ memberId }: Pick<MemberInfo, 'memberId'>) => {
10+
export const getTagList = async (memberId: number) => {
1211
const url = `${TAG_API_URL}?memberId=${memberId}`;
1312

1413
const response = await customFetch<TagListResponse>({

frontend/src/api/templates.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const getTemplateExplore = async ({
8484
page = 1,
8585
size = PAGE_SIZE,
8686
keyword,
87+
tagIds,
8788
}: TemplateListRequest): Promise<TemplateListResponse> => {
8889
const queryParams = new URLSearchParams({
8990
sort,
@@ -95,6 +96,10 @@ export const getTemplateExplore = async ({
9596
queryParams.append('keyword', keyword);
9697
}
9798

99+
if (tagIds?.length !== 0 && tagIds !== undefined) {
100+
queryParams.append('tagIds', tagIds.toString());
101+
}
102+
98103
const response = await apiClient.get(`${END_POINTS.TEMPLATES_EXPLORE}?${queryParams.toString()}`);
99104
const data = response.json();
100105

frontend/src/assets/images/clock.svg

Lines changed: 1 addition & 1 deletion
Loading

frontend/src/assets/images/person.svg

Lines changed: 1 addition & 1 deletion
Loading

frontend/src/components/ContactUs/ContactUs.style.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ export const Form = styled.form`
99
flex-direction: column;
1010
gap: 1.25rem;
1111
`;
12+
13+
export const LoadingContainer = styled.div`
14+
width: 4.5rem;
15+
`;

frontend/src/components/ContactUs/ContactUs.tsx

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import { useState } from 'react';
2+
13
import { useInput, useInputWithValidate, useToggle } from '@/hooks';
4+
import { useAuth } from '@/hooks/authentication';
25
import { useToast } from '@/hooks/useToast';
36
import { validateEmail } from '@/service/validates';
47
import { theme } from '@/style/theme';
58

6-
import { Button, Input, Modal, Text, Textarea } from '..';
9+
import { Button, Input, LoadingBall, Modal, Text, Textarea } from '..';
710
import * as S from './ContactUs.style';
811

912
const ContactUs = () => {
1013
const [isModalOpen, toggleModal] = useToggle();
14+
const [isSending, setIsSending] = useState(false);
1115
const [message, handleMessage, resetMessage] = useInput('');
1216
const {
1317
value: email,
@@ -16,7 +20,11 @@ const ContactUs = () => {
1620
errorMessage: emailErrorMessage,
1721
} = useInputWithValidate('', validateEmail);
1822

19-
const { failAlert, successAlert } = useToast();
23+
const {
24+
memberInfo: { name, memberId },
25+
} = useAuth();
26+
27+
const { successAlert } = useToast();
2028

2129
const isValidContents = message.trim().length !== 0;
2230

@@ -31,16 +39,15 @@ const ContactUs = () => {
3139
};
3240

3341
const submitForm = async () => {
34-
const res = await sendData();
42+
setIsSending(true);
43+
toggleModal();
3544

36-
if (!res.ok) {
37-
failAlert('보내기에 실패했습니다. 계속 실패한다면 이메일로 제보 부탁드립니다.');
45+
const res = await sendData();
3846

39-
return;
47+
if (res) {
48+
successSubmit();
49+
successAlert('보내기 완료! 소중한 의견 감사합니다:)');
4050
}
41-
42-
successSubmit();
43-
successAlert('보내기 완료! 소중한 의견 감사합니다:)');
4451
};
4552

4653
const sendData = () => {
@@ -49,16 +56,16 @@ const ContactUs = () => {
4956
return fetch(URL, {
5057
method: 'POST',
5158
mode: 'no-cors',
52-
body: JSON.stringify({ message, email }),
59+
body: JSON.stringify({ message, email, name, memberId }),
5360
headers: {
5461
'Content-Type': 'application/json',
5562
},
5663
});
5764
};
5865

5966
const successSubmit = () => {
67+
setIsSending(false);
6068
resetForm();
61-
toggleModal();
6269
};
6370

6471
const resetForm = () => {
@@ -73,6 +80,7 @@ const ContactUs = () => {
7380
문의하기
7481
</Text.Medium>
7582
</S.ContactUSButton>
83+
7684
<Modal isOpen={isModalOpen} toggleModal={toggleModal} size='large'>
7785
<Modal.Header>문의하기</Modal.Header>
7886
<Modal.Body>
@@ -83,14 +91,20 @@ const ContactUs = () => {
8391
</Text.Medium>
8492
<Textarea id='voc' variant='outlined'>
8593
<Textarea.Label htmlFor={'voc'}>무엇을 도와드릴까요?</Textarea.Label>
86-
<Textarea.TextField minRows={5} maxRows={10} value={message} onChange={handleMessage} />
94+
<Textarea.TextField
95+
minRows={5}
96+
maxRows={10}
97+
value={message}
98+
onChange={handleMessage}
99+
disabled={isSending}
100+
/>
87101
</Textarea>
88102
<Text.Medium as='p' color={theme.color.light.secondary_500}>
89103
답변이 필요하시면 아래 이메일 주소를 남겨주세요. 이메일은 오직 답변을 위해서만 사용됩니다 :)
90104
</Text.Medium>
91105
<Input variant='outlined' isValid={!emailErrorMessage}>
92106
<Input.Label>이메일 (선택)</Input.Label>
93-
<Input.TextField value={email} onChange={handleEmail} />
107+
<Input.TextField value={email} onChange={handleEmail} disabled={isSending} />
94108
<Input.HelperText>{emailErrorMessage}</Input.HelperText>
95109
</Input>
96110
</S.Form>
@@ -99,9 +113,15 @@ const ContactUs = () => {
99113
<Button onClick={toggleModal} variant='outlined'>
100114
닫기
101115
</Button>
102-
<Button disabled={isValidContents && !emailErrorMessage ? false : true} onClick={handleSubmit}>
103-
보내기
104-
</Button>
116+
{isSending ? (
117+
<S.LoadingContainer>
118+
<LoadingBall />
119+
</S.LoadingContainer>
120+
) : (
121+
<Button disabled={isValidContents && !emailErrorMessage ? false : true} onClick={handleSubmit}>
122+
보내기
123+
</Button>
124+
)}
105125
</Modal.Footer>
106126
</Modal>
107127
</>

frontend/src/components/Footer/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ContactUs, Text } from '@/components';
1+
import { Text } from '@/components';
22
import { useAuth } from '@/hooks/authentication';
33

44
import * as S from './Footer.style';
@@ -20,7 +20,7 @@ const Footer = () => {
2020
© All rights reserved.
2121
</Text.Small>
2222
<S.ContactEmail>
23-
<ContactUs />
23+
<Text.Small color='inherit'>문의: [email protected]</Text.Small>
2424
</S.ContactEmail>
2525
</S.FooterContainer>
2626
);

0 commit comments

Comments
 (0)