Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
b595318
chore: socket.io-client ์„ค์น˜
gominzip Nov 16, 2024
dc896b5
fix: ๋ฉ”์ธํŽ˜์ด์ง€ ์ฑ„ํŒ…์ฐฝ ๊ธ€์”จํฌ๊ธฐ ์กฐ์ ˆ
spearStr Nov 18, 2024
cc814d4
feat: ์ฑ„ํŒ… ์›น์†Œ์ผ“ ์ด๋ฒคํŠธ ์ƒ์ˆ˜ ๋ฐ ํƒ€์ž… ์ถ”๊ฐ€
gominzip Nov 18, 2024
fd225e8
chore: constants ์ ˆ๋Œ€๊ฒฝ๋กœ ์ถ”๊ฐ€
gominzip Nov 18, 2024
fd2217d
chore: eslint no-explicit-any rule off
gominzip Nov 19, 2024
a2e8516
feat: socket.io๋กœ ํด๋ผ์ด์–ธํŠธ ์ฑ„ํŒ… ๋ฐ๋ชจ ๊ตฌํ˜„
gominzip Nov 19, 2024
dc410a0
feat: ๋ฉ”์ธํŽ˜์ด์ง€ ๋žœ๋ค๋ผ์ด๋ธŒ ์˜์ƒ API์—ฐ๊ฒฐ
spearStr Nov 19, 2024
0e8a708
feat: ๋ฉ”์ธํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ํŽ˜์นญ
spearStr Nov 19, 2024
e5cb591
chore: ํƒ€์ž… ํ˜•์‹ ๋ฐ ์˜คํƒ€ ์ˆ˜์ •
gominzip Nov 19, 2024
85e2802
chore: switch๋ฌธ์— ๋“ค์—ฌ์“ฐ๊ธฐ์— ๋Œ€ํ•œ eslint rule ์ถ”๊ฐ€
gominzip Nov 19, 2024
1e4089a
feat: ์ฑ„ํŒ… ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒ„ํŠผ, ๋ชจ๋‹ฌ ์ด๋ฒคํŠธ๋ฅผ ์œ„ํ•œ useReducer ๋ฐ context ์ถ”๊ฐ€
gominzip Nov 19, 2024
24c2a78
feat: ๋ฉ”์ธํŽ˜์ด์ง€์— ๋™์˜์ƒ ์—ฐ๊ฒฐ
spearStr Nov 19, 2024
3e95cd4
fix: ์ฝ”๋“œ ์ค‘๋ณต ์ œ๊ฑฐ
spearStr Nov 19, 2024
3855d3e
console ์ œ๊ฑฐ
spearStr Nov 19, 2024
d9c1ce0
feat: ์ฑ„ํŒ… ๋ฒ„ํŠผ ๋ฐ ํŒ์—… ์ธํ„ฐ๋ ‰์…˜ ๊ตฌํ˜„
gominzip Nov 19, 2024
be0e951
chore: gif ํŒŒ์ผ ๋ณ€๊ฒฝ
jsk3342 Nov 19, 2024
9a8d4af
Merge pull request #146 from boostcampwm-2024/feature-FE-#144-Host_chโ€ฆ
jsk3342 Nov 19, 2024
c5c06d3
fix: ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น, restful API ๋ณ€๊ฒฝ
spearStr Nov 20, 2024
a0647ee
Merge branch 'dev-fe' into feature-fe-#5-chat_socket
gominzip Nov 20, 2024
5682eca
fix: ํŒจํ‚ค์ง€๋งค๋‹ˆ์ € ์˜คํƒ€ ์ˆ˜์ •
gominzip Nov 20, 2024
16bc0bc
fix: yarn lock ์ˆ˜์ •
gominzip Nov 20, 2024
ef5b80d
feat: userId ์ƒ์„ฑ HOC ๊ตฌํ˜„
jsk3342 Nov 20, 2024
29f7b90
feat: withUserId ์ ์šฉ
jsk3342 Nov 20, 2024
8b58c7d
refactor: initializeUserId๋กœ ํ•จ์ˆ˜๋ช… ๋ณ€๊ฒฝ
jsk3342 Nov 20, 2024
31913c4
refactor: sessionKey ์™ธ๋ถ€ ์ฃผ์ž…ํ•˜์—ฌ ์ˆœ์ˆ˜ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝ
jsk3342 Nov 20, 2024
f797e8a
fix: ํƒ€์ž… ์—๋Ÿฌ ๋ฐ ๋ช…์‹œ์  ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์œผ๋กœ lint ์—๋Ÿฌ ํ•ด๊ฒฐ
jsk3342 Nov 20, 2024
ed651cf
Merge pull request #142 from boostcampwm-2024/feature-fe-#117-mainpagโ€ฆ
jsk3342 Nov 20, 2024
7a860e8
Merge pull request #149 from boostcampwm-2024/feature-FE-#147-Create_โ€ฆ
spearStr Nov 20, 2024
026adfc
feat: ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํŒŒ์ผ ์ถ”๊ฐ€ ์‹œ ์ˆ˜์ • ์‚ญ์ œ ๋ฒ„ํŠผ ๊ตฌํ˜„
jsk3342 Nov 20, 2024
438a0a5
Merge branch 'dev-fe' into feature-fe-#5-chat_socket
gominzip Nov 20, 2024
e5e0121
chore: ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜
gominzip Nov 20, 2024
e38d58b
Merge pull request #148 from boostcampwm-2024/feature-fe-#5-chat_socket
spearStr Nov 20, 2024
32273c7
style: ๋ฉ”์ธํŽ˜์ด์ง€ ๋ฉ”์ธ๋ผ์ด๋ธŒ ์˜์ƒ ํ”„๋กœํ•„ hover์‹œ border ๋‘๊บผ์›Œ์งˆ ๋•Œ ๋ฐ€๋ ค๋ณด์ด๋Š” UI ํ•ด๊ฒฐ
spearStr Nov 20, 2024
1daaa4c
feat: ์›€์ง์ด๋Š” ๋ฐฐ๋„ˆ ๊ตฌํ˜„
jsk3342 Nov 20, 2024
e60e47b
feat: video ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ
spearStr Nov 20, 2024
78eee39
feat: ํด๋ผ์ด์–ธํŠธ ํŽ˜์ด์ง€์—์„œ ์˜์ƒ ๋ณด์—ฌ์ฃผ๊ธฐ
spearStr Nov 20, 2024
e53d431
feat: ์‹ค์ œ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ
spearStr Nov 20, 2024
d5071dc
fix: eslint ๋งž์ถ”๊ธฐ
spearStr Nov 20, 2024
fea0f5c
chore: ์ฃผ์„์ œ๊ฑฐ
spearStr Nov 21, 2024
f5d714f
fix: ๋‹จ์–ด ์ถ”๊ฐ€ ๋ฐ ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ ์ˆ˜์ •
jsk3342 Nov 21, 2024
dd14992
Merge pull request #158 from boostcampwm-2024/feature-FE-#157-Main_baโ€ฆ
spearStr Nov 21, 2024
0a1b6ab
Merge pull request #159 from boostcampwm-2024/feature-fe-#117-main_alโ€ฆ
jsk3342 Nov 21, 2024
a6e8816
Merge pull request #156 from boostcampwm-2024/feature-FE-#150-Host_upโ€ฆ
spearStr Nov 21, 2024
bd6ee17
feat: footer์ดˆ์•ˆ ์ถ”๊ฐ€
spearStr Nov 21, 2024
4c5cc8a
chore: ๋ฆฌ์•กํŠธ ํ›… ํผ ์„ค์ •
jsk3342 Nov 21, 2024
1a265bb
feat: ๋ฐฉ์†ก ์ œ๋ชฉ ํ•„๋“œ ๋ถ„๋ฆฌ ๋ฐ ์ตœ์ ํ™”
jsk3342 Nov 21, 2024
f6601fe
chore: ํผ ์Šคํƒ€์ผ ๋ถ„๋ฆฌ
jsk3342 Nov 21, 2024
1148c73
refactor: lint warning ๋ถ€๋ถ„ ์ˆ˜์ •
gominzip Nov 21, 2024
c54189f
feat: ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ˆ˜์ • ๋ฐ˜์˜ ๋ฐ ์งˆ๋ฌธ ์‘๋‹ต ์ด๋ฒคํŠธ emit ์ถ”๊ฐ€
gominzip Nov 21, 2024
a7a16b8
feat: ํผ ์ธํ’‹ ๋ถ„๋ฆฌ ๋ฐ ํ›…ํผ ์ ์šฉ
jsk3342 Nov 21, 2024
d20e15d
fix: ๋ณ€๊ฒฝ๋œ api ํƒ€์ž… ๋ณ€๊ฒฝ
jsk3342 Nov 21, 2024
bc073ed
feat: ํ›…ํผ ์ ์šฉ์œผ๋กœ ๋ Œ๋”๋ง ์ตœ์ ํ™”
jsk3342 Nov 21, 2024
1e2f26c
feat: client ํŽ˜์ด์ง€์— ๋ฐ์ดํ„ฐ ํŽ˜์นญ
spearStr Nov 21, 2024
3e965b3
fix: lint ์ˆ˜์ •
spearStr Nov 21, 2024
72ae85a
fix: ๊ตฌ์กฐ ๋ถ„ํ•ดํ• ๋‹น
spearStr Nov 21, 2024
a12fd27
feat: ๊ณต์ง€ ์ฑ„ํŒ… UI ์ถ”๊ฐ€ ๋ฐ textarea ๋ฆฌ์‚ฌ์ด์ง• ๋ฉ”์„œ๋“œ ์ˆ˜์ •
gominzip Nov 21, 2024
9a3dee6
Merge pull request #162 from boostcampwm-2024/feature-fe-#133-footer
jsk3342 Nov 21, 2024
05fa737
fix: api์š”์ฒญ์— param ์ถ”๊ฐ€
spearStr Nov 21, 2024
b83854f
Merge branch 'dev-fe' of https://github.com/boostcampwm-2024/web22-Liโ€ฆ
spearStr Nov 21, 2024
4dce3b0
fix: ํ•œ๊ธ€ ์ž…๋ ฅ ์‹œ ๋‘ ๋ฒˆ ์ž…๋ ฅ๋˜๋Š” ์˜ค๋ฅ˜ ๊ฐœ์„ 
jsk3342 Nov 21, 2024
de262f4
fix: updateElapsedTime ์ˆœ์ˆ˜ํ•จ์ˆ˜ ๋ถ„๋ฆฌ
spearStr Nov 21, 2024
ca9cd7d
fix: ์ˆœ์ˆ˜ํ•จ์ˆ˜ ๋ถ„๋ฆฌ
spearStr Nov 21, 2024
4326f29
feat: ์—์…‹ ์ƒ์ˆ˜ ์ €์žฅ ๋ฐ ์ ์šฉ
jsk3342 Nov 21, 2024
03ebd9f
feat: ๋ณ€๊ฒฝ ์ ์šฉ ๋ฐ ๋ถˆํ•„์š”ํ•œ ์—์…‹ ์‚ญ์ œ
jsk3342 Nov 21, 2024
c2c2452
feat: ํ˜ธ์ŠคํŠธ์™€ ํด๋ผ์ด์–ธํŠธ์˜ ์ฑ„ํŒ… ๊ถŒํ•œ ๋ถ„๋ฆฌ
gominzip Nov 21, 2024
b91200d
feat: ๋ฐฐ๋„ˆ ์—ฐ๋™
jsk3342 Nov 21, 2024
6b0111e
Merge pull request #167 from boostcampwm-2024/feature-fe-#163-clientpโ€ฆ
jsk3342 Nov 21, 2024
bc060ee
Merge branch 'dev-fe' of https://github.com/boostcampwm-2024/web22-Liโ€ฆ
spearStr Nov 21, 2024
2f22833
fix: ์•ˆ์“ฐ๋Š” ๋ณ€์ˆ˜ ์ œ๊ฑฐ
spearStr Nov 21, 2024
6093bb8
fix: ํ˜ธ์ŠคํŠธ ํผ ํƒ€์ž… ํด๋”๋กœ ๊ด€๋ฆฌ
jsk3342 Nov 21, 2024
e5ebc14
Merge pull request #172 from boostcampwm-2024/feature-FE-#171-image_aโ€ฆ
spearStr Nov 21, 2024
0f1c5a5
fix: ํƒ€์ž… ์—๋Ÿฌ ์ˆ˜์ •
jsk3342 Nov 21, 2024
1c8ba06
Merge pull request #168 from boostcampwm-2024/feature-FE-#123-host_hoโ€ฆ
spearStr Nov 21, 2024
3bc9179
feat: ์ฑ„ํŒ… join์‹œ ์ด์ „ ์งˆ๋ฌธ์ฑ„ํŒ…์œผ๋กœ ์ดˆ๊ธฐํ™”
gominzip Nov 21, 2024
bab5e64
feat: nginx/conf.d/chat.conf file added
spearStr Nov 21, 2024
fbfaa1c
Merge branch 'dev-fe' of https://github.com/boostcampwm-2024/web22-Liโ€ฆ
spearStr Nov 21, 2024
20b3d54
Merge pull request #175 from boostcampwm-2024/feature-fe-#5-chat_socket
spearStr Nov 21, 2024
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
5 changes: 3 additions & 2 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ export default tseslint.config({ ignores: ['.*'] }, js.configs.recommended, ...t
],
'react/react-in-jsx-scope': 'off',
eqeqeq: ['error', 'always'],
indent: ['error', 2],
indent: ['error', 2, { SwitchCase: 1 }],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'@typescript-eslint/no-unused-vars': ['error']
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/no-explicit-any': 'off'
},
settings: {
...reactRecommended.settings
Expand Down
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/pabicon.ico" />
Expand Down
5 changes: 4 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@
"msw:init": "msw init public/"
},
"dependencies": {
"@tanstack/react-query": "^5.59.20",
"@types/node": "^22.9.0",
"@vitejs/plugin-react": "^4.3.3",
"@tanstack/react-query": "^5.59.20",
"axios": "^1.7.7",
"eslint-plugin-react": "^7.37.2",
"framer-motion": "^11.11.17",
"hls.js": "^1.5.17",
"nanoid": "^5.0.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.2",
"react-router-dom": "^6.27.0",
"socket.io-client": "^4.8.1",
"styled-components": "^6.1.13",
"vite": "^5.4.10",
"vite-plugin-svgr": "^4.3.0",
Expand Down
17 changes: 11 additions & 6 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import { theme } from './styles/theme';
import { MainPage, ClientPage, HostPage } from './pages';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from '@apis/index';
import withUserId from '@hocs/withUserId';

function App() {
function AppComponent() {
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<Router future={{
v7_startTransition: true,
v7_relativeSplatPath: true
}}>
<Router
future={{
v7_startTransition: true,
v7_relativeSplatPath: true
}}
>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/live" element={<ClientPage />} />
Expand All @@ -26,4 +29,6 @@ function App() {
);
}

export default App;
const App = withUserId(AppComponent);

export default App;
5 changes: 1 addition & 4 deletions frontend/src/apis/fetchBroadcastStatus.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { getSessionKey } from '@utils/streamKey';
import { fetchInstance } from '.';

export type BroadcastStatusResponse = {
state: boolean;
};

export const fetchBroadcastStatus = async (): Promise<BroadcastStatusResponse> => {
const sessionKey = getSessionKey();

export const fetchBroadcastStatus = async (sessionKey: string): Promise<BroadcastStatusResponse> => {
const response = await fetchInstance().get<BroadcastStatusResponse>('/host/state', {
params: {
sessionKey
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/apis/fetchLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { ClientLive } from '@type/live';

type ClientLiveResponse = {
info: ClientLive;
};

export const fetchLive = async ({ liveId }: { liveId: string }): Promise<ClientLive> => {
const response: AxiosResponse<ClientLiveResponse> = await fetchInstance().get('/streams/live', {
params: {
liveId
}
});

return response.data.info;
};
13 changes: 13 additions & 0 deletions frontend/src/apis/fetchMainLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { MainLive } from '@type/live';

type MainLiveResponse = {
info: MainLive[];
};

export const fetchMainLive = async (): Promise<MainLive[]> => {
const response: AxiosResponse<MainLiveResponse> = await fetchInstance().get('/streams/random');

return response.data.info;
};
13 changes: 13 additions & 0 deletions frontend/src/apis/fetchRecentLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { RecentLive } from '@type/live';

type RecentLiveResponse = {
info: RecentLive[];
};

export const fetchRecentLive = async (): Promise<RecentLive[]> => {
const response: AxiosResponse<RecentLiveResponse> = await fetchInstance().get('/streams/latest');

return response.data.info;
};
12 changes: 12 additions & 0 deletions frontend/src/apis/queries/client/useFetchLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import { fetchLive } from '@apis/fetchLive';
import { ClientLive } from '@type/live';

export const useClientLive = ({ liveId }: { liveId: string }) => {
return useQuery<ClientLive, Error>({
queryKey: ['clientLive'],
queryFn: () => fetchLive({ liveId: liveId }),
refetchOnWindowFocus: false
});
};
6 changes: 3 additions & 3 deletions frontend/src/apis/queries/host/useBroadcastStatusPolling.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useQuery } from '@tanstack/react-query';
import { fetchBroadcastStatus } from '@apis/fetchBroadcastStatus';

export const useBroadcastStatusPolling = (pollingInterVal = 10000) => {
export const useBroadcastStatusPolling = (sessionKey: string, pollingInterVal = 10000) => {
return useQuery({
queryKey: ['broadcastState'],
queryFn: fetchBroadcastStatus,
queryKey: ['broadcastState', sessionKey],
queryFn: () => fetchBroadcastStatus(sessionKey),
refetchInterval: pollingInterVal,
refetchIntervalInBackground: true,
refetchOnWindowFocus: true,
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/apis/queries/host/useUpdateHost.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HostInfo, updateHost } from '@apis/updateHost';
import { updateHost } from '@apis/updateHost';
import { useMutation, UseMutationResult } from '@tanstack/react-query';
import { HostInfo } from '@type/hostInfo';

type Params = {
onSuccess?: (data: HostInfo) => void;
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/apis/queries/main/useFetchMainLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import { fetchMainLive } from '@apis/fetchMainLive';
import { MainLive } from '@type/live';

export const useMainLive = () => {
return useQuery<MainLive[], Error>({
queryKey: ['mainLive'],
queryFn: fetchMainLive,
refetchOnWindowFocus: false
});
};
12 changes: 12 additions & 0 deletions frontend/src/apis/queries/main/useFetchRecentLive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import { fetchRecentLive } from '@apis/fetchRecentLive';
import { RecentLive } from '@type/live';

export const useRecentLive = () => {
return useQuery<RecentLive[], Error>({
queryKey: ['recentLive'],
queryFn: fetchRecentLive,
refetchOnWindowFocus: false
});
};
9 changes: 1 addition & 8 deletions frontend/src/apis/updateHost.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';

export interface HostInfo {
userId: string;
liveTitle: string;
defaultThumbnailImageUrl: string;
category: string;
tags: string[];
}
import { HostInfo } from '@type/hostInfo';

export const updateHost = async (hostInfo: HostInfo): Promise<HostInfo> => {
const response: AxiosResponse<HostInfo> = await fetchInstance().post('/host/update', hostInfo);
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/assets/icons/speaker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed frontend/src/assets/logo.gif
Binary file not shown.
Binary file removed frontend/src/assets/player_loading.gif
Binary file not shown.
Binary file removed frontend/src/assets/sampleThumbnail.png
Binary file not shown.
Binary file added frontend/src/assets/sample_profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 38 additions & 2 deletions frontend/src/components/chat/ChatHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,56 @@
import styled from 'styled-components';
import ThreePointIcon from '@assets/icons/three-point.svg';
import OutIcon from '@assets/icons/out.svg';
import { useCallback, useContext, useEffect, useRef } from 'react';
import LayerPopup from './LayerPopup';
import { ChatContext } from 'src/contexts/chatContext';

interface ChatHeaderProps {
outBtnHandler?: () => void;
}

export const ChatHeader = ({ outBtnHandler }: ChatHeaderProps) => {
const { state, dispatch } = useContext(ChatContext);
const headerRef = useRef<HTMLDivElement>(null);

const toggleSettings = () => {
dispatch({ type: 'TOGGLE_SETTINGS' });
};

const handleClickOutside = useCallback(
(event: MouseEvent) => {
if (headerRef.current && !headerRef.current.contains(event.target as Node)) {
dispatch({ type: 'CLOSE_SETTINGS' });
}
},
[dispatch]
);

useEffect(() => {
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [handleClickOutside]);

return (
<ChatHeaderContainer>
<ChatHeaderContainer ref={headerRef}>
<HeaderBtn onClick={outBtnHandler}>
<StyledIcon as={OutIcon} />
</HeaderBtn>
<h2>์ฑ„ํŒ…</h2>
<HeaderBtn>
<HeaderBtn onClick={toggleSettings}>
<StyledIcon as={ThreePointIcon} />
</HeaderBtn>
<PopupWrapper>{state.isSettingsOpen && <LayerPopup />}</PopupWrapper>
</ChatHeaderContainer>
);
};

export default ChatHeader;

const ChatHeaderContainer = styled.div`
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
Expand All @@ -42,3 +71,10 @@ const StyledIcon = styled.svg`
height: 25px;
cursor: pointer;
`;

const PopupWrapper = styled.div`
position: absolute;
top: 60px;
right: 0;
z-index: 1000;
`;
Loading
Loading