From c26c9d6f55200afae71f3121f23cbffd32c84217 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 6 Nov 2023 16:48:14 +0900 Subject: [PATCH 01/53] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20?= =?UTF-8?q?=EB=93=9C=EB=9E=98=EA=B7=B8=EA=B0=80=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EB=90=A0=20=EA=B0=80=EC=A7=9C=20=EB=93=9C=EB=9E=98=EA=B7=B8=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=20backdrop=20=ED=99=94=EB=A9=B4=EC=9D=B4=20?= =?UTF-8?q?=EB=82=98=ED=83=80=EB=82=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen.styled.ts | 12 ++++++++++++ .../CalendarDragScreen/CalendarDragScreen.tsx | 16 ++++++++++++++++ .../CalendarDragScreen/useCalendarDragScreen.ts | 17 +++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts create mode 100644 frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx create mode 100644 frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts new file mode 100644 index 000000000..1a6838bfd --- /dev/null +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -0,0 +1,12 @@ +import { styled } from 'styled-components'; + +export const Container = styled.div` + position: absolute; + left: 0; + top: 0; + + width: 100%; + height: 100%; + + background-color: #ffffffaa; +`; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx new file mode 100644 index 000000000..c4392427a --- /dev/null +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -0,0 +1,16 @@ +import * as S from './CalendarDragScreen.styled'; +import { useCalendarDragScreen } from './useCalendarDragScreen'; + +interface CalendarDragScreenProps { + visible: boolean; + onMouseUp: () => void; +} + +const CalendarDragScreen = (props: CalendarDragScreenProps) => { + const { visible, onMouseUp } = props; + useCalendarDragScreen({ onMouseUp }); + + return visible ? : null; +}; + +export default CalendarDragScreen; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts new file mode 100644 index 000000000..d83844f3d --- /dev/null +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -0,0 +1,17 @@ +import { useEffect } from 'react'; + +interface UseCalendarDragScreenProps { + onMouseUp: () => void; +} + +export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { + const { onMouseUp } = props; + + useEffect(() => { + document.addEventListener('mouseup', onMouseUp); + + return () => { + document.removeEventListener('mouseup', onMouseUp); + }; + }, [onMouseUp]); +}; From 526e9b6058ff48ff351f3615527369cdde796d5a Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 6 Nov 2023 16:50:09 +0900 Subject: [PATCH 02/53] =?UTF-8?q?feat:=20CalendarDragScreen=EC=9D=84=20?= =?UTF-8?q?=EC=BA=98=EB=A6=B0=EB=8D=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EC=97=90=20=EB=B6=80=EC=B0=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.styled.ts | 2 ++ .../team_calendar/ScheduleBar/ScheduleBar.tsx | 12 +++++++++++- .../TeamCalendar/TeamCalendar.styled.ts | 4 ++++ .../team_calendar/TeamCalendar/TeamCalendar.tsx | 12 ++++++++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts index 1a6838bfd..d91e6ff89 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -9,4 +9,6 @@ export const Container = styled.div` height: 100%; background-color: #ffffffaa; + + cursor: all-scroll; `; diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index 943b50ded..a8f85aefb 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -8,18 +8,28 @@ import type { CalendarSize } from '~/types/size'; export interface ScheduleBarProps extends GeneratedScheduleBar { calendarSize?: CalendarSize; onClick?: () => void; + onDragStart?: () => void; } const ScheduleBar = (props: ScheduleBarProps) => { - const { title, onClick, roundedEnd, calendarSize = 'md', ...rest } = props; + const { + title, + onClick, + roundedEnd, + onDragStart, + calendarSize = 'md', + ...rest + } = props; const { teamPlaceColor } = useTeamPlace(); return ( { const { calendarSize = 'md' } = props; + const [isDragging, setIsDragging] = useState(false); + const { teamPlaceId } = useTeamPlace(); const { year, @@ -223,7 +226,7 @@ const TeamCalendar = (props: TeamCalendarProps) => { return {day}; })} -
+ {calendar.map((week, rowIndex) => { return ( @@ -271,6 +274,7 @@ const TeamCalendar = (props: TeamCalendarProps) => { level, }); }} + onDragStart={() => setIsDragging(() => true)} {...scheduleBar} /> ); @@ -315,7 +319,11 @@ const TeamCalendar = (props: TeamCalendarProps) => { ); })} -
+ setIsDragging(() => false)} + /> +
{modal} From bf67149ec936f3e92735b3bd3ec9ca6bfa1e1741 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 6 Nov 2023 22:46:31 +0900 Subject: [PATCH 03/53] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=20?= =?UTF-8?q?=EB=93=9C=EB=9E=98=EA=B7=B8=20=ED=98=84=ED=99=A9=EC=9D=84=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=ED=9B=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 스케줄 바 드래그 현황에 대한 데이터를 가짜 드래그 스크린에 prop으로 넘길 수 있도록 값 관리 - 스케줄 바의 드래그를 시작하는 경우 / 드래그를 중지하는 경우에 따라 값을 업데이트할 수 있도록 관리 --- .../TeamCalendar/useScheduleBarDragStatus.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts new file mode 100644 index 000000000..9de8e54bb --- /dev/null +++ b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts @@ -0,0 +1,51 @@ +import { useState } from 'react'; +import type { MouseEvent } from 'react'; +import type { Schedule } from '~/types/schedule'; + +interface DragStatus { + isDragging: boolean; + level: number; + schedule: Schedule; + initMouseX: number; + initMouseY: number; +} + +export const useScheduleDragStatus = () => { + const [dragStatus, setDragStatus] = useState({ + isDragging: false, + level: 0, + schedule: {} as Schedule, + initMouseX: 0, + initMouseY: 0, + }); + + const handleDragStart = ( + e: MouseEvent, + level: number, + schedule: Schedule, + ) => { + setDragStatus(() => ({ + isDragging: true, + schedule, + level, + initMouseX: e.clientX, + initMouseY: e.clientY, + })); + }; + + const handleMouseUp = () => { + if (!dragStatus.isDragging) { + return; + } + + setDragStatus(() => ({ + isDragging: false, + level: 0, + schedule: {} as Schedule, + initMouseX: 0, + initMouseY: 0, + })); + }; + + return { dragStatus, handleDragStart, handleMouseUp }; +}; From 463fccefcce691555cf68cad393da622a874d04d Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 6 Nov 2023 22:47:30 +0900 Subject: [PATCH 04/53] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=20=EB=B0=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=93=9C?= =?UTF-8?q?=EB=9E=98=EA=B7=B8=20=EC=8B=9C=EC=9E=91=20=EC=8B=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=ED=95=A8?= =?UTF-8?q?=EA=BB=98=20=EB=84=98=EA=B8=B0=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/team_calendar/ScheduleBar/ScheduleBar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index a8f85aefb..1a30089cd 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -1,5 +1,6 @@ import Text from '~/components/common/Text/Text'; import * as S from './ScheduleBar.styled'; +import type { MouseEvent } from 'react'; import type { GeneratedScheduleBar } from '~/types/schedule'; import { DoubleArrowRightIcon } from '~/assets/svg'; import { useTeamPlace } from '~/hooks/useTeamPlace'; @@ -8,7 +9,7 @@ import type { CalendarSize } from '~/types/size'; export interface ScheduleBarProps extends GeneratedScheduleBar { calendarSize?: CalendarSize; onClick?: () => void; - onDragStart?: () => void; + onDragStart?: (e: MouseEvent) => void; } const ScheduleBar = (props: ScheduleBarProps) => { From 70c440a28e2a430236796675c501cf2ded544d9d Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 6 Nov 2023 22:48:05 +0900 Subject: [PATCH 05/53] =?UTF-8?q?feat:=20=EC=A2=8C=ED=91=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=98=EB=AF=B8=ED=95=98=EB=8A=94=20Point=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - x, y값을 지님 --- frontend/src/types/schedule.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index b85aca6dd..6097def6d 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -47,3 +47,8 @@ export interface GeneratedScheduleBar { roundedStart: boolean; roundedEnd: boolean; } + +export interface Point { + x: number; + y: number; +} From c8c26c1fa6de2ac5a61544ab51b702b6400cbc16 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 7 Nov 2023 01:22:52 +0900 Subject: [PATCH 06/53] =?UTF-8?q?feat:=20=EC=9B=80=EC=A7=81=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이후 마우스 좌표를 받아 마우스를 따라가는 위치에 렌더링되도록 사용 예정 --- .../MovingScheduleBars.styled.ts | 18 +++++++++++ .../MovingScheduleBars/MovingScheduleBars.tsx | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts create mode 100644 frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts new file mode 100644 index 000000000..d826722bb --- /dev/null +++ b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts @@ -0,0 +1,18 @@ +import { styled } from 'styled-components'; + +export const Container = styled.div<{ $relativeX: number; $relativeY: number }>` + display: flex; + flex-direction: column; + position: absolute; + + width: 100%; + height: 100%; + + transform: ${({ $relativeX, $relativeY }) => + `translate(${$relativeX}px, ${$relativeY}px)`}; +`; + +export const CalendarRow = styled.div` + position: relative; + flex-grow: 1; +`; diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx new file mode 100644 index 000000000..dd635bf00 --- /dev/null +++ b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx @@ -0,0 +1,30 @@ +import * as S from './MovingScheduleBars.styled'; +import ScheduleBar from '~/components/team_calendar/ScheduleBar/ScheduleBar'; +import { arrayOf } from '~/utils/arrayOf'; +import type { GeneratedScheduleBar } from '~/types/schedule'; + +interface MovingScheduleBarProps { + scheduleBars: GeneratedScheduleBar[]; + relativeX: number; + relativeY: number; +} + +const MovingScheduleBar = (props: MovingScheduleBarProps) => { + const { scheduleBars, relativeX, relativeY } = props; + + return ( + + {arrayOf(6).map((_, rowIndex) => ( + + {scheduleBars.map((scheduleBar) => { + return scheduleBar.row === rowIndex ? ( + + ) : null; + })} + + ))} + + ); +}; + +export default MovingScheduleBar; From 21889eeec34f50262faa783bd194827175c91448 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 7 Nov 2023 02:01:12 +0900 Subject: [PATCH 07/53] =?UTF-8?q?test:=20=EC=9B=80=EC=A7=81=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=B6=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MovingScheduleBars.stories.tsx | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx new file mode 100644 index 000000000..8791139bd --- /dev/null +++ b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx @@ -0,0 +1,105 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; + +/** + * `MovingScheduleBars` 는 다수의 캘린더 바를 보여주는 컴포넌트이며, 제공되는 x, y값을 기반으로 상대위치만큼 이동하여 렌더링됩니다. **부모 요소가 `position: relative` 속성을 가지고 있어야 올바르게 동작합니다.** + * + * 마우스 조작을 통해 x, y 값을 계속해서 업데이트하면 마우스를 따라다니듯이 작동하도록 만들 수 있습니다. x, y 값을 변경하면서 컴포넌트의 변화를 테스트하세요. + */ +const meta = { + title: 'Schedule/MovingScheduleBars', + component: MovingScheduleBars, + tags: ['autodocs'], + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: { + scheduleBars: { + description: '렌더링할 스케줄 바들의 정보를 의미합니다.', + }, + relativeX: { + description: + '기존 좌표에서 좌우로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 오른쪽으로 이동하여 렌더링되고, 음수일 경우 왼쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다.', + }, + relativeY: { + description: + '기존 좌표에서 상하로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 아래쪽으로 이동하여 렌더링되고, 음수일 경우 위쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다.', + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + scheduleBars: [ + { + id: '1', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 0, + column: 1, + duration: 6, + level: 0, + roundedStart: true, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '2', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 1, + column: 0, + duration: 7, + level: 0, + roundedStart: false, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '3', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 2, + column: 0, + duration: 4, + level: 0, + roundedStart: false, + roundedEnd: true, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + ], + relativeX: 0, + relativeY: 0, + }, +}; From 7a92a9c16b60739bfdd7d1803319d1c09247bd25 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 7 Nov 2023 02:11:04 +0900 Subject: [PATCH 08/53] =?UTF-8?q?feat:=20useCalendarDragScreen=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=ED=9B=85=EC=97=90=20=EC=83=81=EB=8C=80?= =?UTF-8?q?=EC=A2=8C=ED=91=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=EC=9D=98=20=EB=B3=80=ED=99=98=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useCalendarDragScreen.ts | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index d83844f3d..75b6812da 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -1,17 +1,64 @@ -import { useEffect } from 'react'; +import { useState, useEffect } from 'react'; +import { generateScheduleBars } from '~/utils/generateScheduleBars'; +import type { Schedule, Point } from '~/types/schedule'; interface UseCalendarDragScreenProps { + visible: boolean; onMouseUp: () => void; + year: number; + month: number; + level: number; + schedule: Schedule; + initMouseX: number; + initMouseY: number; } export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { - const { onMouseUp } = props; + const { + visible, + onMouseUp, + year, + month, + level, + schedule, + initMouseX, + initMouseY, + } = props; + const [relativePoint, setRelativePoint] = useState({ + x: initMouseX, + y: initMouseY, + }); + + const scheduleBars = generateScheduleBars(year, month, [schedule]).map( + (scheduleBar) => ({ ...scheduleBar, level }), + ); useEffect(() => { + const onMouseMove = (e: globalThis.MouseEvent) => { + if (!visible) { + return; + } + + const { clientX, clientY } = e; + + setRelativePoint(() => ({ + x: clientX - initMouseX, + y: clientY - initMouseY, + })); + }; + + document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); return () => { + document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); }; - }, [onMouseUp]); + }, [visible, onMouseUp, initMouseX, initMouseY]); + + return { + movingScheduleBars: scheduleBars, + relativeX: relativePoint.x, + relativeY: relativePoint.y, + }; }; From 7005975a3c887fc0a001d1cf0c8d85533b2f0259 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 7 Nov 2023 02:16:07 +0900 Subject: [PATCH 09/53] =?UTF-8?q?feat:=20=EA=B0=80=EC=A7=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=ED=9B=85=EA=B3=BC=20=EC=BA=98=EB=A6=B0=EB=8D=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=84=20=EA=B2=B0=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen.styled.ts | 1 + .../CalendarDragScreen/CalendarDragScreen.tsx | 41 +++++++++++++++++-- .../TeamCalendar/TeamCalendar.tsx | 26 +++++++++--- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts index d91e6ff89..5c08083e1 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -2,6 +2,7 @@ import { styled } from 'styled-components'; export const Container = styled.div` position: absolute; + overflow: hidden; left: 0; top: 0; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index c4392427a..c10a5d9c3 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,16 +1,51 @@ import * as S from './CalendarDragScreen.styled'; +import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; +import type { Schedule } from '~/types/schedule'; import { useCalendarDragScreen } from './useCalendarDragScreen'; interface CalendarDragScreenProps { visible: boolean; + year: number; + month: number; + level: number; + schedule: Schedule; + initMouseX: number; + initMouseY: number; onMouseUp: () => void; } const CalendarDragScreen = (props: CalendarDragScreenProps) => { - const { visible, onMouseUp } = props; - useCalendarDragScreen({ onMouseUp }); + const { + visible, + year, + month, + level, + schedule, + initMouseX, + initMouseY, + onMouseUp, + } = props; + const { movingScheduleBars, relativeX, relativeY } = useCalendarDragScreen({ + visible, + onMouseUp, + year, + month, + level, + schedule, + initMouseX, + initMouseY, + }); - return visible ? : null; + return visible ? ( + + + {/* */} + + ) : null; }; export default CalendarDragScreen; diff --git a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx index ee3412d81..23f019066 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx +++ b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx @@ -16,6 +16,7 @@ import { useModal } from '~/hooks/useModal'; import { useTeamPlace } from '~/hooks/useTeamPlace'; import { useCalendarResizePosition } from '~/hooks/useCalendarResizePosition'; import { usePrefetchSchedules } from '~/hooks/queries/usePrefetchSchedules'; +import { useScheduleDragStatus } from './useScheduleBarDragStatus'; import { DAYS_OF_WEEK, MODAL_OPEN_TYPE } from '~/constants/calendar'; import { generateScheduleBars } from '~/utils/generateScheduleBars'; import { arrayOf } from '~/utils/arrayOf'; @@ -39,7 +40,8 @@ interface TeamCalendarProps { const TeamCalendar = (props: TeamCalendarProps) => { const { calendarSize = 'md' } = props; - const [isDragging, setIsDragging] = useState(false); + const { dragStatus, handleDragStart, handleMouseUp } = + useScheduleDragStatus(); const { teamPlaceId } = useTeamPlace(); const { @@ -232,8 +234,15 @@ const TeamCalendar = (props: TeamCalendarProps) => { {scheduleBars.map((scheduleBar) => { - const { id, scheduleId, row, column, level, duration } = - scheduleBar; + const { + id, + scheduleId, + row, + column, + level, + duration, + schedule, + } = scheduleBar; if (row === rowIndex && level > 2) return arrayOf(duration).map((_, index) => { @@ -274,7 +283,9 @@ const TeamCalendar = (props: TeamCalendarProps) => { level, }); }} - onDragStart={() => setIsDragging(() => true)} + onDragStart={(e) => + handleDragStart(e, level, schedule) + } {...scheduleBar} /> ); @@ -320,8 +331,11 @@ const TeamCalendar = (props: TeamCalendarProps) => { ); })} setIsDragging(() => false)} + visible={dragStatus.isDragging} + year={year} + month={month} + onMouseUp={handleMouseUp} + {...dragStatus} /> From b098b858cb2a5c10b3cf70af198a32a53f609025 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 7 Nov 2023 03:03:19 +0900 Subject: [PATCH 10/53] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=EC=9D=98=20=ED=81=AC=EA=B8=B0=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?CalendarDragScreen=EC=97=90=20=ED=91=9C=EC=8B=9C=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=EC=9D=98=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=EA=B0=80=20=EB=B0=98=EC=98=81=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team_calendar/CalendarDragScreen/CalendarDragScreen.tsx | 4 ++++ .../CalendarDragScreen/useCalendarDragScreen.ts | 5 ++++- .../components/team_calendar/TeamCalendar/TeamCalendar.tsx | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index c10a5d9c3..bbb8c58e1 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,10 +1,12 @@ import * as S from './CalendarDragScreen.styled'; import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; import type { Schedule } from '~/types/schedule'; +import type { CalendarSize } from '~/types/size'; import { useCalendarDragScreen } from './useCalendarDragScreen'; interface CalendarDragScreenProps { visible: boolean; + calendarSize: CalendarSize; year: number; month: number; level: number; @@ -17,6 +19,7 @@ interface CalendarDragScreenProps { const CalendarDragScreen = (props: CalendarDragScreenProps) => { const { visible, + calendarSize, year, month, level, @@ -27,6 +30,7 @@ const CalendarDragScreen = (props: CalendarDragScreenProps) => { } = props; const { movingScheduleBars, relativeX, relativeY } = useCalendarDragScreen({ visible, + calendarSize, onMouseUp, year, month, diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index 75b6812da..c532dc1bc 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -1,9 +1,11 @@ import { useState, useEffect } from 'react'; import { generateScheduleBars } from '~/utils/generateScheduleBars'; import type { Schedule, Point } from '~/types/schedule'; +import type { CalendarSize } from '~/types/size'; interface UseCalendarDragScreenProps { visible: boolean; + calendarSize: CalendarSize; onMouseUp: () => void; year: number; month: number; @@ -16,6 +18,7 @@ interface UseCalendarDragScreenProps { export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { visible, + calendarSize, onMouseUp, year, month, @@ -30,7 +33,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { }); const scheduleBars = generateScheduleBars(year, month, [schedule]).map( - (scheduleBar) => ({ ...scheduleBar, level }), + (scheduleBar) => ({ ...scheduleBar, level, calendarSize }), ); useEffect(() => { diff --git a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx index 23f019066..20aa41b4f 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx +++ b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx @@ -332,6 +332,7 @@ const TeamCalendar = (props: TeamCalendarProps) => { })} Date: Tue, 7 Nov 2023 21:30:34 +0900 Subject: [PATCH 11/53] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=EB=A5=BC=20CalendarDragScreen=20=EC=9E=90=EC=B2=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B4=80=EB=A6=AC=ED=95=98=EA=B3=A0,=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A0=88=EB=8C=80=20=EC=A2=8C=ED=91=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.tsx | 22 ++---- .../useCalendarDragScreen.ts | 74 +++++++++++++++---- .../team_calendar/ScheduleBar/ScheduleBar.tsx | 3 +- .../TeamCalendar/TeamCalendar.tsx | 4 +- .../TeamCalendar/useScheduleBarDragStatus.ts | 14 +--- 5 files changed, 68 insertions(+), 49 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index bbb8c58e1..48e4d48f9 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,4 +1,5 @@ import * as S from './CalendarDragScreen.styled'; +import { useRef } from 'react'; import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; @@ -11,37 +12,26 @@ interface CalendarDragScreenProps { month: number; level: number; schedule: Schedule; - initMouseX: number; - initMouseY: number; onMouseUp: () => void; } const CalendarDragScreen = (props: CalendarDragScreenProps) => { - const { - visible, - calendarSize, - year, - month, - level, - schedule, - initMouseX, - initMouseY, - onMouseUp, - } = props; + const { visible, calendarSize, year, month, level, schedule, onMouseUp } = + props; + const calendarRef = useRef(null); const { movingScheduleBars, relativeX, relativeY } = useCalendarDragScreen({ visible, + calendarRef, calendarSize, onMouseUp, year, month, level, schedule, - initMouseX, - initMouseY, }); return visible ? ( - + ; calendarSize: CalendarSize; onMouseUp: () => void; year: number; month: number; level: number; schedule: Schedule; - initMouseX: number; - initMouseY: number; +} + +interface CalendarPointInfos { + initX: number; + initY: number; + relativeX: number; + relativeY: number; + absoluteX: number; + absoluteY: number; } export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { visible, + calendarRef, calendarSize, onMouseUp, year, month, level, schedule, - initMouseX, - initMouseY, } = props; - const [relativePoint, setRelativePoint] = useState({ - x: initMouseX, - y: initMouseY, - }); + const [calendarPointInfos, setCalendarPointInfos] = + useState({ + initX: 0, + initY: 0, + relativeX: 0, + relativeY: 0, + absoluteX: 0, + absoluteY: 0, + }); + const { relativeX, relativeY, absoluteX, absoluteY } = calendarPointInfos; const scheduleBars = generateScheduleBars(year, month, [schedule]).map( (scheduleBar) => ({ ...scheduleBar, level, calendarSize }), ); useEffect(() => { + const onMouseDown = (e: globalThis.MouseEvent) => { + const { clientX, clientY } = e; + + setCalendarPointInfos((prev) => ({ + ...prev, + initX: clientX, + initY: clientY, + })); + }; + const onMouseMove = (e: globalThis.MouseEvent) => { if (!visible) { return; } + const calendarElement = calendarRef.current; + + if (!calendarElement) { + return; + } + const { clientX, clientY } = e; + const { top, left } = calendarElement.getBoundingClientRect(); - setRelativePoint(() => ({ - x: clientX - initMouseX, - y: clientY - initMouseY, + setCalendarPointInfos((prev) => ({ + ...prev, + relativeX: clientX - prev.initX, + relativeY: clientY - prev.initY, + absoluteX: clientX - left, + absoluteY: clientY - top, })); }; + document.addEventListener('mousedown', onMouseDown); document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); return () => { + document.removeEventListener('mousedown', onMouseDown); document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); }; - }, [visible, onMouseUp, initMouseX, initMouseY]); + }, [ + visible, + onMouseUp, + calendarRef, + relativeX, + relativeY, + absoluteX, + absoluteY, + ]); return { movingScheduleBars: scheduleBars, - relativeX: relativePoint.x, - relativeY: relativePoint.y, + relativeX, + relativeY, }; }; diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index 1a30089cd..a8f85aefb 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -1,6 +1,5 @@ import Text from '~/components/common/Text/Text'; import * as S from './ScheduleBar.styled'; -import type { MouseEvent } from 'react'; import type { GeneratedScheduleBar } from '~/types/schedule'; import { DoubleArrowRightIcon } from '~/assets/svg'; import { useTeamPlace } from '~/hooks/useTeamPlace'; @@ -9,7 +8,7 @@ import type { CalendarSize } from '~/types/size'; export interface ScheduleBarProps extends GeneratedScheduleBar { calendarSize?: CalendarSize; onClick?: () => void; - onDragStart?: (e: MouseEvent) => void; + onDragStart?: () => void; } const ScheduleBar = (props: ScheduleBarProps) => { diff --git a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx index 20aa41b4f..3bb384c25 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx +++ b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx @@ -283,9 +283,7 @@ const TeamCalendar = (props: TeamCalendarProps) => { level, }); }} - onDragStart={(e) => - handleDragStart(e, level, schedule) - } + onDragStart={() => handleDragStart(level, schedule)} {...scheduleBar} /> ); diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts index 9de8e54bb..e8198a662 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts +++ b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts @@ -6,8 +6,6 @@ interface DragStatus { isDragging: boolean; level: number; schedule: Schedule; - initMouseX: number; - initMouseY: number; } export const useScheduleDragStatus = () => { @@ -15,21 +13,13 @@ export const useScheduleDragStatus = () => { isDragging: false, level: 0, schedule: {} as Schedule, - initMouseX: 0, - initMouseY: 0, }); - const handleDragStart = ( - e: MouseEvent, - level: number, - schedule: Schedule, - ) => { + const handleDragStart = (level: number, schedule: Schedule) => { setDragStatus(() => ({ isDragging: true, schedule, level, - initMouseX: e.clientX, - initMouseY: e.clientY, })); }; @@ -42,8 +32,6 @@ export const useScheduleDragStatus = () => { isDragging: false, level: 0, schedule: {} as Schedule, - initMouseX: 0, - initMouseY: 0, })); }; From ff09a1f27b2780fb0030328464b693bc70c0520e Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 12:39:17 +0900 Subject: [PATCH 12/53] =?UTF-8?q?feat:=20=EB=B9=84=ED=99=9C=EC=84=B1=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=EC=97=90?= =?UTF-8?q?=EB=8F=84=20unmount=20=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - display: none을 이용하여 커스텀 훅의 state와 listener를 유지 --- .../CalendarDragScreen/CalendarDragScreen.styled.ts | 3 ++- .../team_calendar/CalendarDragScreen/CalendarDragScreen.tsx | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts index 5c08083e1..62c54e9c8 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -1,6 +1,7 @@ import { styled } from 'styled-components'; -export const Container = styled.div` +export const Container = styled.div<{ $visible: boolean }>` + ${({ $visible }) => !$visible && 'display: none'}; position: absolute; overflow: hidden; left: 0; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index 48e4d48f9..a1800cfe5 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -30,8 +30,8 @@ const CalendarDragScreen = (props: CalendarDragScreenProps) => { schedule, }); - return visible ? ( - + return ( + { /> {/* */} - ) : null; + ); }; export default CalendarDragScreen; From 3f862db1cc3940ac1919a21fe49fee0444c7becd Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 12:46:31 +0900 Subject: [PATCH 13/53] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=EC=99=80=20=EC=83=81=EB=8C=80=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20=EC=BA=98?= =?UTF-8?q?=EB=A6=B0=EB=8D=94=20=EC=B9=B8=20=EC=9D=B4=EB=8F=99=20=EC=88=98?= =?UTF-8?q?=EC=B9=98=EB=A5=BC=20=EA=B5=AC=ED=95=98=EB=8A=94=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=20=ED=95=A8=EC=88=98=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - '칸 이동 수치'란 시작 좌표를 기준으로 행, 열을 얼마나 이동했는지를 의미하는 수치이다. 이는 캘린더 바의 모양을 어떻게 정할지를 계산하는 데 사용된다. --- .../generateMovingScheduleBars.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts new file mode 100644 index 000000000..a69f0a728 --- /dev/null +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts @@ -0,0 +1,17 @@ +const getCalendarGridDifference = ( + relativeX: number, + relativeY: number, + calendarWidth: number, + calendarHeight: number, +) => { + const rowDifference = + relativeY > 0 + ? Math.floor((relativeY * 6) / calendarHeight) + : Math.ceil((relativeY * 6) / calendarHeight); + const columnDifference = + relativeX > 0 + ? Math.floor((relativeX * 7) / calendarWidth) + : Math.ceil((relativeX * 7) / calendarWidth); + + return { rowDifference, columnDifference }; +}; From dcb471ef26c996d7b545fa7a078fdb09323548ce Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 12:47:29 +0900 Subject: [PATCH 14/53] =?UTF-8?q?feat:=20=EB=82=A0=EC=A7=9C=20=ED=8F=AC?= =?UTF-8?q?=EB=A7=B7=EC=9D=84=20=EB=B0=9B=EC=95=84=20n=EC=9D=BC=20?= =?UTF-8?q?=EC=A7=80=EB=82=9C=20=EB=82=A0=EC=A7=9C=20=ED=8F=AC=EB=A7=B7?= =?UTF-8?q?=EC=9D=84=20=EB=A6=AC=ED=84=B4=ED=95=B4=20=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateMovingScheduleBars.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts index a69f0a728..46f06a245 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts @@ -1,3 +1,4 @@ +import type { Schedule } from '~/types/schedule'; const getCalendarGridDifference = ( relativeX: number, relativeY: number, @@ -15,3 +16,20 @@ const getCalendarGridDifference = ( return { rowDifference, columnDifference }; }; + +const changeDateTimeByDays = ( + dateTime: Schedule['startDateTime'], + days: number, +) => { + const changedDate = new Date(Number(new Date(dateTime)) + 86_400_000 * days); + + const year = String(changedDate.getFullYear()).padStart(4, '0'); + const month = String(changedDate.getMonth() + 1).padStart(2, '0'); + const day = String(changedDate.getDate()).padStart(2, '0'); + const time = dateTime.split(' ')[1]; + const [minute, second] = time.split(':'); + + const changedDateTime: Schedule['startDateTime'] = `${year}-${month}-${day} ${minute}:${second}`; + + return changedDateTime; +}; From a8e6e5a0ba8d608dcdd96f25fbe1df8205e63535 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 12:49:19 +0900 Subject: [PATCH 15/53] =?UTF-8?q?feat:=20=EC=9B=80=EC=A7=81=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8A=94=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateMovingScheduleBars.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts index 46f06a245..624a2d2e3 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts @@ -1,4 +1,19 @@ +import { generateScheduleBars } from '~/utils/generateScheduleBars'; import type { Schedule } from '~/types/schedule'; +import type { CalendarSize } from '~/types/size'; + +interface GenerateMovingScheduleBarsParams { + schedule: Schedule; + year: number; + month: number; + relativeX: number; + relativeY: number; + calendarWidth: number; + calendarHeight: number; + level: number; + calendarSize: CalendarSize; +} + const getCalendarGridDifference = ( relativeX: number, relativeY: number, @@ -33,3 +48,36 @@ const changeDateTimeByDays = ( return changedDateTime; }; + +export const generateMovingScheduleBars = ( + params: GenerateMovingScheduleBarsParams, +) => { + const { + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + } = params; + + const { columnDifference } = getCalendarGridDifference( + relativeX, + relativeY, + calendarWidth, + calendarHeight, + ); + const { startDateTime, endDateTime } = schedule; + const generatedMovingScheduleBars = generateScheduleBars(year, month, [ + { + ...schedule, + startDateTime: changeDateTimeByDays(startDateTime, columnDifference), + endDateTime: changeDateTimeByDays(endDateTime, columnDifference), + }, + ]).map((scheduleBar) => ({ ...scheduleBar, level, calendarSize })); + + return generatedMovingScheduleBars; +}; From 5727b054d4b28469ca8c645d8b16d522b63cc5d4 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 12:52:00 +0900 Subject: [PATCH 16/53] =?UTF-8?q?feat:=20=EC=A0=88=EB=8C=80=20=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=20=EB=B0=A9=EC=8B=9D=EC=97=90=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useCalendarDragScreen.ts | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index 2416cbc9c..a6d27f0c7 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { generateScheduleBars } from '~/utils/generateScheduleBars'; +import { generateMovingScheduleBars } from './generateMovingScheduleBars'; import type { RefObject } from 'react'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; @@ -20,8 +20,8 @@ interface CalendarPointInfos { initY: number; relativeX: number; relativeY: number; - absoluteX: number; - absoluteY: number; + calendarWidth: number; + calendarHeight: number; } export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { @@ -41,16 +41,33 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { initY: 0, relativeX: 0, relativeY: 0, - absoluteX: 0, - absoluteY: 0, + calendarWidth: 0, + calendarHeight: 0, }); - const { relativeX, relativeY, absoluteX, absoluteY } = calendarPointInfos; + const { initX, initY, relativeX, relativeY, calendarWidth, calendarHeight } = + calendarPointInfos; - const scheduleBars = generateScheduleBars(year, month, [schedule]).map( - (scheduleBar) => ({ ...scheduleBar, level, calendarSize }), - ); + const scheduleBars = visible + ? generateMovingScheduleBars({ + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + }) + : []; useEffect(() => { + const calendarElement = calendarRef.current; + + if (!calendarElement) { + return; + } + const onMouseDown = (e: globalThis.MouseEvent) => { const { clientX, clientY } = e; @@ -66,46 +83,41 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { return; } - const calendarElement = calendarRef.current; - - if (!calendarElement) { - return; - } - const { clientX, clientY } = e; - const { top, left } = calendarElement.getBoundingClientRect(); setCalendarPointInfos((prev) => ({ ...prev, - relativeX: clientX - prev.initX, - relativeY: clientY - prev.initY, - absoluteX: clientX - left, - absoluteY: clientY - top, + relativeX: clientX - initX, + relativeY: clientY - initY, })); }; + const resizeObserver = new ResizeObserver(() => { + const { clientWidth, clientHeight } = calendarElement; + + setCalendarPointInfos((prev) => ({ + ...prev, + calendarWidth: clientWidth, + calendarHeight: clientHeight, + })); + }); + document.addEventListener('mousedown', onMouseDown); - document.addEventListener('mousemove', onMouseMove); + calendarElement.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); + resizeObserver.observe(calendarElement); return () => { document.removeEventListener('mousedown', onMouseDown); - document.removeEventListener('mousemove', onMouseMove); + calendarElement.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); + resizeObserver.disconnect(); }; - }, [ - visible, - onMouseUp, - calendarRef, - relativeX, - relativeY, - absoluteX, - absoluteY, - ]); + }, [visible, onMouseUp, calendarRef, relativeX, relativeY, initX, initY]); return { movingScheduleBars: scheduleBars, - relativeX, + relativeX: relativeX % (calendarWidth / 7), relativeY, }; }; From 4b52e5bc109ff8ba05dffb8dcb947a30d9f5dff5 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 15:44:52 +0900 Subject: [PATCH 17/53] =?UTF-8?q?feat:=20ScheduleBar=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=EC=A2=8C=ED=91=9C=EB=A5=BC=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=ED=95=98=EB=8A=94=20=EB=B0=A9=EC=8B=9D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9E=AC=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - onMouseDown 이벤트로 인해 스케줄 바에 해당하는 일정 모달이 띄워지지 않는 문제가 있음 --- .../CalendarDragScreen/CalendarDragScreen.tsx | 17 +++++++++++-- .../useCalendarDragScreen.ts | 24 ++++++------------- .../team_calendar/ScheduleBar/ScheduleBar.tsx | 3 ++- .../TeamCalendar/TeamCalendar.tsx | 4 +++- .../TeamCalendar/useScheduleBarDragStatus.ts | 16 ++++++++++++- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index a1800cfe5..e09fa2ce5 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -7,6 +7,8 @@ import { useCalendarDragScreen } from './useCalendarDragScreen'; interface CalendarDragScreenProps { visible: boolean; + initX: number; + initY: number; calendarSize: CalendarSize; year: number; month: number; @@ -16,11 +18,22 @@ interface CalendarDragScreenProps { } const CalendarDragScreen = (props: CalendarDragScreenProps) => { - const { visible, calendarSize, year, month, level, schedule, onMouseUp } = - props; + const { + visible, + initX, + initY, + calendarSize, + year, + month, + level, + schedule, + onMouseUp, + } = props; const calendarRef = useRef(null); const { movingScheduleBars, relativeX, relativeY } = useCalendarDragScreen({ visible, + initX, + initY, calendarRef, calendarSize, onMouseUp, diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index a6d27f0c7..d344c826f 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -9,6 +9,8 @@ interface UseCalendarDragScreenProps { calendarRef: RefObject; calendarSize: CalendarSize; onMouseUp: () => void; + initX: number; + initY: number; year: number; month: number; level: number; @@ -16,8 +18,6 @@ interface UseCalendarDragScreenProps { } interface CalendarPointInfos { - initX: number; - initY: number; relativeX: number; relativeY: number; calendarWidth: number; @@ -29,6 +29,8 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { visible, calendarRef, calendarSize, + initX, + initY, onMouseUp, year, month, @@ -37,14 +39,12 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { } = props; const [calendarPointInfos, setCalendarPointInfos] = useState({ - initX: 0, - initY: 0, relativeX: 0, relativeY: 0, calendarWidth: 0, calendarHeight: 0, }); - const { initX, initY, relativeX, relativeY, calendarWidth, calendarHeight } = + const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; const scheduleBars = visible @@ -68,16 +68,6 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { return; } - const onMouseDown = (e: globalThis.MouseEvent) => { - const { clientX, clientY } = e; - - setCalendarPointInfos((prev) => ({ - ...prev, - initX: clientX, - initY: clientY, - })); - }; - const onMouseMove = (e: globalThis.MouseEvent) => { if (!visible) { return; @@ -85,6 +75,8 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { clientX, clientY } = e; + console.log({ x: clientX - initX, y: clientY - initY }); + setCalendarPointInfos((prev) => ({ ...prev, relativeX: clientX - initX, @@ -102,13 +94,11 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { })); }); - document.addEventListener('mousedown', onMouseDown); calendarElement.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); resizeObserver.observe(calendarElement); return () => { - document.removeEventListener('mousedown', onMouseDown); calendarElement.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); resizeObserver.disconnect(); diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index a8f85aefb..0bb7565b1 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -3,12 +3,13 @@ import * as S from './ScheduleBar.styled'; import type { GeneratedScheduleBar } from '~/types/schedule'; import { DoubleArrowRightIcon } from '~/assets/svg'; import { useTeamPlace } from '~/hooks/useTeamPlace'; +import type { MouseEvent } from 'react'; import type { CalendarSize } from '~/types/size'; export interface ScheduleBarProps extends GeneratedScheduleBar { calendarSize?: CalendarSize; onClick?: () => void; - onDragStart?: () => void; + onDragStart?: (e: MouseEvent) => void; } const ScheduleBar = (props: ScheduleBarProps) => { diff --git a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx index 3bb384c25..20aa41b4f 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx +++ b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx @@ -283,7 +283,9 @@ const TeamCalendar = (props: TeamCalendarProps) => { level, }); }} - onDragStart={() => handleDragStart(level, schedule)} + onDragStart={(e) => + handleDragStart(e, level, schedule) + } {...scheduleBar} /> ); diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts index e8198a662..0bd86f240 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts +++ b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts @@ -6,6 +6,8 @@ interface DragStatus { isDragging: boolean; level: number; schedule: Schedule; + initX: number; + initY: number; } export const useScheduleDragStatus = () => { @@ -13,13 +15,23 @@ export const useScheduleDragStatus = () => { isDragging: false, level: 0, schedule: {} as Schedule, + initX: 0, + initY: 0, }); - const handleDragStart = (level: number, schedule: Schedule) => { + const handleDragStart = ( + e: MouseEvent, + level: number, + schedule: Schedule, + ) => { + const { clientX, clientY } = e; + setDragStatus(() => ({ isDragging: true, schedule, level, + initX: clientX, + initY: clientY, })); }; @@ -32,6 +44,8 @@ export const useScheduleDragStatus = () => { isDragging: false, level: 0, schedule: {} as Schedule, + initX: 0, + initY: 0, })); }; From 488fbebd1b1bb10ab507b6b6dc3804c6aba841ad Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 18:07:58 +0900 Subject: [PATCH 18/53] =?UTF-8?q?feat:=20ScheduleBar=EC=97=90=20mode=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 스케줄 바가 이제 여러 목적(일반, 장식용, 인디케이터)으로 쓰이므로, mode를 통해 목적을 정한다. --- frontend/src/types/schedule.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index 6097def6d..63cd814d5 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -46,6 +46,7 @@ export interface GeneratedScheduleBar { level: number; roundedStart: boolean; roundedEnd: boolean; + mode?: 'normal' | 'no-interaction' | 'indicator'; } export interface Point { From 2ed57cffdb9c00e71b3f72a0120586a7ab2e6930 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 18:10:13 +0900 Subject: [PATCH 19/53] =?UTF-8?q?feat:=20ScheduleBar=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=97=90=20mode=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0=EB=A5=BC=20=EC=B6=94=EA=B0=80,=20no-interact?= =?UTF-8?q?ion=20=EB=AA=A8=EB=93=9C=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - no-interaction: 스케줄 바에 hover을 해도 반응이 없으며, 포인터가 바뀌지 않는 등 상호작용이 불가능해진다. 시각적인 용도로 사용해야 할 때 사용한다. --- .../ScheduleBar/ScheduleBar.styled.ts | 18 ++++++++++++------ .../team_calendar/ScheduleBar/ScheduleBar.tsx | 8 ++++++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts index 82885925c..a27ccc384 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts @@ -9,6 +9,7 @@ interface InnerProps { level: number; roundedStart: boolean; roundedEnd: boolean; + mode?: 'normal' | 'no-interaction' | 'indicator'; teamPlaceColor: TeamPlaceColor; } @@ -25,6 +26,7 @@ export const Wrapper = styled.div.withConfig({ 'duration', 'roundedStart', 'roundedEnd', + 'mode', ].includes(prop), })< Pick< @@ -35,6 +37,7 @@ export const Wrapper = styled.div.withConfig({ | 'duration' | 'roundedStart' | 'roundedEnd' + | 'mode' > >` position: absolute; @@ -52,9 +55,7 @@ export const Wrapper = styled.div.withConfig({ }} left: ${({ column }) => (column * 100) / 7}%; - width: ${({ duration }) => (duration * 100) / 7}%; - padding: ${({ roundedStart, roundedEnd }) => `0 ${roundedEnd ? '4px' : 0} 0 ${roundedStart ? '4px' : 0}`}; `; @@ -72,6 +73,7 @@ export const Inner = styled.div.withConfig({ 'roundedStart', 'roundedEnd', 'teamPlaceColor', + 'mode', ].includes(prop), })` display: flex; @@ -90,11 +92,15 @@ export const Inner = styled.div.withConfig({ filter: brightness(${({ level }) => 1 + level * 0.4}); - cursor: pointer; + ${({ mode = 'normal' }) => + mode === 'normal' && + css` + cursor: pointer; - &:hover { - opacity: 0.8; - } + &:hover { + opacity: 0.8; + } + `}; `; export const scheduleBarTitle = (calendarSize: CalendarSize) => css` diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index 0bb7565b1..e467508da 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -18,24 +18,28 @@ const ScheduleBar = (props: ScheduleBarProps) => { onClick, roundedEnd, onDragStart, + mode = 'normal', calendarSize = 'md', ...rest } = props; const { teamPlaceColor } = useTeamPlace(); + const isInteractable = mode === 'normal'; return ( From b532eaaa9375b1b1ecb869492d40624f063d618e Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 18:11:50 +0900 Subject: [PATCH 20/53] =?UTF-8?q?test:=20ScheduleBar=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=B6=81=EC=97=90=20no-interaction=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScheduleBar/ScheduleBar.stories.tsx | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx index bc6912594..23809bd57 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx @@ -119,3 +119,27 @@ export const LongTitle: Story = { onClick: () => alert('clicked!'), }, }; + +/** + * `mode` 값이 `no-interaction`일 경우, 해당 캘린더 바는 오로지 장식 용도가 되며 **상호작용이 불가능**하게 됩니다. 가짜 스케줄 바 드래그 화면 등 시각적인 효과를 위해 사용할 수 있습니다. + */ +export const NoInteraction: Story = { + args: { + id: '1', + scheduleId: 1, + schedule: { + id: 1, + title: 'No Interaction', + startDateTime: '2023-07-07 05:00', + endDateTime: '2023-07-09 10:00', + }, + title: 'No Interaction', + row: 1, + column: 2, + duration: 3, + level: 0, + roundedStart: true, + roundedEnd: true, + mode: 'no-interaction', + }, +}; From dc58954076655e0075bb861a4b58996d5bd993bb Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 18:12:34 +0900 Subject: [PATCH 21/53] =?UTF-8?q?feat:=20MovingScheduleBar=EC=9D=98=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=EB=8A=94=20=EC=83=81?= =?UTF-8?q?=ED=98=B8=EC=9E=91=EC=9A=A9=EC=9D=B4=20=EB=B6=88=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/generateMovingScheduleBars.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts index 624a2d2e3..ebb820c9b 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts @@ -77,7 +77,12 @@ export const generateMovingScheduleBars = ( startDateTime: changeDateTimeByDays(startDateTime, columnDifference), endDateTime: changeDateTimeByDays(endDateTime, columnDifference), }, - ]).map((scheduleBar) => ({ ...scheduleBar, level, calendarSize })); + ]).map((scheduleBar) => ({ + ...scheduleBar, + level, + calendarSize, + mode: 'no-interaction', + })); return generatedMovingScheduleBars; }; From f04465a913beda37a457bdb5d42e1babca188296 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 22:20:03 +0900 Subject: [PATCH 22/53] =?UTF-8?q?feat:=20ScheduleBar=EC=97=90=EC=84=9C=20i?= =?UTF-8?q?ndicator=20=EB=AA=A8=EB=93=9C=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - indicator 모드: 상호작용이 불가능하며, 스케줄 바의 윤곽만 나타난다. 스케줄 바가 놓일 위치를 시각적으로 표시하는 데에 사용한다. --- .../ScheduleBar/ScheduleBar.styled.ts | 25 +++++++++++++++---- .../team_calendar/ScheduleBar/ScheduleBar.tsx | 8 +++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts index a27ccc384..101f68762 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.styled.ts @@ -9,7 +9,7 @@ interface InnerProps { level: number; roundedStart: boolean; roundedEnd: boolean; - mode?: 'normal' | 'no-interaction' | 'indicator'; + mode: 'normal' | 'no-interaction' | 'indicator'; teamPlaceColor: TeamPlaceColor; } @@ -83,16 +83,31 @@ export const Inner = styled.div.withConfig({ height: 100%; padding-left: 6px; - background-color: ${({ theme, teamPlaceColor = 0 }) => - theme.teamColor[teamPlaceColor]}; + background-color: ${({ theme, teamPlaceColor = 0, mode }) => + mode === 'indicator' ? 'transparent' : theme.teamColor[teamPlaceColor]}; border-radius: ${({ roundedStart, roundedEnd }) => `${roundedStart ? '4px' : '0'} ${roundedEnd ? '4px 4px' : '0 0'} ${ roundedStart ? '4px' : '0' }`}; - filter: brightness(${({ level }) => 1 + level * 0.4}); + ${({ mode, theme }) => + mode === 'indicator' && + css` + margin-top: -2px; + + border: 2px solid ${theme.color.GRAY400}; + + box-shadow: 0 0 24px ${theme.color.GRAY600}; + box-sizing: content-box; + `}; + + ${({ mode, level }) => + mode !== 'indicator' && + css` + filter: brightness(${1 + level * 0.4}); + `}; - ${({ mode = 'normal' }) => + ${({ mode }) => mode === 'normal' && css` cursor: pointer; diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index e467508da..07a905af9 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -42,9 +42,11 @@ const ScheduleBar = (props: ScheduleBarProps) => { mode={mode} {...rest} > - - {title} - + {mode !== 'indicator' && ( + + {title} + + )} {!roundedEnd && } From 17eef101172b0a98abed4d5d29bdab858da6a8f6 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 22:21:54 +0900 Subject: [PATCH 23/53] =?UTF-8?q?test:=20ScheduleBar=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=B6=81=EC=97=90=20indicator=EC=9D=B8=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=A5=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScheduleBar/ScheduleBar.stories.tsx | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx index 23809bd57..7cd85f4b7 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.stories.tsx @@ -143,3 +143,27 @@ export const NoInteraction: Story = { mode: 'no-interaction', }, }; + +/** + * `mode` 값이 `indicator`일 경우, 해당 캘린더 바는 **상호작용이 불가능하고 캘린더 바의 윤곽만 드러내는** 시각적 요소가 됩니다. 캘린더 바가 놓일 위치를 시각적으로 표시하는 데에 사용합니다. + */ +export const Indicator: Story = { + args: { + id: '1', + scheduleId: 1, + schedule: { + id: 1, + title: 'This should not shown', + startDateTime: '2023-07-07 05:00', + endDateTime: '2023-07-09 10:00', + }, + title: 'This should not shown', + row: 1, + column: 2, + duration: 3, + level: 0, + roundedStart: true, + roundedEnd: true, + mode: 'indicator', + }, +}; From d5a39c29b2d95edff3558ea4f55e2901c87fa247 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 22:25:30 +0900 Subject: [PATCH 24/53] =?UTF-8?q?feat:=20ScheduleIndicator=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 스케줄 바를 인디케이터 형태로 보여주는 컴포넌트 --- .../ScheduleBarsIndicator.styled.ts | 15 +++++++++ .../ScheduleBarsIndicator.tsx | 32 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts create mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts new file mode 100644 index 000000000..8d97fd2c0 --- /dev/null +++ b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts @@ -0,0 +1,15 @@ +import { styled } from 'styled-components'; + +export const Container = styled.div` + display: flex; + flex-direction: column; + position: absolute; + + width: 100%; + height: 100%; +`; + +export const CalendarRow = styled.div` + position: relative; + flex-grow: 1; +`; diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx new file mode 100644 index 000000000..8661ad4c1 --- /dev/null +++ b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx @@ -0,0 +1,32 @@ +import * as S from './ScheduleBarsIndicator.styled'; +import ScheduleBar from '~/components/team_calendar/ScheduleBar/ScheduleBar'; +import { arrayOf } from '~/utils/arrayOf'; +import type { GeneratedScheduleBar } from '~/types/schedule'; + +interface ScheduleBarsIndicator { + scheduleBars: GeneratedScheduleBar[]; +} + +const ScheduleBarsIndicator = (props: ScheduleBarsIndicator) => { + const { scheduleBars } = props; + + return ( + + {arrayOf(6).map((_, rowIndex) => ( + + {scheduleBars.map((scheduleBar) => { + return scheduleBar.row === rowIndex ? ( + + ) : null; + })} + + ))} + + ); +}; + +export default ScheduleBarsIndicator; From 26b74c9fffa5474e927fcdb02661a35ee246d4d3 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 8 Nov 2023 22:27:00 +0900 Subject: [PATCH 25/53] =?UTF-8?q?test:=20ScheduleIndicator=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20=ED=95=B4=EB=8B=B9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScheduleBarsIndicator.stories.tsx | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx new file mode 100644 index 000000000..0d509522e --- /dev/null +++ b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx @@ -0,0 +1,93 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import ScheduleBarsIndicator from '~/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator'; + +/** + * `ScheduleBarsIndicator` 는 다수의 캘린더 바를 활용하여 스케줄 바가 놓일 위치에 대한 시각적인 정보를 제공하는 컴포넌트입니다. + */ +const meta = { + title: 'Schedule/ScheduleBarsIndicator', + component: ScheduleBarsIndicator, + tags: ['autodocs'], + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: { + scheduleBars: { + description: '렌더링할 스케줄 바들의 정보를 의미합니다.', + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + scheduleBars: [ + { + id: '1', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 0, + column: 1, + duration: 6, + level: 0, + roundedStart: true, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '2', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 1, + column: 0, + duration: 7, + level: 0, + roundedStart: false, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '3', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 2, + column: 0, + duration: 4, + level: 0, + roundedStart: false, + roundedEnd: true, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + ], + }, +}; From b8d7223d927ef4a5b13b6c5471ef2d5e04826474 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 11:52:25 +0900 Subject: [PATCH 26/53] =?UTF-8?q?feat:=20=EB=91=90=20=EC=A2=85=EB=A5=98?= =?UTF-8?q?=EC=9D=98=20=EA=B0=80=EC=A7=9C=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=ED=95=98=EB=82=98=EC=9D=98=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FakeScheduleBarsScreen.stories.tsx | 127 ++++++++++++++++++ .../FakeScheduleBarsScreen.styled.ts} | 0 .../FakeScheduleBarsScreen.tsx | 45 +++++++ .../MovingScheduleBars.stories.tsx | 105 --------------- .../MovingScheduleBars/MovingScheduleBars.tsx | 30 ----- .../ScheduleBarsIndicator.stories.tsx | 93 ------------- .../ScheduleBarsIndicator.styled.ts | 15 --- .../ScheduleBarsIndicator.tsx | 32 ----- 8 files changed, 172 insertions(+), 275 deletions(-) create mode 100644 frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.stories.tsx rename frontend/src/components/team_calendar/{MovingScheduleBars/MovingScheduleBars.styled.ts => FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts} (100%) create mode 100644 frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.tsx delete mode 100644 frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx delete mode 100644 frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx delete mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx delete mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts delete mode 100644 frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx diff --git a/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.stories.tsx b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.stories.tsx new file mode 100644 index 000000000..66a9c0bc4 --- /dev/null +++ b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.stories.tsx @@ -0,0 +1,127 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import type { ComponentType } from 'react'; +import FakeScheduleBarsScreen from '~/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen'; +import type { GeneratedScheduleBar } from '~/types/schedule'; + +/** + * `FakeScheduleBarsScreen` 는 캘린더 바의 드래그 기능을 구현하기 위해 사용자에게 보여주는 가짜 캘린더 바로 구성된, 시각적인 컴포넌트입니다. + * + * `mode = schedule`일 경우, 마우스 조작을 통해 x, y 값을 계속해서 업데이트하면 마우스를 따라다니듯이 작동하도록 만들 수 있습니다. x, y 값을 변경하면서 컴포넌트의 변화를 테스트하세요. + */ +const meta = { + title: 'Schedule/FakeScheduleBarsScreen', + component: FakeScheduleBarsScreen, + tags: ['autodocs'], + decorators: [ + (Story: ComponentType) => ( +
+ +
+ ), + ], + argTypes: { + mode: { + description: + '이 컴포넌트의 모드를 의미합니다. 사용 목적에 따라 `schedule`과 `indicator` 중 하나를 명시해 주세요.', + }, + scheduleBars: { + description: '렌더링할 스케줄 바들의 정보를 의미합니다.', + }, + relativeX: { + description: + '기존 좌표에서 좌우로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 오른쪽으로 이동하여 렌더링되고, 음수일 경우 왼쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다. **이 프로퍼티는 `mode = schedule`일 때만 사용할 수 있습니다.**', + }, + relativeY: { + description: + '기존 좌표에서 상하로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 아래쪽으로 이동하여 렌더링되고, 음수일 경우 위쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다. **이 프로퍼티는 `mode = schedule`일 때만 사용할 수 있습니다.**', + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +const scheduleBars: GeneratedScheduleBar[] = [ + { + id: '1', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 0, + column: 1, + duration: 6, + level: 0, + roundedStart: true, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '2', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 1, + column: 0, + duration: 7, + level: 0, + roundedStart: false, + roundedEnd: false, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, + { + id: '3', + scheduleId: 1105, + title: '바쁜 필립의 3주짜리 일정', + row: 2, + column: 0, + duration: 4, + level: 0, + roundedStart: false, + roundedEnd: true, + schedule: { + id: 1105, + title: '바쁜 필립의 3주짜리 일정', + startDateTime: '2023-06-26 00:00', + endDateTime: '2023-07-12 23:59', + }, + }, +]; + +/** + * 이 모드는 가짜 스케줄 바를 보여줘야 할 경우에 사용합니다. + */ +export const ScheduleMode: Story = { + args: { + mode: 'schedule', + scheduleBars, + relativeX: 0, + relativeY: 0, + }, +}; + +/** + * 이 모드는 스케줄 바가 놓일 위치를 시각적으로 보여줘야 할 경우에 사용합니다. + */ +export const IndicatorMode: Story = { + args: { + mode: 'indicator', + scheduleBars, + }, +}; diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts similarity index 100% rename from frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.styled.ts rename to frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts diff --git a/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.tsx b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.tsx new file mode 100644 index 000000000..ab67b64bc --- /dev/null +++ b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.tsx @@ -0,0 +1,45 @@ +import * as S from './FakeScheduleBarsScreen.styled'; +import ScheduleBar from '~/components/team_calendar/ScheduleBar/ScheduleBar'; +import { arrayOf } from '~/utils/arrayOf'; +import type { GeneratedScheduleBar } from '~/types/schedule'; + +interface ScheduleModeProps { + mode: 'schedule'; + scheduleBars: GeneratedScheduleBar[]; + relativeX: number; + relativeY: number; +} + +interface IndicatorModeProps { + mode: 'indicator'; + scheduleBars: GeneratedScheduleBar[]; +} + +type FakeScheduleBarsScreenProps = ScheduleModeProps | IndicatorModeProps; + +const FakeScheduleBarsScreen = (props: FakeScheduleBarsScreenProps) => { + const { mode, scheduleBars } = props; + + return ( + + {arrayOf(6).map((_, rowIndex) => ( + + {scheduleBars.map((scheduleBar) => { + return scheduleBar.row === rowIndex ? ( + + ) : null; + })} + + ))} + + ); +}; + +export default FakeScheduleBarsScreen; diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx deleted file mode 100644 index 8791139bd..000000000 --- a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.stories.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; - -/** - * `MovingScheduleBars` 는 다수의 캘린더 바를 보여주는 컴포넌트이며, 제공되는 x, y값을 기반으로 상대위치만큼 이동하여 렌더링됩니다. **부모 요소가 `position: relative` 속성을 가지고 있어야 올바르게 동작합니다.** - * - * 마우스 조작을 통해 x, y 값을 계속해서 업데이트하면 마우스를 따라다니듯이 작동하도록 만들 수 있습니다. x, y 값을 변경하면서 컴포넌트의 변화를 테스트하세요. - */ -const meta = { - title: 'Schedule/MovingScheduleBars', - component: MovingScheduleBars, - tags: ['autodocs'], - decorators: [ - (Story) => ( -
- -
- ), - ], - argTypes: { - scheduleBars: { - description: '렌더링할 스케줄 바들의 정보를 의미합니다.', - }, - relativeX: { - description: - '기존 좌표에서 좌우로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 오른쪽으로 이동하여 렌더링되고, 음수일 경우 왼쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다.', - }, - relativeY: { - description: - '기존 좌표에서 상하로 얼마나 이동한 위치에 렌더링 시킬 것인지를 의미합니다. 이 값이 양수이면 기존 좌표에서 수치만큼 아래쪽으로 이동하여 렌더링되고, 음수일 경우 위쪽으로 이동하여 렌더링됩니다. 단위는 픽셀(px)입니다.', - }, - }, -} satisfies Meta; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = { - args: { - scheduleBars: [ - { - id: '1', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 0, - column: 1, - duration: 6, - level: 0, - roundedStart: true, - roundedEnd: false, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - { - id: '2', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 1, - column: 0, - duration: 7, - level: 0, - roundedStart: false, - roundedEnd: false, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - { - id: '3', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 2, - column: 0, - duration: 4, - level: 0, - roundedStart: false, - roundedEnd: true, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - ], - relativeX: 0, - relativeY: 0, - }, -}; diff --git a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx b/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx deleted file mode 100644 index dd635bf00..000000000 --- a/frontend/src/components/team_calendar/MovingScheduleBars/MovingScheduleBars.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as S from './MovingScheduleBars.styled'; -import ScheduleBar from '~/components/team_calendar/ScheduleBar/ScheduleBar'; -import { arrayOf } from '~/utils/arrayOf'; -import type { GeneratedScheduleBar } from '~/types/schedule'; - -interface MovingScheduleBarProps { - scheduleBars: GeneratedScheduleBar[]; - relativeX: number; - relativeY: number; -} - -const MovingScheduleBar = (props: MovingScheduleBarProps) => { - const { scheduleBars, relativeX, relativeY } = props; - - return ( - - {arrayOf(6).map((_, rowIndex) => ( - - {scheduleBars.map((scheduleBar) => { - return scheduleBar.row === rowIndex ? ( - - ) : null; - })} - - ))} - - ); -}; - -export default MovingScheduleBar; diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx deleted file mode 100644 index 0d509522e..000000000 --- a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.stories.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import ScheduleBarsIndicator from '~/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator'; - -/** - * `ScheduleBarsIndicator` 는 다수의 캘린더 바를 활용하여 스케줄 바가 놓일 위치에 대한 시각적인 정보를 제공하는 컴포넌트입니다. - */ -const meta = { - title: 'Schedule/ScheduleBarsIndicator', - component: ScheduleBarsIndicator, - tags: ['autodocs'], - decorators: [ - (Story) => ( -
- -
- ), - ], - argTypes: { - scheduleBars: { - description: '렌더링할 스케줄 바들의 정보를 의미합니다.', - }, - }, -} satisfies Meta; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = { - args: { - scheduleBars: [ - { - id: '1', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 0, - column: 1, - duration: 6, - level: 0, - roundedStart: true, - roundedEnd: false, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - { - id: '2', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 1, - column: 0, - duration: 7, - level: 0, - roundedStart: false, - roundedEnd: false, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - { - id: '3', - scheduleId: 1105, - title: '바쁜 필립의 3주짜리 일정', - row: 2, - column: 0, - duration: 4, - level: 0, - roundedStart: false, - roundedEnd: true, - schedule: { - id: 1105, - title: '바쁜 필립의 3주짜리 일정', - startDateTime: '2023-06-26 00:00', - endDateTime: '2023-07-12 23:59', - }, - }, - ], - }, -}; diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts deleted file mode 100644 index 8d97fd2c0..000000000 --- a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.styled.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { styled } from 'styled-components'; - -export const Container = styled.div` - display: flex; - flex-direction: column; - position: absolute; - - width: 100%; - height: 100%; -`; - -export const CalendarRow = styled.div` - position: relative; - flex-grow: 1; -`; diff --git a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx b/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx deleted file mode 100644 index 8661ad4c1..000000000 --- a/frontend/src/components/team_calendar/ScheduleBarsIndicator/ScheduleBarsIndicator.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as S from './ScheduleBarsIndicator.styled'; -import ScheduleBar from '~/components/team_calendar/ScheduleBar/ScheduleBar'; -import { arrayOf } from '~/utils/arrayOf'; -import type { GeneratedScheduleBar } from '~/types/schedule'; - -interface ScheduleBarsIndicator { - scheduleBars: GeneratedScheduleBar[]; -} - -const ScheduleBarsIndicator = (props: ScheduleBarsIndicator) => { - const { scheduleBars } = props; - - return ( - - {arrayOf(6).map((_, rowIndex) => ( - - {scheduleBars.map((scheduleBar) => { - return scheduleBar.row === rowIndex ? ( - - ) : null; - })} - - ))} - - ); -}; - -export default ScheduleBarsIndicator; From 8fd537e924175aa6e67d6833d7d7b76846ff5f21 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 11:53:23 +0900 Subject: [PATCH 27/53] =?UTF-8?q?feat:=20CalendarDragScreen=EC=97=90=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9=EB=90=9C=20=EA=B0=80=EC=A7=9C=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=80=EC=A4=84=20=EB=B0=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EB=B6=80=EC=B0=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.tsx | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index e09fa2ce5..20cf8de30 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,6 +1,6 @@ import * as S from './CalendarDragScreen.styled'; import { useRef } from 'react'; -import MovingScheduleBars from '~/components/team_calendar/MovingScheduleBars/MovingScheduleBars'; +import FakeScheduleBarsScreen from '~/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; import { useCalendarDragScreen } from './useCalendarDragScreen'; @@ -30,27 +30,32 @@ const CalendarDragScreen = (props: CalendarDragScreenProps) => { onMouseUp, } = props; const calendarRef = useRef(null); - const { movingScheduleBars, relativeX, relativeY } = useCalendarDragScreen({ - visible, - initX, - initY, - calendarRef, - calendarSize, - onMouseUp, - year, - month, - level, - schedule, - }); + const { movingScheduleBars, scheduleBarsIndicator, relativeX, relativeY } = + useCalendarDragScreen({ + visible, + initX, + initY, + calendarRef, + calendarSize, + onMouseUp, + year, + month, + level, + schedule, + }); return ( - + - {/* */} ); }; From 411cd4bb11367544093dee5f2c8b9a09f00aac1b Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 13:15:48 +0900 Subject: [PATCH 28/53] =?UTF-8?q?feat:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=EC=9D=98=20=EB=B3=80=EC=88=98=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD,=20=EC=9D=B8=EB=94=94=EC=BC=80=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=93=9C=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=ED=99=94?= =?UTF-8?q?=EC=82=B4=ED=91=9C=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team_calendar/ScheduleBar/ScheduleBar.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index 07a905af9..d12a0add4 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -23,16 +23,17 @@ const ScheduleBar = (props: ScheduleBarProps) => { ...rest } = props; const { teamPlaceColor } = useTeamPlace(); - const isInteractable = mode === 'normal'; + const isInteractive = mode === 'normal'; + const isIndicator = mode === 'indicator'; return ( @@ -42,12 +43,12 @@ const ScheduleBar = (props: ScheduleBarProps) => { mode={mode} {...rest} > - {mode !== 'indicator' && ( + {!isIndicator && ( {title} )} - {!roundedEnd && } + {!roundedEnd && !isIndicator && } ); From bcdbacffbf3b6a73e8ee29114354a491d9b06a6d Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 13:33:16 +0900 Subject: [PATCH 29/53] =?UTF-8?q?feat:=20=EA=B0=80=EC=A7=9C=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=80=EC=A4=84=EB=B0=94=EB=A5=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=9C=A0=ED=8B=B8=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD,=20=EC=84=B8=EB=A1=9C=EB=A1=9C?= =?UTF-8?q?=20=EC=8A=A4=EC=BC=80=EC=A4=84=EB=B0=94=EB=A5=BC=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EC=8B=9C=EC=BC=9C=EB=8F=84=20=EC=9E=90=EC=97=B0?= =?UTF-8?q?=EC=8A=A4=EB=9F=BD=EA=B2=8C=20=EC=9E=91=EB=8F=99=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.tsx | 32 ++++++++----------- ...ts => generateScheduleBarsByMousePoint.ts} | 21 ++++++------ .../useCalendarDragScreen.ts | 8 ++--- 3 files changed, 29 insertions(+), 32 deletions(-) rename frontend/src/components/team_calendar/CalendarDragScreen/{generateMovingScheduleBars.ts => generateScheduleBarsByMousePoint.ts} (74%) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index 20cf8de30..efcbd3adb 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -30,29 +30,25 @@ const CalendarDragScreen = (props: CalendarDragScreenProps) => { onMouseUp, } = props; const calendarRef = useRef(null); - const { movingScheduleBars, scheduleBarsIndicator, relativeX, relativeY } = - useCalendarDragScreen({ - visible, - initX, - initY, - calendarRef, - calendarSize, - onMouseUp, - year, - month, - level, - schedule, - }); + const { scheduleBars, relativeX, relativeY } = useCalendarDragScreen({ + visible, + initX, + initY, + calendarRef, + calendarSize, + onMouseUp, + year, + month, + level, + schedule, + }); return ( - + diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts similarity index 74% rename from frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts rename to frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts index ebb820c9b..47fa500b0 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/generateMovingScheduleBars.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts @@ -2,7 +2,7 @@ import { generateScheduleBars } from '~/utils/generateScheduleBars'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; -interface GenerateMovingScheduleBarsParams { +interface GenerateScheduleBarsByMousePointProps { schedule: Schedule; year: number; month: number; @@ -29,7 +29,9 @@ const getCalendarGridDifference = ( ? Math.floor((relativeX * 7) / calendarWidth) : Math.ceil((relativeX * 7) / calendarWidth); - return { rowDifference, columnDifference }; + const calculatedDifference = rowDifference * 7 + columnDifference; + + return calculatedDifference; }; const changeDateTimeByDays = ( @@ -49,8 +51,8 @@ const changeDateTimeByDays = ( return changedDateTime; }; -export const generateMovingScheduleBars = ( - params: GenerateMovingScheduleBarsParams, +export const generateScheduleBarsByMousePoint = ( + params: GenerateScheduleBarsByMousePointProps, ) => { const { schedule, @@ -64,25 +66,24 @@ export const generateMovingScheduleBars = ( calendarSize, } = params; - const { columnDifference } = getCalendarGridDifference( + const difference = getCalendarGridDifference( relativeX, relativeY, calendarWidth, calendarHeight, ); const { startDateTime, endDateTime } = schedule; - const generatedMovingScheduleBars = generateScheduleBars(year, month, [ + const generatedScheduleBars = generateScheduleBars(year, month, [ { ...schedule, - startDateTime: changeDateTimeByDays(startDateTime, columnDifference), - endDateTime: changeDateTimeByDays(endDateTime, columnDifference), + startDateTime: changeDateTimeByDays(startDateTime, difference), + endDateTime: changeDateTimeByDays(endDateTime, difference), }, ]).map((scheduleBar) => ({ ...scheduleBar, level, calendarSize, - mode: 'no-interaction', })); - return generatedMovingScheduleBars; + return generatedScheduleBars; }; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index d344c826f..dffb9581d 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { generateMovingScheduleBars } from './generateMovingScheduleBars'; +import { generateScheduleBarsByMousePoint } from './generateScheduleBarsByMousePoint'; import type { RefObject } from 'react'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; @@ -48,7 +48,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { calendarPointInfos; const scheduleBars = visible - ? generateMovingScheduleBars({ + ? generateScheduleBarsByMousePoint({ schedule, year, month, @@ -106,8 +106,8 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { }, [visible, onMouseUp, calendarRef, relativeX, relativeY, initX, initY]); return { - movingScheduleBars: scheduleBars, + scheduleBars, relativeX: relativeX % (calendarWidth / 7), - relativeY, + relativeY: relativeY % (calendarHeight / 6), }; }; From c4d5c9ca695f4b2d640bb004649a62f91dfe63ee Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 15:24:24 +0900 Subject: [PATCH 30/53] =?UTF-8?q?feat:=20=EA=B0=80=EC=A7=9C=20=EC=BA=98?= =?UTF-8?q?=EB=A6=B0=EB=8D=94=20=EB=B0=94=EB=A5=BC=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=EC=8B=9C=ED=82=AC=20=EB=95=8C=20=EC=84=B8=EB=A1=9C=20=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=EC=9C=BC=EB=A1=9C=EB=8F=84=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=90=EC=97=B0=EC=8A=A4=EB=9F=BD=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B0=9C=EC=84=A0,=20=EC=A0=84=EB=B0=98=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=B4=EB=8F=99=EC=84=B1=EC=9D=84=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateScheduleBarsByMousePoint.ts | 11 +---- .../useCalendarDragScreen.ts | 48 +++++++++++-------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts b/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts index 47fa500b0..fa3ddca12 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts @@ -20,15 +20,8 @@ const getCalendarGridDifference = ( calendarWidth: number, calendarHeight: number, ) => { - const rowDifference = - relativeY > 0 - ? Math.floor((relativeY * 6) / calendarHeight) - : Math.ceil((relativeY * 6) / calendarHeight); - const columnDifference = - relativeX > 0 - ? Math.floor((relativeX * 7) / calendarWidth) - : Math.ceil((relativeX * 7) / calendarWidth); - + const rowDifference = Math.round((relativeY * 6) / calendarHeight); + const columnDifference = Math.round((relativeX * 7) / calendarWidth); const calculatedDifference = rowDifference * 7 + columnDifference; return calculatedDifference; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index dffb9581d..ef3c93835 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -47,19 +47,16 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; - const scheduleBars = visible - ? generateScheduleBarsByMousePoint({ - schedule, - year, - month, - relativeX, - relativeY, - calendarWidth, - calendarHeight, - level, - calendarSize, - }) - : []; + const getProcessedRelativePoint = () => { + const processedRelativeX = + ((relativeX + calendarWidth * (15 / 14)) % (calendarWidth / 7)) - + calendarWidth / 14; + const processedRelativeY = + ((relativeY + calendarHeight * (13 / 12)) % (calendarHeight / 6)) - + calendarHeight / 12; + + return { x: processedRelativeX, y: processedRelativeY }; + }; useEffect(() => { const calendarElement = calendarRef.current; @@ -74,10 +71,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { } const { clientX, clientY } = e; - - console.log({ x: clientX - initX, y: clientY - initY }); - - setCalendarPointInfos((prev) => ({ + +setCalendarPointInfos((prev) => ({ ...prev, relativeX: clientX - initX, relativeY: clientY - initY, @@ -105,9 +99,25 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { }; }, [visible, onMouseUp, calendarRef, relativeX, relativeY, initX, initY]); + const scheduleBars = visible + ? generateScheduleBarsByMousePoint({ + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + }) + : []; + + const processedRelativePoint = getProcessedRelativePoint(); + return { scheduleBars, - relativeX: relativeX % (calendarWidth / 7), - relativeY: relativeY % (calendarHeight / 6), + relativeX: processedRelativePoint.x, + relativeY: processedRelativePoint.y, }; }; From bcc4831e558b9f8cc71c9f0713a27f2b720bb3b2 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 18:05:20 +0900 Subject: [PATCH 31/53] =?UTF-8?q?feat:=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EC=9D=84=20=EB=81=9D=EB=82=B4=EB=A9=B4=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=9C=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20post=ED=98=95=ED=83=9C=EB=A1=9C=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useCalendarDragScreen.ts | 83 ++++++++++++++----- .../TeamCalendar/useScheduleBarDragStatus.ts | 38 +++++++-- 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index ef3c93835..ee2898b1f 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { generateScheduleBarsByMousePoint } from './generateScheduleBarsByMousePoint'; import type { RefObject } from 'react'; import type { Schedule } from '~/types/schedule'; @@ -8,7 +8,11 @@ interface UseCalendarDragScreenProps { visible: boolean; calendarRef: RefObject; calendarSize: CalendarSize; - onMouseUp: () => void; + onMouseUp: ( + title: string, + startDateTime: Schedule['startDateTime'], + endDateTime: Schedule['endDateTime'], + ) => void; initX: number; initY: number; year: number; @@ -47,6 +51,35 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; + const scheduleBars = useMemo( + () => + visible + ? generateScheduleBarsByMousePoint({ + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + }) + : [], + [ + calendarHeight, + calendarSize, + calendarWidth, + level, + month, + relativeX, + relativeY, + schedule, + visible, + year, + ], + ); + const getProcessedRelativePoint = () => { const processedRelativeX = ((relativeX + calendarWidth * (15 / 14)) % (calendarWidth / 7)) - @@ -65,19 +98,28 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { return; } - const onMouseMove = (e: globalThis.MouseEvent) => { + const handleMouseMove = (e: globalThis.MouseEvent) => { if (!visible) { return; } const { clientX, clientY } = e; - +setCalendarPointInfos((prev) => ({ + setCalendarPointInfos((prev) => ({ ...prev, relativeX: clientX - initX, relativeY: clientY - initY, })); }; + const handleMouseUp = () => { + if (!visible) { + return; + } + + const { title, startDateTime, endDateTime } = scheduleBars[0].schedule; + onMouseUp(title, startDateTime, endDateTime); + }; + const resizeObserver = new ResizeObserver(() => { const { clientWidth, clientHeight } = calendarElement; @@ -88,30 +130,25 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { })); }); - calendarElement.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); + calendarElement.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); resizeObserver.observe(calendarElement); return () => { - calendarElement.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); + calendarElement.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); resizeObserver.disconnect(); }; - }, [visible, onMouseUp, calendarRef, relativeX, relativeY, initX, initY]); - - const scheduleBars = visible - ? generateScheduleBarsByMousePoint({ - schedule, - year, - month, - relativeX, - relativeY, - calendarWidth, - calendarHeight, - level, - calendarSize, - }) - : []; + }, [ + visible, + onMouseUp, + calendarRef, + relativeX, + relativeY, + initX, + initY, + scheduleBars, + ]); const processedRelativePoint = getProcessedRelativePoint(); diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts index 0bd86f240..579420923 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts +++ b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts @@ -1,4 +1,7 @@ import { useState } from 'react'; +import { useTeamPlace } from '~/hooks/useTeamPlace'; +import { useToast } from '~/hooks/useToast'; +import { useModifySchedule } from '~/hooks/queries/useModifySchedule'; import type { MouseEvent } from 'react'; import type { Schedule } from '~/types/schedule'; @@ -18,6 +21,10 @@ export const useScheduleDragStatus = () => { initX: 0, initY: 0, }); + const { showToast } = useToast(); + const { teamPlaceId } = useTeamPlace(); + const scheduleId = dragStatus.schedule.id; + const { mutateModifySchedule } = useModifySchedule(teamPlaceId, scheduleId); const handleDragStart = ( e: MouseEvent, @@ -35,17 +42,36 @@ export const useScheduleDragStatus = () => { })); }; - const handleMouseUp = () => { + const handleMouseUp = ( + title: string, + startDateTime: Schedule['startDateTime'], + endDateTime: Schedule['endDateTime'], + ) => { if (!dragStatus.isDragging) { return; } - setDragStatus(() => ({ + mutateModifySchedule( + { + title, + startDateTime, + endDateTime, + }, + { + onSuccess: () => { + showToast('success', '일정이 수정되었습니다.'); + }, + onError: (error) => { + const response = error as Response; + if (response.status === 500) + showToast('error', '일정 제목이 최대 글자(250자)를 초과했습니다.'); + }, + }, + ); + + setDragStatus((prev) => ({ + ...prev, isDragging: false, - level: 0, - schedule: {} as Schedule, - initX: 0, - initY: 0, })); }; From a7a08da5e977460d29b58408a79f41f98f10ff90 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 9 Nov 2023 18:48:38 +0900 Subject: [PATCH 32/53] =?UTF-8?q?feat:=20=EB=93=9C=EB=9E=98=EA=B7=B8?= =?UTF-8?q?=ED=95=9C=20=EC=9D=B4=ED=9B=84=20=EC=9D=BC=EC=A0=95=EC=9D=B4=20?= =?UTF-8?q?=EB=B3=80=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=98=EC=9D=84=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0,=20API=20=EC=9A=94=EC=B2=AD=EC=9D=84=20?= =?UTF-8?q?=EB=B3=B4=EB=82=B4=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/useCalendarDragScreen.ts | 6 +++++- .../TeamCalendar/useScheduleBarDragStatus.ts | 16 +++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts index ee2898b1f..e5af2cbde 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts @@ -12,6 +12,7 @@ interface UseCalendarDragScreenProps { title: string, startDateTime: Schedule['startDateTime'], endDateTime: Schedule['endDateTime'], + shouldUpdate: boolean, ) => void; initX: number; initY: number; @@ -117,7 +118,9 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { } const { title, startDateTime, endDateTime } = scheduleBars[0].schedule; - onMouseUp(title, startDateTime, endDateTime); + const shouldUpdate = schedule.startDateTime !== startDateTime; + + onMouseUp(title, startDateTime, endDateTime, shouldUpdate); }; const resizeObserver = new ResizeObserver(() => { @@ -148,6 +151,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { initX, initY, scheduleBars, + schedule.startDateTime, ]); const processedRelativePoint = getProcessedRelativePoint(); diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts index 579420923..42e831e97 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts +++ b/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts @@ -30,6 +30,7 @@ export const useScheduleDragStatus = () => { e: MouseEvent, level: number, schedule: Schedule, + shouldUpdate: boolean, ) => { const { clientX, clientY } = e; @@ -46,11 +47,21 @@ export const useScheduleDragStatus = () => { title: string, startDateTime: Schedule['startDateTime'], endDateTime: Schedule['endDateTime'], + shouldUpdate: boolean, ) => { if (!dragStatus.isDragging) { return; } + setDragStatus((prev) => ({ + ...prev, + isDragging: false, + })); + + if (!shouldUpdate) { + return; + } + mutateModifySchedule( { title, @@ -68,11 +79,6 @@ export const useScheduleDragStatus = () => { }, }, ); - - setDragStatus((prev) => ({ - ...prev, - isDragging: false, - })); }; return { dragStatus, handleDragStart, handleMouseUp }; From c019bc1a405bd3f36b0958f64f79c8a0d04ac8ae Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 16:06:35 +0900 Subject: [PATCH 33/53] =?UTF-8?q?refactor:=20FakeScheduleBarScreen=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9E=90=EC=A3=BC=20=EB=B0=94=EB=80=8C=EB=8A=94=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=EC=9D=84=20attrs=EB=A1=9C=20=EB=B0=9B?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 불필요함에도 불구하고 클래스가 매번 새롭게 생성되는 현상을 방지하고, 인라인 스타일만 수정되도록 하여 퍼포먼스 향상을 기대할 수 있음 --- .../FakeScheduleBarsScreen.styled.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts index d826722bb..b8e16388a 100644 --- a/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts +++ b/frontend/src/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen.styled.ts @@ -1,15 +1,19 @@ import { styled } from 'styled-components'; -export const Container = styled.div<{ $relativeX: number; $relativeY: number }>` +export const Container = styled.div.attrs<{ + $relativeX: number; + $relativeY: number; +}>(({ $relativeX, $relativeY }) => ({ + style: { + transform: `translate(${$relativeX}px, ${$relativeY}px)`, + }, +}))` display: flex; flex-direction: column; position: absolute; width: 100%; height: 100%; - - transform: ${({ $relativeX, $relativeY }) => - `translate(${$relativeX}px, ${$relativeY}px)`}; `; export const CalendarRow = styled.div` From 4ec43c0b59909d9276deb10de9368d9475353c87 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 16:13:34 +0900 Subject: [PATCH 34/53] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20Point=20=ED=83=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/types/schedule.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index 63cd814d5..be25b08b7 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -48,8 +48,3 @@ export interface GeneratedScheduleBar { roundedEnd: boolean; mode?: 'normal' | 'no-interaction' | 'indicator'; } - -export interface Point { - x: number; - y: number; -} From 43fb55daffa49ad982408f5faf96a8b7c4ef2700 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 16:39:31 +0900 Subject: [PATCH 35/53] =?UTF-8?q?chore:=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98,=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=EC=9D=98?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team_calendar/CalendarDragScreen/CalendarDragScreen.tsx | 2 +- .../schedule}/useCalendarDragScreen.ts | 2 +- .../generateScheduleBarsByMousePoint.ts | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename frontend/src/{components/team_calendar/CalendarDragScreen => hooks/schedule}/useCalendarDragScreen.ts (93%) rename frontend/src/{components/team_calendar/CalendarDragScreen => utils}/generateScheduleBarsByMousePoint.ts (100%) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index efcbd3adb..6f1153e6f 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -3,7 +3,7 @@ import { useRef } from 'react'; import FakeScheduleBarsScreen from '~/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; -import { useCalendarDragScreen } from './useCalendarDragScreen'; +import { useCalendarDragScreen } from '~/hooks/schedule/useCalendarDragScreen'; interface CalendarDragScreenProps { visible: boolean; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts similarity index 93% rename from frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts rename to frontend/src/hooks/schedule/useCalendarDragScreen.ts index e5af2cbde..1a8880d23 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -1,5 +1,5 @@ import { useState, useEffect, useMemo } from 'react'; -import { generateScheduleBarsByMousePoint } from './generateScheduleBarsByMousePoint'; +import { generateScheduleBarsByMousePoint } from '~/utils/generateScheduleBarsByMousePoint'; import type { RefObject } from 'react'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts b/frontend/src/utils/generateScheduleBarsByMousePoint.ts similarity index 100% rename from frontend/src/components/team_calendar/CalendarDragScreen/generateScheduleBarsByMousePoint.ts rename to frontend/src/utils/generateScheduleBarsByMousePoint.ts From 6d31c42da69aca1ce19e3ef3e31ccd3ae1928f43 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 17:30:03 +0900 Subject: [PATCH 36/53] =?UTF-8?q?refactor:=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=20=EB=82=A0=EC=A7=9C=EC=9D=98=20=EB=B3=80=ED=99=94=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20=EA=B5=AC=ED=95=98=EB=8A=94=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=ED=95=A8=EC=88=98=EC=9D=98=20=EC=9D=B4=EB=A6=84=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=EB=82=B4=EB=B6=80=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/generateScheduleBarsByMousePoint.ts | 68 ++++++++++--------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/frontend/src/utils/generateScheduleBarsByMousePoint.ts b/frontend/src/utils/generateScheduleBarsByMousePoint.ts index fa3ddca12..a7a67a12e 100644 --- a/frontend/src/utils/generateScheduleBarsByMousePoint.ts +++ b/frontend/src/utils/generateScheduleBarsByMousePoint.ts @@ -1,4 +1,5 @@ import { generateScheduleBars } from '~/utils/generateScheduleBars'; +import { CALENDAR, ONE_DAY } from '~/constants/calendar'; import type { Schedule } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; @@ -14,36 +15,6 @@ interface GenerateScheduleBarsByMousePointProps { calendarSize: CalendarSize; } -const getCalendarGridDifference = ( - relativeX: number, - relativeY: number, - calendarWidth: number, - calendarHeight: number, -) => { - const rowDifference = Math.round((relativeY * 6) / calendarHeight); - const columnDifference = Math.round((relativeX * 7) / calendarWidth); - const calculatedDifference = rowDifference * 7 + columnDifference; - - return calculatedDifference; -}; - -const changeDateTimeByDays = ( - dateTime: Schedule['startDateTime'], - days: number, -) => { - const changedDate = new Date(Number(new Date(dateTime)) + 86_400_000 * days); - - const year = String(changedDate.getFullYear()).padStart(4, '0'); - const month = String(changedDate.getMonth() + 1).padStart(2, '0'); - const day = String(changedDate.getDate()).padStart(2, '0'); - const time = dateTime.split(' ')[1]; - const [minute, second] = time.split(':'); - - const changedDateTime: Schedule['startDateTime'] = `${year}-${month}-${day} ${minute}:${second}`; - - return changedDateTime; -}; - export const generateScheduleBarsByMousePoint = ( params: GenerateScheduleBarsByMousePointProps, ) => { @@ -59,7 +30,7 @@ export const generateScheduleBarsByMousePoint = ( calendarSize, } = params; - const difference = getCalendarGridDifference( + const difference = getCalendarDateDifferenceByMousePoint( relativeX, relativeY, calendarWidth, @@ -80,3 +51,38 @@ export const generateScheduleBarsByMousePoint = ( return generatedScheduleBars; }; + +const getCalendarDateDifferenceByMousePoint = ( + relativeX: number, + relativeY: number, + calendarWidth: number, + calendarHeight: number, +) => { + const rowDifference = Math.round( + (relativeY * CALENDAR.ROW_SIZE) / calendarHeight, + ); + const columnDifference = Math.round( + (relativeX * CALENDAR.COLUMN_SIZE) / calendarWidth, + ); + const calculatedDifference = + rowDifference * CALENDAR.COLUMN_SIZE + columnDifference; + + return calculatedDifference; +}; + +const changeDateTimeByDays = ( + dateTime: Schedule['startDateTime'], + days: number, +) => { + const changedDate = new Date(Number(new Date(dateTime)) + ONE_DAY * days); + + const year = String(changedDate.getFullYear()).padStart(4, '0'); + const month = String(changedDate.getMonth() + 1).padStart(2, '0'); + const day = String(changedDate.getDate()).padStart(2, '0'); + const time = dateTime.split(' ')[1]; + const [minute, second] = time.split(':'); + + const changedDateTime: Schedule['startDateTime'] = `${year}-${month}-${day} ${minute}:${second}`; + + return changedDateTime; +}; From 83b7a6e18cd1d31495b3071f4b2fcb0eb95744fe Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 20:58:05 +0900 Subject: [PATCH 37/53] =?UTF-8?q?fix:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=EA=B0=80=20=EB=B2=94=EC=9C=84=20=EB=B0=96=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98=EC=97=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=9D=B4=20=EB=90=98=EC=97=88=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EA=B0=80=20=EC=83=9D=EA=B8=B0=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EB=A5=BC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 스케줄 바에서 정보를 가져오는 데 이동된 스케줄 바가 더 이상 렌더링되지 않으므로 생기는 문제. 스케줄 바가 비어 있더라도 일정 시작과 끝 정보는 보존되도록 유틸 함수를 수정 --- .../src/hooks/schedule/useCalendarDragScreen.ts | 15 ++++++++------- .../src/utils/generateScheduleBarsByMousePoint.ts | 13 ++++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index 1a8880d23..f54e7f4c0 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -52,7 +52,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; - const scheduleBars = useMemo( + const scheduleBarsInfo = useMemo( () => visible ? generateScheduleBarsByMousePoint({ @@ -66,7 +66,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { level, calendarSize, }) - : [], + : null, [ calendarHeight, calendarSize, @@ -113,11 +113,12 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { }; const handleMouseUp = () => { - if (!visible) { + if (!visible || !scheduleBarsInfo) { return; } - const { title, startDateTime, endDateTime } = scheduleBars[0].schedule; + const { title } = schedule; + const { startDateTime, endDateTime } = scheduleBarsInfo; const shouldUpdate = schedule.startDateTime !== startDateTime; onMouseUp(title, startDateTime, endDateTime, shouldUpdate); @@ -150,14 +151,14 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { relativeY, initX, initY, - scheduleBars, - schedule.startDateTime, + scheduleBarsInfo, + schedule, ]); const processedRelativePoint = getProcessedRelativePoint(); return { - scheduleBars, + scheduleBars: scheduleBarsInfo ? scheduleBarsInfo.scheduleBars : [], relativeX: processedRelativePoint.x, relativeY: processedRelativePoint.y, }; diff --git a/frontend/src/utils/generateScheduleBarsByMousePoint.ts b/frontend/src/utils/generateScheduleBarsByMousePoint.ts index a7a67a12e..22d6911b0 100644 --- a/frontend/src/utils/generateScheduleBarsByMousePoint.ts +++ b/frontend/src/utils/generateScheduleBarsByMousePoint.ts @@ -36,12 +36,15 @@ export const generateScheduleBarsByMousePoint = ( calendarWidth, calendarHeight, ); + const { startDateTime, endDateTime } = schedule; + const changedStartDateTime = changeDateTimeByDays(startDateTime, difference); + const changedEndDateTime = changeDateTimeByDays(endDateTime, difference); const generatedScheduleBars = generateScheduleBars(year, month, [ { ...schedule, - startDateTime: changeDateTimeByDays(startDateTime, difference), - endDateTime: changeDateTimeByDays(endDateTime, difference), + startDateTime: changedStartDateTime, + endDateTime: changedEndDateTime, }, ]).map((scheduleBar) => ({ ...scheduleBar, @@ -49,7 +52,11 @@ export const generateScheduleBarsByMousePoint = ( calendarSize, })); - return generatedScheduleBars; + return { + scheduleBars: generatedScheduleBars, + startDateTime: changedStartDateTime, + endDateTime: changedEndDateTime, + }; }; const getCalendarDateDifferenceByMousePoint = ( From 15c1b7a648059907782568ddb14d05b8358c6127 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 21:37:55 +0900 Subject: [PATCH 38/53] =?UTF-8?q?refactor:=20=EA=BC=AD=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EA=B2=BD=EC=9A=B0=EC=97=90=EB=A7=8C=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EA=B0=80=20=EB=8B=A4=EC=8B=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=90=98=EB=8F=84=EB=A1=9D=20useCallback=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9,=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20useMemo=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 꼭 필요한 경우에만 생성되도록 한쪽에 쏠린 dependency array를 배분 --- .../hooks/schedule/useCalendarDragScreen.ts | 95 ++++++++----------- 1 file changed, 37 insertions(+), 58 deletions(-) diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index f54e7f4c0..4bae8a1aa 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { generateScheduleBarsByMousePoint } from '~/utils/generateScheduleBarsByMousePoint'; import type { RefObject } from 'react'; import type { Schedule } from '~/types/schedule'; @@ -52,34 +52,19 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; - const scheduleBarsInfo = useMemo( - () => - visible - ? generateScheduleBarsByMousePoint({ - schedule, - year, - month, - relativeX, - relativeY, - calendarWidth, - calendarHeight, - level, - calendarSize, - }) - : null, - [ - calendarHeight, - calendarSize, - calendarWidth, - level, - month, - relativeX, - relativeY, - schedule, - visible, - year, - ], - ); + const scheduleBarsInfo = visible + ? generateScheduleBarsByMousePoint({ + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + }) + : null; const getProcessedRelativePoint = () => { const processedRelativeX = @@ -92,37 +77,41 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { return { x: processedRelativeX, y: processedRelativeY }; }; - useEffect(() => { - const calendarElement = calendarRef.current; - - if (!calendarElement) { - return; - } - - const handleMouseMove = (e: globalThis.MouseEvent) => { + const handleMouseMove = useCallback( + (e: globalThis.MouseEvent) => { if (!visible) { return; } const { clientX, clientY } = e; + setCalendarPointInfos((prev) => ({ ...prev, relativeX: clientX - initX, relativeY: clientY - initY, })); - }; + }, + [initX, initY, visible], + ); - const handleMouseUp = () => { - if (!visible || !scheduleBarsInfo) { - return; - } + const handleMouseUp = useCallback(() => { + if (!visible || !scheduleBarsInfo) { + return; + } - const { title } = schedule; - const { startDateTime, endDateTime } = scheduleBarsInfo; - const shouldUpdate = schedule.startDateTime !== startDateTime; + const { title } = schedule; + const { startDateTime, endDateTime } = scheduleBarsInfo; + const shouldUpdate = schedule.startDateTime !== startDateTime; - onMouseUp(title, startDateTime, endDateTime, shouldUpdate); - }; + onMouseUp(title, startDateTime, endDateTime, shouldUpdate); + }, [onMouseUp, schedule, scheduleBarsInfo, visible]); + + useEffect(() => { + const calendarElement = calendarRef.current; + + if (!calendarElement) { + return; + } const resizeObserver = new ResizeObserver(() => { const { clientWidth, clientHeight } = calendarElement; @@ -143,17 +132,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { document.removeEventListener('mouseup', handleMouseUp); resizeObserver.disconnect(); }; - }, [ - visible, - onMouseUp, - calendarRef, - relativeX, - relativeY, - initX, - initY, - scheduleBarsInfo, - schedule, - ]); + }, [calendarRef, handleMouseMove, handleMouseUp]); const processedRelativePoint = getProcessedRelativePoint(); From fdf5c1d713f4347c316d0557549b7ae0e21dfa60 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 22:15:37 +0900 Subject: [PATCH 39/53] =?UTF-8?q?fix:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20?= =?UTF-8?q?=EB=B0=94=EB=A5=BC=20=EB=93=9C=EB=9E=98=EA=B7=B8=ED=95=A0=20?= =?UTF-8?q?=EB=95=8C=20=EC=95=84=EC=A3=BC=20=EC=9E=A0=EA=B9=90=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20=EC=A2=8C=ED=91=9C=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=98=EB=A9=B0=20=EB=B2=84=EB=B2=85=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이전 캘린더 바의 이동에서 남아있는 상대좌표의 값이 이후의 캘린더 바의 이동에 영향을 끼친 것. 이동 완료 후 상대좌표의 값을 0으로 초기화시키는 것으로 해결 --- frontend/src/hooks/schedule/useCalendarDragScreen.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index 4bae8a1aa..4c85d0715 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -104,6 +104,12 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const shouldUpdate = schedule.startDateTime !== startDateTime; onMouseUp(title, startDateTime, endDateTime, shouldUpdate); + + setCalendarPointInfos((prev) => ({ + ...prev, + relativeX: 0, + relativeY: 0, + })); }, [onMouseUp, schedule, scheduleBarsInfo, visible]); useEffect(() => { From 421fdadb590617eaa734f1a57201eab971371312 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Mon, 13 Nov 2023 22:35:15 +0900 Subject: [PATCH 40/53] =?UTF-8?q?chore:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=83=9D=EC=84=B1=20=EC=9C=A0=ED=8B=B8=ED=95=A8?= =?UTF-8?q?=EC=88=98=EC=9D=98=20import=20=EA=B2=BD=EB=A1=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=88=EB=8C=80=EA=B2=BD=EB=A1=9C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/utils/test/generateScheduleBars.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/utils/test/generateScheduleBars.test.ts b/frontend/src/utils/test/generateScheduleBars.test.ts index f34288505..530a27bd1 100644 --- a/frontend/src/utils/test/generateScheduleBars.test.ts +++ b/frontend/src/utils/test/generateScheduleBars.test.ts @@ -1,4 +1,4 @@ -import { generateScheduleBars } from '../generateScheduleBars'; +import { generateScheduleBars } from '~/utils/generateScheduleBars'; import type { GeneratedScheduleBar, Schedule } from '~/types/schedule'; const removeIdFromScheduleBars = (scheduleBars: GeneratedScheduleBar[]) => { From d099bd4c7f0f5972b3db70da6a590ffe9a007b23 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 02:30:44 +0900 Subject: [PATCH 41/53] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=20=EB=B0=94=20=ED=83=80=EC=9E=85=EC=97=90=20calendarSize=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 직접 해당 타입을 스케줄 바에서 사용하게 되는 일이 많아짐에 따라 추가하게 됨 --- .../src/components/team_calendar/ScheduleBar/ScheduleBar.tsx | 2 -- frontend/src/types/schedule.ts | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx index d12a0add4..3473542a8 100644 --- a/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx +++ b/frontend/src/components/team_calendar/ScheduleBar/ScheduleBar.tsx @@ -4,10 +4,8 @@ import type { GeneratedScheduleBar } from '~/types/schedule'; import { DoubleArrowRightIcon } from '~/assets/svg'; import { useTeamPlace } from '~/hooks/useTeamPlace'; import type { MouseEvent } from 'react'; -import type { CalendarSize } from '~/types/size'; export interface ScheduleBarProps extends GeneratedScheduleBar { - calendarSize?: CalendarSize; onClick?: () => void; onDragStart?: (e: MouseEvent) => void; } diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index be25b08b7..1c40fddf1 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -1,4 +1,5 @@ import type { MODAL_OPEN_TYPE } from '~/constants/calendar'; +import type { CalendarSize } from '~/types/size'; export interface Schedule { id: number; @@ -46,5 +47,6 @@ export interface GeneratedScheduleBar { level: number; roundedStart: boolean; roundedEnd: boolean; + calendarSize?: CalendarSize; mode?: 'normal' | 'no-interaction' | 'indicator'; } From c431986c36aa86f46b8c380e8d684d57e0359058 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 03:07:28 +0900 Subject: [PATCH 42/53] =?UTF-8?q?test:=20=EC=83=81=EB=8C=80=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=20=EA=B8=B0=EB=B0=98=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=9C=A0=ED=8B=B8=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=A2=8C=ED=91=9C=20=EB=8C=80=EC=9D=91=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateScheduleBarsByMousePoint.test.ts | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts diff --git a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts new file mode 100644 index 000000000..a701c02db --- /dev/null +++ b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts @@ -0,0 +1,243 @@ +import { generateScheduleBarsByMousePoint } from '~/utils/generateScheduleBarsByMousePoint'; +import type { GeneratedScheduleBar, Schedule } from '~/types/schedule'; + +const removeIdFromScheduleBars = (scheduleBars: GeneratedScheduleBar[]) => { + /* eslint-disable-next-line */ + const scheduleBarsWithoutId = scheduleBars.map(({ id, ...rest }) => { + return rest; + }); + + return scheduleBarsWithoutId; +}; + +const defaultParams = { + year: 2023, + month: 10, + calendarWidth: 700, + calendarHeight: 600, + level: 0, + calendarSize: 'md' as const, +}; + +type GeneratedScheduleBarWithoutId = Omit; + +interface ResultValue { + startDateTime: Schedule['startDateTime']; + endDateTime: Schedule['endDateTime']; + scheduleBars: GeneratedScheduleBarWithoutId[]; +} + +describe('Test #1 - 좌표 대응 테스트', () => { + test('상대 좌표가 우측에 있을 경우, 그에 대응되는 날짜가 이동된 스케줄 바가 반환되어야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }; + + const params = { + ...defaultParams, + schedule, + relativeX: 155, + relativeY: 0, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-11-16 00:00', + endDateTime: '2023-11-18 23:59', + scheduleBars: [ + { + scheduleId: 1, + title: '내 일정', + row: 2, + column: 4, + duration: 3, + level: 0, + roundedStart: true, + roundedEnd: true, + schedule: { + id: 1, + title: '내 일정', + startDateTime: '2023-11-16 00:00', + endDateTime: '2023-11-18 23:59', + }, + calendarSize: 'md', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); + + test('상대 좌표가 좌상단에 있을 경우, 그에 대응되는 날짜가 이동된 스케줄 바가 반환되어야 한다. 또한, 범위 바깥의 스케줄 바는 잘려야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }; + + const params = { + ...defaultParams, + schedule, + relativeX: -349.9, + relativeY: -150.1, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-10-28 00:00', + endDateTime: '2023-10-30 23:59', + scheduleBars: [ + { + scheduleId: 1, + title: '내 일정', + row: 0, + column: 0, + duration: 2, + level: 0, + roundedStart: false, + roundedEnd: true, + schedule: { + id: 1, + title: '내 일정', + startDateTime: '2023-10-28 00:00', + endDateTime: '2023-10-30 23:59', + }, + calendarSize: 'md', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); + + test('상대 좌표가 우하단에 있을 경우, 그에 대응되는 날짜가 이동된 스케줄 바가 반환되어야 한다. 또한, 이동된 일정에 따라 적절하게 스케줄 바의 모양이 바뀌어야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '빡구현좋아', + startDateTime: '2023-11-14 14:00', + endDateTime: '2023-11-20 16:30', + }; + + const params = { + ...defaultParams, + schedule, + relativeX: 316, + relativeY: 83, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-11-24 14:00', + endDateTime: '2023-11-30 16:30', + scheduleBars: [ + { + scheduleId: 1, + title: '빡구현좋아', + row: 3, + column: 5, + duration: 2, + level: 0, + roundedStart: true, + roundedEnd: false, + schedule: { + id: 1, + title: '빡구현좋아', + startDateTime: '2023-11-24 14:00', + endDateTime: '2023-11-30 16:30', + }, + calendarSize: 'md', + }, + { + scheduleId: 1, + title: '빡구현좋아', + row: 4, + column: 0, + duration: 5, + level: 0, + roundedStart: false, + roundedEnd: true, + schedule: { + id: 1, + title: '빡구현좋아', + startDateTime: '2023-11-24 14:00', + endDateTime: '2023-11-30 16:30', + }, + calendarSize: 'md', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); + + test('상대 좌표의 이동거리가 짧아 일정에 변화가 없는 경우, 변화되지 않은 스케줄 바 그대로를 반환해야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }; + + const params = { + ...defaultParams, + schedule, + relativeX: 0, + relativeY: 49.9999, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + scheduleBars: [ + { + scheduleId: 1, + title: '내 일정', + row: 2, + column: 2, + duration: 3, + level: 0, + roundedStart: true, + roundedEnd: true, + schedule: { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }, + calendarSize: 'md', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); +}); From e15702f72d14ff008e51c84d099767750ecd4d03 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 10:16:07 +0900 Subject: [PATCH 43/53] =?UTF-8?q?test:=20=EC=83=81=EB=8C=80=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=20=EA=B8=B0=EB=B0=98=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=9C=A0=ED=8B=B8=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=BA=98=EB=A6=B0=EB=8D=94=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EB=8C=80=EC=9D=91=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateScheduleBarsByMousePoint.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts index a701c02db..0fc64c3c0 100644 --- a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts +++ b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts @@ -241,3 +241,56 @@ describe('Test #1 - 좌표 대응 테스트', () => { }).toEqual(expectedResult); }); }); + +describe('Test #2 - 캘린더 크기 대응 테스트', () => { + test('캘린더의 크기가 평소와 달라진 경우, 상대 좌표도 다르게 계산하여 반영하여야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }; + + const params = { + ...defaultParams, + schedule, + calendarWidth: 732, + calendarHeight: 481, + relativeX: 156.8571, + relativeY: -160.3334, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-11-01 00:00', + endDateTime: '2023-11-03 23:59', + scheduleBars: [ + { + scheduleId: 1, + title: '내 일정', + row: 0, + column: 3, + duration: 3, + level: 0, + roundedStart: true, + roundedEnd: true, + schedule: { + id: 1, + title: '내 일정', + startDateTime: '2023-11-01 00:00', + endDateTime: '2023-11-03 23:59', + }, + calendarSize: 'md', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); +}); From 58409c6e46714b61b87b5100a3fb596c2af4dda8 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 10:23:05 +0900 Subject: [PATCH 44/53] =?UTF-8?q?test:=20=EC=83=81=EB=8C=80=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=20=EA=B8=B0=EB=B0=98=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=9C=A0=ED=8B=B8=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EB=B6=80=EA=B0=80=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generateScheduleBarsByMousePoint.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts index 0fc64c3c0..11868eae2 100644 --- a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts +++ b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts @@ -294,3 +294,56 @@ describe('Test #2 - 캘린더 크기 대응 테스트', () => { }).toEqual(expectedResult); }); }); + +describe('Test #3 - 부가 기능 테스트', () => { + test('캘린더 바의 사이즈, 레벨을 별도로 지정한 후 해당 설정으로 반영된 스케줄 바가 반환되어야 한다.', () => { + const schedule: Schedule = { + id: 1, + title: '내 일정', + startDateTime: '2023-11-14 00:00', + endDateTime: '2023-11-16 23:59', + }; + + const params = { + ...defaultParams, + schedule, + relativeX: 23, + relativeY: 81, + calendarSize: 'sm' as const, + level: 2, + }; + + const expectedResult: ResultValue = { + startDateTime: '2023-11-21 00:00', + endDateTime: '2023-11-23 23:59', + scheduleBars: [ + { + scheduleId: 1, + title: '내 일정', + row: 3, + column: 2, + duration: 3, + level: 2, + roundedStart: true, + roundedEnd: true, + schedule: { + id: 1, + title: '내 일정', + startDateTime: '2023-11-21 00:00', + endDateTime: '2023-11-23 23:59', + }, + calendarSize: 'sm', + }, + ], + }; + + const { startDateTime, endDateTime, scheduleBars } = + generateScheduleBarsByMousePoint(params); + + expect({ + startDateTime, + endDateTime, + scheduleBars: removeIdFromScheduleBars(scheduleBars), + }).toEqual(expectedResult); + }); +}); From 0be7107ce5633073f162137aa37bd62a25c6a6cf Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 10:33:17 +0900 Subject: [PATCH 45/53] =?UTF-8?q?chore:=20=EC=83=81=EB=8C=80=EC=A2=8C?= =?UTF-8?q?=ED=91=9C=20=EA=B8=B0=EB=B0=98=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EB=B0=94=20=EC=9C=A0=ED=8B=B8=ED=95=A8=EC=88=98=EC=97=90=20JSD?= =?UTF-8?q?oc=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/generateScheduleBarsByMousePoint.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/frontend/src/utils/generateScheduleBarsByMousePoint.ts b/frontend/src/utils/generateScheduleBarsByMousePoint.ts index 22d6911b0..440ff3d3d 100644 --- a/frontend/src/utils/generateScheduleBarsByMousePoint.ts +++ b/frontend/src/utils/generateScheduleBarsByMousePoint.ts @@ -15,6 +15,26 @@ interface GenerateScheduleBarsByMousePointProps { calendarSize: CalendarSize; } +/** + * 《generateScheduleBarsByMousePoint》 + * 제공된 마우스 상대좌표를 기반으로 렌더링에 적합한 모양의 스케줄 바와 렌더링에 필요한 부가 정보들을 생성하여 반환합니다. + * + * @typedef {GenerateScheduleBarsByMousePointProps} params + * @property {schedule} schedule - 캘린더 바 생성에 사용할 일정 정보를 의미합니다. + * @property {number} year - 캘린더의 연도를 의미합니다. + * @property {number} month - 캘린더의 달을 의미합니다. 수를 0부터 셈에 주의하세요. + * @property {number} relativeX - 드래그를 시작한 지점을 기준으로 현재 마우스의 상대적인 x좌표를 의미합니다. + * @property {number} relativeY - 드래그를 시작한 지점을 기준으로 현재 마우스의 상대적인 y좌표를 의미합니다. + * @property {number} calendarWidth - 캘린더 컴포넌트의 가로 길이를 의미합니다. + * @property {number} calendarHeight - 캘린더 컴포넌트의 세로 길이를 의미합니다. + * @property {number} level - 생성되는 스케줄 바에 지정되어야 할 레벨을 의미합니다. 레벨이란 여러 스케줄 바가 겹칠 경우 어느 위치에 렌더링되어야 할 지를 결정하는 값으로, 0이 최상단이고 값이 오를수록 아래에 배치됩니다. + * @property {CalendarSize} calendarSize - 이 함수를 사용하는 캘린더의 크기를 의미합니다. 캘린더의 크기에 따라 생성되는 스케줄 바의 크기도 달라집니다. + * + * @returns {Object} + * @property {GeneratedScheduleBar[]} scheduleBars - 생성된 스케줄 바들을 의미합니다. + * @property {Schedule['startDateTime']} startDateTime - 상대좌표를 고려하여 새롭게 반영된 시작 날짜를 의미합니다. + * @property {Schedule['endDateTime']} endDateTime - 상대좌표를 고려하여 새롭게 반영된 끝 날짜를 의미합니다. + */ export const generateScheduleBarsByMousePoint = ( params: GenerateScheduleBarsByMousePointProps, ) => { @@ -59,6 +79,17 @@ export const generateScheduleBarsByMousePoint = ( }; }; +/** + * 《getCalendarDateDifferenceByMousePoint》 + * 제공된 마우스 상대좌표를 기반으로 올바른 모양의 캘린더 바를 보여주려면 날짜가 얼마나 바뀌어야 하는지를 계산하여 반환합니다. + * + * @param {number} relativeX - 드래그를 시작한 지점을 기준으로 현재 마우스의 상대적인 x좌표를 의미합니다. + * @param {number} relativeY - 드래그를 시작한 지점을 기준으로 현재 마우스의 상대적인 y좌표를 의미합니다. + * @param {number} calendarWidth - 캘린더 컴포넌트의 가로 길이를 의미합니다. + * @param {number} calendarHeight - 캘린더 컴포넌트의 세로 길이를 의미합니다. + * + * @returns {number} calculatedDifference - 변경되어야 하는 날짜의 일 수를 정수 형태로 변환한 값을 의미합니다. 이 값은 음수일 수 있습니다. + */ const getCalendarDateDifferenceByMousePoint = ( relativeX: number, relativeY: number, @@ -77,6 +108,15 @@ const getCalendarDateDifferenceByMousePoint = ( return calculatedDifference; }; +/** + * 《changeDateTimeByDays》 + * YYYY-MM-DD 형식의 날짜와 함께 변경되어야 하는 날의 수가 주어지면, 이를 반영하여 똑같이 YYYY-MM-DD 형식으로 변경된 날짜를 반환합니다. + * + * @param {Schedule['startDateTime']} dateTime - 변경을 진행할 YYYY-MM-DD 형식의 날짜 정보입니다. + * @param {number} days - 입력으로 들어가는 날짜 정보의 날짜를 얼마나 변경할 것인지를 의미합니다. 이 값은 정수여야 합니다. + * + * @returns {Schedule['startDateTime']} changedDateTime - 변경이 반영된 YYYY-MM-DD 형식의 날짜 정보입니다. + */ const changeDateTimeByDays = ( dateTime: Schedule['startDateTime'], days: number, From 4981756146e3c76b9413da1f7602144112f115f6 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 14:52:54 +0900 Subject: [PATCH 46/53] =?UTF-8?q?chore:=20useScheduleBarDragStatus=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=EC=9D=84=20hooks=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/team_calendar/TeamCalendar/TeamCalendar.tsx | 2 +- .../TeamCalendar => hooks/schedule}/useScheduleBarDragStatus.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename frontend/src/{components/team_calendar/TeamCalendar => hooks/schedule}/useScheduleBarDragStatus.ts (100%) diff --git a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx index 517ba9e3b..031f40ffa 100644 --- a/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx +++ b/frontend/src/components/team_calendar/TeamCalendar/TeamCalendar.tsx @@ -16,7 +16,7 @@ import { useModal } from '~/hooks/useModal'; import { useTeamPlace } from '~/hooks/useTeamPlace'; import { useCalendarResizePosition } from '~/hooks/useCalendarResizePosition'; import { usePrefetchSchedules } from '~/hooks/queries/usePrefetchSchedules'; -import { useScheduleDragStatus } from './useScheduleBarDragStatus'; +import { useScheduleDragStatus } from '~/hooks/schedule/useScheduleBarDragStatus'; import { DAYS_OF_WEEK, MODAL_OPEN_TYPE } from '~/constants/calendar'; import { generateScheduleBars } from '~/utils/generateScheduleBars'; import { arrayOf } from '~/utils/arrayOf'; diff --git a/frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts similarity index 100% rename from frontend/src/components/team_calendar/TeamCalendar/useScheduleBarDragStatus.ts rename to frontend/src/hooks/schedule/useScheduleBarDragStatus.ts From ea37ebe1ff45b8f3b563f5f6320a1fcff85d0e69 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 15:10:12 +0900 Subject: [PATCH 47/53] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=A0=9C=EA=B1=B0,?= =?UTF-8?q?=20onMouseUp=EC=9D=98=20=ED=83=80=EC=9E=85=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.tsx | 7 ++++++- frontend/src/hooks/schedule/useScheduleBarDragStatus.ts | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index 6f1153e6f..02c2bf5ed 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -14,7 +14,12 @@ interface CalendarDragScreenProps { month: number; level: number; schedule: Schedule; - onMouseUp: () => void; + onMouseUp: ( + title: string, + startDateTime: Schedule['startDateTime'], + endDateTime: Schedule['endDateTime'], + shouldUpdate: boolean, + ) => void; } const CalendarDragScreen = (props: CalendarDragScreenProps) => { diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index 42e831e97..012ce4825 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -30,7 +30,6 @@ export const useScheduleDragStatus = () => { e: MouseEvent, level: number, schedule: Schedule, - shouldUpdate: boolean, ) => { const { clientX, clientY } = e; From 82d2416d433715a4ce68b64979bf34acb086b6ef Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 15:39:49 +0900 Subject: [PATCH 48/53] =?UTF-8?q?refactor:=20as=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8A=94=20=EB=8C=80=EC=8B=A0=20=EB=B9=88=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=A5=BC=20=EC=84=A0=EC=96=B8=ED=95=B4=20=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=A4=84=EC=9D=B4=20=EB=B9=84=EC=97=88=EC=9D=84=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/schedule/useScheduleBarDragStatus.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index 012ce4825..8329329f3 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -13,11 +13,18 @@ interface DragStatus { initY: number; } +const emptySchedule = { + id: 0, + title: '', + startDateTime: '2000-01-01 00:00', + endDateTime: '2000-01-01 00:10', +} as const; + export const useScheduleDragStatus = () => { const [dragStatus, setDragStatus] = useState({ isDragging: false, level: 0, - schedule: {} as Schedule, + schedule: emptySchedule, initX: 0, initY: 0, }); From 09cf84b32b59a61063db3e9c1dca5ddaa342b86e Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Tue, 14 Nov 2023 15:44:38 +0900 Subject: [PATCH 49/53] =?UTF-8?q?refactor:=20CalendarDragScreen=EC=9D=98?= =?UTF-8?q?=20backdrop=20=EC=83=89=EC=83=81=EC=9D=84=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=20=EC=84=A0=EC=96=B8=EB=90=9C=20=EC=83=89=EC=83=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.styled.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts index 62c54e9c8..dd06e268e 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -10,7 +10,7 @@ export const Container = styled.div<{ $visible: boolean }>` width: 100%; height: 100%; - background-color: #ffffffaa; + background-color: ${({ theme }) => theme.color.WHITE_BLUR}; cursor: all-scroll; `; From e54a2248e4af833c94f16e96f621c29e63f06ac0 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Wed, 6 Dec 2023 22:01:32 +0900 Subject: [PATCH 50/53] =?UTF-8?q?refactor:=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=20props=EC=9D=98=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20YYYYMMDDHHMM=EC=9D=84=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen/CalendarDragScreen.tsx | 6 +++--- .../src/hooks/schedule/useCalendarDragScreen.ts | 6 +++--- .../hooks/schedule/useScheduleBarDragStatus.ts | 6 +++--- .../utils/generateScheduleBarsByMousePoint.ts | 17 +++++++---------- .../generateScheduleBarsByMousePoint.test.ts | 10 +++++++--- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index 02c2bf5ed..2e5561d3a 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,7 +1,7 @@ import * as S from './CalendarDragScreen.styled'; import { useRef } from 'react'; import FakeScheduleBarsScreen from '~/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen'; -import type { Schedule } from '~/types/schedule'; +import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; import { useCalendarDragScreen } from '~/hooks/schedule/useCalendarDragScreen'; @@ -16,8 +16,8 @@ interface CalendarDragScreenProps { schedule: Schedule; onMouseUp: ( title: string, - startDateTime: Schedule['startDateTime'], - endDateTime: Schedule['endDateTime'], + startDateTime: YYYYMMDDHHMM, + endDateTime: YYYYMMDDHHMM, shouldUpdate: boolean, ) => void; } diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index 4c85d0715..271282e41 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -1,7 +1,7 @@ import { useState, useEffect, useCallback } from 'react'; import { generateScheduleBarsByMousePoint } from '~/utils/generateScheduleBarsByMousePoint'; import type { RefObject } from 'react'; -import type { Schedule } from '~/types/schedule'; +import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; interface UseCalendarDragScreenProps { @@ -10,8 +10,8 @@ interface UseCalendarDragScreenProps { calendarSize: CalendarSize; onMouseUp: ( title: string, - startDateTime: Schedule['startDateTime'], - endDateTime: Schedule['endDateTime'], + startDateTime: YYYYMMDDHHMM, + endDateTime: YYYYMMDDHHMM, shouldUpdate: boolean, ) => void; initX: number; diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index 8329329f3..2da5a1001 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -3,7 +3,7 @@ import { useTeamPlace } from '~/hooks/useTeamPlace'; import { useToast } from '~/hooks/useToast'; import { useModifySchedule } from '~/hooks/queries/useModifySchedule'; import type { MouseEvent } from 'react'; -import type { Schedule } from '~/types/schedule'; +import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; interface DragStatus { isDragging: boolean; @@ -51,8 +51,8 @@ export const useScheduleDragStatus = () => { const handleMouseUp = ( title: string, - startDateTime: Schedule['startDateTime'], - endDateTime: Schedule['endDateTime'], + startDateTime: YYYYMMDDHHMM, + endDateTime: YYYYMMDDHHMM, shouldUpdate: boolean, ) => { if (!dragStatus.isDragging) { diff --git a/frontend/src/utils/generateScheduleBarsByMousePoint.ts b/frontend/src/utils/generateScheduleBarsByMousePoint.ts index 440ff3d3d..42b72477c 100644 --- a/frontend/src/utils/generateScheduleBarsByMousePoint.ts +++ b/frontend/src/utils/generateScheduleBarsByMousePoint.ts @@ -1,6 +1,6 @@ import { generateScheduleBars } from '~/utils/generateScheduleBars'; import { CALENDAR, ONE_DAY } from '~/constants/calendar'; -import type { Schedule } from '~/types/schedule'; +import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; interface GenerateScheduleBarsByMousePointProps { @@ -32,8 +32,8 @@ interface GenerateScheduleBarsByMousePointProps { * * @returns {Object} * @property {GeneratedScheduleBar[]} scheduleBars - 생성된 스케줄 바들을 의미합니다. - * @property {Schedule['startDateTime']} startDateTime - 상대좌표를 고려하여 새롭게 반영된 시작 날짜를 의미합니다. - * @property {Schedule['endDateTime']} endDateTime - 상대좌표를 고려하여 새롭게 반영된 끝 날짜를 의미합니다. + * @property {YYYYMMDDHHMM} startDateTime - 상대좌표를 고려하여 새롭게 반영된 시작 날짜를 의미합니다. + * @property {YYYYMMDDHHMM} endDateTime - 상대좌표를 고려하여 새롭게 반영된 끝 날짜를 의미합니다. */ export const generateScheduleBarsByMousePoint = ( params: GenerateScheduleBarsByMousePointProps, @@ -112,15 +112,12 @@ const getCalendarDateDifferenceByMousePoint = ( * 《changeDateTimeByDays》 * YYYY-MM-DD 형식의 날짜와 함께 변경되어야 하는 날의 수가 주어지면, 이를 반영하여 똑같이 YYYY-MM-DD 형식으로 변경된 날짜를 반환합니다. * - * @param {Schedule['startDateTime']} dateTime - 변경을 진행할 YYYY-MM-DD 형식의 날짜 정보입니다. + * @param {YYYYMMDDHHMM} dateTime - 변경을 진행할 YYYY-MM-DD 형식의 날짜 정보입니다. * @param {number} days - 입력으로 들어가는 날짜 정보의 날짜를 얼마나 변경할 것인지를 의미합니다. 이 값은 정수여야 합니다. * - * @returns {Schedule['startDateTime']} changedDateTime - 변경이 반영된 YYYY-MM-DD 형식의 날짜 정보입니다. + * @returns {YYYYMMDDHHMM} changedDateTime - 변경이 반영된 YYYY-MM-DD 형식의 날짜 정보입니다. */ -const changeDateTimeByDays = ( - dateTime: Schedule['startDateTime'], - days: number, -) => { +const changeDateTimeByDays = (dateTime: YYYYMMDDHHMM, days: number) => { const changedDate = new Date(Number(new Date(dateTime)) + ONE_DAY * days); const year = String(changedDate.getFullYear()).padStart(4, '0'); @@ -129,7 +126,7 @@ const changeDateTimeByDays = ( const time = dateTime.split(' ')[1]; const [minute, second] = time.split(':'); - const changedDateTime: Schedule['startDateTime'] = `${year}-${month}-${day} ${minute}:${second}`; + const changedDateTime: YYYYMMDDHHMM = `${year}-${month}-${day} ${minute}:${second}`; return changedDateTime; }; diff --git a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts index 11868eae2..49626d509 100644 --- a/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts +++ b/frontend/src/utils/test/generateScheduleBarsByMousePoint.test.ts @@ -1,5 +1,9 @@ import { generateScheduleBarsByMousePoint } from '~/utils/generateScheduleBarsByMousePoint'; -import type { GeneratedScheduleBar, Schedule } from '~/types/schedule'; +import type { + GeneratedScheduleBar, + Schedule, + YYYYMMDDHHMM, +} from '~/types/schedule'; const removeIdFromScheduleBars = (scheduleBars: GeneratedScheduleBar[]) => { /* eslint-disable-next-line */ @@ -22,8 +26,8 @@ const defaultParams = { type GeneratedScheduleBarWithoutId = Omit; interface ResultValue { - startDateTime: Schedule['startDateTime']; - endDateTime: Schedule['endDateTime']; + startDateTime: YYYYMMDDHHMM; + endDateTime: YYYYMMDDHHMM; scheduleBars: GeneratedScheduleBarWithoutId[]; } From 31dadee7b7e94cf358d69d66bacf154cbd801300 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 7 Dec 2023 22:25:49 +0900 Subject: [PATCH 51/53] =?UTF-8?q?refactor:=20=EC=9D=BC=EC=A0=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20=EB=93=9C?= =?UTF-8?q?=EB=9E=98=EA=B7=B8=20=EC=83=81=ED=83=9C=EC=97=90=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8A=94=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=80=EC=A4=84=EC=9D=84=20=EB=B9=88=20=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=A4=84=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/schedule/useScheduleBarDragStatus.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index 2da5a1001..b8ed3101b 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -77,9 +77,15 @@ export const useScheduleDragStatus = () => { { onSuccess: () => { showToast('success', '일정이 수정되었습니다.'); + + setDragStatus((prev) => ({ + ...prev, + schedule: emptySchedule, + })); }, onError: (error) => { const response = error as Response; + if (response.status === 500) showToast('error', '일정 제목이 최대 글자(250자)를 초과했습니다.'); }, From 6e5e258543e99d3fc5dc25261bf3d3def7a68682 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Thu, 7 Dec 2023 23:04:24 +0900 Subject: [PATCH 52/53] =?UTF-8?q?refactor:=20dragStatus=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EB=93=9C=EB=9E=98?= =?UTF-8?q?=EA=B7=B8=20=EC=8A=A4=ED=81=AC=EB=A6=B0=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20dragStatus=EB=A1=9C=20=EB=B0=9B=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CalendarDragScreen.styled.ts | 4 +-- .../CalendarDragScreen/CalendarDragScreen.tsx | 25 +++++-------------- .../TeamCalendar/TeamCalendar.tsx | 3 +-- .../hooks/schedule/useCalendarDragScreen.ts | 14 +++++------ .../schedule/useScheduleBarDragStatus.ts | 10 +------- frontend/src/types/schedule.ts | 8 ++++++ 6 files changed, 25 insertions(+), 39 deletions(-) diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts index dd06e268e..9b746248b 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.styled.ts @@ -1,7 +1,7 @@ import { styled } from 'styled-components'; -export const Container = styled.div<{ $visible: boolean }>` - ${({ $visible }) => !$visible && 'display: none'}; +export const Container = styled.div<{ $isDragging: boolean }>` + ${({ $isDragging }) => !$isDragging && 'display: none'}; position: absolute; overflow: hidden; left: 0; diff --git a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx index 2e5561d3a..500e6153b 100644 --- a/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx +++ b/frontend/src/components/team_calendar/CalendarDragScreen/CalendarDragScreen.tsx @@ -1,19 +1,15 @@ import * as S from './CalendarDragScreen.styled'; import { useRef } from 'react'; import FakeScheduleBarsScreen from '~/components/team_calendar/FakeScheduleBarsScreen/FakeScheduleBarsScreen'; -import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; +import type { YYYYMMDDHHMM, DragStatus } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; import { useCalendarDragScreen } from '~/hooks/schedule/useCalendarDragScreen'; interface CalendarDragScreenProps { - visible: boolean; - initX: number; - initY: number; calendarSize: CalendarSize; year: number; month: number; - level: number; - schedule: Schedule; + dragStatus: DragStatus; onMouseUp: ( title: string, startDateTime: YYYYMMDDHHMM, @@ -23,20 +19,11 @@ interface CalendarDragScreenProps { } const CalendarDragScreen = (props: CalendarDragScreenProps) => { - const { - visible, - initX, - initY, - calendarSize, - year, - month, - level, - schedule, - onMouseUp, - } = props; + const { calendarSize, year, month, dragStatus, onMouseUp } = props; + const { isDragging, level, schedule, initX, initY } = dragStatus; const calendarRef = useRef(null); const { scheduleBars, relativeX, relativeY } = useCalendarDragScreen({ - visible, + isDragging, initX, initY, calendarRef, @@ -49,7 +36,7 @@ const CalendarDragScreen = (props: CalendarDragScreenProps) => { }); return ( - + { ); })} diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index 271282e41..94da8fd39 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -5,7 +5,7 @@ import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; import type { CalendarSize } from '~/types/size'; interface UseCalendarDragScreenProps { - visible: boolean; + isDragging: boolean; calendarRef: RefObject; calendarSize: CalendarSize; onMouseUp: ( @@ -31,7 +31,7 @@ interface CalendarPointInfos { export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { - visible, + isDragging, calendarRef, calendarSize, initX, @@ -52,7 +52,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; - const scheduleBarsInfo = visible + const scheduleBarsInfo = isDragging ? generateScheduleBarsByMousePoint({ schedule, year, @@ -79,7 +79,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const handleMouseMove = useCallback( (e: globalThis.MouseEvent) => { - if (!visible) { + if (!isDragging) { return; } @@ -91,11 +91,11 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { relativeY: clientY - initY, })); }, - [initX, initY, visible], + [initX, initY, isDragging], ); const handleMouseUp = useCallback(() => { - if (!visible || !scheduleBarsInfo) { + if (!isDragging || !scheduleBarsInfo) { return; } @@ -110,7 +110,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { relativeX: 0, relativeY: 0, })); - }, [onMouseUp, schedule, scheduleBarsInfo, visible]); + }, [onMouseUp, schedule, scheduleBarsInfo, isDragging]); useEffect(() => { const calendarElement = calendarRef.current; diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index b8ed3101b..fc3218f1f 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -3,15 +3,7 @@ import { useTeamPlace } from '~/hooks/useTeamPlace'; import { useToast } from '~/hooks/useToast'; import { useModifySchedule } from '~/hooks/queries/useModifySchedule'; import type { MouseEvent } from 'react'; -import type { Schedule, YYYYMMDDHHMM } from '~/types/schedule'; - -interface DragStatus { - isDragging: boolean; - level: number; - schedule: Schedule; - initX: number; - initY: number; -} +import type { Schedule, YYYYMMDDHHMM, DragStatus } from '~/types/schedule'; const emptySchedule = { id: 0, diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index 1c40fddf1..0e5ef0aa3 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -50,3 +50,11 @@ export interface GeneratedScheduleBar { calendarSize?: CalendarSize; mode?: 'normal' | 'no-interaction' | 'indicator'; } + +export interface DragStatus { + isDragging: boolean; + level: number; + schedule: Schedule; + initX: number; + initY: number; +} From 28cb380d52058a1872992140deca0a86a87504c7 Mon Sep 17 00:00:00 2001 From: WizardRabbit Date: Fri, 8 Dec 2023 02:47:17 +0900 Subject: [PATCH 53/53] =?UTF-8?q?refactor:=20=EB=8D=94=EB=AF=B8=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=B0=94=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0,=20null=20=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B9=88=20=EC=8A=A4=EC=BC=80=EC=A4=84=EC=9D=84=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hooks/schedule/useCalendarDragScreen.ts | 32 +++++++++---------- .../schedule/useScheduleBarDragStatus.ts | 13 ++------ frontend/src/types/schedule.ts | 2 +- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/frontend/src/hooks/schedule/useCalendarDragScreen.ts b/frontend/src/hooks/schedule/useCalendarDragScreen.ts index 94da8fd39..fe98e8005 100644 --- a/frontend/src/hooks/schedule/useCalendarDragScreen.ts +++ b/frontend/src/hooks/schedule/useCalendarDragScreen.ts @@ -19,7 +19,7 @@ interface UseCalendarDragScreenProps { year: number; month: number; level: number; - schedule: Schedule; + schedule: Schedule | null; } interface CalendarPointInfos { @@ -52,20 +52,20 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { const { relativeX, relativeY, calendarWidth, calendarHeight } = calendarPointInfos; - const scheduleBarsInfo = isDragging - ? generateScheduleBarsByMousePoint({ - schedule, - year, - month, - relativeX, - relativeY, - calendarWidth, - calendarHeight, - level, - calendarSize, - }) - : null; - + const scheduleBarsInfo = + schedule === null + ? null + : generateScheduleBarsByMousePoint({ + schedule, + year, + month, + relativeX, + relativeY, + calendarWidth, + calendarHeight, + level, + calendarSize, + }); const getProcessedRelativePoint = () => { const processedRelativeX = ((relativeX + calendarWidth * (15 / 14)) % (calendarWidth / 7)) - @@ -95,7 +95,7 @@ export const useCalendarDragScreen = (props: UseCalendarDragScreenProps) => { ); const handleMouseUp = useCallback(() => { - if (!isDragging || !scheduleBarsInfo) { + if (!isDragging || !scheduleBarsInfo || !schedule) { return; } diff --git a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts index fc3218f1f..c9a0558a3 100644 --- a/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts +++ b/frontend/src/hooks/schedule/useScheduleBarDragStatus.ts @@ -5,24 +5,17 @@ import { useModifySchedule } from '~/hooks/queries/useModifySchedule'; import type { MouseEvent } from 'react'; import type { Schedule, YYYYMMDDHHMM, DragStatus } from '~/types/schedule'; -const emptySchedule = { - id: 0, - title: '', - startDateTime: '2000-01-01 00:00', - endDateTime: '2000-01-01 00:10', -} as const; - export const useScheduleDragStatus = () => { const [dragStatus, setDragStatus] = useState({ isDragging: false, level: 0, - schedule: emptySchedule, + schedule: null, initX: 0, initY: 0, }); const { showToast } = useToast(); const { teamPlaceId } = useTeamPlace(); - const scheduleId = dragStatus.schedule.id; + const scheduleId = dragStatus.schedule === null ? 0 : dragStatus.schedule.id; const { mutateModifySchedule } = useModifySchedule(teamPlaceId, scheduleId); const handleDragStart = ( @@ -72,7 +65,7 @@ export const useScheduleDragStatus = () => { setDragStatus((prev) => ({ ...prev, - schedule: emptySchedule, + schedule: null, })); }, onError: (error) => { diff --git a/frontend/src/types/schedule.ts b/frontend/src/types/schedule.ts index 0e5ef0aa3..661a85396 100644 --- a/frontend/src/types/schedule.ts +++ b/frontend/src/types/schedule.ts @@ -54,7 +54,7 @@ export interface GeneratedScheduleBar { export interface DragStatus { isDragging: boolean; level: number; - schedule: Schedule; + schedule: Schedule | null; initX: number; initY: number; }