From 6bd91dfb7e866e8ae14a30f9aa1b320b8cc6ad37 Mon Sep 17 00:00:00 2001 From: gaeon <rkdjs1104@ajou.ac.kr> Date: Sun, 10 Dec 2023 14:38:07 +0900 Subject: [PATCH] design: channel, mypage style --- src/components/Header.js | 2 +- src/components/Header.module.css | 3 + src/components/infiniteScroll.js | 1 + src/components/mypage/my_group.module.css | 4 +- .../mypage/mywritingModal.module.css | 4 +- src/components/recruit/my_recruitList.js | 138 +++++++++++++++--- .../recruit/my_recruitList.module.css | 73 +++++++-- src/components/search.js | 6 +- src/pages/mypage.js | 2 +- src/pages/mypage.module.css | 2 +- 10 files changed, 192 insertions(+), 43 deletions(-) diff --git a/src/components/Header.js b/src/components/Header.js index 359160f..0753ed5 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -78,7 +78,7 @@ const Header=()=>{ {showUserInfo &&( <div className={header_styles.user_info}> <div className={header_styles.profileinfo}> - <div><img className={header_styles.circular_img} src='/id.png' alt="Profile"></img></div> + <div><img className={header_styles.circular_img} src={userData.imagePath} alt="Profile"></img></div> <div className={header_styles.userTextInfo}> <div className={header_styles.userName}>{userData.name}</div> <div className={header_styles.userNickname}>{userData.nickname}</div> diff --git a/src/components/Header.module.css b/src/components/Header.module.css index bc87b6a..a0fb0c3 100644 --- a/src/components/Header.module.css +++ b/src/components/Header.module.css @@ -99,6 +99,9 @@ header { margin-bottom:10px; } +.userName{ + font-size:14px; +} .logout { background-color:#9FB8AB; diff --git a/src/components/infiniteScroll.js b/src/components/infiniteScroll.js index 151b2bb..ca906d6 100644 --- a/src/components/infiniteScroll.js +++ b/src/components/infiniteScroll.js @@ -80,6 +80,7 @@ function InfiniteScroll(props){ if(page==='channels'){ const response = await fetch(`/api/${page}?${min}=${minDate}${queryString2}`); + console.log(`/api/${page}?${min}=${minDate}${queryString2}`); const jsonData = await response.json(); setMinDate(jsonData['minDate']); const newData = jsonData[page]; diff --git a/src/components/mypage/my_group.module.css b/src/components/mypage/my_group.module.css index bce2a2c..e0c6394 100644 --- a/src/components/mypage/my_group.module.css +++ b/src/components/mypage/my_group.module.css @@ -18,7 +18,7 @@ } .groupcontent{ background-color: white; - width:80%; + width:61%; height:100%; text-align: center; padding-top:10px; @@ -30,7 +30,7 @@ } .groupcontent label{ padding: 5%; - font-size: 30px; + font-size: 28px; } .close_button{ diff --git a/src/components/mypage/mywritingModal.module.css b/src/components/mypage/mywritingModal.module.css index cde8981..5776ee3 100644 --- a/src/components/mypage/mywritingModal.module.css +++ b/src/components/mypage/mywritingModal.module.css @@ -18,7 +18,7 @@ } .writingcontent{ background-color: white; - width:80%; + width:61%; height:100%; text-align: center; padding-top:10px; @@ -30,7 +30,7 @@ } .writingcontent label{ padding: 5%; - font-size: 30px; + font-size: 28px; } .close_button{ diff --git a/src/components/recruit/my_recruitList.js b/src/components/recruit/my_recruitList.js index d95f684..b717ce4 100644 --- a/src/components/recruit/my_recruitList.js +++ b/src/components/recruit/my_recruitList.js @@ -1,10 +1,27 @@ -import React, { useState } from 'react'; -import recruitListStyles from './my_recruitList.module.css'; - +import React, { useState, useContext, useEffect } from 'react'; +import recruitListStyles from './recruitList.module.css'; +import InfiniteScroll from '../infiniteScroll'; import RecruitDetail from './recruitDetail'; +import TimeInquiry from './timeInquiry'; +import Vote from './vote'; +import Search from '../search'; +import { AuthContext } from '../../App'; function PageItem(props){ const [isModalOpen, setIsModalOpen] = useState(false); + const [isInquiryOpen, setIsInquiryOpen] = useState(false); + const [isVoteOpen, setIsVoteOpen] = useState(false); + const [isParticipants, setIsParticipants] = useState(false); + + const { userData } = useContext(AuthContext); + + const checkParticipants = () => { + props.props.participants.map((participantId) => { + if (participantId === userData.id){ + setIsParticipants(true); + } + }) + } const openModal = () => { setIsModalOpen(true); @@ -14,31 +31,51 @@ function PageItem(props){ setIsModalOpen(false); }; - let state = ''; + const openInquiry = (e) => { + e.stopPropagation(); + setIsInquiryOpen(true); + }; + + const closeInquiry = () => { + setIsInquiryOpen(false); + }; + + const openVote = (e) => { + e.stopPropagation(); + setIsVoteOpen(true); + }; - + const closeVote = () => { + setIsVoteOpen(false); + }; + + let state = ''; + if(props.props.state === 'Recruiting'){ state = '모집중'; } else if(props.props.state === 'Closed'){ - state = '모집 완료'; + state = '모집완료'; } else if(props.props.state === 'Completed'){ - state = '활동 종료'; + state = '활동종료'; } - + + useEffect(()=>{ + checkParticipants(); + }, []) return ( <div className={recruitListStyles.recruit}> <div className={recruitListStyles.container} onClick={openModal}> <div className={recruitListStyles.imgContainer}> - {props.props.imagePath ? (<img className={recruitListStyles.img} src={props.props.imagePath} alt='recruit img' />) : (<img src={props.props.imagePath}/>)} + <img className={recruitListStyles.img} src={props.props.imagePath} alt='recruit img' /> </div> <div className={recruitListStyles.notImgContainer}> <div className={recruitListStyles.top}> <div className={recruitListStyles.title}>{props.props.title}</div> - {props.props.timeCategory === 'D' ? (null) : (<div className={recruitListStyles.tbd}>시간 미정</div>)} + {props.props.timeCategory === 'D' ? (null) : (<div className={recruitListStyles.tbd}>시간미정</div>)} <div className={`${state === '모집중' ? recruitListStyles.Recruiting: - (state === '모집 완료'? recruitListStyles.Closed: + (state === '모집완료'? recruitListStyles.Closed: recruitListStyles.Completed)}`}>{state} </div> </div> @@ -58,17 +95,44 @@ function PageItem(props){ <svg className={recruitListStyles.dateIcon} width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 2H17V0H15V2H5V0H3V2H2C0.9 2 0 2.9 0 4V20C0 21.1 0.9 22 2 22H18C19.1 22 20 21.1 20 20V4C20 2.9 19.1 2 18 2ZM18 20H2V9H18V20ZM18 7H2V4H18V7Z" fill="#FF5959"/> </svg> - <span className={recruitListStyles.date}>{props.props.startDate}</span> - {props.props.endDate ? (<span className={recruitListStyles.date}>~{props.props.endDate}</span>) : (null)} + <span className={recruitListStyles.date}>{props.props.startDate}~{props.props.endDate}</span> </div> - {props.props.timeCategory === 'D' ? ( - <div className={recruitListStyles.timeContainer}> - <svg className={recruitListStyles.timeIcon} width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> - <path d="M21.8333 4.19668L16.85 0.0150146L15.4525 1.67251L20.4358 5.85418L21.8333 4.19668ZM6.53667 1.67251L5.15 0.0150146L0.166668 4.18585L1.56417 5.84335L6.53667 1.67251ZM11.5417 6.66668H9.91667V13.1667L15.0625 16.2542L15.875 14.9217L11.5417 12.3542V6.66668ZM11 2.33335C5.61583 2.33335 1.25 6.69918 1.25 12.0833C1.25 17.4675 5.605 21.8333 11 21.8333C16.3842 21.8333 20.75 17.4675 20.75 12.0833C20.75 6.69918 16.3842 2.33335 11 2.33335ZM11 19.6667C6.8075 19.6667 3.41667 16.2758 3.41667 12.0833C3.41667 7.89085 6.8075 4.50001 11 4.50001C15.1925 4.50001 18.5833 7.89085 18.5833 12.0833C18.5833 16.2758 15.1925 19.6667 11 19.6667Z" fill="#FF5959"/> - </svg> - <span className={recruitListStyles.time}>{props.props.startTime}~{props.props.endTime}</span> + <div className={recruitListStyles.timeContainer}> + {props.props.timeCategory === 'D' ? ( + <div> + <svg className={recruitListStyles.timeIcon} width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M21.8333 4.19668L16.85 0.0150146L15.4525 1.67251L20.4358 5.85418L21.8333 4.19668ZM6.53667 1.67251L5.15 0.0150146L0.166668 4.18585L1.56417 5.84335L6.53667 1.67251ZM11.5417 6.66668H9.91667V13.1667L15.0625 16.2542L15.875 14.9217L11.5417 12.3542V6.66668ZM11 2.33335C5.61583 2.33335 1.25 6.69918 1.25 12.0833C1.25 17.4675 5.605 21.8333 11 21.8333C16.3842 21.8333 20.75 17.4675 20.75 12.0833C20.75 6.69918 16.3842 2.33335 11 2.33335ZM11 19.6667C6.8075 19.6667 3.41667 16.2758 3.41667 12.0833C3.41667 7.89085 6.8075 4.50001 11 4.50001C15.1925 4.50001 18.5833 7.89085 18.5833 12.0833C18.5833 16.2758 15.1925 19.6667 11 19.6667Z" fill="#FF5959"/> + </svg> + <span className={recruitListStyles.time}>{props.props.startTime}~{props.props.endTime}</span> </div> + ) : (null)} + </div> + + {state === '모집완료' && props.props.timeCategory === 'TBD' ? ( + <div className={recruitListStyles.buttonContainer}> + {userData.nickname === props.props.Writer.nickname ?( //props.data.Writer.id + <div className={recruitListStyles.inquiryContainer}> + <button type="button" className={recruitListStyles.inquiry} onClick={openInquiry}>시간조회</button> + <div className={recruitListStyles.timeInquiry}> + <TimeInquiry isOpen={isInquiryOpen} onClose={closeInquiry} data={props.props}/> + </div> + </div> + ):(null)} + + {isParticipants ?( + <div className={recruitListStyles.voteContainer}> + {props.props.vote === 'Before' || props.props.vote === 'During' ? ( + <button type="button" className={recruitListStyles.vote} onClick={openVote}>투표하기</button> + ):( + <button type="button" className={recruitListStyles.vote} onClick={openVote}>결과확인</button> + )} + <div className={recruitListStyles.voteInquiry}> + <Vote isOpen={isVoteOpen} onClose={closeVote} data={props.props}/> + </div> + </div> + ):(null)} + </div> ) : (null)} </div> </div> @@ -78,5 +142,39 @@ function PageItem(props){ ) } +function RecruitList(){ + const [generatedUrl, setGeneratedUrl] = useState('recruits'); + const [firstQueryString, setFirstQueryString] = useState(''); + const [secondQueryString, setSecondQueryString] = useState(''); + + const handleUrlGeneration = (url) => { + setGeneratedUrl(url); + }; + + const handleFirstQueryString = (url) => { + setFirstQueryString(url); + }; + + const handleSecondQueryString = (url) => { + setSecondQueryString(url); + }; + + return( + <div className={recruitListStyles.RecruitList}> + <Search + currentPage='recruits' + onUrlGenerated={handleUrlGeneration} + onFirstQueryString={handleFirstQueryString} + onSecondQueryString={handleSecondQueryString} + /> + <InfiniteScroll + pagename={generatedUrl} + queryString1={firstQueryString} + queryString2={secondQueryString} + min='minId' + /> + </div> + ) +} -export { PageItem}; \ No newline at end of file +export {RecruitList, PageItem}; \ No newline at end of file diff --git a/src/components/recruit/my_recruitList.module.css b/src/components/recruit/my_recruitList.module.css index df7a92f..7e6aa53 100644 --- a/src/components/recruit/my_recruitList.module.css +++ b/src/components/recruit/my_recruitList.module.css @@ -1,4 +1,8 @@ - +.RecruitList{ + display: flex; + flex-direction: column; + align-items: center; +} .container{ display: flex; @@ -6,10 +10,8 @@ height: 194px; border: 3px solid #E7E7E7; margin-top: 20px; - margin-left:13%; + background: #FFFFFF; - overflow-x: auto; - } .imgContainer{ @@ -34,7 +36,6 @@ .bottom{ display: flex; - width: 500px; } .img{ @@ -73,7 +74,7 @@ align-items: center; /* 세로 방향에서 가운데 정렬. */ justify-content: center; - width: 67px; + width: 90px; height: 33px; margin-left: auto; @@ -81,7 +82,6 @@ font-weight: bolder; font-size: 20px; - line-height: 20px; color: #FFFFFF; @@ -92,8 +92,6 @@ align-items: center; /* 세로 방향에서 가운데 정렬. */ justify-content: center; - margin-right: auto; - width: 90px; height: 33px; margin-left: auto; @@ -102,7 +100,6 @@ font-weight: bolder; font-size: 20px; - line-height: 20px; color: #FFFFFF; @@ -113,8 +110,6 @@ align-items: center; /* 세로 방향에서 가운데 정렬. */ justify-content: center; - margin-right: auto; - width: 90px; height: 33px; margin-left: auto; @@ -123,7 +118,6 @@ font-weight: bolder; font-size: 20px; - line-height: 20px; color: #FFFFFF; @@ -160,11 +154,18 @@ line-height: 40px; } +.dateContainer{ + width: 250px; +} + +.timeContainer{ + width: 240px; +} + .date, .time{ font-weight: 600; font-size: 20px; line-height: 33px; - color: #000000; } @@ -180,4 +181,48 @@ height: 26px; margin-left: 10px; margin-right: 5px; +} + +.buttonContainer{ + display: flex; + width: 185px; +} + +.inquiryContainer, .voteContainer{ + margin-left: auto +} + +.inquiry{ + display: flex; /* Flexbox를 사용하여 자식 요소들을 가로로 배열합니다. */ + align-items: center; /* 세로 방향에서 가운데 정렬. */ + justify-content: center; + + width: 90px; + height: 33px; + + background: #808DC2; + + font-weight: bolder; + font-size: 20px; + + color: #FFFFFF; + border: none; +} + +.vote{ + display: flex; /* Flexbox를 사용하여 자식 요소들을 가로로 배열합니다. */ + align-items: center; /* 세로 방향에서 가운데 정렬. */ + justify-content: center; + + width: 90px; + height: 33px; + margin-left: px; + + background: #808DC2; + + font-weight: bolder; + font-size: 20px; + + color: #FFFFFF; + border: none; } \ No newline at end of file diff --git a/src/components/search.js b/src/components/search.js index f90cfff..ecf1275 100644 --- a/src/components/search.js +++ b/src/components/search.js @@ -57,9 +57,11 @@ function Search({ currentPage, onUrlGenerated, onFirstQueryString, onSecondQuery } }; useEffect(() => { - - fetchChannelData(); + if (fetchCount !== 0) { + fetchChannelData(); + } }, [fetchCount]); + const handleSearch = () => { let searchURL = `${currentPage}/search`; let firstQueryString = '?'; diff --git a/src/pages/mypage.js b/src/pages/mypage.js index a18fe74..bbf0045 100644 --- a/src/pages/mypage.js +++ b/src/pages/mypage.js @@ -125,7 +125,7 @@ const Mypage=()=>{ <button className={mypage_styles.profileEdit} onClick={openEditModal}>내 프로필 수정</button> <div className={mypage_styles.profileinfo}> <div className={mypage_styles.profile_picture_container}> - <img src={userData.image} className={mypage_styles.profile_picture} alt="profile"/> + <img src={userData.imagePath} className={mypage_styles.profile_picture} alt="profile"/> </div> <div className={mypage_styles.profileText}> diff --git a/src/pages/mypage.module.css b/src/pages/mypage.module.css index efa94c9..505dcaa 100644 --- a/src/pages/mypage.module.css +++ b/src/pages/mypage.module.css @@ -4,7 +4,7 @@ border: 2px solid #ccc; /* border-width, border-style, border-color를 한 번에 설정 */ padding: 20px; - height: 140px; + height: 150px; margin-bottom:8%; -- GitLab