-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #245 from ASAP-as-soon-as-possible/feat/overallSch…
- Loading branch information
Showing
31 changed files
with
660 additions
and
289 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
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
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,165 +1,47 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { availableDatesAtom, preferTimesAtom, timeSlotUserNameAtom } from 'atoms/atom'; | ||
import { useRecoilState, useRecoilValue } from 'recoil'; | ||
|
||
import LoadingPage from 'pages/errorLoading/LoadingPage'; | ||
import { OverallScheduleData } from 'src/types/overallScheduleType'; | ||
import Text from 'components/atomComponents/Text'; | ||
import TimeTable from './components/TimeTable'; | ||
import { availableScheduleOptionApi } from 'utils/apis/legacy/availbleScheduleOptionApi'; | ||
import { getFormattedAvailableDateTimes } from './utils/getFormattedAvailableDateTimes'; | ||
import { overallScheduleApi } from 'utils/apis/legacy/overallScheduleApi'; | ||
import { styled } from 'styled-components'; | ||
import { theme } from 'styles/theme'; | ||
import { getAvailableTimes } from 'components/timetableComponents/utils'; | ||
import { useParams } from 'react-router-dom'; | ||
import styled from 'styled-components'; | ||
import { useGetOverallSchedule } from 'utils/apis/useGetOverallSchedule'; | ||
import { useGetTimetable } from 'utils/apis/useGetTimetable'; | ||
|
||
const OverallSchedule = () => { | ||
const { meetingId } = useParams(); | ||
const [overallScheduleData, setOverallScheduleData] = useState<OverallScheduleData>(); | ||
|
||
const [availableDates, setAvailableDates] = useRecoilState(availableDatesAtom); | ||
|
||
const [preferTimes, setPreferTimes] = useRecoilState(preferTimesAtom); | ||
|
||
const timeSlotUserNames = useRecoilValue(timeSlotUserNameAtom); | ||
|
||
const [memberCount, setMemberCount] = useState<number>(0); | ||
const [totalUserNames, setTotalUserNames] = useState<string[]>(); | ||
import OverallScheduleTable from './components/OverallScheduleTable'; | ||
import Title from './components/Title'; | ||
|
||
const getAvailableScheduleOption = async () => { | ||
try { | ||
const { data } = await availableScheduleOptionApi(meetingId); | ||
setAvailableDates(data.data.availableDates); | ||
setPreferTimes(data.data.preferTimes); | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
}; | ||
|
||
|
||
const getOverallSchedule = async () => { | ||
try { | ||
const result = await overallScheduleApi(meetingId); | ||
const { data } = result.data; | ||
const uniqueData = [...new Set(data.totalUserNames)]; | ||
setOverallScheduleData(data); | ||
setMemberCount(data.memberCount); | ||
setTotalUserNames(uniqueData); | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
getAvailableScheduleOption(); | ||
getOverallSchedule(); | ||
}, []); | ||
function OverallSchedule() { | ||
const { meetingId } = useParams(); | ||
const { data: dataTimetable, isLoading: isLoadingTimetable } = useGetTimetable(meetingId); | ||
const { data: dataOverallSchedule, isLoading: isLoadingOverallSchedule } = useGetOverallSchedule( | ||
meetingId, | ||
); | ||
|
||
const formattedAvailableDateTimes = | ||
overallScheduleData && getFormattedAvailableDateTimes(overallScheduleData); | ||
// 시간대 선택 단계가 없어질 것을 고려하여 상수값을 설정해놓음 | ||
const PREFER_TIMES = { startTime: '06:00', endTime: '24:00' }; | ||
|
||
return ( | ||
<OverallScheduleWrapper> | ||
{overallScheduleData ? ( | ||
<> | ||
<TextOneLine> | ||
<Text font={'title1'} color={`${theme.colors.white}`}> | ||
현재까지 | ||
</Text> | ||
<Text font={'title1'} color={`${theme.colors.sub1}`}> | ||
{memberCount.toString()}명 | ||
</Text> | ||
<Text font={'title1'} color={`${theme.colors.white}`}> | ||
이 입력했어요 | ||
</Text> | ||
</TextOneLine> | ||
<TotalUserNames> | ||
{totalUserNames && | ||
totalUserNames.map((name, idx) => ( | ||
<Text key={idx + name} font={'body4'} color={`${theme.colors.grey5}`}> | ||
{name} | ||
{idx !== totalUserNames.length - 1 ? ',' : ''} | ||
</Text> | ||
))} | ||
</TotalUserNames> | ||
<TimeTable | ||
selectedSchedule={formattedAvailableDateTimes?.availableDateTimes} | ||
availableDates={availableDates} | ||
preferTimes={preferTimes} | ||
scheduleType="available" | ||
<Title memberCount={dataOverallSchedule?.memberCount} totalUserNames={dataOverallSchedule?.totalUserNames}/> | ||
{!isLoadingTimetable && | ||
!isLoadingOverallSchedule && | ||
dataTimetable && | ||
dataOverallSchedule && ( | ||
<OverallScheduleTable | ||
timeSlots={getAvailableTimes(PREFER_TIMES)} | ||
availableDates={dataTimetable.availableDates} | ||
dataOverallSchedule={dataOverallSchedule} | ||
/> | ||
<UserNameWrapper> | ||
{!timeSlotUserNames ? ( | ||
<TextTwoLine> | ||
<Text font={'body4'} color={`${theme.colors.grey5}`}> | ||
블럭을 선택하면 해당 시간대에 참여가능한 | ||
</Text> | ||
<Text font={'body4'} color={`${theme.colors.grey5}`}> | ||
인원을 확인할 수 있어요 | ||
</Text> | ||
</TextTwoLine> | ||
) : ( | ||
timeSlotUserNames.map((name, idx) => ( | ||
<Text key={idx + name} font={'body2'} color={`${theme.colors.grey2}`}> | ||
{name} | ||
{idx !== timeSlotUserNames.length - 1 ? ',' : ''} | ||
</Text> | ||
)) | ||
)} | ||
</UserNameWrapper> | ||
</> | ||
) : ( | ||
<LoadingWrapper> | ||
<LoadingPage /> | ||
</LoadingWrapper> | ||
)} | ||
)} | ||
</OverallScheduleWrapper> | ||
); | ||
}; | ||
} | ||
|
||
export default OverallSchedule; | ||
|
||
const UserNameWrapper = styled.aside` | ||
const OverallScheduleWrapper = styled.div` | ||
display: flex; | ||
position: fixed; | ||
bottom: 4.4rem; | ||
flex-wrap: wrap; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
border: 1px solid ${({ theme }) => theme.colors.grey5}; | ||
border-radius: 0.8rem; | ||
background: ${({ theme }) => theme.colors.grey9}; | ||
width: 33.5rem; | ||
min-height: 8.3rem; | ||
text-align: center; | ||
color: ${({ theme }) => theme.colors.white}; | ||
`; | ||
|
||
const OverallScheduleWrapper = styled.main` | ||
margin-bottom: 16.1rem; | ||
margin-bottom: 16.4rem; | ||
`; | ||
|
||
const TextOneLine = styled.div` | ||
display: flex; | ||
flex-wrap: wrap; | ||
margin-top: 3.7rem; | ||
width: 100%; | ||
`; | ||
|
||
const TotalUserNames = styled.div` | ||
display: flex; | ||
margin-top: 1.2rem; | ||
margin-bottom: 2.4rem; | ||
`; | ||
|
||
const LoadingWrapper = styled.div` | ||
position: relative; | ||
top: 25rem; | ||
width: 100%; | ||
`; | ||
|
||
const TextTwoLine = styled.div` | ||
display:flex; | ||
flex-direction:column; | ||
align-items: center; | ||
justify-content:center; | ||
` |
45 changes: 45 additions & 0 deletions
45
src/pages/OverallSchedule/components/OverallScheduleColumn.tsx
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,45 @@ | ||
import Slot from 'components/timetableComponents/parts/Slot'; | ||
import { ColumnStructure } from 'components/timetableComponents/types'; | ||
import { theme } from 'styles/theme'; | ||
import { TimeSlot } from 'utils/apis/useGetOverallSchedule'; | ||
|
||
import { useSlotClick } from '../hooks/useSlotClick'; | ||
|
||
interface OverallScheduleColumnProps extends ColumnStructure { | ||
availableSlotInfo: TimeSlot[]; | ||
} | ||
|
||
function OverallScheduleColumn({ date, timeSlots, availableSlotInfo }: OverallScheduleColumnProps) { | ||
|
||
const { clickedSlot, onClickSlot } = useSlotClick(); | ||
|
||
const getTimeSlotStyle = (colorLevel: number, slotId:string) => { | ||
const COLOR :{ [key : number]: string } = { | ||
0: 'transparent', | ||
1: theme.colors.level1, | ||
2: theme.colors.level2, | ||
3: theme.colors.level3, | ||
4: theme.colors.level4, | ||
5: theme.colors.level5, | ||
}; | ||
|
||
const isClickedSlot = clickedSlot === slotId; | ||
return ` | ||
background-color: ${isClickedSlot && colorLevel!==0 ? theme.colors.sub1 : COLOR[colorLevel]}; | ||
cursor: ${colorLevel !== 0 ? 'pointer' : 'default'}; | ||
` | ||
} | ||
|
||
return ( | ||
<> | ||
{timeSlots.map((timeSlot) => { | ||
const { colorLevel = 0, userNames = [] } = availableSlotInfo.find((info) => info.time === timeSlot) ?? {}; | ||
const slotId = `${date}/${timeSlot}`; | ||
|
||
return <Slot key={slotId} slotId={slotId} slotStyle={getTimeSlotStyle(colorLevel, slotId)} onClick={()=>onClickSlot(slotId, userNames)}/>; | ||
})} | ||
</> | ||
); | ||
} | ||
|
||
export default OverallScheduleColumn; |
Oops, something went wrong.