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

[FEAT] 메인 세팅 모달 퍼블리싱 #334

Merged
merged 8 commits into from
Jan 12, 2025
Merged
3 changes: 2 additions & 1 deletion src/components/common/v2/TextBox/PopUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ type PopUpProps = {

function PopUp({ type }: PopUpProps) {
const { state, handleFocus, handleBlur, handleChange } = useInputHandler();
const placeholder = type === TYPE.TITLE ? '제목을 입력하세요' : '설명을 추가하세요';

return (
<PopUpContainer>
{type === TYPE.DESC && state === INPUT_STATE.DEFAULT && <Icon name="IcnDescription" size="tiny" />}
<StyledInput
type={type}
state={state}
placeholder="제목을 입력하세요"
placeholder={placeholder}
Comment on lines +19 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

헉 ㅋㅋ 👍 👍

onFocus={handleFocus}
onBlur={handleBlur}
onChange={handleChange}
Expand Down
11 changes: 9 additions & 2 deletions src/components/common/v2/dropdown/TimeDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@ import styled from '@emotion/styled';
import Button from '@/components/common/v2/button/Button';
import quarterTimes from '@/utils/generateQuarterTimes';

function TimeDropdown() {
interface TimeDropdownProps {
handleSelectTime: (time: string) => void;
}

function TimeDropdown({ handleSelectTime }: TimeDropdownProps) {
return (
<TimeDropdownContainer>
{quarterTimes.map((time) => (
<Button key={time} label={time} onClick={() => {}} size="large" type="text-assistive" />
<Button key={time} label={time} onClick={() => handleSelectTime(time)} size="large" type="text-assistive" />
))}
</TimeDropdownContainer>
);
}

const TimeDropdownContainer = styled.div`
box-sizing: border-box;
width: 16.8rem;
height: 30rem;
padding: 0.8rem;
overflow-y: auto;

background-color: ${({ theme }) => theme.colorToken.Neutral.normal};
border-radius: 12px;

${({ theme }) => theme.shadow.FloatingAction3};
${({ theme }) => theme.fontTheme.LABEL_03};

/* 스크롤바 전체 */
::-webkit-scrollbar {
Expand Down
98 changes: 98 additions & 0 deletions src/components/common/v2/modal/MainSettingModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import styled from '@emotion/styled';
import { useState } from 'react';

import Button from '@/components/common/v2/button/Button';
import DropdownButton from '@/components/common/v2/control/DropdownButton';
import IconButton from '@/components/common/v2/IconButton';
import DeadlineBox from '@/components/common/v2/popup/DeadlineBox';
import PopUp from '@/components/common/v2/TextBox/PopUp';
import { StatusType } from '@/types/tasks/taskType';

function MainSettingModal() {
const [status, setStatus] = useState<StatusType>('미완료');

const handleStatusChange = (newStatus: StatusType) => {
setStatus(newStatus);
};

return (
<MainSettingModalLayout>
<MainSettingModalHeadLayout>
<ModalTopButtonBox>
<DropdownButton status={status} handleStatusChange={handleStatusChange} />
<ButtonBox>
<IconButton iconName="IcnDelete" type="normal" size="small" disabled />
<IconButton iconName="IcnX" type="normal" size="small" disabled />
</ButtonBox>
</ModalTopButtonBox>
<PopUp type="title" />
</MainSettingModalHeadLayout>
<MainSettingModalBodyLayout>
<DeadlineBox date={new Date()} endTime="06:00pm" label="마감 기간" />
Copy link
Member

Choose a reason for hiding this comment

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

리턴문 위에서 변수 지정해 Date 담아두고 사용하면 렌더링할 때마다 데이트 오브젝트가 새로 생기지 않게 할 수 있을 것 같아요!!

Copy link
Member Author

Choose a reason for hiding this comment

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

해당 date를 전달한 곳은 임시로 데이터를 넘겨주는 부분이라서 기능 붙이면서 수정하도록 하겠습니다!!

<PopUpTitleBox>
<PopUp type="description" />
</PopUpTitleBox>
<DeadlineBox date={new Date()} startTime="11:00am" endTime="06:00pm" label="진행 기간" />
Comment on lines +31 to +35
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<DeadlineBox date={new Date()} endTime="06:00pm" label="마감 기간" />
<PopUpTitleBox>
<PopUp type="description" />
</PopUpTitleBox>
<DeadlineBox date={new Date()} startTime="11:00am" endTime="06:00pm" label="진행 기간" />
<DeadlineBox date={new Date()} endTime="06:00 pm" label="마감 기간" />
<PopUpTitleBox>
<PopUp type="description" />
</PopUpTitleBox>
<DeadlineBox date={new Date()} startTime="11:00 am" endTime="06:00 pm" label="진행 기간" />

시간 수정할 때 정렬이 살짝 이상해서 봤더니 사이에 띄어쓰기가 업서요 수정해주세요!!

Copy link
Member Author

Choose a reason for hiding this comment

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

여기 나중에 데이터 임시로 넣어둔 부분이라서 나중에 데이터 넣으면서 수정하도록 하겠습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

위에 버튼 정렬에서 제가 보기에는 정렬이 맞게 보이는데 이상하네용 ,,ㅜ
image

</MainSettingModalBodyLayout>
<MainSettingModalButtonLayout>
<Button type="solid" size="medium" label="확인" />
</MainSettingModalButtonLayout>
</MainSettingModalLayout>
);
}

const MainSettingModalLayout = styled.article`
display: flex;
flex-direction: column;
gap: 2.4rem;
box-sizing: border-box;
width: 41.6rem;
height: auto;
padding: 2.4rem 2.4rem 3.2rem;

background-color: ${({ theme }) => theme.colorToken.Neutral.normal};
box-shadow:
4px 4px 40px 20px #717e9833,
-4px -4px 40px 0 #717e9833;
border-radius: 20px;
`;

const MainSettingModalHeadLayout = styled.section`
display: flex;
flex-direction: column;
gap: 3.2rem;
width: 100%;
height: 9.2rem;
`;

const MainSettingModalBodyLayout = styled.section`
display: flex;
flex-direction: column;
width: 100%;
`;

const ModalTopButtonBox = styled.div`
display: flex;
justify-content: space-between;
`;

const ButtonBox = styled.div`
display: flex;
gap: 0.8rem;
`;

const PopUpTitleBox = styled.div`
display: flex;
align-items: center;
width: 100%;
height: 5.9rem;
`;

const MainSettingModalButtonLayout = styled.div`
display: flex;
justify-content: flex-end;
width: 100%;
height: 3.2rem;
`;

export default MainSettingModal;
108 changes: 108 additions & 0 deletions src/components/common/v2/popup/DateBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import styled from '@emotion/styled';
import { useState } from 'react';

import DateCorrectionModal from '@/components/common/datePicker/DateCorrectionModal';
import Icon from '@/components/common/Icon';
import formatDateWithDay from '@/utils/formatDateWithDay';

interface DateBtnProps {
isAllday: boolean;
isSetDate: boolean;
startTime?: string;
endTime: string;
date: Date;
setDate: (newDate: Date) => void;
Copy link
Member

Choose a reason for hiding this comment

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

사소한 부분이지만 상탸를 직접적으로 변경하는 함수랑 헷갈릴 수도 있어 핸들~ 정도로 네이밍 바꿔주면 혼란을 줄일 수 있을 것 같아용

Copy link
Member Author

Choose a reason for hiding this comment

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

앗 그러네요!! 해당 사항 수정하였습니다

}

function DateBtn({ isAllday, isSetDate, startTime, endTime, date, setDate }: DateBtnProps) {
const [isOpen, setIsOpen] = useState(false);

const renderTimeText = () => {
if (isAllday) return null;
if (startTime && endTime) {
return `${startTime}-${endTime}`;
}
if (endTime) {
return `${endTime} 까지`;
}
return null;
};

const onClickDateBtn = () => {
if (!isSetDate) setIsOpen((prev) => !prev);
};

const handleModalClose = () => {
setIsOpen(false);
};

const handleCurrentDate = (newDate: Date) => {
setDate(newDate);
setIsOpen(false);
};

const handleBlur = (event: React.FocusEvent<HTMLDivElement>) => {
if (!event.currentTarget.contains(event.relatedTarget)) {
setIsOpen(false);
}
};

return (
<DateWrapper onBlur={handleBlur} tabIndex={-1}>
<DateBtnLayout onClick={onClickDateBtn} isActive={isOpen}>
<Icon name={isSetDate ? 'IcnModify' : 'IcnCalendar'} size="tiny" color="nomal" />
<TextBox>
{formatDateWithDay(date)} {isSetDate && renderTimeText()}
</TextBox>
</DateBtnLayout>
{isOpen && (
<DropdownStyle tabIndex={-1}>
Copy link
Member

Choose a reason for hiding this comment

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

온블러 굳굳 👍

<DateCorrectionModal
date={formatDateWithDay(date)}
onClick={handleModalClose}
handleCurrentDate={handleCurrentDate}
top={0.8}
/>
</DropdownStyle>
)}
</DateWrapper>
);
}

const DateWrapper = styled.div`
position: relative;
`;

const DateBtnLayout = styled.button<{ isActive: boolean }>`
display: flex;
gap: 0.8rem;
align-items: center;
justify-content: center;
width: auto;
height: 3.2rem;
padding: 0 1.6rem;

background-color: ${({ theme, isActive }) => (isActive ? theme.color.Grey.Grey3 : theme.colorToken.Neutral.normal)};
border: 1px solid ${({ theme }) => theme.colorToken.Outline.neutralNormal};
border-radius: 8px;

:hover {
background-color: ${({ theme, isActive }) => (isActive ? theme.color.Grey.Grey3 : theme.color.Grey.Grey2)};
}
`;

const TextBox = styled.p`
width: auto;
height: 1.4rem;

color: ${({ theme }) => theme.colorToken.Text.assistive};
${({ theme }) => theme.font.label05};
font-weight: 500;
`;

const DropdownStyle = styled.div`
position: absolute;
z-index: 3;
`;

export default DateBtn;
92 changes: 45 additions & 47 deletions src/components/common/v2/popup/DateTimeBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,72 @@
import styled from '@emotion/styled';
import { useState } from 'react';

import Icon from '@/components/common/Icon';
import DateBtn from '@/components/common/v2/popup/DateBtn';
import TimeBtn from '@/components/common/v2/popup/TimeBtn';

interface DateTimeBtnProps {
date: string;
date: Date;
startTime?: string;
endTime: string;
isSetDate: boolean;
isAllday?: boolean;
onClick: () => void;
}

function DateTimeBtn({ date, startTime, endTime, isSetDate = false, isAllday = false, onClick }: DateTimeBtnProps) {
const renderTimeText = () => {
if (isAllday) return null;
if (startTime && endTime) {
return `${startTime}-${endTime}`;
}
if (endTime) {
return `${endTime} 까지`;
}
return null;
function DateTimeBtn({
date: initDate,
startTime: initStartTime,
endTime: initEndTime,
isSetDate,
isAllday = false,
onClick,
}: DateTimeBtnProps) {
const [startTime, setStartTime] = useState(initStartTime);
const [endTime, setEndTime] = useState(initEndTime);
const [date, setDate] = useState(initDate);

const updateStartTime = (newTime: string) => {
setStartTime(newTime);
};

const updateEndTime = (newTime: string) => {
setEndTime(newTime);
};

const updateDate = (newDate: Date) => {
setDate(newDate);
};

return isSetDate ? (
<DateTimeBtnContainer onClick={onClick}>
<DateTimeBtnLayout>
<Icon name="IcnModify" size="tiny" color="nomal" />
<TextBox>
{date} {renderTimeText()}
</TextBox>
</DateTimeBtnLayout>
<DateBtn
isAllday={isAllday}
isSetDate={isSetDate}
startTime={startTime}
endTime={endTime}
date={date}
setDate={updateDate}
/>
</DateTimeBtnContainer>
) : (
<DateTimeBtnContainer isSingle={!startTime}>
<DateTimeBtnLayout>
<Icon name="IcnCalendar" size="tiny" color="nomal" />
<TextBox>{date}</TextBox>
</DateTimeBtnLayout>
<DateBtn
isAllday={isAllday}
isSetDate={isSetDate}
startTime={startTime}
endTime={endTime}
date={date}
setDate={updateDate}
/>
{!isAllday && (
<TimeBtnContainer>
{startTime && (
<>
<TimeBtn time={startTime} />
<TimeBtn time={startTime} setTime={updateStartTime} />
<GrayText>부터</GrayText>
</>
)}
<TimeBtn time={endTime} />
<TimeBtn time={endTime} setTime={updateEndTime} />
<GrayText>까지</GrayText>
</TimeBtnContainer>
)}
Expand All @@ -63,36 +82,15 @@ const DateTimeBtnContainer = styled.div<{ isSingle?: boolean }>`
margin: 0 0 0 0.8rem;
`;

const DateTimeBtnLayout = styled.button`
display: flex;
gap: 0.8rem;
align-items: center;
justify-content: center;
width: auto;
height: 3.2rem;
padding: 0 1.6rem;

background-color: ${({ theme }) => theme.colorToken.Neutral.normal};
border: 1px solid ${({ theme }) => theme.colorToken.Outline.neutralNormal};
border-radius: 8px;
`;

const TextBox = styled.p`
width: auto;
height: 1.4rem;

color: ${({ theme }) => theme.colorToken.Text.assistive};
${({ theme }) => theme.font.label05};
font-weight: 500;
`;

const GrayText = styled.p`
align-content: center;
height: 3.2rem;

color: ${({ theme }) => theme.colorToken.Text.disable};
font-weight: 600;
font-size: 1.4rem;

${({ theme }) => theme.font.label05};
`;

const TimeBtnContainer = styled.div`
Expand Down
Loading
Loading