Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 에러페이지 적용 #256

Merged
merged 13 commits into from
Dec 2, 2024
7 changes: 2 additions & 5 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import { theme } from './styles/theme';
import { MainPage, ClientPage, HostPage } from './pages';
import { ClientPage, ErrorPage, HostPage, MainPage, ReplayPage } from './pages';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from '@apis/index';
import withUserId from '@hocs/withUserId';
import ReplayPage from '@pages/ReplayPage';

function AppComponent() {
return (
Expand All @@ -19,12 +18,10 @@ function AppComponent() {
>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/live" element={<ClientPage />} />
<Route path="/live/:id" element={<ClientPage />} />
<Route path="/replay" element={<ReplayPage />} />
<Route path="/replay/:id" element={<ReplayPage />} />
<Route path="/host" element={<HostPage />} />
<Route path="/host/:id" element={<HostPage />} />
<Route path="*" element={<ErrorPage />} />
</Routes>
</Router>
</ThemeProvider>
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/apis/checkLiveExist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { LiveExistenceResponse } from '@type/live';

export const checkLiveExist = async ({ liveId }: { liveId: string }): Promise<LiveExistenceResponse> => {
const response: AxiosResponse<LiveExistenceResponse> = await fetchInstance().get('/streams/existence', {
params: {
sessionKey: liveId
}
});

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

export const checkReplayExist = async ({ videoId }: { videoId: string }): Promise<ReplayExistenceResponse> => {
const response: AxiosResponse<ReplayExistenceResponse> = await fetchInstance().get('/replay/existence', {
params: {
videoId
}
});

return response.data;
};
25 changes: 13 additions & 12 deletions frontend/src/apis/fetchLive.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { ClientLive } from '@type/live';
import { ClientLiveResponse } 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
export const fetchLive = async ({ liveId }: { liveId: string }): Promise<ClientLiveResponse> => {
try {
const response: AxiosResponse = await fetchInstance().get('/streams/live', {
params: { liveId }
});
return response.data;
} catch (error: any) {
if (error.response && error.response.status === 400) {
console.log('error', error);
throw error;
}
});

return response.data.info;
throw error;
}
};
27 changes: 15 additions & 12 deletions frontend/src/apis/fetchReplay.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { AxiosResponse } from 'axios';
import { fetchInstance } from '.';
import { ReplayStream } from '@type/replay';
import { ClientReplayResponse } from '@type/replay';

type ReplayStreamResponse = {
info: ReplayStream;
};

export const fetchReplay = async ({ videoId }: { videoId: string }): Promise<ReplayStream> => {
const response: AxiosResponse<ReplayStreamResponse> = await fetchInstance().get('/replay/video', {
params: {
videoId
export const fetchReplay = async ({ videoId }: { videoId: string }): Promise<ClientReplayResponse> => {
try {
const response: AxiosResponse = await fetchInstance().get('/replay/video', {
params: {
videoId
}
});
return response.data;
} catch (error: any) {
if (error.response && error.response.status === 400) {
console.log('error', error);
throw error;
}
});

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

import { checkLiveExist } from '@apis/checkLiveExist';
import { LiveExistenceResponse } from '@type/live';

export const useCheckLiveExist = ({ liveId }: { liveId: string }) => {
return useQuery<LiveExistenceResponse, Error>({
queryKey: ['checkLiveExist'],
queryFn: () => checkLiveExist({ liveId }),
refetchOnWindowFocus: false,
initialData: { existed: true }
});
};
12 changes: 7 additions & 5 deletions frontend/src/apis/queries/client/useFetchLive.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useQuery } from '@tanstack/react-query';

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

export const useClientLive = ({ liveId }: { liveId: string }) => {
return useQuery<ClientLive, Error>({
return useQuery<ClientLiveResponse, Error>({
queryKey: ['clientLive'],
queryFn: () => fetchLive({ liveId: liveId }),
refetchOnWindowFocus: false
queryFn: () => fetchLive({ liveId }),
refetchOnWindowFocus: false,
initialData: { info: {} as ClientLive },
throwOnError: true,
retry: 0,
});
};
13 changes: 13 additions & 0 deletions frontend/src/apis/queries/replay/useCheckReplayExist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useQuery } from '@tanstack/react-query';

import { checkReplayExist } from '@apis/checkReplayExist';
import { ReplayExistenceResponse } from '@type/replay';

export const useCheckReplayExist = ({ videoId }: { videoId: string }) => {
return useQuery<ReplayExistenceResponse, Error>({
queryKey: ['checkReplayExist'],
queryFn: () => checkReplayExist({ videoId }),
refetchOnWindowFocus: false,
initialData: { existed: true }
});
};
11 changes: 7 additions & 4 deletions frontend/src/apis/queries/replay/useFetchReplay.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { useQuery } from '@tanstack/react-query';

import { fetchReplay } from '@apis/fetchReplay';
import { ReplayStream } from '@type/replay';
import { ClientReplayResponse, ReplayStream } from '@type/replay';

export const useClientReplay = ({ videoId }: { videoId: string }) => {
return useQuery<ReplayStream, Error>({
return useQuery<ClientReplayResponse, Error>({
queryKey: ['clientReplay'],
queryFn: () => fetchReplay({ videoId: videoId }),
refetchOnWindowFocus: false
queryFn: () => fetchReplay({ videoId }),
refetchOnWindowFocus: false,
initialData: { info: {} as ReplayStream },
throwOnError: true,
retry: 0
});
};
1 change: 1 addition & 0 deletions frontend/src/assets/icons/warning_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 0 additions & 30 deletions frontend/src/components/client/Chat.tsx

This file was deleted.

13 changes: 7 additions & 6 deletions frontend/src/components/client/ClientView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ import PlayerInfo from './PlayerInfo';
import Footer from '@common/Footer';
import Header from '@common/Header';
import { useClientLive } from '@queries/client/useFetchLive';
import { getLiveURL } from '@utils/getVideoURL';

const ClientView = () => {
const { id: liveId } = useParams();
const { data: clientLiveData } = useClientLive({ liveId: liveId as string });
const { data: clientLiveData } = useClientLive({
liveId: liveId as string
});

if (!clientLiveData) {
return <div>로딩 중...</div>;
}
const { info } = clientLiveData;

return (
<ClientViewContainer>
<Header />
<h1 className="hidden">클라이언트 페이지</h1>
<Player videoUrl={clientLiveData.streamUrl} />
<PlayerInfo clientLiveData={clientLiveData} />
<Player videoUrl={getLiveURL(liveId as string)} />
<PlayerInfo clientLiveData={info} />
<Footer />
</ClientViewContainer>
);
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/client/PlayerInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ASSETS } from '@constants/assets';
import styled from 'styled-components';

import ElapsedTime from './ElapsedTime';
import sampleProfile from '@assets/sample_profile.png';
import ShowInfoBadge from '@common/ShowInfoBadge';
import { ASSETS } from '@constants/assets';
import { ClientLive } from '@type/live';

const PlayerInfo = ({ clientLiveData }: { clientLiveData: ClientLive }) => {
Expand All @@ -20,10 +20,10 @@ const PlayerInfo = ({ clientLiveData }: { clientLiveData: ClientLive }) => {
<LiveBox>LIVE</LiveBox>
</HostProfileBox>
<VideoInfo>
<VideoUploader>{channel.channelName}</VideoUploader>
<VideoUploader>{channel?.channelName}</VideoUploader>
<Category>{category}</Category>
<TagBox>
{tags.map((tag, index) => (
{tags?.map((tag, index) => (
<ShowInfoBadge key={index} badgeType="tag" text={tag} />
))}
</TagBox>
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { default as Header } from '@common/Header';
export { default as ClientView } from './ClientView';
export { default as Chat } from './Chat';
3 changes: 1 addition & 2 deletions frontend/src/components/common/AsyncBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ export const AsyncBoundary = forwardRef<any, AsyncBoundaryProps>(
reset: () => setError(null)
}));

const handleError = (error: Error, errorInfo: React.ErrorInfo) => {
const handleError = (error: Error) => {
setError(error);
console.error('ErrorBoundary caught an error', error, errorInfo);
};

return (
Expand Down
55 changes: 0 additions & 55 deletions frontend/src/components/common/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import styled from 'styled-components';
import { useNavigate } from 'react-router-dom';

import SearchIcon from '@assets/icons/search_icon.svg';
import VideoIcon from '@assets/icons/video_icon.svg';
import { ASSETS } from '@constants/assets';

Expand All @@ -13,13 +12,6 @@ const Header = () => {
<LogoContainer onClick={() => navigate('/')}>
<img src={ASSETS.IMAGES.LOGO.GIF} alt="로고" />
</LogoContainer>
<SearchBox>
<SearchInputWrapper>
<SearchInput type="text" placeholder="컨퍼런스, 태그 검색" />
<SearchIconStyled />
</SearchInputWrapper>
<SearchButton />
</SearchBox>
<StudioBox onClick={() => navigate('/host')}>
<VideoIconStyled />
스튜디오
Expand Down Expand Up @@ -55,53 +47,6 @@ const LogoContainer = styled.div`
}
`;

const SearchBox = styled.div`
display: flex;
align-items: center;
width: 400px;
`;

const SearchInputWrapper = styled.div`
position: relative;
width: 100%;
`;

const SearchInput = styled.input`
width: 100%;
height: 100%;
padding: 10px 40px 10px 20px;
border: 1px solid ${({ theme }) => theme.colorMap.gray[900]};
border-radius: 20px;
color: ${({ theme }) => theme.tokenColors['text-strong']};
background-color: ${({ theme }) => theme.tokenColors['surface-default']};
${({ theme }) => theme.tokenTypographys['display-medium16']};

&:focus {
border-color: ${({ theme }) => theme.tokenColors['brand-default']};
outline: none;
}
`;

const SearchIconStyled = styled(SearchIcon)`
position: absolute;
top: 50%;
right: -50px;
transform: translateY(-50%);
width: 24px;
height: 24px;
cursor: pointer;
`;

const SearchButton = styled.button`
background: ${({ theme }) => theme.tokenColors['primary-default']};
color: ${({ theme }) => theme.tokenColors['color-white']};
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
margin-left: 10px;
`;

const StudioBox = styled.div`
display: flex;
align-items: center;
Expand Down
Loading
Loading