diff --git a/src/components/introduce/ModeratorViewButton.jsx b/src/components/introduce/ModeratorViewButton.jsx index ba6114b..c4fc084 100644 --- a/src/components/introduce/ModeratorViewButton.jsx +++ b/src/components/introduce/ModeratorViewButton.jsx @@ -1,10 +1,24 @@ import React, { useState } from 'react'; +import styled from '@emotion/styled'; + import { changeDateToTime, isCheckedOnlyTimeStatus } from '../../util/utils'; +import ApproveStatus from '../../styles/ApproveStatus'; import ParticipantListModal from './modals/ParticipantListModal'; import StyledApplyStatusButton from '../../styles/StyledApplyStatusButton'; +const OrganizerStatus = styled.div` + display: flex; + flex-direction: row; +`; + +const organizerRemove = (applicant) => applicant.filter((_, index) => index !== 0); + +const approveParticipantsNumber = (approveUsers) => organizerRemove(approveUsers) + .filter(({ confirm }) => confirm === false) + .length; + const ModeratorViewButton = ({ group, user, onUpdateConfirm, realTime, }) => { @@ -14,6 +28,8 @@ const ModeratorViewButton = ({ const applyEndTime = changeDateToTime(applyEndDate); + const approveUsersCount = approveParticipantsNumber(participants); + const checkTime = { time: realTime, applyEndTime, @@ -44,18 +60,25 @@ const ModeratorViewButton = ({ return ( <> - - 스터디 참여 승인하기 - + + {approveUsersCount !== 0 && ( + + {`${approveUsersCount}명이 승인을 기다리고 있습니다!`} + + )} + + 스터디 참여 승인하기 + + index !== 0)} + participants={organizerRemove(participants)} /> ); diff --git a/src/components/introduce/ModeratorViewButton.test.jsx b/src/components/introduce/ModeratorViewButton.test.jsx index bb1d4bf..b44561e 100644 --- a/src/components/introduce/ModeratorViewButton.test.jsx +++ b/src/components/introduce/ModeratorViewButton.test.jsx @@ -91,6 +91,33 @@ describe('ModeratorViewButton', () => { expect(container).not.toHaveTextContent('스터디 신청자 목록'); }); + + context('When there is an applicant pending approval', () => { + it('renders "Waiting for approval!" text', () => { + const { container } = renderModeratorViewButton({ group, user, realTime }); + + expect(container).toHaveTextContent('1명이 승인을 기다리고 있습니다!'); + }); + }); + + context('When there are no applicants waiting for approval', () => { + const changeGroup = { + ...STUDY_GROUP, + moderatorId: 'user', + participants: [ + { + confirm: true, + id: 'test1', + }, + ], + }; + + it("doesn't renders 'Waiting for approval!' text", () => { + const { container } = renderModeratorViewButton({ group: changeGroup, user, realTime }); + + expect(container).not.toHaveTextContent('1명이 승인을 기달리고 있습니다!'); + }); + }); }); context('When the current date is after the deadline', () => { diff --git a/src/styles/ApproveStatus.jsx b/src/styles/ApproveStatus.jsx index 9de0be8..2fb6439 100644 --- a/src/styles/ApproveStatus.jsx +++ b/src/styles/ApproveStatus.jsx @@ -21,7 +21,11 @@ const ApproveStatusWrapper = styled.div` `}; ${({ approve }) => approve && css` - color:#40c057; + color: #40c057; + `}; + + ${({ wait }) => wait && css` + color: #f783ac; `}; `; @@ -47,12 +51,35 @@ const LoadingContent = styled.span` } `; +const WaitApprovalContent = styled.span` + margin-left: .3rem; + border-radius: 100%; + border-top: 3px solid #fcc2d7; + border-bottom: 3px solid #fcc2d7; + border-right: 3px solid #f783ac; + border-left: 3px solid #f783ac; + width: 12px; + height: 12px; + animation: load 0.75s ease infinite; + + @keyframes load { + 0% { + transform: rotate( 0deg ); + } + + 100% { + transform: rotate(180deg); + } + } +`; + const ApproveStatus = ({ children, ...props }) => { - const { load, approve } = props; + const { load, approve, wait } = props; return ( {children} + {wait && } {load && } {approve && } diff --git a/src/styles/StyledApplyStatusButton.jsx b/src/styles/StyledApplyStatusButton.jsx index 8e70d5e..c1aad7f 100644 --- a/src/styles/StyledApplyStatusButton.jsx +++ b/src/styles/StyledApplyStatusButton.jsx @@ -57,6 +57,7 @@ const StyledApplyStatusButtonWrapper = styled.button` &.confirm { cursor: pointer; + padding: 0.25rem 2.5rem; color: white; background: #4dabf7;