Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions src/components/introduce/modals/ApplicationViewModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React from 'react';

import styled from '@emotion/styled';

import { css } from '@emotion/react';

import Button from '../../../styles/Button';
import palette from '../../../styles/palette';

const ApplicationViewModalWrapper = styled.div`
position: fixed;
z-index: 101;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.25);
display: flex;
justify-content: center;
align-items: center;

${(props) => props.visible && css`
&.animation {
animation-name: fade-in;
animation-fill-mode: both;
animation-duration: 0.3s;
}

@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
`};
`;

const ModalBoxWrapper = styled.div`
display: flex;
flex-direction: column;
height: auto;
width: 400px;
background: white;
padding: 1.5rem;
border-radius: 6px;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.125);
h2 {
margin-top: 0;
margin-bottom: 1rem;
text-align: center;
}
.buttons {
display: flex;
justify-content: flex-end;
}
`;

const ContentBoxWrapper = styled.div`
display: flex;
flex-direction: column;
margin-bottom: 0.2rem;

label {
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 0.3rem;
}
`;

const ContentViewerWrapper = styled.textarea`
display: block;
padding: 5px;
resize: none;
outline: none;
border: 2px solid #D7E2EB;
border-radius: 3px;
font-weight: bold;
color: rgb(33, 37, 41);
margin-bottom: 0.7rem;
transition-duration: 0.08s;
transition-property: all;
transition-timing-function: ease-in-out;
transition-delay: initial;
cursor: unset;
&:focus {
border: 2px solid ${palette.gray[5]};
}
`;

const StyledButton = styled(Button)`
&:last-of-type {
margin-left: .7rem;
}
`;

const ApplicationViewModal = ({
visible, onClose, participant,
}) => {
const { reason, wantToGet, id } = participant;

if (!visible) {
return null;
}

return (
<ApplicationViewModalWrapper visible className="animation">
<ModalBoxWrapper>
<h2>{`${id} 신청서 📚`}</h2>
<ContentBoxWrapper>
<label htmlFor="apply-reason">신청하게 된 이유</label>
<ContentViewerWrapper
rows="10"
id="apply-reason"
value={reason}
readOnly
/>
</ContentBoxWrapper>
<ContentBoxWrapper>
<label htmlFor="study-want">스터디를 통해 얻고 싶은 것은 무엇인가요?</label>
<ContentViewerWrapper
rows="10"
id="study-want"
value={wantToGet}
readOnly
/>
</ContentBoxWrapper>
<div className="buttons">
<StyledButton onClick={onClose}>닫기</StyledButton>
</div>
</ModalBoxWrapper>
</ApplicationViewModalWrapper>
);
};

export default ApplicationViewModal;
68 changes: 68 additions & 0 deletions src/components/introduce/modals/ApplicationViewModal.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';

import { fireEvent, render } from '@testing-library/react';

import ApplicationViewModal from './ApplicationViewModal';

describe('ApplicationViewModal', () => {
const handleClose = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
});

const renderApplicationViewModal = ({ visible, participant }) => render((
<ApplicationViewModal
visible={visible}
participant={participant}
onClose={handleClose}
/>
));

context('with visible', () => {
const modal = {
visible: true,
participant: {
id: 'test',
reason: 'reason',
wantToGet: 'wantToGet',
},
};

it('renders Modal text', () => {
const { container } = renderApplicationViewModal(modal);

const { participant } = modal;

expect(container).toHaveTextContent(`${participant.id} 신청서 📚`);
expect(container).toHaveTextContent('신청하게 된 이유');
expect(container).toHaveTextContent('스터디를 통해 얻고 싶은 것은 무엇인가요?');
});

it('calls confirm event action', () => {
const { getByText } = renderApplicationViewModal(modal);

const button = getByText('닫기');

fireEvent.click(button);

expect(handleClose).toBeCalled();
});
});

context('without visible', () => {
const modal = {
visible: false,
participant: {
reason: '',
wantToGet: '',
},
};

it("doesn't renders Modal text", () => {
const { container } = renderApplicationViewModal(modal);

expect(container).toBeEmptyDOMElement();
});
});
});
69 changes: 47 additions & 22 deletions src/components/introduce/modals/ParticipantList.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import React, { useState } from 'react';

import styled from '@emotion/styled';

import ParticipantListButton from '../../../styles/ParticipantListButton';
import ApplicationViewModal from './ApplicationViewModal';

const ParticipantListWrapper = styled.div`
display: grid;
Expand All @@ -14,26 +15,50 @@ const ParticipantListWrapper = styled.div`
min-width: 0;
`;

const ParticipantList = ({ id, confirm }) => (
<ParticipantListWrapper>
<div>{id}</div>
<div>
<ParticipantListButton sky>
신청서 보기
</ParticipantListButton>
</div>
<div>
{confirm === true ? (
<ParticipantListButton cancel>
취소하기
</ParticipantListButton>
) : (
<ParticipantListButton confirm>
승인하기
</ParticipantListButton>
)}
</div>
</ParticipantListWrapper>
);
const ParticipantList = ({ participant }) => {
const [viewApplyModal, setViewApplyModal] = useState(false);

const { id, confirm } = participant;

const handleApplyFormClick = () => {
setViewApplyModal(true);
};

const handelApplyFormClose = () => {
setViewApplyModal(false);
};

return (
<>
<ParticipantListWrapper>
<div>{id}</div>
<div>
<ParticipantListButton
sky
onClick={handleApplyFormClick}
>
신청서 보기
</ParticipantListButton>
</div>
<div>
{confirm === true ? (
<ParticipantListButton cancel>
취소하기
</ParticipantListButton>
) : (
<ParticipantListButton confirm>
승인하기
</ParticipantListButton>
)}
</div>
</ParticipantListWrapper>
<ApplicationViewModal
visible={viewApplyModal}
onClose={handelApplyFormClose}
participant={participant}
/>
</>
);
};

export default ParticipantList;
44 changes: 40 additions & 4 deletions src/components/introduce/modals/ParticipantList.test.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React from 'react';

import { render } from '@testing-library/react';
import { fireEvent, render } from '@testing-library/react';

import ParticipantList from './ParticipantList';

describe('ParticipantList', () => {
const renderParticipantList = ({ id, confirm }) => render((
const renderParticipantList = (participant) => render((
<ParticipantList
id={id}
confirm={confirm}
participant={participant}
/>
));

Expand Down Expand Up @@ -39,4 +38,41 @@ describe('ParticipantList', () => {
expect(container).toHaveTextContent('승인하기');
});
});

describe('click "View application" button', () => {
const participant = {
id: 'test',
reason: 'reason',
wantToGet: 'wantToGet',
confirm: false,
};

it("renders Applicant's application", () => {
const { container, getByText } = renderParticipantList(participant);

const button = getByText('신청서 보기');

fireEvent.click(button);

const { reason, wantToGet } = participant;

expect(container).toHaveTextContent(reason);
expect(container).toHaveTextContent(wantToGet);
});

it('close button click', () => {
const { container, getByText } = renderParticipantList(participant);

const button = getByText('신청서 보기');

fireEvent.click(button);

fireEvent.click(getByText('닫기'));

const { reason, wantToGet } = participant;

expect(container).not.toHaveTextContent(reason);
expect(container).not.toHaveTextContent(wantToGet);
});
});
});
7 changes: 3 additions & 4 deletions src/components/introduce/modals/ParticipantListModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,10 @@ const ParticipantListModal = ({ visible, onClose, participants }) => {
<div>승인 여부</div>
</ParticipantTitleWrapper>
<ParticipantListWrapper>
{participants.length && participants.map(({ id, confirm }) => (
{participants.length && participants.map((participant) => (
<ParticipantList
key={id}
id={id}
confirm={confirm}
key={participant.id}
participant={participant}
/>
))}
</ParticipantListWrapper>
Expand Down