Skip to content

Commit

Permalink
Merge pull request #58 from MOVIEJOJO7/feature/#48
Browse files Browse the repository at this point in the history
Feat : 채팅방 Open, Private 분기 pr
  • Loading branch information
LikeFireAndSky authored Nov 15, 2023
2 parents bd5a8cd + f8a2257 commit 176e241
Show file tree
Hide file tree
Showing 37 changed files with 419 additions and 96 deletions.
21 changes: 21 additions & 0 deletions Components/Common/AsyncLoading/AsyncLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import React from 'react';
import { asyncLoadingAtom } from '@/atoms/asyncLoadingAtom';
import { useRecoilValue } from 'recoil';
import AsyncSpinner from './AsyncSpinner';

const AsyncLoadingProvider = () => {
const asyncLoading = useRecoilValue(asyncLoadingAtom);
return (
<>
{asyncLoading && (
<div className="absolute top-0 left-0 bottom-0 right-0 z-[999] bg-opacity-70 w-full h-screen flex justify-center items-center bg-gray-700">
<AsyncSpinner />
</div>
)}
</>
);
};

export default AsyncLoadingProvider;
14 changes: 14 additions & 0 deletions Components/Common/AsyncLoading/AsyncSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use client';

import React from 'react';
import { Spinner } from '@material-tailwind/react';

const AsyncSpinner = () => {
return (
<>
<Spinner className="h-10 w-10" />
</>
);
};

export default AsyncSpinner;
97 changes: 83 additions & 14 deletions Components/Common/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,100 @@ import Image from 'next/image';
import Link from 'next/link';
import { removeCookie } from '../Login/Cookie';

import icon_footer_cat from '@/public/icon_footer_cat.svg';
import icon_footer_open from '@/public/icon_footer_open.svg';
import icon_footer_private from '@/public/icon_footer_private.svg';
import icon_footer_search from '@/public/icon_footer_search.svg';
import { Button, Tooltip } from '@material-tailwind/react';
import { useRouter } from 'next/navigation';

const Footer = () => {
const router = useRouter();
const handleLogout = () => {
removeCookie('accessToken');
removeCookie('refreshToken');
removeCookie('userId');
// Optionally, redirect the user to the login page or another page
window.location.href = '/login';
router.push('/login');
};

return (
<div className="w-auto gap-20 h-20 mx-auto fixed bottom-0 flex justify-center items-center bg-white">
<Link href={'/users'}>
<Image width={21} height={21} src="/people.svg" alt="친구 목록 보기" />
</Link>
<Link href={'/chatting'}>
<Image width={25} height={25} src="/more.svg" alt="더보기" />
</Link>
<Link href={'/search'}>
<Image width={21} height={21} src="/search.svg" alt="검색하기" />
</Link>
<button
<div className="w-full sm:w-[425px] md:w-[645px] h-14 flex justify-around items-center bg-primary mx-auto fixed inset-x-0 bottom-0">
<Tooltip
content="유저들 👋"
animate={{
mount: { scale: 1, y: 0 },
unmount: { scale: 0, y: 25 },
}}
>
<Link href={'/users'}>
<Image
width={20}
height={20}
src={icon_footer_cat}
alt="친구 목록 보기"
className="cursor-pointer hover:shadow-lg w-8 sm:w-12 "
/>
</Link>
</Tooltip>
<Tooltip
content="개인 채팅방 🏃‍♂️"
animate={{
mount: { scale: 1, y: 0 },
unmount: { scale: 0, y: 25 },
}}
>
<Link href={'/private'}>
<Image
width={20}
height={20}
src={icon_footer_private}
alt="더보기"
className="cursor-pointer hover:shadow-lg w-6 sm:w-10"
/>
</Link>
</Tooltip>
<Tooltip
content="오픈 채팅방 🤸‍♂️"
animate={{
mount: { scale: 1, y: 0 },
unmount: { scale: 0, y: 25 },
}}
>
<Link href={'/open'}>
<Image
width={20}
height={20}
src={icon_footer_open}
alt="검색하기"
className="cursor-pointer hover:shadow-lg w-6 sm:w-10"
/>
</Link>
</Tooltip>
<Tooltip
content="검색 🧐"
animate={{
mount: { scale: 1, y: 0 },
unmount: { scale: 0, y: 25 },
}}
>
<Link href={'/search'}>
<Image
width={20}
height={20}
src={icon_footer_search}
alt="검색하기"
className="cursor-pointer hover:shadow-lg w-6 sm:w-10"
/>
</Link>
</Tooltip>
<Button
type="button"
onClick={handleLogout}
className="flex justify-center items-center"
className="flex justify-center items-center bg-orange-900"
>
로그아웃
</button>
</Button>
</div>
);
};
Expand Down
10 changes: 10 additions & 0 deletions Components/Common/PageLoading/PageSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use client';

import React from 'react';
import { Spinner } from '@material-tailwind/react';

const PageSpinner = () => {
return <Spinner color="pink" className="w-8 h-8" />;
};

export default PageSpinner;
30 changes: 30 additions & 0 deletions Components/Common/PageLoading/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import React, { useEffect, useState } from 'react';
import { Progress } from '@material-tailwind/react';

const ProgressBar = () => {
const [value, setValue] = useState<number>(0);

useEffect(() => {
const interval = setInterval(() => {
setValue((oldValue) => {
const newValue = oldValue + 10;

if (newValue >= 100) {
clearInterval(interval);
}

return newValue;
});
}, 600);
}, []);

return (
<>
<Progress value={value} size="sm" color="pink" className="h-1" />
</>
);
};

export default ProgressBar;
13 changes: 13 additions & 0 deletions Components/Join/Join.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type RequestBody = {
id: string; // 사용자 아이디 (필수!, 영어와 숫자만)
password: string; // 사용자 비밀번호, 5자 이상 (필수!)
name: string; // 사용자 이름, 20자 이하 (필수!)
picture: string; // 사용자 이미지(url or base64, under 1MB)
};

export type FetchImageProps = {
file: string;
id: string;
password: string;
name: string;
};
25 changes: 9 additions & 16 deletions Components/Join/JoinForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React from 'react';
import React, { useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { Button, Typography } from '@material-tailwind/react';
import { fetchJoin } from '@/app/join/join.utils';
Expand All @@ -11,22 +11,10 @@ import Image from 'next/image';
import DropZone from './DropZone/DropZone';
import axios from 'axios';
import { useMutation } from '@tanstack/react-query';
import useAsyncLoading from '@/hooks/Open/useAsyncLoading';
import { FetchImageProps, RequestBody } from './Join.types';
// import Image from 'next/image';

type RequestBody = {
id: string; // 사용자 아이디 (필수!, 영어와 숫자만)
password: string; // 사용자 비밀번호, 5자 이상 (필수!)
name: string; // 사용자 이름, 20자 이하 (필수!)
picture: string; // 사용자 이미지(url or base64, under 1MB)
};

type FetchImageProps = {
file: string;
id: string;
password: string;
name: string;
};

const fetchImage = async (params: FetchImageProps) => {
const data = await axios.post('api/image/post', {
id: params.id,
Expand All @@ -38,8 +26,9 @@ const fetchImage = async (params: FetchImageProps) => {
};

const JoinForm = () => {
const loadingControl = useAsyncLoading();
const router = useRouter();
const [baseImageUrl, setBaseImageUrl] = React.useState<string>();
const [baseImageUrl, setBaseImageUrl] = useState<string>();

const mutation = useMutation({
mutationFn: (data: FetchImageProps) => fetchImage(data),
Expand All @@ -51,6 +40,7 @@ const JoinForm = () => {
props.name,
props.picture,
);
console.log(props);
if (message === 'User created') {
Swal.fire({
text: '회원가입이 완료되었습니다.',
Expand All @@ -68,6 +58,7 @@ const JoinForm = () => {
confirmButtonColor: 'red',
});
}
loadingControl(false);
},
onMutate: () => {
console.log('onMutate');
Expand All @@ -90,6 +81,8 @@ const JoinForm = () => {
password,
name,
}) => {
loadingControl(true);

if (!baseImageUrl) {
Swal.fire({
text: '이미지를 넣어주세요.',
Expand Down
4 changes: 4 additions & 0 deletions Components/Login/Login.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type IFormInput = {
id: string; // 사용자 아이디 (필수!, 영어와 숫자만)
password: string; // 사용자 비밀번호, 5자 이상 (필수!)
};
15 changes: 5 additions & 10 deletions Components/Login/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ import { useRouter } from 'next/navigation';
import Swal from 'sweetalert2';
import { Input } from '@material-tailwind/react';
import Image from 'next/image';

type IFormInput = {
id: string; // 사용자 아이디 (필수!, 영어와 숫자만)
password: string; // 사용자 비밀번호, 5자 이상 (필수!)
};
import useAsyncLoading from '@/hooks/Open/useAsyncLoading';
import { IFormInput } from './Login.types';

const LoginForm = () => {
const loadingControl = useAsyncLoading();
const router = useRouter();

const {
Expand All @@ -27,12 +25,8 @@ const LoginForm = () => {

// 로그인 버튼 클릭 시
const onSubmit: SubmitHandler<IFormInput> = async ({ id, password }) => {
console.log('id: ', id, 'password:', password);
const data = await fetchLogin(id, password);
console.log(data);
loadingControl(true);
const { accessToken, refreshToken } = await fetchLogin(id, password);
console.log('accessToken:', accessToken);
console.log('refreshToken:', refreshToken);
// 현재 시간
const time = new Date();
// 1일 뒤
Expand All @@ -51,6 +45,7 @@ const LoginForm = () => {
confirmButtonColor: '#3085d6',
});
}
loadingControl(false);
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from 'react';
import { ChatListProps } from '../ChatList/ChatList.type';
import { getCookie } from '@/Components/Login/Cookie';
import { useQuery } from '@tanstack/react-query';
import { fetchAllChat, filterChat } from '@/app/chatting/chatting.utils';
import { fetchAllChat, filterChat } from '@/app/private/chatting.utils';
import ChatList from '../ChatList/ChatList';
import {
Tab,
Expand All @@ -17,12 +17,12 @@ import {
const ChatDivder = ({ myChatList }: ChatListProps) => {
const data = [
{
label: '내가 참여한 오픈 채팅방',
value: 'open',
label: '개인 채팅방',
value: 'personal',
},
{
label: '내가 참여한 비밀 채팅방',
value: 'private',
label: '단체 채팅방',
value: 'multi',
},
];

Expand All @@ -35,24 +35,23 @@ const ChatDivder = ({ myChatList }: ChatListProps) => {
refetchInterval: 1000 * 5,
});

const { OpenChatList, PrivateChatList } = filterChat(chatList.chats);

const { PersonalChat, MultiChat } = filterChat(chatList.chats);
return (
<>
<Tabs value="open">
<Tabs value="personal" className="overflow-y-scroll">
<TabsHeader>
{data.map((item) => (
<Tab key={item.value} value={item.value}>
{item.label}
</Tab>
))}
</TabsHeader>
<TabsBody>
<TabPanel value="open">
<ChatList myChatList={OpenChatList} accessToken={accessToken} />
<TabsBody className="h-full">
<TabPanel value="personal" className="min-h-[calc(80vh)]">
<ChatList myChatList={PersonalChat} accessToken={accessToken} />
</TabPanel>
<TabPanel value="private">
<ChatList myChatList={PrivateChatList} accessToken={accessToken} />
<TabPanel value="multi" className="min-h-[calc(80vh)]">
<ChatList myChatList={MultiChat} accessToken={accessToken} />
</TabPanel>
</TabsBody>
</Tabs>
Expand Down
Loading

0 comments on commit 176e241

Please sign in to comment.