Skip to content

Commit

Permalink
Merge pull request #116 from ktmihs/develop
Browse files Browse the repository at this point in the history
친구 추가 로직 구현
  • Loading branch information
JJongBin authored Dec 1, 2022
2 parents 64a74f5 + 5335e09 commit ce6ca21
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 43 deletions.
27 changes: 26 additions & 1 deletion frontend/src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ import Signin from './page/Signin';
import Signup from './page/Signup';
import { useEffect } from 'react';
import axios from 'axios';
import { useSetRecoilState } from 'recoil';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { userState } from './store/atom/user';
import { friendsState } from './store/atom/friends';

type friendList = {
nickname: string;
characterName: string;
};

const Router = () => {
const setUser = useSetRecoilState(userState);
const setFriends = useSetRecoilState(friendsState);

useEffect(() => {
const checkAuth = async () => {
Expand All @@ -20,6 +27,24 @@ const Router = () => {
nickname: data.nickname.trim(),
hair: data.characterName.trim(),
});

(async () => {
const response = await axios.get('/api/friendship');

const friendList: friendList[] = response.data;
if (!friendList.length) return;

const initialList: any = {};
friendList.forEach(({ nickname }) => {
initialList[nickname] = {
isOnline: false,
name: nickname,
isCalling: false,
};
});

setFriends(initialList);
})();
}
};

Expand Down
14 changes: 11 additions & 3 deletions frontend/src/component/Sidebar/Friends/callingList.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { MouseEvent } from 'react';
import { useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { friendsState } from '../../../store/atom/friends';
import Content from '../Content';
import FriendItem from './friendItem';
import { friendType } from './friends';
import { callingList } from './friends.styled';

const CallingList = () => {
const friends = useRecoilValue(friendsState);
const [friends, setFriends] = useRecoilState(friendsState);
const friendList = Object.values(friends).filter(value => value.isCalling);

const handleDragOver = (e: MouseEvent) => {
Expand All @@ -19,7 +19,15 @@ const CallingList = () => {

if (target.tagName !== 'UL' || !draggingElement) return;

target.appendChild(draggingElement);
const id = draggingElement.children[0].id;

setFriends({
...friends,
[id]: {
...friends[id],
isCalling: true,
},
});
};

return (
Expand Down
21 changes: 16 additions & 5 deletions frontend/src/component/Sidebar/Friends/friendItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,32 @@ import { friendType } from './friends';
import { friendItemWrapper, userName } from './friends.styled';
import message from '../../../assets/icon/messageIcon.svg';
import unfollow from '../../../assets/icon/unfollowIcon.svg';
import axios from 'axios';

const FriendItem = (data: friendType) => {
const { id, isOnline, name } = data;
const { isOnline, name } = data;

const sendChatting = () => {
alert(`${name}님과 채팅하기`);
};

const unfollowing = () => {
alert(`${name}님을 언팔로우 하시겠습니까?`);
const unfollowing = async () => {
const isConfirm = confirm(`${name}님을 언팔로우 하시겠습니까?`);

if (isConfirm) {
try {
await axios.delete(`/api/friendship/${name}`);

alert(`${name}님을 언팔로우 하였습니다.`);
} catch {
alert('언팔로우 실패');
}
}
};

return (
<Content draggable={isOnline} key={id}>
<section id={id} css={friendItemWrapper(isOnline)}>
<Content draggable={isOnline} key={name}>
<section id={name} css={friendItemWrapper(isOnline)}>
<div css={userName(isOnline)}>{name}</div>
<div>
<img src={message} alt="채팅하기" onClick={sendChatting}></img>
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/component/Sidebar/Friends/friendList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ import { useRecoilValue } from 'recoil';
import Content from '../Content';
import FriendItem from './friendItem';
import { friendType } from './friends';
import { findFriend, friendListWrapper } from './friends.styled';
import { friendListWrapper } from './friends.styled';
import { friendsState } from '../../../store/atom/friends';
import Search from './search';

const FriendList = () => {
const friends = useRecoilValue(friendsState);
const friendList = Object.values(friends).filter(value => !value.isCalling);

const handleDrag = (e: MouseEvent) => {
const target = e.target as HTMLElement;

target.classList.toggle('dragging');
};

const friends = useRecoilValue(friendsState);
const friendList = Object.values(friends).filter(value => !value.isCalling);

return (
<Content>
<h2 className="srOnly">친구 목록</h2>
Expand All @@ -25,9 +26,7 @@ const FriendList = () => {
onDragEnd={handleDrag}>
{friendList.map((friend: friendType) => FriendItem(friend))}
</ul>
<div css={findFriend}>
<input type="text" placeholder="추가할 친구 이름" />
</div>
<Search />
</Content>
);
};
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/component/Sidebar/Friends/friends.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const userName = (state: boolean) => css`
`;

export const findFriend = css`
position: relative;
display: flex;
justify-content: space-evenly;
align-items: center;
Expand All @@ -83,6 +84,36 @@ export const findFriend = css`
background-color: rgba(255, 255, 255, 0.7);
margin-top: 10px;
ul {
position: absolute;
top: 0;
left: 0;
display: flex;
flex-flow: column nowrap;
gap: 8px;
width: 180px;
transform: translate(50px, -100%);
background-color: rgba(245, 245, 245, 0.9);
border-radius: 10px;
padding: 5px;
margin-top: -5px;
li {
border-radius: 5px;
font-weight: 700;
padding: 5px;
cursor: pointer;
:hover {
color: ${theme.green};
background-color: rgba(255, 255, 255, 0.9);
}
}
}
::before {
content: url(${addFriendIcon});
}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/component/Sidebar/Friends/friends.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type friendType = {
id: string;
isCalling: boolean;
isOnline: boolean;
name: string;
Expand Down
73 changes: 73 additions & 0 deletions frontend/src/component/Sidebar/Friends/search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import axios from 'axios';
import { FormEvent, MouseEvent, useState } from 'react';
import { findFriend } from './friends.styled';

const testSearchWord = (word: string) =>
['hj', 'ktmihs22', 'jongbin', 'kt', 'ktm', 'ktmi', 'ktmih', 'ktmihs'].filter(
name => name.indexOf(word) !== -1
);

const Search = () => {
const [searchWord, setSearchWord] = useState<string>('');
const [nicknameList, setNicknameList] = useState<string[]>([]);

const addToFriend = async (e: MouseEvent) => {
const target = e.target as HTMLUListElement;

const selectedWord = target.innerText;

setSearchWord('');
setNicknameList([]);

const response = confirm(`${selectedWord}를 친구추가 하시겠습니까?`);
if (response) {
try {
await axios.put(`/api/friendship/${selectedWord}`);

alert('팔로우 되었습니다.');
} catch {
alert('팔로우 실패');
}
}
};

const [timer, setTimer] = useState<NodeJS.Timeout>();

const handleSearchNickname = (e: FormEvent) => {
const target = e.target as HTMLInputElement;

const value = target.value;
setSearchWord(value);

if (timer) clearTimeout(timer);
const newTimer = setTimeout(() => {
// 서버로 리스트 받아오는 요청 보내기
const findList = testSearchWord(value);
setNicknameList(findList);
}, 500);

setTimer(newTimer);
};

return (
<section css={findFriend}>
{nicknameList.length ? (
<ul onClick={addToFriend}>
{nicknameList.map(name => (
<li key={name}>{name}</li>
))}
</ul>
) : (
<></>
)}
<input
type="text"
value={searchWord}
placeholder="추가할 친구 이름"
onInput={handleSearchNickname}
/>
</section>
);
};

export default Search;
4 changes: 0 additions & 4 deletions frontend/src/page/Main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import axios from 'axios';
import { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
import Background from '../../component/Background';
import MainContent from '../../component/MainContent';
import { userState } from '../../store/atom/user';

export const getCookieValue = (key: string) => {
const cookieArr = document.cookie.split(';');
Expand Down
35 changes: 13 additions & 22 deletions frontend/src/store/atom/friends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { atom } from 'recoil';

export interface friendsProps {
[key: string]: {
id: string;
name: string;
isOnline: boolean;
isCalling: boolean;
Expand All @@ -12,52 +11,44 @@ export interface friendsProps {
export const friendsState = atom<friendsProps>({
key: 'friendsState',
default: {
'1': {
id: '1',
isOnline: false,
안현서: {
isOnline: true,
name: '안현서',
isCalling: false,
},
'2': {
id: '2',
원종빈: {
isOnline: true,
name: '원종빈',
isCalling: true,
},
'3': {
id: '3',
강성준: {
isOnline: true,
name: '강성준',
isCalling: true,
},
'4': {
id: '4',
이형진: {
isOnline: true,
name: '이형진',
isCalling: false,
},
'5': {
id: '5',
안현서2: {
isOnline: false,
name: '안현서',
name: '안현서2',
isCalling: false,
},
'6': {
id: '6',
원종빈2: {
isOnline: false,
name: '원종빈',
name: '원종빈2',
isCalling: false,
},
'7': {
id: '7',
강성준2: {
isOnline: true,
name: '강성준',
name: '강성준2',
isCalling: false,
},
'8': {
id: '8',
이형진2: {
isOnline: true,
name: '이형진',
name: '이형진2',
isCalling: false,
},
},
Expand Down

0 comments on commit ce6ca21

Please sign in to comment.