Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[민우] - 작성 가능 리마인드 아이템 컴포넌트 구현 #54

Merged
merged 9 commits into from
Nov 14, 2023
2 changes: 2 additions & 0 deletions src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const ICON_NAME_MAP = {
DROP_DOWN: 'arrow_drop_down',
DROP_UP: 'arrow_drop_up',
CLOSE: 'close',
CHECKED: 'check_box',
UN_CHECKED: 'check_box_outline_blank',
};

interface IconProps {
Expand Down
6 changes: 5 additions & 1 deletion src/components/RemindInput/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
padding: 1rem;
width: 100%;
height: 15rem;
color: var(--origin-gray-100);
color: var(--origin-gray-300);
background-color: var(--origin-white-100);
font-size: 1.25rem;
border: none;
background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='12' ry='12' stroke='%23FECEABFF' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
border-radius: var(--border-radius);
outline: none;
resize: none;

&::placeholder{
color: var(--origin-gray-100);
}
}
157 changes: 157 additions & 0 deletions src/components/WritableRemindItem/WritableRemindItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
'use client';

import { Icon, Modal, ModalBasic, RemindInput } from '@/components';
import classNames from 'classnames';
import React, { useEffect, useMemo, useState } from 'react';
import './index.scss';

interface WritableRemindItemProps {
remindMonth: number;
remindDay: number;
remindMessage: string;
handleChangeRemindMessage: (text: string) => void;
makeAllRemindMessageSame?: () => void;
}

const MAX_REMIND_MESSAGE_LENGTH = 255;

export default function WritableRemindItem({
remindMonth,
remindDay,
remindMessage,
handleChangeRemindMessage,
makeAllRemindMessageSame,
}: WritableRemindItemProps) {
const isRemindMessageEmpty = useMemo(() => {
Copy link
Contributor

@qkdl60 qkdl60 Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

계산이 복잡하지 않으니 useMemo를 안써도 isRemindMessageEmpty 를 사용하는 곳에 remidMessage.length === 0 통해서 처리해도 괜찮을것 같습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 컴포넌트 return 부분이 좀 복잡해서 최대한 줄여서 가독성을 높이려는 의도로 만들긴 했는데 한번 고려해보겠슴다 ^^

return remindMessage.length === 0;
}, [remindMessage]);

const isFirstRemindItem = useMemo(() => {
return makeAllRemindMessageSame !== undefined;
}, [makeAllRemindMessageSame]);
Comment on lines +25 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useMemo 사용하셨군요 👍


const [isItemOpened, setIsItemOpened] = useState(
makeAllRemindMessageSame ? true : false,
);

const handleClickToggleIsItemOpened = () => {
setIsItemOpened(!isItemOpened);
};

const [isSameMessageChecked, setIsSameMessageChecked] = useState(false);
const [isSameMessageModalOpen, setIsSameMessageModalOpen] = useState(false);

const handleClickSameMessageCheck = () => {
if (isSameMessageChecked) {
setIsSameMessageChecked(false);
} else {
setIsSameMessageModalOpen(!isSameMessageModalOpen);
}
};

const handleModalClickYes = () => {
setIsSameMessageChecked(true);
setIsSameMessageModalOpen(false);
};

const handleModalClickNo = () => {
setIsSameMessageChecked(false);
setIsSameMessageModalOpen(false);
};

useEffect(() => {
if (isFirstRemindItem && isSameMessageChecked) {
makeAllRemindMessageSame!();
}
}, [isFirstRemindItem, isSameMessageChecked, makeAllRemindMessageSame]);

return (
<>
<div className="remind-item">
<div
className="remind-item__header"
onClick={handleClickToggleIsItemOpened}>
<p className="remind-item__header__title">
{remindMonth}월 {remindDay}일에 받을 리마인드 메세지
</p>

<div className="remind-item__header__meta">
{isRemindMessageEmpty && (
<div
className={classNames(
'remind-item__header__warning',
'background-origin-primary',
)}>
<Icon name="WARNING" size="xs" color="white-100" />
<span
className={classNames(
'remind-item__header__warning__text',
'color-origin-white-100',
)}>
리마인드 메세지가 아직 작성되지 않았습니다
</span>
</div>
)}
<span className="remind-item__header__button-text">
{isRemindMessageEmpty ? '작성하기' : '수정하기'}
</span>
<Icon
name={isItemOpened ? 'ITEM_CLOSE' : 'ITEM_OPEN'}
size="xl"
color="gray-300"
classNameList={['remind-item__header__icon']}
/>
</div>
</div>
{isItemOpened && (
<div
className={classNames(
'remind-item__message',
'background-origin-white-300',
{
'remind-item__message--open': isItemOpened,
},
)}>
<RemindInput
textInput={remindMessage}
onChangeInput={handleChangeRemindMessage}
placeholder="미래의 내가 받게 될 리마인드 메세지를 작성해보세요 !"
maxLength={MAX_REMIND_MESSAGE_LENGTH}
editable={true}
/>

{isFirstRemindItem && (
<span
className="remind-item__message__check"
onClick={handleClickSameMessageCheck}>
<Icon
name={isSameMessageChecked ? 'CHECKED' : 'UN_CHECKED'}
size="2xl"
color="primary"
isFilled={isSameMessageChecked ? true : false}
/>
<p
className={classNames(
'remind-item__message__check__text',
'color-origin-primary',
)}>
항상 같은 리마인드 메세지 받기
</p>
</span>
)}
</div>
)}
</div>
{isSameMessageModalOpen && isSameMessageChecked === false && (
Copy link
Contributor

@suehdn suehdn Nov 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로직이 복잡하네요..😭 약간이라도 짧게 쓰려면 이 방법은 어떠신가요

Suggested change
{isSameMessageModalOpen && isSameMessageChecked === false && (
{isSameMessageModalOpen && !isSameMessageChecked && (

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오 왜 저렇게 썼을까요 저 ㅋㅋㅋㅋ 감사합니닷

<Modal>
<ModalBasic
onClickYes={handleModalClickYes}
onClickNo={handleModalClickNo}>
다른 모든 리마인드 메세지가 해당 메세지와 동일한 내용으로
변경됩니다. 정말 적용하시겠습니까?
</ModalBasic>
</Modal>
)}
</>
);
}
104 changes: 104 additions & 0 deletions src/components/WritableRemindItem/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
.remind-item {
display: flex;
flex-direction: column;
width: 100%;
border-radius: var(--border-radius);
border: var(--border-width) solid var(--origin-orange-200);

&__header {
display: flex;
position: relative;
padding: 1rem 2rem;
justify-content: center;
align-items: center;
cursor: pointer;

&__title {
font-size: 1.25rem;
line-height: 1.25rem;
overflow: hidden;
white-space: nowrap;
}

&__meta {
position: absolute;
display: inline-flex;
align-items: center;
right: 0rem;
}

&__warning {
transition: all 1s ease;
display: flex;
margin-right: 0.75rem;
padding: 0.25rem 0.5rem;
border-radius: var(--border-radius);

&__text {
margin-left: 0.25rem;
font-size: 0.6rem;
line-height: 0.7rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}

&__button-text {
font-size: 1rem;
line-height: 1rem;
margin-right: 1.25rem;
}

&__icon {
margin-right: 2rem;
}
}

&__message {
display: none;
flex-direction: column;
align-items: center;
border-top: var(--border-width) solid var(--origin-orange-200);
border-radius: 0 0 12px 12px;
padding: 1rem;

&--open {
display: flex;
}

&__check {
display: flex;
margin-top: 1.2rem;
cursor: pointer;

&__text {
margin-left: 0.25rem;
font-size: 1.25rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}

@media (max-width: 1200px) {
.remind-item {
&__header {
&__warning {
display: none;
}
}
}
}

@media (max-width: 750px) {
.remind-item {
&__header {
&__button-text {
display: none;
}
}
}
}
3 changes: 3 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ export { default as IconSwitchButton } from '@components/IconSwitchButton/IconSw
export { default as Icon } from '@components/Icon/Icon';
export { default as Modal } from '@components/Modal/Modal';
export { default as ModalBasic } from '@components/Modal/ModalBasic';
export { default as RemindInput } from '@components/RemindInput/RemindInput';
export { default as PlanInput } from '@components/PlanInput/PlanInput';
export { default as Dropdown } from '@components/Dropdown/Dropdown';
4 changes: 3 additions & 1 deletion src/types/IconName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ export type IconName =
| 'HELP'
| 'DROP_DOWN'
| 'DROP_UP'
| 'CLOSE';
| 'CLOSE'
| 'CHECKED'
| 'UN_CHECKED';