Skip to content

Commit 467b2f2

Browse files
authored
Merge pull request #63 from gummmmmy0v0/feature/#62
[post / send page] 단순 변경 사항 및 오류 수정
2 parents 88ef5d1 + ca0a87e commit 467b2f2

File tree

4 files changed

+92
-107
lines changed

4 files changed

+92
-107
lines changed

index.html

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,16 @@
1111
crossorigin
1212
href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
1313
/>
14-
<link
15-
rel="stylesheet"
16-
href="https://unpkg.com/[email protected]/dist/quill.snow.css"
17-
/>
1814
<link rel="preconnect" href="https://fonts.googleapis.com" />
1915
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
2016
<link
2117
href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap"
2218
rel="stylesheet"
2319
/>
24-
<link rel="preconnect" href="https://fonts.googleapis.com" />
25-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
2620
<link
2721
href="https://fonts.googleapis.com/css2?family=Nanum+Gothic&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap"
2822
rel="stylesheet"
2923
/>
30-
<link rel="preconnect" href="https://fonts.googleapis.com" />
31-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
3224
<link
3325
href="https://fonts.googleapis.com/css2?family=Edu+SA+Hand:[email protected]&family=Nanum+Gothic&family=Nanum+Pen+Script&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap"
3426
rel="stylesheet"

src/components/option/background-select.jsx

Lines changed: 36 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,26 @@ const OptionItem = styled.div`
2020
height: 168px;
2121
border-radius: 8px;
2222
cursor: pointer;
23-
background-color: ${({ type, color }) => (type === "color" ? color : "none")};
23+
position: relative;
24+
`;
25+
26+
const CheckedIcon = styled.img`
27+
background-color: ${Colors.gray(500)};
28+
box-shadow: none;
29+
border-radius: 50%;
30+
position: absolute;
31+
top: 50%;
32+
left: 50%;
33+
transform: translate(-50%, -50%);
34+
padding: 5px;
35+
}
36+
`;
37+
38+
const BackgroundOverlay = styled.div`
39+
height: 100%;
40+
border-radius: 8px;
41+
background-color: ${({ type, color }) =>
42+
type === "color" ? color : "transparent"};
2443
background-image: ${({ type, url }) =>
2544
type === "image" ? `url(${url})` : "none"};
2645
background-position: center;
@@ -29,20 +48,8 @@ const OptionItem = styled.div`
2948
opacity: ${({ selected }) => (selected ? 0.3 : 1)};
3049
`;
3150

32-
const CircleButtonWrapper = styled.div`
33-
height: 100%;
34-
overflow: hidden;
35-
display: flex;
36-
justify-content: center;
37-
align-items: center;
38-
39-
& > button {
40-
border-radius: 50%;
41-
}
42-
`;
43-
4451
function BackgroundSelect({ type, selected, onSelect }) {
45-
const [imageUrls, setImageUrls] = useState([]);
52+
const [backgroundUrls, setBackgroundUrls] = useState([]);
4653

4754
const colorOptions = [
4855
{ color: BACKGROUND_COLOR.beige },
@@ -51,62 +58,34 @@ function BackgroundSelect({ type, selected, onSelect }) {
5158
{ color: BACKGROUND_COLOR.green },
5259
];
5360

54-
/* useEffect(() => {
55-
if (type !== "image") return;
56-
57-
const BackgroundImageUrls = async () => {
58-
try {
59-
const response = await fetch(
60-
"https://rolling-api.vercel.app/background-images"
61-
);
62-
const data = await response.json();
63-
setImageUrls(data.imageUrls || []);
64-
} catch (error) {
65-
console.error(error);
66-
setImageUrls([]);
67-
}
68-
};
69-
BackgroundImageUrls();
70-
}, [type]); */
71-
72-
// 이미지 옵션 테스트 코드
7361
useEffect(() => {
7462
if (type !== "image") return;
7563

76-
const testImages = [
77-
"https://i.pinimg.com/280x280_RS/44/d2/b0/44d2b0b9e08cf1f05b7215356925a146.jpg",
78-
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTPe2BEhk6RfeibdWPG-1Iac78Tk1bdO1Rtqg&s",
79-
"https://center.exm.co.kr/data/goodsimg/phob/l/0018/027/18027744/61709_1661145612.jpg",
80-
"https://i.pinimg.com/736x/35/4e/03/354e03cd79702063da7353ffea0c8f8b.jpg",
64+
const imageUrls = [
65+
"https://picsum.photos/id/683/3840/2160",
66+
"https://picsum.photos/id/24/3840/2160",
67+
"https://picsum.photos/id/599/3840/2160",
68+
"https://picsum.photos/id/1058/3840/2160",
8169
];
82-
setImageUrls(testImages || []);
70+
setBackgroundUrls(imageUrls || []);
8371
}, [type]);
8472

8573
const options =
8674
type === "color"
8775
? colorOptions
88-
: imageUrls.map((url, index) => ({ label: `${index}`, url }));
76+
: backgroundUrls.map((url, index) => ({ label: `${index}`, url }));
8977

9078
return (
9179
<BackgroundWrapper>
9280
{options.map((option, index) => (
93-
<OptionItem
94-
key={index}
95-
type={type}
96-
color={option.color}
97-
url={option.url}
98-
onClick={() => onSelect(index)}
99-
selected={selected === index}
100-
>
101-
{selected === index && (
102-
<CircleButtonWrapper>
103-
<OutlinedButton
104-
size={BUTTON_SIZE.extraSmall}
105-
icon={CheckImage}
106-
style={{ backgroundColor: Colors.gray(500), boxShadow: "none" }}
107-
/>
108-
</CircleButtonWrapper>
109-
)}
81+
<OptionItem key={index} onClick={() => onSelect(index)}>
82+
<BackgroundOverlay
83+
type={type}
84+
color={option.color}
85+
url={option.url}
86+
selected={selected === index}
87+
/>
88+
{selected === index && <CheckedIcon src={CheckImage} />}
11089
</OptionItem>
11190
))}
11291
</BackgroundWrapper>

src/pages/create-post-page.jsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ function CreatePostPage() {
6060
setNameError(""); // 값 입력 중 에러 없애기
6161
};
6262

63+
const trimmed = name.trim();
64+
6365
const handleBlur = () => {
64-
const trimmed = name.trim();
66+
setName(trimmed);
6567
if (trimmed === "") {
66-
setNameError("값을 입력해 주세요");
67-
} else if (trimmed !== name) {
68-
setNameError("앞 뒤 공백 없이 입력해 주세요"); // 텍스트 앞 뒤 공백 에러 처리(임시)
68+
setNameError("이름을 입력해 주세요");
6969
}
7070
};
7171

@@ -83,7 +83,7 @@ function CreatePostPage() {
8383
navigate(`/post/${randomID}`);
8484
};
8585

86-
const canCreate = name.trim() !== "";
86+
const canCreate = trimmed !== "";
8787

8888
return (
8989
<PostContainer>

src/pages/send-message-page.jsx

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@ const AvatarOption = styled.div`
5353

5454
const AvatarPreview = styled.div`
5555
cursor: pointer;
56-
`;
57-
58-
const DefaultAvatar = styled.div`
59-
cursor: pointer;
56+
box-shadow: ${({ $isSelected }) =>
57+
$isSelected ? `0 0 0 2px ${Colors.purple(600)}` : "none"};
58+
border-radius: 50%;
6059
`;
6160

6261
const ButtonWrapper = styled.div`
@@ -69,13 +68,20 @@ const CreateButton = styled(PrimaryButton)`
6968
width: 100%;
7069
`;
7170

71+
const TextFieldStyle = styled(TextField)`
72+
width: 50%;
73+
`;
74+
7275
function SendMessagePage() {
7376
const [name, setName] = useState("");
7477
const [nameError, setNameError] = useState("");
7578
const [relationOption, setRelationOption] = useState("지인");
7679
const [selectedAvatar, setSelectedAvatar] = useState(null);
7780
const [content, setContent] = useState("I am your reach text editor.");
78-
const [fontOption, setFontOption] = useState("Noto Sans");
81+
const [selectedFont, setSelectedFont] = useState({
82+
title: "Noto Sans",
83+
fontFamily: "Noto Sans",
84+
});
7985
const navigate = useNavigate();
8086

8187
const handleChange = (e) => {
@@ -88,33 +94,43 @@ function SendMessagePage() {
8894
}
8995
};
9096

97+
const trimmed = name.trim();
98+
9199
const handleBlur = () => {
92-
if (name.trim() === "") {
93-
setNameError("값을 입력해 주세요");
94-
} else if (name !== name.trim()) {
95-
setNameError("공백 없이 입력해 주세요"); // 텍스트 앞 뒤 공백 에러 처리(임시)
100+
setName(trimmed);
101+
if (trimmed === "") {
102+
setNameError("이름을 입력해 주세요");
96103
}
97104
};
98105

99106
const avatarList = [
100-
"https://i.pinimg.com/236x/49/86/62/4986627b45cecd1a5c4330bda777c2bf.jpg",
101-
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRok3sjZOWtm7o5kFf0BdW0w7IUHI1oAlC-Z6RCKAiCvvCExG_qq7qMzPOQlEzfknS3B3U&usqp=CAU",
102-
"https://i.pinimg.com/236x/20/d1/6f/20d16f236500e8daa315a298a8586193.jpg",
103-
"https://i.pinimg.com/474x/28/6c/fd/286cfdcdaeaf2768d4b285a226c33a02.jpg",
104-
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRvxR-Twic2lXwfF87JweyQ81vrGDUgn7zzYj60N-wD21DwS4JzOc0BLhzaOuUt4PGfLcI&usqp=CAU",
105-
"https://i.pinimg.com/236x/74/68/89/7468894ce7592357a3514dbb8dc5f181.jpg",
106-
"https://mblogthumb-phinf.pstatic.net/MjAyMTA5MDNfMjE1/MDAxNjMwNTk5NjE4NTc5.b-OgHjcav5kz8kt_9Cr2u1Z_eJYmKY_H9Ii9mOnwo74g.r0G6iGYg-oQMLnTymwyrjDlOMGLEnWGYJXefCSy2ixwg.JPEG.gmlwjd5363/FB_IMG_1630599533529.jpg?type=w800",
107-
"https://mblogthumb-phinf.pstatic.net/MjAyMTA5MDNfMTIy/MDAxNjMwNTk5NjE5MDA5.w_wMeYmMF2kOhDAVXXxe0JgVqJhtGd0EuR0b2D2k3S0g.Nds6Oxagjks2DjjwFz5yWyjCGcEOL1iS84XqhAQw3wUg.JPEG.gmlwjd5363/FB_IMG_1630599535069.jpg?type=w800",
108-
"https://mblogthumb-phinf.pstatic.net/MjAyMTA5MDNfNDQg/MDAxNjMwNTk5NjE5MzQ4.J4lhtJZRKMzEXj0HjrG1aH65qIcBv9GI1LdVQsWlC-Ug.10QCNt81CdbIyBkd1bFOAOAolDL6hxYXrb9dXgmS8zQg.JPEG.gmlwjd5363/FB_IMG_1630599536666.jpg?type=w800",
109-
"https://mblogthumb-phinf.pstatic.net/MjAyMTA5MDNfMzAg/MDAxNjMwNTk5NjE5ODI2.cmwNyDHTza4N64bhN0rIRu2KaFHUxqv0BkuaX6GBHJ0g.ufZqe7x1GLrCLJg2zb6N_nJ_fTgFPXq09TTe_fhsMiog.JPEG.gmlwjd5363/FB_IMG_1630599538261.jpg?type=w800",
107+
"https://learn-codeit-kr-static.s3.ap-northeast-2.amazonaws.com/sprint-proj-image/default_avatar.png",
108+
"https://picsum.photos/id/522/100/100",
109+
"https://picsum.photos/id/547/100/100",
110+
"https://picsum.photos/id/268/100/100",
111+
"https://picsum.photos/id/1082/100/100",
112+
"https://picsum.photos/id/571/100/100",
113+
"https://picsum.photos/id/494/100/100",
114+
"https://picsum.photos/id/859/100/100",
115+
"https://picsum.photos/id/437/100/100",
116+
"https://picsum.photos/id/1064/100/100",
110117
];
111118

112119
const handleCreate = () => {
113120
const randomID = Math.floor(Math.random() * 10000);
114121
navigate(`/post/${randomID}`);
115122
};
116123

117-
const canCreate = name.trim() !== "";
124+
const canCreate =
125+
trimmed !== "" && content.replace(/<[^>]+>/g, "").trim() !== "";
126+
// 정규식 유효성 검사로 html 태그 찾기("<"로 시작해서 ">"로 끝나는 문자 중 > 를 제외한(^ not) 모든 문자 제외)
127+
128+
const fontOptions = [
129+
{ title: "Noto Sans", fontFamily: "Noto Sans" },
130+
{ title: "Pretendard", fontFamily: "Pretendard" },
131+
{ title: "나눔고딕", fontFamily: "Nanum Ghthic" },
132+
{ title: "나눔손글씨 펜체", fontFamily: "Nanum Pen Script" },
133+
];
118134

119135
return (
120136
<SendContainer>
@@ -132,11 +148,7 @@ function SendMessagePage() {
132148
<Wrapper>
133149
<SendTitle>프로필 이미지</SendTitle>
134150
<AvatarWrapper>
135-
<DefaultAvatar
136-
onClick={() => setSelectedAvatar((prev) => (prev ? null : prev))} // 아바타 선택 상태에서 재클릭 시 기본 아바타로
137-
>
138-
<Avatar size={AVATAR_SIZE.large} source={selectedAvatar} />
139-
</DefaultAvatar>
151+
<Avatar size={AVATAR_SIZE.large} source={selectedAvatar} />
140152
<AvatarOptionWrapper>
141153
<AvatarDescription>
142154
프로필 이미지를 선택해 주세요!
@@ -145,6 +157,7 @@ function SendMessagePage() {
145157
{avatarList.map((url, index) => (
146158
<AvatarPreview
147159
key={index}
160+
$isSelected={selectedAvatar === url}
148161
onClick={() => setSelectedAvatar(url)}
149162
>
150163
<Avatar size={AVATAR_SIZE.medium} source={url} />
@@ -156,7 +169,7 @@ function SendMessagePage() {
156169
</Wrapper>
157170
<Wrapper>
158171
<SendTitle>상대와의 관계</SendTitle>
159-
<TextField
172+
<TextFieldStyle
160173
type={TEXT_FIELD_TYPE.dropdown}
161174
dropdownId="realtionship-dropdown"
162175
placeholder={relationOption}
@@ -176,24 +189,25 @@ function SendMessagePage() {
176189
}}
177190
value={content}
178191
onChange={(value) => setContent(value)}
179-
font={fontOption}
192+
font={selectedFont.fontFamily}
180193
/>
181194
</div>
182195
</Wrapper>
183196
<Wrapper>
184197
<SendTitle>폰트 선택</SendTitle>
185-
<TextField
198+
<TextFieldStyle
186199
type={TEXT_FIELD_TYPE.dropdown}
187200
dropdownId="font-option-dropdown"
188-
placeholder={fontOption}
189-
value={fontOption}
190-
options={[
191-
"Noto Sans",
192-
"Pretendard",
193-
"Nanum Gothic",
194-
"Nanum Pen Script",
195-
]}
196-
onSelect={setFontOption}
201+
placeholder={selectedFont.title}
202+
value={selectedFont.title}
203+
options={fontOptions}
204+
onSelect={(selectedFontOption) => {
205+
const selected = fontOptions.find(
206+
(fontOption) => fontOption.title === selectedFontOption
207+
);
208+
setSelectedFont(selected);
209+
}}
210+
style={{ fontFamily: selectedFont.fontFamily }}
197211
/>
198212
</Wrapper>
199213
<ButtonWrapper>

0 commit comments

Comments
 (0)