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
95 changes: 95 additions & 0 deletions src/components/common/ModalWindow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';

import styled from '@emotion/styled';

import { css } from '@emotion/react';
import Button from '../../styles/Button';

const ModalWindowWrapper = 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;
width: 320px;
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;
}
p {
margin-bottom: 2rem;
}
.buttons {
display: flex;
justify-content: flex-end;
}
`;

const StyledButton = styled(Button)`
height: 2rem;
& + & {
margin-left: 0.75rem;
}
`;

const ModalWindow = ({
visible,
title,
description,
confirmText = '확인',
cancelText = '취소',
onConfirm,
onCancel,
}) => {
if (!visible) {
return null;
}

return (
<ModalWindowWrapper visible className="animation">
<ModalBoxWrapper>
<h2>{title}</h2>
<p>{description}</p>
<div className="buttons">
<StyledButton warn onClick={onCancel}>{cancelText}</StyledButton>
{onConfirm && (
<StyledButton success onClick={onConfirm}>{confirmText}</StyledButton>
)}
</div>
</ModalBoxWrapper>
</ModalWindowWrapper>
);
};

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

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

import ModalWindow from './ModalWindow';

describe('ModalWindow', () => {
const handleConfirm = jest.fn();
const handleCancel = jest.fn();

const renderModalWindow = ({ visible, title, description }) => render((
<ModalWindow
visible={visible}
title={title}
description={description}
onConfirm={handleConfirm}
onCancel={handleCancel}
/>
));

context('with visible', () => {
const modal = {
visible: true,
title: '타이틀',
description: '내용',
};

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

expect(container).toHaveTextContent('타이틀');
expect(container).toHaveTextContent('내용');
});
});

context('without visible', () => {
const modal = {
visible: false,
title: '타이틀',
description: '내용',
};

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

expect(container).toBeEmptyDOMElement();
});
});
});
13 changes: 1 addition & 12 deletions src/components/introduce/ApplyStatusButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const ApplyStatusButtonWrapper = styled.button`
`;

const ApplyStatusButton = ({
timeStatus, onApply, user, applyStatus,
timeStatus, onApply, applyStatus,
}) => {
if (applyStatus) {
return (
Expand All @@ -68,17 +68,6 @@ const ApplyStatusButton = ({
);
}

if (!user) {
return (
<ApplyStatusButtonWrapper
type="button"
className="no-login"
>
로그인 후 신청 가능합니다.
</ApplyStatusButtonWrapper>
);
}

return (
<ApplyStatusButtonWrapper
type="button"
Expand Down
10 changes: 0 additions & 10 deletions src/components/introduce/ApplyStatusButton.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ describe('ApplyStatusButton', () => {
const renderApplyStatusButton = ({
applyStatus = false,
timeStatus = false,
user = true,
}) => render((
<ApplyStatusButton
applyStatus={applyStatus}
onApply={handleApply}
timeStatus={timeStatus}
user={user}
/>
));

Expand All @@ -36,14 +34,6 @@ describe('ApplyStatusButton', () => {
});
});

context('When not log in', () => {
it('renders "You can apply after logging in." text', () => {
const { container } = renderApplyStatusButton({ user: false });

expect(container).toHaveTextContent('로그인 후 신청 가능합니다.');
});
});

context('When it is possible to apply', () => {
it('renders "apply" text', () => {
const { container } = renderApplyStatusButton({});
Expand Down
70 changes: 70 additions & 0 deletions src/components/introduce/IntroduceHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useState } from 'react';

import styled from '@emotion/styled';

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

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

const IntroduceHeaderWrapper = styled.div`
border-bottom: 2px solid ${palette.gray[4]};
padding-bottom: 1.5rem;
margin-bottom: 2rem;
display: flex;
justify-content: space-between;
h1 {
font-size: 2.3rem;
line-height: 1.5;
margin: 0;
}
`;

const IntroduceHeader = ({
group, onApply, user, realTime,
}) => {
const [modal, setModal] = useState(false);

const {
title, moderatorId, participants, applyEndDate,
} = group;

const applyEndTime = changeDateToTime(applyEndDate);

const onApplyClick = () => {
setModal(true);
};

const handleCancel = () => {
setModal(false);
};

const handleApply = () => {
if (!user) {
onApplyClick();
return;
}

onApply();
};

return (
<IntroduceHeaderWrapper>
<h1>{title}</h1>
{moderatorId !== user && (
<>
<ApplyStatusButton
user={user}
onApply={handleApply}
applyStatus={participants.includes(user)}
timeStatus={isCheckedTimeStatus({ ...group, time: realTime, applyEndTime })}
/>
<AskLoginModal visible={modal} onCancel={handleCancel} />
</>
)}
</IntroduceHeaderWrapper>
);
};

export default IntroduceHeader;
Loading