Skip to content

Commit 59776b6

Browse files
authored
๐ŸŽจstyle: ๋ฉ”์ธ ํŽ˜์ด์ง€ ๋ฐ ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜„ ๊ตฌํ˜„
๐ŸŽจstyle: ๋ฉ”์ธ ํŽ˜์ด์ง€ ๋ฐ ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ ๋ฐ˜์‘ํ˜„ ๊ตฌํ˜„
2 parents 107cd1c + e61f13d commit 59776b6

File tree

19 files changed

+246
-127
lines changed

19 files changed

+246
-127
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { api } from './api';
22

3-
export default async function fetchProfileImages() {
3+
export default async function getProfileImages() {
44
try {
55
const res = await api.get('/profile-images/');
66
return res.data.imageUrls;
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export default async function createMessage({
99
content,
1010
font,
1111
}) {
12-
const res = await api.post(`/${team}/recipients/${recipientId}/messages/`, {
12+
const teamId = import.meta.env.VITE_TEAM_ID;
13+
const res = await api.post(`/${teamId}/recipients/${recipientId}/messages/`, {
1314
team,
1415
recipientId,
1516
sender,

โ€Žsrc/assets/images/logo.svgโ€Ž

Lines changed: 3 additions & 0 deletions
Loading

โ€Žsrc/components/Editor/Editor.jsxโ€Ž

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { useMemo, useEffect } from 'react';
1+
import { useMemo, useEffect, useRef } from 'react';
22
import ReactQuill from 'react-quill';
33
import 'react-quill/dist/quill.snow.css';
4-
import styled from './Editor.module.scss';
4+
import styles from './Editor.module.scss';
55

66
const formats = [
77
'bold',
@@ -21,40 +21,49 @@ const fontFamilyMap = {
2121
'Noto Sans': '"Noto Sans", sans-serif',
2222
};
2323

24-
export default function Editor({ value, onChange, font }) {
24+
export default function Editor({ value, onChange, font, onBlur, isError }) {
25+
const quillRef = useRef();
26+
2527
const modules = useMemo(() => {
2628
return {
2729
toolbar: [
2830
['bold', 'italic', 'underline'],
2931
[{ align: [] }],
32+
[{ color: [] }, { background: [] }],
3033
[{ list: 'ordered' }, { list: 'bullet' }],
3134
['link'],
32-
[{ color: [] }, { background: [] }],
3335
],
3436
};
3537
}, []);
3638

3739
useEffect(() => {
38-
const editorElement = document.querySelector('.ql-editor');
39-
if (editorElement) {
40-
editorElement.style.fontFamily = fontFamilyMap[font];
41-
editorElement.style.fontSize = '18px';
40+
const editorRoot = quillRef.current?.editor?.root;
41+
if (editorRoot) {
42+
editorRoot.style.fontFamily = fontFamilyMap[font];
43+
editorRoot.style.fontSize = '18px';
4244
}
4345
}, [font]);
4446

4547
return (
46-
<div className={styled['editor']}>
47-
<h2 className={styled['editor__title']}>๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”</h2>
48+
<div className={styles['editor']}>
49+
<h2 className={styles['editor__title']}>๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”</h2>
4850

49-
<div className={styled['editor__box']}>
51+
<div
52+
className={`${styles['editor__box']} ${isError ? styles['editor__box--error'] : ''}`}
53+
>
5054
<ReactQuill
55+
ref={quillRef}
5156
theme="snow"
5257
modules={modules}
5358
formats={formats}
5459
value={value}
5560
onChange={onChange}
61+
onBlur={onBlur}
5662
placeholder="์ „ํ•˜๊ณ  ์‹ถ์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ ์–ด๋ณด์„ธ์š”."
5763
/>
64+
{isError && (
65+
<p className={styles['editor__error-message']}>๊ฐ’์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.</p>
66+
)}
5867
</div>
5968
</div>
6069
);

โ€Žsrc/components/Editor/Editor.module.scssโ€Ž

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,27 @@
33
.editor {
44
display: flex;
55
flex-direction: column;
6-
width: 72rem;
7-
height: 30.8rem;
6+
max-width: 720px;
7+
min-width: 320px;
8+
width: 100%;
89
gap: 12px;
910

1011
&__box {
1112
height: 260px;
13+
margin-bottom: 4px;
1214
border: 1px solid $gray-300;
1315
border-radius: 8px;
16+
17+
&--error {
18+
border: 1px solid $error;
19+
color: $gray-900;
20+
}
1421
}
1522

1623
:global(.ql-toolbar) {
24+
display: flex;
25+
align-items: center;
26+
height: 49px;
1727
border: none;
1828
border-bottom: 1px;
1929
border-top-right-radius: 8px;
@@ -22,7 +32,10 @@
2232
}
2333

2434
:global(.ql-container) {
25-
height: 215px;
35+
max-width: 688px;
36+
min-width: 288px;
37+
height: 178px;
38+
margin: 16px;
2639
border: none;
2740
}
2841

@@ -31,4 +44,24 @@
3144
@include font-24-bold;
3245
color: $gray-900;
3346
}
47+
48+
&__error-message {
49+
@include font-12-regular;
50+
color: $error;
51+
}
52+
53+
@media (max-width: 767px) {
54+
& {
55+
max-width: 320px;
56+
}
57+
:global(.ql-toolbar button),
58+
:global(.ql-toolbar .ql-picker) {
59+
width: 24px;
60+
}
61+
62+
:global(.ql-toolbar .ql-color-picker),
63+
:global(.ql-toolbar .ql-icon-picker) {
64+
width: 24px;
65+
}
66+
}
3467
}

โ€Žsrc/components/FontSelect/FontSelect.jsxโ€Ž

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ const fontClassMap = {
1111
'๋‚˜๋ˆ”์†๊ธ€์”จ ์†ํŽธ์ง€์ฒด': styles['font-naunm-hand'],
1212
};
1313

14-
export default function FontSelect({ defaultValue = 'Noto Sans', onChange }) {
14+
export default function FontSelect({ value = 'Noto Sans', onChange }) {
1515
const dropdownRef = useRef(null);
1616
const id = useId();
17-
const [selected, setSelected] = useState(defaultValue);
1817
const [isOpen, setIsOpen] = useDetectClose(dropdownRef);
1918

2019
const handleSelect = (font) => {
21-
setSelected(font);
2220
onChange?.(font);
2321
setIsOpen(false);
2422
};
@@ -32,10 +30,10 @@ export default function FontSelect({ defaultValue = 'Noto Sans', onChange }) {
3230
<button
3331
id={id}
3432
type="button"
35-
className={`${styles['dropdown__button']} ${fontClassMap[selected]}`}
33+
className={`${styles['dropdown__button']} ${fontClassMap[value]}`}
3634
onClick={() => setIsOpen((prev) => !prev)}
3735
>
38-
{selected}
36+
{value}
3937
<span
4038
className={`${styles.dropdown__arrow} ${isOpen ? styles.open : ''}`}
4139
/>

โ€Žsrc/components/FontSelect/FontSelect.module.scssโ€Ž

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
display: flex;
55
flex-direction: column;
66
width: 320px;
7-
height: 98px;
87
gap: 12px;
98

109
&__label {
@@ -17,6 +16,7 @@
1716
display: flex;
1817
justify-content: space-between;
1918
align-items: center;
19+
position: relative;
2020
width: 286px;
2121
height: 24px;
2222
padding: 12px 16px;
@@ -57,6 +57,7 @@
5757
display: flex;
5858
justify-content: space-between;
5959
flex-direction: column;
60+
position: static;
6061
width: 318px;
6162
height: 220px;
6263
margin-top: 8px;
@@ -68,8 +69,7 @@
6869
}
6970

7071
&__item {
71-
width: 316px;
72-
height: 50px;
72+
width: 318px;
7373
padding: 12px 16px;
7474
@include font-16-regular;
7575
color: $gray-900;
@@ -78,6 +78,11 @@
7878
background-color: $gray-100;
7979
}
8080
}
81+
@media (max-width: 767px) {
82+
&__list {
83+
position: absolute;
84+
}
85+
}
8186
}
8287

8388
.font-noto {

โ€Žsrc/components/RelationshipSelect/RelationshipSelect.jsxโ€Ž

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,12 @@ import styles from './RelationshipSelect.module.scss';
44

55
const OPTIONS = ['์นœ๊ตฌ', '์ง€์ธ', '๋™๋ฃŒ', '๊ฐ€์กฑ'];
66

7-
export default function RelationshipSelect({
8-
defaultValue = '์ง€์ธ',
9-
onChange,
10-
}) {
7+
export default function RelationshipSelect({ value = '์ง€์ธ', onChange }) {
118
const dropdownRef = useRef(null);
129
const id = useId();
13-
const [selected, setSelected] = useState(defaultValue);
1410
const [isOpen, setIsOpen] = useDetectClose(dropdownRef);
1511

1612
const handleSelect = (option) => {
17-
setSelected(option);
1813
onChange?.(option);
1914
setIsOpen(false);
2015
};
@@ -31,7 +26,7 @@ export default function RelationshipSelect({
3126
className={styles['dropdown__button']}
3227
onClick={() => setIsOpen((prev) => !prev)}
3328
>
34-
{selected}
29+
{value}
3530
<span
3631
className={`${styles.dropdown__arrow} ${isOpen ? styles.open : ''}`}
3732
/>

โ€Žsrc/components/RelationshipSelect/RelationshipSelect.module.scssโ€Ž

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
display: flex;
55
flex-direction: column;
66
width: 320px;
7-
height: 98px;
87
gap: 12px;
98

109
&__label {
@@ -17,6 +16,7 @@
1716
display: flex;
1817
justify-content: space-between;
1918
align-items: center;
19+
position: relative;
2020
width: 286px;
2121
height: 24px;
2222
padding: 12px 16px;
@@ -57,19 +57,20 @@
5757
display: flex;
5858
justify-content: space-between;
5959
flex-direction: column;
60+
position: absolute;
6061
width: 318px;
6162
height: 220px;
6263
margin-top: 8px;
6364
padding: 10px 1px;
6465
border: 1px solid $gray-300;
6566
border-radius: 8px;
6667
background-color: $white;
68+
z-index: 1;
6769
list-style: none;
6870
}
6971

7072
&__item {
71-
width: 316px;
72-
height: 50px;
73+
width: 318px;
7374
padding: 12px 16px;
7475
@include font-16-regular;
7576
color: $gray-900;

โ€Žsrc/components/UserProfileSelector/UserProfileSelector.jsxโ€Ž

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
import { useEffect, useState } from 'react';
2-
import fetchProfileImages from '../../api/fetchProfileImages.js';
2+
import getProfileImages from '../../api/getProfileImages.js';
33
import DEFAULT_PROFILE_IMAGE from '../../constants/image.js';
44
import styles from './UserProfileSelector.module.scss';
55

6-
export default function UserProfileSelector({ onSelect }) {
6+
export default function UserProfileSelector({
7+
value = DEFAULT_PROFILE_IMAGE,
8+
onSelect,
9+
}) {
710
const [profileImages, setProfileImages] = useState([]);
8-
const [selectedImage, setSelectedImage] = useState(DEFAULT_PROFILE_IMAGE);
911

1012
useEffect(() => {
1113
const loadImages = async () => {
12-
const images = await fetchProfileImages();
14+
const images = await getProfileImages();
1315
setProfileImages(images);
1416
};
1517
loadImages();
1618
}, []);
1719

18-
const handleSelect = (url) => {
19-
setSelectedImage(url);
20-
onSelect?.(url);
21-
};
22-
2320
return (
2421
<div className={styles['profile-select']}>
2522
<h2 className={styles['profile-select__title']}>ํ”„๋กœํ•„ ์ด๋ฏธ์ง€</h2>
2623
<div className={styles['profile-select__content']}>
2724
<img
28-
src={selectedImage}
25+
src={value}
2926
alt="์„ ํƒ๋œ ํ”„๋กœํ•„"
3027
className={styles['profile-select__selected-image']}
3128
/>
@@ -40,11 +37,9 @@ export default function UserProfileSelector({ onSelect }) {
4037
src={url}
4138
alt={`profile-${idx}`}
4239
className={`${styles['profile-select__image']} ${
43-
selectedImage === url
44-
? styles['profile-select__image--selected']
45-
: ''
40+
value === url ? styles['profile-select__image--selected'] : ''
4641
}`}
47-
onClick={() => handleSelect(url)}
42+
onClick={() => onSelect?.(url)}
4843
/>
4944
))}
5045
</div>

0 commit comments

Comments
ย (0)