[CATSPOT]층별 학교 강의실 구조 설정 & 시간표 연동 BA2 페이지 구현기
2025. 3. 27. 15:48ㆍ프론트엔드/REACT
728x90
상태 관리 & API 데이터 패칭
const BA2 = () => {
const [selectedRoom, setSelectedRoom] = useState(null);
const [highlightedRooms, setHighlightedRooms] = useState([]);
useEffect(() => {
const fetchHighlightedRooms = async () => {
const { day, hour } = getKoreanDayAndHour();
try {
const response = await axiosInstance.post("/api/classroom", {
buildingName: 'BA',
floor: 2,
day,
hour,
});
setHighlightedRooms(response.data.classrooms);
} catch (error) {
console.error("Error fetching highlighted rooms:", error);
}
};
fetchHighlightedRooms();
}, []);
설명:
- 선택된 강의실 및 강조 대상 강의실 상태 관리
- API 호출을 통해 현재 시간 기준 데이터 수신
- 데이터 반영 – 연동
강의실 클릭 이벤트 & 시간표 요청
const handleRoomClick = async (room) => {
if (room !== "상담실") {
const { day, hour } = getKoreanDayAndHour();
try {
const response = await axiosInstance.post("/api/roomSchedule", {
buildingName: 'BA',
classroomNumber: room.substring(2),
day,
hour,
});
setSelectedRoom(response.data);
} catch (error) {
console.error("Error fetching room schedule:", error);
}
}
};
const closeModal = () => {
setSelectedRoom(null);
};
설명:
- 강의실 클릭 시 해당 시간표 요청 및 모달 표시
- 선택한 강의실 데이터 업데이트 – 요청
화면 구성 & JSX 렌더링
return (
<>
<Navbar title="빈강의실" />
<div className="ba2_container">
<div className="border-marker marker-blue marker-bottom-right"></div>
<div
className={`room-box-max_ba2 ${highlightedRooms.includes(parseInt("203")) ? "room-box-highlight" : ""}`}
onClick={() => handleRoomClick("BA203")}
>
<div className="room-box-content">BA203</div>
</div>
<div style={{ marginBottom: "50px" }}></div>
<div className="flex-container">
<div className={`room-box-max-left ${highlightedRooms.includes(parseInt("202")) ? "room-box-highlight" : ""}`}
onClick={() => handleRoomClick("BA202")}>
<div className="room-box-content" style={{ transform: "rotate(-90deg)" }}>
BA202
</div>
</div>
<div className="centered3-text">
<span>밤</span>
<span>비</span>
<span>노</span>
<span>2</span>
<span>층</span>
</div>
<div className={`room-box-max-right ${highlightedRooms.includes(parseInt("204")) ? "room-box-highlight" : ""}`}
onClick={() => handleRoomClick("BA204")}>
<div className="room-box-content" style={{ transform: "rotate(90deg)" }}>
BA204
</div>
</div>
</div>
</div>
<p className="helper-text">강의실을 클릭하여 시간표를 확인하세요!</p>
<div className="label-container">
<div className="label label-use "></div>
<span className="label-text label-margin">사용중</span>
<div className="label label-exit"></div>
<span className="label-text">입출구</span>
<div className="label label-stairs" style={{ marginLeft: "20px" }}></div>
<span className="label-text">계단</span>
</div>
{selectedRoom && <ScheduleModal schedule={selectedRoom} onClose={closeModal} />}
</>
);
};
export default BA2;
설명:
- Navbar, 강의실 박스, 중앙 텍스트, 라벨 및 모달을 통한 전체 레이아웃 구성
- 조건부 렌더링으로 강조 및 모달 제어 – 구성
CSS로 완성한 강의실 디자인
.ba2_container {
position: relative;
width: calc(100% - 40px);
height: 643px;
margin: 143px auto 0 auto;
border: 3px solid #dfdfdf;
border-radius: 5px;
background-color: #ffffff;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 20px 40px;
}
.room-box-max_ba2 {
position: relative;
width: 100%;
height: 80px;
background-color: #b9bfe3;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
color: black;
margin-top: 20px;
}
.room-box-max-left,
.room-box-max-right {
position: relative;
width: 80px;
height: 300px;
background-color: #b9bfe3;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
color: black;
margin-top: 20px;
}
.room-box-max_ba2::before,
.room-box-max_ba2::after,
.room-box-max-left::before,
.room-box-max-left::after,
.room-box-max-right::before,
.room-box-max-right::after {
content: "";
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-width: 0 15px 15px 15px;
border-color: transparent transparent #b9bfe3 transparent;
border-radius: 15px 15px 0 0;
}
.room-box-max-left::before {
transform: rotate(-90deg);
top: 240px;
left: -20px;
}
.room-box-max-left::after {
transform: rotate(-90deg);
top: 50px;
left: -20px;
}
.room-box-max-right::before {
transform: rotate(90deg);
top: 240px;
left: 70px;
}
.room-box-max-right::after {
transform: rotate(90deg);
top: 50px;
left: 70px;
}
.room-box-highlight {
background-color: #ffd700 !important;
}
.room-box-highlight::before,
.room-box-highlight::after {
border-color: transparent transparent #ffd700 transparent !important;
}
설명:
- 전체 컨테이너, 강의실 박스, 삼각형 장식 및 강조 스타일을 CSS로 구현
- 시각적 입체감 및 하이라이트 처리 – 디자인
728x90
'프론트엔드 > REACT' 카테고리의 다른 글
| React와 Chart.js로 구현하는 레이더 차트: RadarChart 컴포넌트 분석[FC] (0) | 2025.04.01 |
|---|---|
| QRReader 컴포넌트[FC] (0) | 2025.04.01 |
| [CATSPOT]React + Recoil 기반 계단 애니메이션 구현 (0) | 2025.03.27 |
| React 드래그 요소가 선택 취소 후 원래 자리로 돌아가지 않는 문제 해결하기 (0) | 2025.03.26 |
| 🧩 MatchPriorityModal 구현기 – 사용자 친화적인 모달 만들기 (0) | 2025.03.25 |