Skip to content

Commit 8022a06

Browse files
authored
Merge pull request #23 from NyangGleNyangGle/develop
[Develop] 12월 8일 Update
2 parents 4c1c1b8 + 4e05624 commit 8022a06

25 files changed

Lines changed: 567 additions & 298 deletions

public/assets/font/KOTRA_HOPE.ttf

6.35 MB
Binary file not shown.

public/assets/font/font.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@
1212
url('./EF_jejudoldam.eot?iefix') format('embedded-opentype'),
1313
url('./EF_jejudoldam.woff') format('woff');
1414
}
15+
16+
@font-face {
17+
font-family: 'kotra';
18+
font-display: fallback;
19+
src: url('./KOTRA_HOPE.ttf');
20+
}
2.03 KB
Loading

src/GlobalStyle.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const GlobalStyle = createGlobalStyle`
1616
body {
1717
background-color: #f9f9f9;
1818
19-
font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
19+
font-family:"Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
2020
}
2121
2222
a {

src/atoms/fishBreadList.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,14 @@ export const tapIndexState = atom({
2323
key: 'tapIndexState',
2424
default: 0,
2525
});
26+
27+
export const alertState = atom({
28+
key: 'alertState',
29+
default: false,
30+
});
31+
32+
export const currentIndexState = atom({
33+
key: 'currentIndexState',
34+
default: 0,
35+
});
36+
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import styled, { css } from 'styled-components';
2+
import {
3+
modalState,
4+
readingDataList,
5+
idState,
6+
alertState,
7+
dataList,
8+
} from '../../../atoms/fishBreadList';
9+
import { useRecoilValue, useSetRecoilState, useRecoilState } from 'recoil';
10+
import { deleteBread } from '../../../utils/fetchBreadDetail';
11+
12+
function DetailAlert() {
13+
const [breadList, setBreadList] = useRecoilState(dataList);
14+
const [readingData, setReadingData] = useRecoilState(readingDataList);
15+
const readingid = useRecoilValue(idState);
16+
const setIsOpened = useSetRecoilState(modalState);
17+
const setIsAlertOpened = useSetRecoilState(alertState);
18+
19+
const onClickWrapper = () => setIsAlertOpened(false);
20+
const onClickCancel = () => setIsAlertOpened(false);
21+
const onClickDelete = () => {
22+
const filterReadingData = [...readingData].filter((e) => e.id !== readingid);
23+
setReadingData(filterReadingData);
24+
const { token } = JSON.parse(localStorage.getItem('user'));
25+
const filterBread = [...breadList].flat().filter((e) => e.fishId !== readingid);
26+
const filterList = [];
27+
for (let i = 0; i < filterBread.length; i += 9) {
28+
filterList.push(filterBread.slice(i, i + 9));
29+
}
30+
setBreadList(filterList);
31+
deleteBread(readingid, token);
32+
setIsAlertOpened(false);
33+
setIsOpened(false);
34+
};
35+
36+
return (
37+
<Wrapper>
38+
<ModalBackground onClick={onClickWrapper} />
39+
<AlertContainer>
40+
<h5>편지를 삭제할거냥?</h5>
41+
<p>삭제한 편지는 복구할 수 없다냥</p>
42+
<BtnWrapper>
43+
<Button onClick={onClickCancel}>취소</Button>
44+
<Button btnType="delete" onClick={onClickDelete}>
45+
삭제
46+
</Button>
47+
</BtnWrapper>
48+
</AlertContainer>
49+
</Wrapper>
50+
);
51+
}
52+
53+
export default DetailAlert;
54+
55+
const Wrapper = styled.div`
56+
position: absolute;
57+
top: 0;
58+
left: 0;
59+
width: 100%;
60+
height: 100%;
61+
display: flex;
62+
justify-content: center;
63+
align-items: center;
64+
z-index: 3;
65+
`;
66+
67+
const ModalBackground = styled.div`
68+
position: absolute;
69+
top: 0;
70+
left: 0;
71+
width: 100%;
72+
height: 100%;
73+
background-color: rgba(0, 0, 0, 0.5);
74+
`;
75+
76+
const AlertContainer = styled.div`
77+
width: calc(100% - 26px);
78+
max-width: 742px;
79+
height: 220px;
80+
background-color: #fff;
81+
z-index: 4;
82+
border: 2px solid #000000;
83+
border-radius: 10px;
84+
font-family: 'kotra';
85+
display: flex;
86+
flex-direction: column;
87+
justify-content: center;
88+
align-items: center;
89+
90+
h5 {
91+
font-size: 26px;
92+
font-weight: 500;
93+
color: #a54e09;
94+
margin-bottom: 6px;
95+
}
96+
97+
p {
98+
font-size: 20px;
99+
color: #989898;
100+
line-height: 33px;
101+
margin-bottom: 38px;
102+
}
103+
`;
104+
105+
const BtnWrapper = styled.div`
106+
width: calc(100% - 68px);
107+
display: flex;
108+
justify-content: space-between;
109+
gap: 40px;
110+
`;
111+
112+
const Button = styled.div`
113+
display: flex;
114+
justify-content: center;
115+
align-items: center;
116+
width: 100%;
117+
height: 40px;
118+
font-size: 22px;
119+
color: #000;
120+
121+
${({ btnType }) =>
122+
btnType === 'delete' &&
123+
css`
124+
color: #a54e09;
125+
`}
126+
`;

src/components/breadDetail/DetailModal.jsx renamed to src/components/breadDetail/detail/DetailModal.jsx

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import styled, { css } from 'styled-components';
2-
import { useRecoilValue, useSetRecoilState } from 'recoil';
3-
import { modalState, readingDataList, idState } from '../../atoms/fishBreadList';
2+
import { useRecoilValue, useSetRecoilState, useRecoilState } from 'recoil';
3+
import { modalState, readingDataList, idState, alertState } from '../../../atoms/fishBreadList';
44
import { useEffect, useState } from 'react';
5+
import DetailAlert from './DetailAlert';
56

6-
const TypeObj = {
7+
const typeObj = {
78
밀가루: '1',
89
고구마: '2',
910
녹차: '3',
@@ -14,28 +15,32 @@ function DetailModal() {
1415
const setIsOpened = useSetRecoilState(modalState);
1516
const readingId = useRecoilValue(idState);
1617
const data = useRecoilValue(readingDataList);
18+
const [isAlertOpend, setIsAlertOpened] = useRecoilState(alertState);
1719
const [backSrc, setBackSrc] = useState('background1');
1820
const [letterSrc, setLetterSrc] = useState('letter1');
19-
const { Type, message, senderNickname } = data.find((e) => e.id === readingId);
21+
const { type, message, senderNickname } = data.find((e) => e.id === readingId);
22+
2023
const onClickClose = () => setIsOpened(false);
2124
const onClickWrapper = () => setIsOpened(false);
2225

23-
let [dough, sediment] = Type.split('/');
26+
let [dough, sediment] = type.split('/');
2427
const userData = JSON.parse(localStorage.getItem('user'));
2528
const { nickname } = userData ? userData : { nickname: '익명의냥냥이' };
2629

27-
const TypeReplace = () => {
28-
Object.keys(TypeObj).forEach((e) => {
29-
if (e === dough) dough = TypeObj[e];
30+
const replaceType = () => {
31+
Object.keys(typeObj).forEach((e) => {
32+
if (e === dough) dough = typeObj[e];
3033
});
3134
};
3235

3336
const setImageSrc = () => {
34-
TypeReplace();
37+
replaceType();
3538
setBackSrc(`background${dough}`);
3639
setLetterSrc(`letter${dough}`);
3740
};
3841

42+
const onClickDelete = () => setIsAlertOpened(true);
43+
3944
useEffect(() => {
4045
setImageSrc();
4146
});
@@ -50,12 +55,19 @@ function DetailModal() {
5055
<MessageContent>{message}</MessageContent>
5156
<MessageSender>{senderNickname}</MessageSender>
5257
</MessageWrapper>
53-
<ModalCloseButton onClick={onClickClose}>
54-
<ButtonContent>확인 완료</ButtonContent>
55-
<ButtonBack />
56-
</ModalCloseButton>
58+
<ButtonWrapper>
59+
<ModalCloseButton onClick={onClickDelete}>
60+
<ButtonContent type="delete">삭제</ButtonContent>
61+
<ButtonBack type="delete" />
62+
</ModalCloseButton>
63+
<ModalCloseButton onClick={onClickClose}>
64+
<ButtonContent>확인</ButtonContent>
65+
<ButtonBack />
66+
</ModalCloseButton>
67+
</ButtonWrapper>
5768
</ModalContent>
5869
</ModalContainer>
70+
{isAlertOpend && <DetailAlert />}
5971
</ModalWrapper>
6072
);
6173
}
@@ -66,7 +78,7 @@ const ModalWrapper = styled.div`
6678
position: fixed;
6779
top: 0;
6880
left: 0;
69-
width: 100vh;
81+
width: 100%;
7082
height: 100%;
7183
display: flex;
7284
justify-content: center;
@@ -108,7 +120,7 @@ const ModalContent = styled.div`
108120
`;
109121

110122
const MessageWrapper = styled.div`
111-
font-family: 'Room703';
123+
font-family: 'kotra';
112124
font-weight: 400;
113125
font-size: 22px;
114126
position: relative;
@@ -154,14 +166,20 @@ const MessageSender = styled.div`
154166
`;
155167

156168
const ModalCloseButton = styled.div`
157-
width: calc(100% - 28px);
169+
width: 100%;
158170
margin: 30px 0;
159171
height: 60px;
160172
position: relative;
161173
162174
cursor: pointer;
163175
`;
164176

177+
const ButtonWrapper = styled.div`
178+
width: 100%;
179+
display: flex;
180+
gap: 10px;
181+
`;
182+
165183
const ButtonContent = styled.div`
166184
position: relative;
167185
z-index: 1;
@@ -175,6 +193,12 @@ const ButtonContent = styled.div`
175193
color: #fff;
176194
font-size: 20px;
177195
font-weight: 700;
196+
197+
${({ type }) =>
198+
type === 'delete' &&
199+
css`
200+
background-color: #c0c0c0;
201+
`}
178202
`;
179203

180204
const ButtonBack = styled.div`
@@ -185,4 +209,10 @@ const ButtonBack = styled.div`
185209
background-color: #813c05;
186210
border-radius: 10px;
187211
border: 2px solid #000;
212+
213+
${({ type }) =>
214+
type === 'delete' &&
215+
css`
216+
background-color: #989898;
217+
`}
188218
`;

src/components/breadDetail/list/DetailList.jsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { useNavigate, useParams } from 'react-router-dom';
33
import DetailListItems from './DetailListItems';
44
import DetailListTaps from './DetailListTaps';
55
import DetailListButtons from './DetailListButtons';
6-
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
7-
import { dataList, tapIndexState } from '../../../atoms/fishBreadList';
6+
import { useRecoilState, useSetRecoilState } from 'recoil';
7+
import { dataList, tapIndexState, currentIndexState } from '../../../atoms/fishBreadList';
88
import { getBreadListData } from '../../../utils/fetchBreadDetail';
99
import styled from 'styled-components';
1010

@@ -15,7 +15,7 @@ function DetailList() {
1515
const [lastId, setLastId] = useState(0);
1616
const [prevId, setPrevId] = useState(0);
1717
const [status, setStatus] = useState('All');
18-
const [currentIndex, setCurrentIndex] = useState(0);
18+
const [currentIndex, setCurrentIndex] = useRecoilState(currentIndexState);
1919
const [currentPage, setCurrentPage] = useState(1);
2020
const [callingType, setCallingType] = useState();
2121
const [isRefetch, setIsRefetch] = useState(false);
@@ -25,29 +25,34 @@ function DetailList() {
2525
const userData = JSON.parse(localStorage.getItem('user'));
2626
const { token } = userData ? userData : { token: null };
2727

28-
const getBreadList = useCallback(async () => {
28+
const getBreadList = useCallback(async (callingType, callStatus, lastId, prevId, currentPage) => {
2929
console.log('fetching...');
3030
if (token === null) return;
31-
const { data, callStatus } = await getBreadListData(
31+
const { data, status } = await getBreadListData(
3232
token,
3333
callingType,
34-
status,
34+
callStatus,
3535
lastId,
3636
prevId,
3737
currentPage,
3838
);
3939
const { content, totalPages, last, first } = data;
40-
if (callStatus === 200) {
41-
setLastId(content.at(-1).id);
42-
setPrevId(content[0].id);
40+
if (status === 200) {
41+
setLastId(content?.at(-1).fishId);
42+
setPrevId(content[0]?.fishId);
4343
const dataSet = [];
4444
const size = 9;
4545
for (let i = 0; i < content.length; i += size) {
4646
dataSet.push(content.slice(i, i + size));
4747
}
4848
setBreadList(dataSet);
4949
setPageData({ totalPages, last, first });
50-
setCurrentIndex(0);
50+
if(callingType !== 'Prev') {
51+
setCurrentIndex(0);
52+
} else {
53+
setCurrentIndex(dataSet.length - 1);
54+
}
55+
5156
}
5257
}, []);
5358

@@ -58,6 +63,7 @@ function DetailList() {
5863
const onClickTap = (type, index) => {
5964
if (type === status) return;
6065
setStatus(type);
66+
setCurrentPage(1);
6167
setIsRefetch((state) => !state);
6268
setTapIndex(index);
6369
};
@@ -90,7 +96,7 @@ function DetailList() {
9096
};
9197

9298
useEffect(() => {
93-
getBreadList();
99+
getBreadList(callingType, status, lastId, prevId, currentPage);
94100
}, [isRefetch]);
95101

96102
useEffect(() => {
@@ -103,11 +109,10 @@ function DetailList() {
103109
<TurnBack onClick={onClickLocation}>돌아가기</TurnBack>
104110
<DetailListTaps onClickTap={onClickTap} />
105111
<DetailLists>
106-
<DetailListItems currentIndex={currentIndex} token={token} />
112+
<DetailListItems token={token} />
107113
</DetailLists>
108114
{pageData && (
109115
<DetailListButtons
110-
currentIndex={currentIndex}
111116
pageData={pageData}
112117
onClickNext={onClickNext}
113118
onClickPrev={onClickPrev}

0 commit comments

Comments
 (0)