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
32 changes: 25 additions & 7 deletions src/components/introduce/ApplicantViewButton.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React, { useState } from 'react';

import styled from '@emotion/styled';

import { changeDateToTime, isCheckedTimeStatus } from '../../util/utils';

import ApplyStatusButton from './ApplyStatusButton';
import ApplicationFormModal from './modals/ApplicationFormModal';
import AskApplyCancelModal from './modals/AskApplyCancelModal';
import AskLoginModal from './modals/AskLoginModal';

const ParticipantsStatus = styled.div`
display: flex;
flex-direction: row;
`;

const ApplicantViewButton = ({
group, onApply, user, realTime, onApplyCancel, onChangeApplyFields, applyFields, clearForm,
}) => {
Expand Down Expand Up @@ -54,19 +61,30 @@ const ApplicantViewButton = ({
clearForm();
};

const isCheckedUserStatus = (applicant) => (userEmail) => applicant
.find(({ id }) => id === userEmail);

const status = {
...group,
time: realTime,
applyEndTime,
};

if (moderatorId === user) {
return null;
}

return (
<>
<ApplyStatusButton
user={user}
onApply={handleApply}
onCancel={handleApplyCancelConfirmClick}
applyStatus={participants.some(({ id }) => id === user)}
timeStatus={isCheckedTimeStatus({ ...group, time: realTime, applyEndTime })}
/>
<ParticipantsStatus>
<ApplyStatusButton
user={user}
onApply={handleApply}
onCancel={handleApplyCancelConfirmClick}
userStatus={isCheckedUserStatus(participants)(user)}
timeStatus={isCheckedTimeStatus(status)}
/>
</ParticipantsStatus>
<AskLoginModal
visible={loginCheckModal}
onCancel={handleLoginCheckCancel}
Expand Down
12 changes: 6 additions & 6 deletions src/components/introduce/ApplicantViewButton.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('ApplicantViewButton', () => {
applyEndDate: tomorrow,
participants: [
{ id: 'user2' },
{ id: 'user' },
{ id: 'user', confirm: false },
],
personnel: 3,
};
Expand Down Expand Up @@ -110,13 +110,13 @@ describe('ApplicantViewButton', () => {
...STUDY_GROUP,
applyEndDate: yesterday,
participants: [
{ id: 'user2' },
{ id: 'user1', confirm: false },
],
personnel: 2,
};

it('renders recruitment closed text', () => {
const { container } = renderApplicantViewButton({ group, time });
const { container } = renderApplicantViewButton({ group, time, user: 'user1' });

expect(container).toHaveTextContent('모집 마감');
});
Expand All @@ -131,13 +131,13 @@ describe('ApplicantViewButton', () => {
applyEndDate: tomorrow,
participants: [
{ id: 'user2' },
{ id: 'user3' },
{ id: 'user3', confirm: false },
],
personnel: 2,
personnel: 1,
};

it('renders recruitment closed text', () => {
const { container } = renderApplicantViewButton({ group, time });
const { container } = renderApplicantViewButton({ group, time, user: 'user3' });

expect(container).toHaveTextContent('모집 마감');
});
Expand Down
62 changes: 44 additions & 18 deletions src/components/introduce/ApplyStatusButton.jsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,77 @@
import React from 'react';

import ApproveStatus from '../../styles/ApproveStatus';

import StyledApplyStatusButton from '../../styles/StyledApplyStatusButton';

const checkConfirm = (confirm) => confirm === true;

const ApplyStatusButton = ({
timeStatus, onApply, applyStatus, onCancel,
timeStatus, onApply, userStatus, onCancel,
}) => {
if (!timeStatus && applyStatus) {
if (!timeStatus && !userStatus) {
return (
<StyledApplyStatusButton
type="button"
className="apply-cancel"
onClick={onCancel}
className="apply"
onClick={onApply}
>
신청 취소
신청하기
</StyledApplyStatusButton>
);
}

if (applyStatus) {
if (!timeStatus && !checkConfirm(userStatus.confirm)) {
return (
<StyledApplyStatusButton
type="button"
className="apply-complete"
>
신청 완료
</StyledApplyStatusButton>
<>
<ApproveStatus>
승인 대기중..
</ApproveStatus>
<StyledApplyStatusButton
type="button"
className="apply-cancel"
onClick={onCancel}
>
신청 취소
</StyledApplyStatusButton>
</>
);
}

if (timeStatus) {
if (!timeStatus && checkConfirm(userStatus.confirm)) {
return (
<>
<ApproveStatus>
승인 완료!
</ApproveStatus>
<StyledApplyStatusButton
type="button"
className="apply-cancel"
onClick={onCancel}
>
신청 취소
</StyledApplyStatusButton>
</>
);
}

if (timeStatus && checkConfirm(userStatus.confirm)) {
return (
<StyledApplyStatusButton
type="button"
className="deadline"
className="apply-complete"
>
모집 마감
신청 완료
</StyledApplyStatusButton>
);
}

return (
<StyledApplyStatusButton
type="button"
className="apply"
onClick={onApply}
className="deadline"
>
신청하기
모집 마감
</StyledApplyStatusButton>
);
};
Expand Down
36 changes: 29 additions & 7 deletions src/components/introduce/ApplyStatusButton.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,57 @@ describe('ApplyStatusButton', () => {
const handleApply = jest.fn();

const renderApplyStatusButton = ({
applyStatus = false,
userStatus,
timeStatus = false,
}) => render((
<ApplyStatusButton
applyStatus={applyStatus}
userStatus={userStatus}
onApply={handleApply}
timeStatus={timeStatus}
/>
));

context('When the applicant applies before the application deadline', () => {
it('renders Cancel application', () => {
const { container } = renderApplyStatusButton({ applyStatus: true });
context('Before approval', () => {
it('renders cancel application and Pending approval', () => {
const { container } = renderApplyStatusButton({
userStatus: { confirm: false },
});

expect(container).toHaveTextContent('신청 취소');
expect(container).toHaveTextContent('신청 취소');
expect(container).toHaveTextContent('승인 대기중..');
});
});

context('After approval', () => {
it('renders Cancel application and Approved', () => {
const { container } = renderApplyStatusButton({
userStatus: { confirm: true },
});

expect(container).toHaveTextContent('신청 취소');
expect(container).toHaveTextContent('승인 완료!');
});
});
});

context('When the study application is completed', () => {
it('renders application completed', () => {
const { container } = renderApplyStatusButton({ applyStatus: true, timeStatus: true });
const { container } = renderApplyStatusButton({
userStatus: { confirm: true },
timeStatus: true,
});

expect(container).toHaveTextContent('신청 완료');
});
});

context('When the study application deadline', () => {
it('renders application deadline', () => {
const { container } = renderApplyStatusButton({ timeStatus: true });
const { container } = renderApplyStatusButton({
userStatus: { confirm: false },
timeStatus: true,
});

expect(container).toHaveTextContent('모집 마감');
});
Expand Down
2 changes: 1 addition & 1 deletion src/containers/introduce/IntroduceHeaderContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ describe('IntroduceHeaderContainer', () => {
applyEndDate: tomorrow,
participants: [
{ id: 'user2' },
{ id: 'user' },
{ id: 'user', confirm: false },
],
personnel: 3,
};
Expand Down
42 changes: 42 additions & 0 deletions src/styles/ApproveStatus.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';

import styled from '@emotion/styled';

import palette from './palette';

const ApproveStatusWrapper = styled.div`
display: inline-flex;
align-items: center;
font-weight: bold;
line-height: 0;
font-size: 1rem;
color: ${palette.violet[4]};
padding: 0.8rem 1rem;
`;

const LoadingContent = styled.span`
margin-left: .3rem;
width: 12px;
height: 12px;
border-top: 3px solid ${palette.violet[2]};
border-bottom: 3px solid ${palette.violet[2]};
border-right: 3px solid ${palette.violet[4]};
border-left: 3px solid ${palette.violet[4]};
animation: load 0.75s ease infinite;
border-radius: 100%;

@keyframes load {
0% { transform: rotate( 0deg ); }
100% { transform: rotate(180deg); }
}
`;

const ApproveStatus = ({ children, ...props }) => (
<ApproveStatusWrapper {...props}>
{children}
<LoadingContent />
</ApproveStatusWrapper>
);

export default ApproveStatus;
13 changes: 8 additions & 5 deletions src/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ export function equal(key, value) {
return (obj) => obj[key] === value;
}

export const authorizedUsersNumber = (participants) => participants
.filter(({ confirm }) => confirm && confirm === true)
.length + 1;

export const isCheckedTimeStatus = ({
time, applyEndTime, participants, personnel,
}) => (!!((time - applyEndTime >= 0 || participants.length === parseInt(personnel, 10))));
}) => (!!((
time - applyEndTime >= 0
|| authorizedUsersNumber(participants) >= parseInt(personnel, 10)
)));

export const isCheckedOnlyTimeStatus = ({ time, applyEndTime }) => (time - applyEndTime >= 0);

Expand All @@ -18,10 +25,6 @@ export const isCheckValidate = (values) => values.map(checkTrim).includes('');

export const changeDateToTime = (date) => new Date(date).getTime();

export const authorizedUsersNumber = (participants) => participants
.filter(({ confirm }) => confirm && confirm === true)
.length + 1;

export const applyDateToString = (response) => response
.data()
.applyEndDate
Expand Down