본문 바로가기
Project💻/M.C.C homepage

04. Study 화면 : 모달창 띄우기

by ZZiwon Choi 2024. 7. 5.

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