Skip to content

Commit

Permalink
Merge pull request #123 from boostcamp-2020/dev
Browse files Browse the repository at this point in the history
Dev -> master 배포
  • Loading branch information
rnjshippo authored Dec 15, 2020
2 parents 18ded2f + ffa5167 commit 51d816e
Show file tree
Hide file tree
Showing 64 changed files with 1,280 additions and 310 deletions.
6 changes: 3 additions & 3 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ const ChannelListBox = ({
<>
{createChannelModalVisible && (
<DimModal
width="520px"
width="600px"
header={<CreateChannelModalHeader secret={secret} />}
body={
// eslint-disable-next-line react/jsx-wrap-multilines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import React, { useState } from 'react';
import { flex } from '@/styles/mixin';
import styled from 'styled-components';
import { useUserState } from '@/hooks';
import { useDuplicatedChannelState, useUserState } from '@/hooks';
import { createChannelRequest } from '@/store/modules/channel.slice';
import { checkDuplicateRequest } from '@/store/modules/duplicatedChannel.slice';
import { useDispatch } from 'react-redux';
import { PoundIcon, LockIcon } from '@/components';
import theme from '@/styles/theme';
Expand Down Expand Up @@ -144,6 +145,10 @@ const CreateButton = styled(SubmitButton)<Props>`

const IconBox = styled.div``;

const WarningMessage = styled(NameAlert)`
margin-left: 0;
`;

interface CreateChannelModalBodyProps {
setCreateChannelModalVisible: (fn: (state: boolean) => boolean) => void;
setSecret: (fn: (state: boolean) => boolean) => void;
Expand All @@ -155,13 +160,18 @@ const CreateChannelModalBody: React.FC<CreateChannelModalBodyProps> = ({
setSecret,
secret,
}: CreateChannelModalBodyProps) => {
const dispatch = useDispatch();

const [name, setName] = useState('');
const [description, setDescription] = useState('');

const { userInfo } = useUserState();
const dispatch = useDispatch();
const { isDuplicated, loading } = useDuplicatedChannelState();

const changeName = (e: React.ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value: channelName } = e.target;
setName(channelName);
dispatch(checkDuplicateRequest({ channelName }));
};

const changeDescription = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -205,6 +215,7 @@ const CreateChannelModalBody: React.FC<CreateChannelModalBodyProps> = ({
Name {name === '' && <NameAlert>Don't forget to name your channel.</NameAlert>}
</LabelContent>
</LabelBox>
{isDuplicated && !loading && <WarningMessage>중복된 채널 이름입니다.</WarningMessage>}
<InputBox>
<IconBox className="icon">
{secret ? (
Expand All @@ -214,7 +225,7 @@ const CreateChannelModalBody: React.FC<CreateChannelModalBodyProps> = ({
)}
</IconBox>
<NameInput
onChange={changeName}
onChange={handleNameChange}
value={name}
required
placeholder="e.g. plan-budget"
Expand Down Expand Up @@ -246,7 +257,12 @@ const CreateChannelModalBody: React.FC<CreateChannelModalBodyProps> = ({
</BottomContent>
</Bottom>
<ModalFooter>
<CreateButton type="submit" name={name} onClick={clickCreateChannel} disabled={name === ''}>
<CreateButton
type="submit"
name={name}
onClick={clickCreateChannel}
disabled={name === '' || isDuplicated}
>
Create
</CreateButton>
</ModalFooter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,66 @@
import { loadNotJoinedChannelsRequest } from '@/store/modules/findChannel.slice';
import { sendMessageRequest } from '@/store/modules/socket.slice';
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { flex } from '@/styles/mixin';
import styled from 'styled-components';
import { useFindChannelState, useUserState } from '@/hooks';
import { useDispatch } from 'react-redux';
import { Channel } from '@/types';
import { CHANNEL_SUBTYPE, SOCKET_MESSAGE_TYPE } from '@/utils/constants';
import { FormInput, SubmitButton as SB } from '@/styles/shared';
import { darken } from 'polished';

const Container = styled.div``;
const ChannelInfo = styled.div``;
const JoinButton = styled.button``;
const ChannelName = styled.div``;
const Container = styled.div`
padding: 0 4px;
margin: 1rem 0 3rem 0;
`;

const JoinButton = styled(SB)`
margin-left: auto;
`;

const ChannelListContainer = styled.div`
width: 100%;
height: 12rem;
overflow-y: scroll;
padding: 0 24px;
`;

const ChannelItemBox = styled.div`
padding: 8px 5px;
margin: 0.5rem 0;
border-radius: 5px;
${flex('center', 'flex-start')}
cursor: pointer;
color: ${(props) => props.theme.color.lightBlack};
&:hover {
background-color: ${(props) => darken(0.02, props.theme.color.threadHover)};
}
`;

const ChannelName = styled.div`
font-weight: bold;
font-size: 1rem;
color: ${(props) => props.theme.color.lightBlack};
`;

const SearchInput = styled(FormInput)`
width: calc(100% - 48px);
height: 50px;
padding: 0 24px;
margin: 0 auto;
margin-bottom: 1rem;
font-size: ${(props) => props.theme.size.l};
`;

const NoResultBox = styled.div`
font-weight: bold;
font-size: 1rem;
color: ${(props) => props.theme.color.lightBlack};
padding: 0.5rem;
`;

const debounce = (callback: any) => setTimeout(callback, 200);

interface FindChannelModalProps {
setFindChannelModalVisible: (fn: (state: boolean) => boolean) => void;
Expand All @@ -24,11 +73,11 @@ const FindChannelModalBody: React.FC<FindChannelModalProps> = ({
const dispatch = useDispatch();
const { notJoinedChannelList } = useFindChannelState();

useEffect(() => {
if (userInfo) {
dispatch(loadNotJoinedChannelsRequest({ userId: userInfo.id }));
}
}, []);
const [filteredChannelList, setFilteredChannelList] = useState<Channel[]>([]);

const inputRef = useRef<HTMLInputElement>(null);
const [keyword, setKeyword] = useState('');
const [debouceClear, setDebouceClear] = useState<number | null>(null);

const clickJoinButton = ({ channel }: { channel: Channel }) => {
if (userInfo) {
Expand All @@ -48,14 +97,58 @@ const FindChannelModalBody: React.FC<FindChannelModalProps> = ({
}
};

const setfilterdList = (value: string) => {
const filtered = notJoinedChannelList.filter((chan) => chan.name.match(value));
setFilteredChannelList(filtered);
};

const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;
setKeyword(value);
if (debouceClear) {
clearTimeout(debouceClear);
}
setDebouceClear(debounce(() => setfilterdList(value)));
};

useEffect(() => {
if (userInfo) {
dispatch(loadNotJoinedChannelsRequest({ userId: userInfo.id }));
}
}, []);

useEffect(() => {
return () => {
if (debouceClear) {
clearTimeout(debouceClear);
}
};
});

useEffect(() => {
setFilteredChannelList(notJoinedChannelList);
}, [notJoinedChannelList]);

return (
<Container>
{notJoinedChannelList.map((channel: Channel) => (
<ChannelInfo key={channel.id}>
<ChannelName>{channel.name}</ChannelName>
<JoinButton onClick={() => clickJoinButton({ channel })}>Join</JoinButton>
</ChannelInfo>
))}
<SearchInput
ref={inputRef}
onChange={handleKeywordChange}
value={keyword}
placeholder="Search by name, email, or user group"
/>
<ChannelListContainer>
{filteredChannelList.length ? (
filteredChannelList.map((channel: Channel) => (
<ChannelItemBox key={channel.id}>
<ChannelName>{channel.name}</ChannelName>
<JoinButton onClick={() => clickJoinButton({ channel })}>Join</JoinButton>
</ChannelItemBox>
))
) : (
<NoResultBox>검색 결과가 없습니다.</NoResultBox>
)}
</ChannelListContainer>
</Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
/* eslint-disable react/no-unescaped-entities */
/* eslint-disable @typescript-eslint/ban-types */
import React from 'react';
import styled from 'styled-components';
import { flex } from '@/styles/mixin';

const HeaderContent = styled.div`
font-size: ${(props) => props.theme.size.xxxl};
font-weight: 700;
const Container = styled.div`
${flex('center', 'flex-start')}
width: 100%;
height: 3.2rem;
flex-shrink: 0;
font-size: 1.4rem;
font-weight: 800;
background-color: white;
color: ${(props) => props.theme.color.lightBlack};
`;

const FindChannelModalHeader: React.FC = () => {
return <HeaderContent>'Find Not Subscribed Channel'</HeaderContent>;
return <Container>Channel browser</Container>;
};

export default FindChannelModalHeader;
22 changes: 8 additions & 14 deletions client/src/components/CodeVerifyBox/CodeVerifyBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,19 @@ import { flex, focusedInputBoxShadow } from '@/styles/mixin';
import { removeVerifyCode } from '@/store/modules/signup.slice';
import { useSignupState } from '@/hooks';
import { decrypt } from '@/utils/utils';
import { WarningIcon } from '@/components';
import { WarningIcon, LogoBox } from '@/components';

const Container = styled.div`
width: 50rem;
margin: 0 auto;
${flex('center', 'center', 'column')};
`;

const AppIcon = styled.div`
margin: 1rem auto;
font-size: 2rem;
font-weight: bold;
`;

const Title = styled.div`
margin: 0.5rem auto;
margin: 1.4rem auto 0.4rem auto;
font-size: 2.8rem;
font-weight: 800;
color: ${(props) => props.theme.color.black1};
font-weight: bold;
color: #453841;
`;

const SubTitle = styled.div`
Expand Down Expand Up @@ -179,11 +173,11 @@ const CodeVerifyBox = () => {

return (
<Container>
<AppIcon>Slack</AppIcon>
<Title>코드는 이메일에서 확인하세요</Title>
<LogoBox />
<Title>코드는 이메일에서 확인해 주세요</Title>
<SubTitle>
<BoldText>{email}</BoldText>(으)로 6자 코드를 보냈습니다. 코드는 잠시 후에 만료되니 빨리
입력하세요.
입력해 주세요.
</SubTitle>
<CodeBox>
<LeftCodeBox>
Expand Down Expand Up @@ -225,7 +219,7 @@ const CodeVerifyBox = () => {
{!valid && (
<InvaildBox>
<WarningIcon />
<WarningText>유효하지 않은 코드입니다. 다시 시도해보세요!</WarningText>
<WarningText>유효하지 않은 코드입니다. 코드를 확인 후 다시 시도해보세요!</WarningText>
</InvaildBox>
)}
<InfoText>고객님의 코드를 찾을 수 없나요? 스팸 폴더를 확인해 보세요!</InfoText>
Expand Down
16 changes: 12 additions & 4 deletions client/src/components/EmailBox/EmailBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import isEmail from 'validator/es/lib/isEmail';
import { useDispatch } from 'react-redux';
import { FormButton, FormInput } from '@/styles/shared';
import { flex } from '@/styles/mixin';
import { WarningIcon, DimModal } from '@/components';
import { WarningIcon, LogoBox } from '@/components';
import { useSignupState } from '@/hooks';
import {
verifyEmailSendRequest,
Expand All @@ -20,14 +20,15 @@ const Container = styled.div`

const Header = styled.div`
width: 30rem;
margin: 4rem auto 2rem auto;
margin: 2rem auto 1rem auto;
`;

const Title = styled.div`
font-size: 2.3rem;
font-size: 2.4rem;
font-weight: bold;
margin: 0 auto 2rem auto;
margin: 1rem auto 1.5rem auto;
${flex()}
color: #453841;
`;

const SubTitle = styled(Title)`
Expand Down Expand Up @@ -122,10 +123,17 @@ const EmailBox: React.FC = () => {
}
}, [checkExistEmail]);

useEffect(() => {
return () => {
dispatch(resetCheckExistEmailState());
};
}, []);

const warningMessage = !valid ? notValidEmailMessage : existEmailMessage;

return (
<Container>
<LogoBox />
<Header>
<Title>우선 이메일 입력하기</Title>
<SubTitle>
Expand Down
Loading

0 comments on commit 51d816e

Please sign in to comment.