-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Slot 컴포넌트 관련 유틸 함수 구현 * refactor: Task type을 공통 type으로 분리 * design: Slot 관련 css 속성 추가 * feat: TimeSlot 컴포넌트 구현 * feat: TimeSlot 컴포넌트 구현 * feat: Slot 컴포넌트 구현 * refactor: calculateTaskOffsetAndHeightPercent 함수 반환값 변경
- Loading branch information
Showing
6 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
.slot { | ||
display: flex; | ||
gap: 10px; | ||
} | ||
|
||
.timeSlotLayout { | ||
position: relative; | ||
flex: 0 1 10%; // flex-grow: 0, flex-shrink: 1, flex-basis: 10% | ||
min-width: 50px; | ||
max-width: 70px; | ||
height: 100%; | ||
} | ||
|
||
.headerDate { | ||
position: absolute; | ||
top: -0.5em; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
.taskSlotLayout { | ||
box-sizing: border-box; | ||
position: relative; | ||
flex: 1 1 90%; // flex-grow: 1, flex-shrink: 1, flex-basis: 90% | ||
min-width: 100px; | ||
height: 100%; | ||
} | ||
|
||
.taskSlotBackground { | ||
position: absolute; | ||
width: 100%; | ||
z-index: 0; | ||
} | ||
|
||
.taskSlotContent { | ||
z-index: 20; | ||
position: relative; | ||
} | ||
|
||
.title { | ||
font-size: 1.25rem; | ||
margin: 20px 0; | ||
} | ||
|
||
.description { | ||
font-size: 1rem; | ||
margin: 20px 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import TimeSlot from '@/timetable/components/TimeSlot'; | ||
import TaskSlot from '@/timetable/components/TaskSlot'; | ||
import type { Task } from './Timetable.type'; | ||
import styled from './Slot.module.scss'; | ||
|
||
interface SlotProps { | ||
headerDate: Date; | ||
slotTime: number; | ||
taskItem: Task | undefined; | ||
} | ||
|
||
function Slot({ headerDate, slotTime, taskItem }: SlotProps) { | ||
return ( | ||
<div className={styled.slot}> | ||
<TimeSlot headerDate={headerDate} /> | ||
<TaskSlot headerDate={headerDate} slotTime={slotTime} taskItem={taskItem} /> | ||
</div> | ||
); | ||
} | ||
|
||
export default Slot; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { add } from 'date-fns'; | ||
import { calculateTaskOffsetAndHeightPercent } from '@/timetable/utils'; | ||
import styled from './Slot.module.scss'; | ||
import type { Task } from './Timetable.type'; | ||
|
||
interface TaskSlotProps { | ||
headerDate: Date; | ||
slotTime: number; | ||
taskItem: Task | undefined; | ||
} | ||
|
||
function TaskSlot({ headerDate, slotTime, taskItem }: TaskSlotProps) { | ||
if (!taskItem) { | ||
return <div className={styled.taskSlotLayout} />; | ||
} | ||
|
||
const { startTime, endTime, slotColor, title, subTitle } = taskItem; | ||
|
||
const slotStartTime = headerDate; | ||
const slotEndTime = add(headerDate, { minutes: slotTime }); | ||
|
||
const { offsetPercent, heightPercent } = calculateTaskOffsetAndHeightPercent( | ||
slotStartTime, | ||
slotEndTime, | ||
startTime, | ||
endTime, | ||
slotTime, | ||
); | ||
|
||
return ( | ||
<div className={styled.taskSlotLayout}> | ||
<div | ||
className={styled.taskSlotBackground} | ||
style={{ | ||
top: `${offsetPercent}%`, | ||
left: '0', | ||
height: `${heightPercent}%`, | ||
backgroundColor: `${slotColor}`, | ||
}} | ||
/> | ||
<div className={styled.taskSlotContent}> | ||
<p className={styled.title}>{title}</p> | ||
<p className={styled.description}>{subTitle}</p> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default TaskSlot; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { getHourAndMinutesFormat } from '@/timetable/utils'; | ||
import styled from './Slot.module.scss'; | ||
|
||
interface TimeSlotProps { | ||
headerDate: Date; | ||
} | ||
|
||
function TimeSlot({ headerDate }: TimeSlotProps) { | ||
const currentTime = getHourAndMinutesFormat(headerDate); | ||
return ( | ||
<div className={`${styled.timeSlotLayout} ${styled.title}`}> | ||
<p className={styled.headerDate}>{currentTime}</p> | ||
</div> | ||
); | ||
} | ||
|
||
export default TimeSlot; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
interface Task { | ||
id: number; | ||
title: string; | ||
subTitle: string; | ||
slotColor: string; | ||
startTime: Date; | ||
endTime: Date; | ||
} | ||
|
||
export type { Task }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const getHourAndMinutesFormat = (data: Date) => { | ||
const hours = data.getHours(); | ||
const minutes = data.getMinutes(); | ||
const minutesFormat = minutes < 10 ? `0${minutes}` : minutes; | ||
const currentTime = minutes === 0 ? hours : `${hours}:${minutesFormat}`; | ||
|
||
return currentTime; // HH:MM | ||
}; | ||
|
||
// 시간을 분단위로 바꿔버리고 더해주는 함수 | ||
const sumHoursAndMinutes = (date: Date) => date.getHours() * 60 + date.getMinutes(); | ||
|
||
const calculateTaskOffsetAndHeightPercent = ( | ||
slotStartTime: Date, | ||
slotEndTime: Date, | ||
taskStartTime: Date, | ||
taskEndTime: Date, | ||
slotTime: number, | ||
) => { | ||
const slotStartMinutes = sumHoursAndMinutes(slotStartTime); | ||
const slotEndMinutes = sumHoursAndMinutes(slotEndTime); | ||
const taskStartMinutes = sumHoursAndMinutes(taskStartTime); | ||
const taskEndMinutes = sumHoursAndMinutes(taskEndTime); | ||
|
||
let offsetPercent = 0; | ||
let endPercent = 100; | ||
|
||
if (slotStartMinutes < taskStartMinutes) { | ||
// 슬롯의 시작시간보다 task의 시작 시간이 늦었다면(즉 slot 도중에 시작했다면) | ||
offsetPercent = ((taskStartMinutes - slotStartMinutes) / slotTime) * 100; | ||
} | ||
|
||
if (taskEndMinutes < slotEndMinutes) { | ||
// task의 끝나는 시간이 slot의 종료 시간보다 늦다면(즉 slot 도중에 끝난다면) | ||
endPercent = ((taskEndMinutes - slotStartMinutes) / slotTime) * 100; | ||
} | ||
|
||
const heightPercent = endPercent - offsetPercent; | ||
|
||
return { offsetPercent, heightPercent }; | ||
}; | ||
|
||
export { getHourAndMinutesFormat, sumHoursAndMinutes, calculateTaskOffsetAndHeightPercent }; |