study 화면에서는 1학기에 진행됐던 스터디 팀들을 텍스트로 나타내고, 해당 텍스트를 누르면 모달창을 띄워 설명하는 기능을 만들고 싶었다.
사실 이번에 모달창이라는 개념을 처음 알게됐다. (많이 쓰이는 것이지만 지금 처음 알았다니....🫣)
찾아보니 복잡하게 만든것들이 많았는데 처음이니까 간단하게 해보고싶었다.
<StudyPage.jsx>
import React, { useEffect, useState } from 'react';
import '../styles/studyPage.scss'
import Key from '../assets/images/keyboard.PNG'
import Java from '../contants/study45-1/Java';
import Frontend from '../contants/study45-1/Frontend';
import C_1 from '../contants/study45-1/C_1';
import C_2 from '../contants/study45-1/C_2';
import C_3 from '../contants/study45-1/C_3';
import Python from '../contants/study45-1/Python';
import Spring from '../contants/study45-1/Spring';
import Django from '../contants/study45-1/Django';
const StudyPage = () => {
const [modalOpen, setModalOpen]=useState(false);
const [selectedItem, setSelectedItem]=useState(null);
const showModal=(item)=>{
setSelectedItem(item);
setModalOpen(true);
}
useEffect(()=>{
},[])
return (
<div className='study'>
<div className='study_activity'>
<img src={Key} alt='logo'></img>
<h1>Study Activity</h1>
</div>
<div className='title'>
<h5>45기-1학기</h5>
</div>
<div className='grid_container'>
<div className='grid_item'>
<p onClick={()=>showModal('JAVA')}>JAVA</p>
{modalOpen&&selectedItem==='JAVA'&&<Java setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('Frontend')}>Frontend<br/>+<br/>Design</p>
{modalOpen&&selectedItem==='Frontend'&&<Frontend setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('C_1')}>C(1)</p>
{modalOpen&&selectedItem==='C_1'&&<C_1 setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('C_2')}>C(2)</p>
{modalOpen&&selectedItem==='C_2'&&<C_2 setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('C_3')}>C(3)</p>
{modalOpen&&selectedItem==='C_3'&&<C_3 setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('Python')}>Python</p>
{modalOpen&&selectedItem==='Python'&&<Python setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('Spring')}>Spring</p>
{modalOpen&&selectedItem==='Spring'&&<Spring setModalOpen={setModalOpen}/>}
</div>
<div className='grid_item'>
<p onClick={()=>showModal('Django')}>Django</p>
{modalOpen&&selectedItem==='Django'&&<Django setModalOpen={setModalOpen}/>}
</div>
</div>
</div>
);
};
export default StudyPage;
showModal 함수를 만들어서 각 아이템들이 클릭 됐을 때 modalOpen을 true로 만들었다. 그리고 중요한건 각 모달창 컴포넌트로 setModalOpen을 props로 넘겨준다!
각각의 스터디 팀에 해당하는 모달창 컴포넌트들을 contants 폴더에 만들어놨다. 그중에서 하나만 설명을 하자면..
<Java.jsx>
import React from 'react';
import '../study45-1/style/java.scss'
import Img from './image/java.jpg'
const Java = ({setModalOpen}) => {
const closeModal=()=>{
setModalOpen(false);
}
return (
<div className='java'>
<div>
<img src={Img} alt='img'></img>
</div>
<div className='ex'>
<div>
<button className='close' onClick={closeModal}>X</button>
</div>
<div className='ex1'>
<h1>JAVA</h1>
<p>팀장: 윤현선</p>
<p>'자바의 정석'을 기반으로 스터디를 진행하였으며, 추가적으로 모던자바와 Stream API에 대해 공부하였습니다.<br/>
매 주차 파트 별 내용 정리 및 예시 코드를 작성 해온 뒤 발표 형식으로 진행하였습니다.<br/>
수시로 백준 문제 풀이를 하며 막연한 이론 공부가 아닌, 코드에 적 용해보는 연습을 했습니다.<br/>
마지막 스터디에서는 그 동안 배운 개념들을 기반으로 각자 자유롭게 코드를 작성해온 뒤 코드 리뷰로 스터디를 마무리하였습니다.
</p>
</div>
<div className='talk'>
<div id='l'><p>김주연 : Java에 대해서 이해할 수 있어서 좋았습니다.😊</p></div>
<div id='r'><p>김연수 : 자바 스터디에서 배운 스트림을 캡스톤에서도 써먹을 수 있었습니다. 알차고 JAVA의 개념에 대해 전반적으로 훑을 수 있었 던 좋은 스터디였슴둥🤠</p></div>
<div id='l'><p>박인영: 결국 우린 해냈다 ♥︎</p></div>
<div id='r'><p>이주영 : 자바 조오았다~~~~~!!</p></div>
<div id='l'> <p>한종석 : 한학기동안 열심히 공부해서 자바버렸다.👊</p></div>
<div id='l' style={{marginTop:'10px'}}> <p>윤현선 : JAVA 자봤다😛</p></div>
</div>
</div>
</div>
);
};
export default Java;
setModalOpen을 넘겨 받아서 close 할 때 사용한다. 모달창 내에 x 버튼을 누르면 setModalOpen을 false로 만들어 창을 닫는다.
그리고 내부에 글과 사진을 넣어주면 된다. 나는 팀원들의 소감을 채팅 느낌으로 표현하고 싶어서 l과 r로 나눠서 위치를 배치해줬다.
java.scss
.java{
width: 95vw !important;
max-width: 1300px;
height: 90vw !important;
max-height: 850px;
z-index: 999; //최상단에 노출시키기 위해
position: absolute;
left: 50%;
transform: translate(-50%,-50%);
background-color:white;
color: black;
border: 1px solid black;
border-radius: 20px;
display: flex;
flex-direction: row;
.close{
position: absolute;
right: 10px;
top: 10px;
color: black;
}
img{
height: 90vw !important;;
max-height: 850px;
}
.ex{
// padding: 10vh;
.ex1{
h1{
font-size: clamp(10px,2vw,40px) ;
}
p{
font-size: clamp(6px,1vw,18px);
}
}
.talk{
display: flex;
flex-direction: column;
#l{
font-size: clamp(5px,1vw,15px) !important;
background-color: #3895ff;
border-radius: 10vw;
padding: clamp(1px,1vw,10px) !important;
width: 30vw !important;
max-width: 300px ;
height: 6vw !important;
max-height:60px;
align-self: baseline;
margin: clamp(1px,1vw,2px);
}
#r{
font-size: clamp(5px,1vw,15px) !important;
background-color: #3895ff;
border-radius: 10vw;
padding: 1vw !important;
width: 30vw !important;
max-width: 300px ;
height: 7vw !important;
max-height:60px;
align-self: flex-end;
}
}
}
}
모달창 크기는 vw, vh로 화면 비율에 따라 유동적으로 조절되게 했고, z-index로 화면 최상단에 위치하도록 했다. !important를 하지 않았을 때 부모 컴포넌트의 스타일이 모달 창에 영향을 주는거 같아서 화면 크기에 대한 부분은 !important를 해주었다.
'Project💻 > M.C.C homepage' 카테고리의 다른 글
03. About 화면: 글자 회전 (0) | 2024.07.05 |
---|---|
02-1 main 화면: 사진 자동 슬라이드 (0) | 2024.07.05 |
02. main 화면: footer 고정 (0) | 2024.07.02 |
01. 프로젝트 소개 (0) | 2024.06.24 |