Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/244' into feature/244
Browse files Browse the repository at this point in the history
# Conflicts:
#	frontend/src/pages/SeminarRoom/Reservation.tsx
  • Loading branch information
pillow12360 committed Jan 5, 2025
2 parents e68f548 + 352892e commit a73b5ce
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 166 deletions.
2 changes: 1 addition & 1 deletion frontend/src/config/apiConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const API_URL = process.env.REACT_APP_API_URL;
export const API_URL = process.env.REACT_APP_API_URL;

export interface BoardReqDto {
title: string;
Expand Down
250 changes: 85 additions & 165 deletions frontend/src/pages/SeminarRoom/Reservation.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { useState } from 'react';
// 📁 src/pages/SeminarRoom/Reservation.tsx

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import moment, { MomentInput } from 'moment';
import {
Container,
HeaderContainer,
Navigation,
NavButton,
NavButtonGroup,
RoomContainer,
RoomInfo,
RoomName,
Expand All @@ -11,197 +19,109 @@ import {
StyledCalendar,
} from './ReservationStyle';
import { Modal, useModal } from '../../components/Modal';
import moment, { MomentInput } from 'moment';
import styled from 'styled-components';
import { ReservationModal } from './ReservationModal';
import { ReservationData } from './types/reservation.types';

// 더미 데이터
const dummyReservations: ReservationData[] = [
{
id: 1,
roomId: '세미나실',
date: '2025-01-04',
startTime: '09:00',
endTime: '11:00',
userName: '김철수',
purpose: '세미나',
contact: '010-1234-5678',
department: '컴퓨터공학과',
},
// ... other dummy data with updated roomId
];
import {API_URL} from '../../config/apiConfig'; // API 베이스 URI 가져오기

function Reservation() {
const { openModal, closeModal } = useModal();
const [selectedDate, setSelectedDate] = useState(
moment(new Date()).format('YYYY-MM-DD'),
);
const [selectedDate, setSelectedDate] = useState(moment(new Date()).format('YYYY-MM-DD'));
const [reservations, setReservations] = useState<ReservationData[]>([]);

// 🧩 GET 요청 함수: API를 통해 해당 월의 예약 데이터 가져오기
const fetchReservations = async (yearMonth: string) => {
try {
const response = await axios.get(`${API_URL}/room/1/reservation/month`, {
params: { yearMonth },
});
setReservations(response.data);
} catch (error) {
console.error('예약 데이터를 가져오는 중 에러 발생:', error);
}
};

// 📆 달력 날짜 변경 시 예약 데이터 다시 가져오기
useEffect(() => {
const yearMonth = moment(selectedDate).format('YYYY-MM');
fetchReservations(yearMonth);
}, [selectedDate]);

const handleReservationClick = () => {
openModal(
<ReservationModal
isOpen={true}
onClose={closeModal}
selectedDate={selectedDate}
selectedRoom="세미나실"
existingReservations={dummyReservations}
/>,
<ReservationModal
isOpen={true}
onClose={closeModal}
selectedDate={selectedDate}
selectedRoom="세미나실1"
existingReservations={reservations}
/>,
);
};

const handleDateChange = (date: MomentInput) => {
setSelectedDate(moment(date).format('YYYY-MM-DD'));
};

const List = styled.p<{ className?: string }>`
margin: 0 0 8px 0;
padding: 8px 12px;
color: white;
border-radius: 4px;
background-color: ${({ className }) =>
className === '세미나'
? '#1a73e8'
: className === '스터디'
? '#34d399'
: className === '미팅'
? '#f59e0b'
: '#9ca3af'};
`;

const tileContent = ({ date }: { date: Date }) => {
const formattedDate = moment(date).format('YYYY-MM-DD');
const reservationsForDate = dummyReservations.filter(
(reservation) => reservation.date === formattedDate,
const reservationsForDate = reservations.filter(
(reservation) => reservation.date === formattedDate,
);

if (reservationsForDate.length === 0) return null;

const visibleReservations = reservationsForDate.slice(0, 2);
const moreCount = reservationsForDate.length - visibleReservations.length;

const showAllReservation = (formattedDate: string) => {
openModal(
<>
<Modal.Header>
{moment(formattedDate).format('YYYY년 MM월 DD일')} 예약 현황
</Modal.Header>
<Modal.Content>
<div>
{reservationsForDate.map((reservation, index) => (
<List key={index} className={reservation.purpose}>
{reservation.startTime}~{reservation.endTime}{' '}
{reservation.purpose} ({reservation.userName})
</List>
))}
</div>
</Modal.Content>
<Modal.Footer>
<Modal.CloseButton onClick={() => closeModal()}>
닫기
</Modal.CloseButton>
</Modal.Footer>
</>,
);
};

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
fontSize: '8px',
marginTop: '2px',
}}
>
{visibleReservations.map((reservation, index) => (
<div
key={index}
style={{
backgroundColor: getColorByPurpose(reservation.purpose),
padding: '1px',
margin: '1px',
borderRadius: '2px',
color: 'white',
}}
>
{reservation.startTime}~{reservation.endTime}
</div>
))}
{moreCount > 0 && (
<div
style={{
marginTop: '2px',
fontSize: '10px',
color: '#555',
textAlign: 'center',
cursor: 'pointer',
}}
onClick={() => showAllReservation(formattedDate)}
>
{moreCount}개 더보기
</div>
)}
</div>
);
};

const getColorByPurpose = (purpose: string) => {
const colors = {
세미나: '#1a73e8',
스터디: '#34d399',
미팅: '#f59e0b',
기타: '#9ca3af',
};
return colors[purpose as keyof typeof colors] || colors.기타;
};

const tileClassName = ({ date }: { date: Date }) => {
const formattedDate = moment(date).format('YYYY-MM-DD');
const hasReservations = dummyReservations.some(
(reservation) => reservation.date === formattedDate,
<div>
{reservationsForDate.map((reservation, index) => (
<div key={index} style={{ backgroundColor: '#1a73e8', padding: '2px', margin: '2px', color: 'white' }}>
{reservation.startTime}~{reservation.endTime}
</div>
))}
</div>
);
return hasReservations ? 'has-reservation' : '';
};

return (
<Container>
<RoomContainer>
<RoomInfo>
<RoomName>세미나실</RoomName>
<div style={{ display: 'flex', gap: '20px' }}>
<div>
<RoomImg src="/seminarRoom1.jpg" alt="세미나실" />
</div>
<div>
<Capacity>수용인원</Capacity>
<span>30명</span>
<br />
<Location>장소</Location>
<span>충무관 501호</span>
<Container>
<HeaderContainer>
<Navigation>
<NavButtonGroup>
<NavButton isActive={true}>세미나실1</NavButton>
</NavButtonGroup>
</Navigation>
</HeaderContainer>
<RoomContainer>
<RoomInfo>
<RoomName>세미나실1</RoomName>
<div style={{ display: 'flex', gap: '20px' }}>
<div>
<RoomImg src="/seminarRoom1.jpg" alt="세미나실1" />
</div>
<div>
<Capacity>수용인원</Capacity>
<span>30명</span>
<br />
<Location>장소</Location>
<span>충무관 501호</span>
</div>
</div>
</div>
</RoomInfo>
</RoomContainer>
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<ReservationBtn onClick={handleReservationClick}>
예약하기
</ReservationBtn>
</div>
<StyledCalendar
calendarType="gregory"
locale="ko"
formatDay={(locale, date) => moment(date).format('D')}
prev2Label={null}
next2Label={null}
minDetail="year"
onChange={handleDateChange}
tileContent={tileContent}
tileClassName={tileClassName}
minDate={new Date()}
/>
</Container>
</RoomInfo>
</RoomContainer>
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<ReservationBtn onClick={handleReservationClick}>예약하기</ReservationBtn>
</div>
<StyledCalendar
calendarType="gregory"
locale="ko"
formatDay={(locale, date) => moment(date).format('D')}
prev2Label={null}
next2Label={null}
minDetail="year"
onChange={handleDateChange}
tileContent={tileContent}
minDate={new Date()}
/>
</Container>
);
}

Expand Down

0 comments on commit a73b5ce

Please sign in to comment.