Skip to content

Commit

Permalink
Merge pull request #121 from BCSDLab/feature/#116
Browse files Browse the repository at this point in the history
[동방예약] 월간 동방예약 기능 추가
  • Loading branch information
dooohun authored Mar 25, 2024
2 parents 42d95aa + e28c23e commit 66960f0
Show file tree
Hide file tree
Showing 9 changed files with 579 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/api/reservations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export const postReservations = (data: Reservations) => accessClient.post('/rese
export const deleteReservations = (id: number) => accessClient.delete(`/reservations/${id}`);

export const putReservations = (id: number, data: Reservations) => accessClient.put(`/reservations/${id}`, data);

export const myReservation = () => accessClient.get<GetReservationsResponse[]>('reservations/member');
3 changes: 2 additions & 1 deletion src/page/Reservation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Button, ButtonGroup } from '@mui/material';
import LoadingSpinner from 'layout/LoadingSpinner';
import { Suspense, useState } from 'react';
import Week from './view/Week';
import Month from './view/Month';
import * as S from './style';

interface CurrentPageDate {
Expand Down Expand Up @@ -38,7 +39,7 @@ function ReservationOutlet() {
</ButtonGroup>
{/* 주를 만들자 */}
{mode === 'week' && <Week setDate={setDate} />}
{mode === 'month' && <div></div>}
{mode === 'month' && <Month /> }
</div>
);
}
Expand Down
160 changes: 160 additions & 0 deletions src/page/Reservation/view/Month.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import {
Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Button,
} from '@mui/material';
import { ArrowBackIosNewOutlined, ArrowForwardIosOutlined } from '@mui/icons-material';
import { useGetReservations } from 'query/reservations';
import { Reservations } from 'model/reservations';
import { useEffect, useState } from 'react';
import * as S from './style';
// eslint-disable-next-line import/no-cycle
import MonthModal from './Month/MonthModal';
import MyReservation from './Month/MyReservation';

type Calendar = {
day: number | null,
date: number | null,
today: string | null,
};

type Calendars = Calendar[];

export type CalendarContent = {
data: Reservations[],
date: number | null,
today: string | null,
currentMonth: number,
};

function CalendarCell({
date, today, data, currentMonth,
}: CalendarContent) {
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const filteredData = data.filter((item) => item.startDateTime.slice(0, 10) === today);

return (
<>
<TableCell css={S.Cell(currentMonth === new Date().getMonth() && date === new Date().getDate())} onClick={() => date && handleOpen()}>
<div css={S.Date(currentMonth === new Date().getMonth() && date === new Date().getDate())}>
{date}
</div>
<div css={S.scheduleContent}>
{date && filteredData.map((item, index) => (
<p css={S.schedule(index)}>
{item.startDateTime.slice(10, 20)}
{' '}
{item.reason}
</p>
))}
</div>
</TableCell>
<MonthModal today={today} date={date} data={filteredData} handleClose={handleClose} open={open} currentMonth={currentMonth} />
</>
);
}

// 각 요일 구하기
const getCurrentDay = (currentYear: number, currentMonth: number, day: number) => {
return new Date(currentYear, currentMonth, day).getDay();
};

const emptySpace = (calendars: Calendars) => {
if (calendars[0].day) {
const length = calendars[0].day;
for (let i = 0; i < length; i += 1) {
calendars.unshift({ day: null, date: null, today: null });
}
}
};

const chunkArray = (arr: Calendars, chunkSize: number) => {
const result: Calendars[] = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize);
result.push(chunk);
}
return result;
};

export default function Month() {
const { data } = useGetReservations();
const [currentYear, setCurrentYear] = useState(new Date().getFullYear());
const [currentMonth, setCurrentMonth] = useState(new Date().getMonth());
const [currentCalendar, setCurrentCalendar] = useState<Calendars[]>([]);
const [open, setOpen] = useState<boolean>(false);

const handleClose = () => setOpen(false);
const nextYear = () => setCurrentYear((prev) => prev + 1);
const nextMonth = () => setCurrentMonth((prev) => prev + 1);
const previousYear = () => setCurrentYear((prev) => prev - 1);
const previousMonth = () => setCurrentMonth((prev) => prev - 1);

useEffect(() => {
// 현재 월의 일 수
const currentMonthDate = new Date(currentYear, currentMonth + 1, 0).getDate();

const calendar = Array.from({ length: currentMonthDate }, (_, i) => {
const index = i + 1;
const obj: Calendar = {
day: getCurrentDay(currentYear, currentMonth, index),
date: index,
today: new Date(currentYear, currentMonth, index + 1).toISOString().slice(0, 10),
};

return obj;
});

emptySpace(calendar);
const weeklyCalendar = chunkArray(calendar, 7);

setCurrentCalendar(weeklyCalendar);
}, [currentMonth, currentYear]);

return (
<TableContainer>
<div css={S.AlignItems}>
<Button onClick={previousYear}>
<ArrowBackIosNewOutlined />
</Button>
<div css={S.current}>{`${currentYear}년`}</div>
<Button onClick={nextYear}>
<ArrowForwardIosOutlined />
</Button>
<Button onClick={previousMonth}>
<ArrowBackIosNewOutlined />
</Button>
<div css={S.current}>{`${currentMonth + 1}월`}</div>
<Button onClick={nextMonth}>
<ArrowForwardIosOutlined />
</Button>
<Button onClick={() => setOpen(true)}>
예약 확인
</Button>
</div>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">일요일</TableCell>
<TableCell align="center">월요일</TableCell>
<TableCell align="center">화요일</TableCell>
<TableCell align="center">수요일</TableCell>
<TableCell align="center">목요일</TableCell>
<TableCell align="center">금요일</TableCell>
<TableCell align="center">토요일</TableCell>
</TableRow>
</TableHead>
<TableBody>
{currentCalendar.map((week) => (
<TableRow>
{week.map((day) => (
<CalendarCell today={day.today} date={day.date} data={data} currentMonth={currentMonth} />
))}
</TableRow>
))}
</TableBody>
</Table>
<MyReservation open={open} handleClose={handleClose} />
</TableContainer>
);
}
53 changes: 53 additions & 0 deletions src/page/Reservation/view/Month/DetailInfomation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Reservations } from 'model/reservations';
import { Button } from '@mui/material';
import { useDeleteReservations } from 'query/reservations';
import * as S from './style';

interface DetailInfomationProps extends Reservations {
// eslint-disable-next-line
id?: number;
}

export default function DetailInfomation({
detailedReason, startDateTime, endDateTime, memberCount, id, reason,
}: DetailInfomationProps) {
const { mutate } = useDeleteReservations();
return (
<div css={S.Detail}>
<div css={S.DetailContainer}>
<div>
<div>
시간 :
{startDateTime.slice(10, 20)}
{' '}
~
{' '}
{endDateTime.slice(10, 20)}
</div>
<div>
정보 :
{' '}
{reason}
</div>
<div>
상세정보 :
{' '}
{detailedReason}
</div>
<div>
인원 :
{' '}
{memberCount}
</div>
</div>
{
id && (
<Button variant="outlined" color="error" onClick={() => mutate(id)}>
취소
</Button>
)
}
</div>
</div>
);
}
Loading

0 comments on commit 66960f0

Please sign in to comment.