Skip to content

Commit

Permalink
Merge pull request #165 from BCSDLab/feature/#116
Browse files Browse the repository at this point in the history
[동방예약] 월 단위 동방예약 관련 이슈 해결
  • Loading branch information
chaeseungyun authored Apr 8, 2024
2 parents eec27a5 + fb28382 commit ddb79a3
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 34 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
9 changes: 9 additions & 0 deletions src/model/reservations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ export interface GetReservationsResponse extends Reservations {
id: number;
memberName: string;
}

export interface Reservation {
memberCount: number;
reason: string;
detailedReason: string;
startDateTime: string;
endDateTime: string;
memberName: string;
}
24 changes: 17 additions & 7 deletions src/page/Reservation/view/Month.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
} from '@mui/material';
import { ArrowBackIosNewOutlined, ArrowForwardIosOutlined } from '@mui/icons-material';
import { useGetReservations } from 'query/reservations';
import { Reservations } from 'model/reservations';
import { Reservation } from 'model/reservations';
import { useEffect, useState } from 'react';
import * as S from './style';
// eslint-disable-next-line import/no-cycle
Expand All @@ -19,7 +19,7 @@ type Calendar = {
type Calendars = Calendar[];

export type CalendarContent = {
data: Reservations[],
data: Reservation[],
date: number | null,
today: string | null,
currentMonth: number,
Expand All @@ -35,7 +35,10 @@ function CalendarCell({

return (
<>
<TableCell css={S.Cell(currentMonth === new Date().getMonth() && date === new Date().getDate())} onClick={() => date && handleOpen()}>
<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>
Expand Down Expand Up @@ -86,9 +89,16 @@ export default function Month() {

const handleClose = () => setOpen(false);
const nextYear = () => setCurrentYear((prev) => prev + 1);
const nextMonth = () => setCurrentMonth((prev) => prev + 1);
const nextMonth = () => {
setCurrentMonth((prev) => (prev + 1) % 12);
if (currentMonth === 11) nextYear();
};
const previousYear = () => setCurrentYear((prev) => prev - 1);
const previousMonth = () => setCurrentMonth((prev) => prev - 1);
const previousMonth = () => setCurrentMonth((prev) => {
if ((prev - 1) >= 0) return (prev - 1) % 12;
previousYear();
return 11;
});

useEffect(() => {
// 현재 월의 일 수
Expand Down Expand Up @@ -128,7 +138,7 @@ export default function Month() {
<Button onClick={nextMonth}>
<ArrowForwardIosOutlined />
</Button>
<Button onClick={() => setOpen(true)}>
<Button variant="outlined" onClick={() => setOpen(true)}>
예약 확인
</Button>
</div>
Expand All @@ -146,7 +156,7 @@ export default function Month() {
</TableHead>
<TableBody>
{currentCalendar.map((week) => (
<TableRow>
<TableRow sx={{ width: '100%' }}>
{week.map((day) => (
<CalendarCell today={day.today} date={day.date} data={data} currentMonth={currentMonth} />
))}
Expand Down
19 changes: 15 additions & 4 deletions src/page/Reservation/view/Month/DetailInfomation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,30 @@ import { Button } from '@mui/material';
import { useDeleteReservations } from 'query/reservations';
import * as S from './style';

interface DetailInfomationProps extends Reservations {
interface DetailInformationProps extends Reservations {
// eslint-disable-next-line
id?: number;
// eslint-disable-next-line
passed?: boolean;
memberName: string;
}

export default function DetailInfomation({
detailedReason, startDateTime, endDateTime, memberCount, id, reason,
}: DetailInfomationProps) {
detailedReason, startDateTime, endDateTime, memberCount, id, reason, memberName, passed,
}: DetailInformationProps) {
const { mutate } = useDeleteReservations();
return (
<div css={S.Detail}>
<div css={S.DetailContainer}>
<div>
<div>
{startDateTime.slice(0, 10)}
</div>
<div>
예약자명 :
{' '}
{memberName}
</div>
<div>
시간 :
{startDateTime.slice(10, 20)}
Expand All @@ -41,7 +52,7 @@ export default function DetailInfomation({
</div>
</div>
{
id && (
id && !passed && (
<Button variant="outlined" color="error" onClick={() => mutate(id)}>
취소
</Button>
Expand Down
59 changes: 43 additions & 16 deletions src/page/Reservation/view/Month/MonthModal.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {
Box, Modal, TextField, Button, MenuItem,
Box, Modal, TextField, Button, MenuItem, ToggleButton, ToggleButtonGroup,
} from '@mui/material';
import { useCreateReservations } from 'query/reservations';
import { useState } from 'react';
import { HOUR_LIST, MINUTE_LIST } from 'util/constants/time';
import DetailInfomation from './DetailInfomation';
// eslint-disable-next-line import/no-cycle
import { CalendarContent } from '../Month';

// eslint-disable-next-line import/no-cycle
import { useToggleButtonGroup } from './MyReservation';
import * as S from './style';

export const style = {
Expand Down Expand Up @@ -43,17 +44,36 @@ export default function MonthModal({
}: ModalContent) {
const currentDate = new Date().getDate();
const nowMonth = new Date().getMonth();
const { mutate: reservation } = useCreateReservations();
const { mutate: reservation, isError } = useCreateReservations();
const [reserve, setReserve] = useState(initialState);
const { alignment, handleChange } = useToggleButtonGroup();
const canReserve = () => {
if (currentMonth > nowMonth) return true;
if (date && nowMonth === currentMonth && date >= currentDate) return true;
return false;
};

const changeMemberCount = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setReserve({ ...reserve, memberCount: parseInt(e.target.value, 10) });
const changeMemberCount = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
// if (!e.target.value) setReserve({ ...reserve, memberCount: 0 });
if (parseInt(e.target.value, 10) < 0) setReserve({ ...reserve, memberCount: 0 });
setReserve({ ...reserve, memberCount: parseInt(e.target.value, 10) }); // 양수만 입력받음
};
const changeReason = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setReserve({ ...reserve, reason: e.target.value });
const changeDetailedReason = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setReserve({ ...reserve, detailedReason: e.target.value });
const postReservation = () => {
if (today
&& reserve.memberCount >= 1
) {
reservation({
memberCount: reserve.memberCount,
reason: reserve.reason,
detailedReason: reserve.detailedReason,
startDateTime: `${today.slice(0, 4)}-${today.slice(5, 7)}-${today.slice(8, 10)} ${reserve.startHour}:${reserve.startMinute}`,
endDateTime: `${today.slice(0, 4)}-${today.slice(5, 7)}-${today.slice(8, 10)} ${reserve.endHour}:${reserve.endMinute}`,
});
if (!isError) handleClose();
}
};

return (
<Modal
Expand All @@ -63,25 +83,35 @@ export default function MonthModal({
<Box sx={style}>
<h2>
{today}
{' '}
예약정보
</h2>
<ToggleButtonGroup
color="primary"
exclusive
value={alignment}
onChange={handleChange}
aria-label="Platform"
>
<ToggleButton value="information">예약 정보</ToggleButton>
<ToggleButton value="reservation" disabled={!canReserve()}>예약 하기</ToggleButton>
</ToggleButtonGroup>

{data.length > 0 ? (
{alignment === 'information' && (data.length > 0 ? (
<div css={S.DetailLayout}>
{data.map((item) => (
<DetailInfomation
key={item.detailedReason}
detailedReason={item.detailedReason}
startDateTime={item.startDateTime}
endDateTime={item.endDateTime}
reason={item.reason}
memberCount={item.memberCount}
memberName={item.memberName}
/>
))}
</div>
) : <div css={S.DetailLayout}>예약정보가 없습니다.</div>}
) : <div css={S.DetailLayout}>예약정보가 없습니다.</div>)}

{date && canReserve()
{date && canReserve() && alignment === 'reservation'
&& (
<div css={S.ReserveContainer}>
<h2>예약하기</h2>
Expand All @@ -93,6 +123,7 @@ export default function MonthModal({
variant="outlined"
size="small"
type="number"
error={reserve.memberCount < 0}
sx={{ width: 100 }}
value={reserve.memberCount}
onChange={changeMemberCount}
Expand Down Expand Up @@ -175,13 +206,9 @@ export default function MonthModal({
</TextField>
</div>
</div>
<Button onClick={() => today && reservation({
memberCount: reserve.memberCount,
reason: reserve.reason,
detailedReason: reserve.detailedReason,
startDateTime: `${today.slice(0, 4)}-${today.slice(5, 7)}-${today.slice(8, 10)} ${reserve.startHour}:${reserve.startMinute}`,
endDateTime: `${today.slice(0, 4)}-${today.slice(5, 7)}-${today.slice(8, 10)} ${reserve.endHour}:${reserve.endMinute}`,
})}
<Button
variant="outlined"
onClick={postReservation}
>
예약
</Button>
Expand Down
64 changes: 62 additions & 2 deletions src/page/Reservation/view/Month/MyReservation.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,79 @@
import { Modal, Box } from '@mui/material';
import {
Modal, Box, ToggleButtonGroup, ToggleButton,
} from '@mui/material';
import { useGetMyReservations } from 'query/reservations';
import { useState } from 'react';
// eslint-disable-next-line
import { style } from './MonthModal';
import DetailInfomation from './DetailInfomation';
import * as S from './style';

type Alignment = 'information' | 'passed' | 'reservation';

export const useToggleButtonGroup = () => {
const [alignment, setAlignment] = useState<Alignment>('information');

const handleChange = (
event: React.MouseEvent<HTMLElement>,
newAlignment: Alignment,
) => {
if (event.target instanceof HTMLElement) setAlignment(newAlignment);
};

return { alignment, handleChange };
};

export default function MyReservation({ open, handleClose }: { open: boolean, handleClose: () => void }) {
const { data } = useGetMyReservations();
const { alignment, handleChange } = useToggleButtonGroup();

return (
<Modal
open={open}
onClose={handleClose}
>
<Box sx={style}>
{data.map((item) => <DetailInfomation detailedReason={item.detailedReason} startDateTime={item.startDateTime} endDateTime={item.endDateTime} memberCount={item.memberCount} reason={item.reason} id={item.id} />)}
<ToggleButtonGroup
color="primary"
exclusive
value={alignment}
onChange={handleChange}
aria-label="Platform"
>
<ToggleButton value="information">예약 정보</ToggleButton>
<ToggleButton value="passed">지난 예약</ToggleButton>
</ToggleButtonGroup>
<div css={S.DetailLayout}>
{alignment === 'information'
&& data.filter((item) => (Number(item.endDateTime.slice(5, 7)) > new Date().getMonth() + 1) || (Number(item.endDateTime.slice(5, 7)) === new Date().getMonth() + 1 && Number(item.endDateTime.slice(8, 10)) >= new Date().getDate())).map(
(filtered) => (
<DetailInfomation
detailedReason={filtered.detailedReason}
startDateTime={filtered.startDateTime}
endDateTime={filtered.endDateTime}
memberCount={filtered.memberCount}
reason={filtered.reason}
id={filtered.id}
memberName={filtered.memberName}
/>
),
)}
{alignment === 'passed'
&& data.filter((item) => (Number(item.endDateTime.slice(5, 7)) < new Date().getMonth() + 1) || (Number(item.endDateTime.slice(5, 7)) === new Date().getMonth() + 1 && (Number(item.endDateTime.slice(8, 10)) < new Date().getDate()))).map(
(filtered) => (
<DetailInfomation
detailedReason={filtered.detailedReason}
startDateTime={filtered.startDateTime}
endDateTime={filtered.endDateTime}
memberCount={filtered.memberCount}
reason={filtered.reason}
id={filtered.id}
memberName={filtered.memberName}
passed={true}
/>
),
)}
</div>
</Box>
</Modal>
);
Expand Down
6 changes: 4 additions & 2 deletions src/page/Reservation/view/Month/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const DetailLayout = css`
display: flex;
flex-direction: column;
gap: 15px;
height: 170px;
overflow: scroll;
height: 400px;
`;

export const ReservationLayout = css`
Expand All @@ -38,7 +38,7 @@ export const ReservationLayout = css`
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
gap: 30px;
width: 100%;
`;

Expand All @@ -64,6 +64,8 @@ export const SpaceBetween = css`
export const ReserveContainer = css`
border: 1px solid ${colors.borderGray};
padding: 7px;
height: 350px;
margin-top: 30px;
`;

export const DetailContainer = css`
Expand Down
8 changes: 7 additions & 1 deletion src/page/Reservation/view/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export const Cell = (isToday: boolean) => css`
border: 1px solid ${colors.borderGray};
box-sizing: border-box;
width: calc(100% / 7);
height: 100px;
position: relative;
background-color: ${isToday && '#ECEAE4'};
padding: 0;
`;

export const Date = (isToday: boolean) => css`
Expand Down Expand Up @@ -51,8 +53,12 @@ export const current = css`
`;

export const scheduleContent = css`
height: 80px;
height: 100px;
margin-top: 20px;
overflow: scroll;
display: flex;
flex-direction: column;
align-items: center;
&::-webkit-scrollbar {
display: none; /* 크롬, 사파리, 오페라 */
}
Expand Down
Loading

0 comments on commit ddb79a3

Please sign in to comment.