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

Feature 074 #120

Merged
merged 12 commits into from
Feb 19, 2024
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="ko">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/assets/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vi.No</title>
<!-- Google Fonts -->
Expand Down
Binary file added public/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 22 additions & 2 deletions src/apis/videos.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { APIBaseResponse, APIResponse } from '@/models/config/axios';
import { ModelingFinalData } from '@/models/modeling';
import {
CreateVideoResponse,
IVideo,
UpdateVideoCategoryRequest,
UpdateVideoRequest,
Expand All @@ -13,8 +15,11 @@ import { IVideoProps } from 'types/videos';

const PREFIX = '/videos';

export const createVideoAPI = (data: IVideo) => {
return axios.post<APIResponse<IVideo>>(PREFIX + `/new-video`, data);
export const createVideoAPI = (data: ModelingFinalData) => {
return axios.post<APIResponse<CreateVideoResponse>>(
PREFIX + `/new-video`,
data,
);
};

export const getVideoAPI = (
Expand All @@ -24,6 +29,10 @@ export const getVideoAPI = (
return axios.get<APIResponse<IVideo>>(PREFIX + `/${videoId}/${versionId}`);
};

export const getDummyVideoAPI = (videoId: string | number) => {
return axios.get<APIResponse<IVideo>>(PREFIX + `/dummyVideos/${videoId}/get`);
};

export const deleteVideos = async (videos: number[] | undefined) => {
const response = await axiosInstance.delete('/videos/selectDelete', {
data: { videos },
Expand Down Expand Up @@ -76,6 +85,17 @@ export const getUnReadDummyVideosAPI = () => {
return axios.get<APIResponse<VideoResponse>>('/videos/dummyVideos/unRead');
};

export const getAllDummyVideosAPI = () => {
return axios.get<APIResponse<VideoResponse>>('/videos/dummyVideos');
};

export const getUnReadDummyVideos = async (): Promise<
APIResponse<Record<'videos', IVideoProps[]>>
> => {
const response = await axiosInstance.get('/videos/dummyVideos/unRead');
return response.data;
};

export const getAllDummyVideos = async (): Promise<
APIResponse<Record<'videos', IVideoProps[]>>
> => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Home/InsightVideos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const InsightVideos: React.FC<InsightVideosProps> = ({
}, [userToken]);

return (
<InsightVideosContainer user={userToken}>
<InsightVideosContainer>
<div className="insight-container">
<div className="text-container">
<h2 className="insight-title">이런 인사이트는 어때요?</h2>
Expand All @@ -66,7 +66,7 @@ const InsightVideos: React.FC<InsightVideosProps> = ({
<CardContainer>
{dummyVideos.map((video) => (
<Card
mode={userToken ? 'recommend' : 'default'}
mode="recommend"
video={video}
checkedVideos={checkedItems}
setCheckedVideos={setCheckedItems}
Expand Down
9 changes: 5 additions & 4 deletions src/components/Home/RecentVideos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import { IVideoProps } from 'types/videos';

interface IRecentVideosProp {
videos: IVideoProps[];
searchRef: React.RefObject<HTMLInputElement>;
}

const RecentVideos = ({ videos, searchRef }: IRecentVideosProp) => {
const RecentVideos = ({ videos }: IRecentVideosProp) => {
return (
<RecentVideosContainer length={videos.length}>
<RecentVideosContainer>
<div className="container">
<div className="title-container">
<VideosTitle>최근 읽은 영상</VideosTitle>
Expand All @@ -37,7 +36,9 @@ const RecentVideos = ({ videos, searchRef }: IRecentVideosProp) => {
<VideosSubtitle>
처음 방문하셨나요? <br /> 아직 정리해본 영상이 없어요!
</VideosSubtitle>
<VideoButton onClick={() => searchRef?.current?.focus()}>
<VideoButton
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
>
<h2 className="button-text">영상 정리해보기</h2>
</VideoButton>
</div>
Expand Down
8 changes: 2 additions & 6 deletions src/components/Home/SearchYoutube.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ import { validateYoutubeLink } from '@/utils/validation';

import ProgressBar from './ProgressBar';

type Props = {
searchRef: React.RefObject<HTMLInputElement>;
};

const SearchYoutube = ({ searchRef }: Props) => {
const SearchYoutube = () => {
const navigate = useNavigate();

const userToken = useRecoilValue(userTokenState);
Expand Down Expand Up @@ -96,6 +92,7 @@ const SearchYoutube = ({ searchRef }: Props) => {
setVideoLink(null);
setStatus('NONE');
setProgress(0);
setModelingData(null);
};

const handleClickCreateVideoButton = async () => {
Expand Down Expand Up @@ -156,7 +153,6 @@ const SearchYoutube = ({ searchRef }: Props) => {
</div>

<SearchInput
ref={searchRef}
type="text"
value={inputLink}
disabled={status === 'CONTINUE'}
Expand Down
113 changes: 71 additions & 42 deletions src/components/SearchPage/SearchResultBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,77 @@ import { userInfoState } from '@/stores/user';
import { useRecoilValue } from 'recoil';

interface SearchResultProp {
video : IVideo;
tags : string[];
video: IVideo;
tags: string[];
}

const SearchResultBox : React.FC<SearchResultProp>= ({video, tags}) => {
const nav = useNavigate();
const userName = useRecoilValue(userInfoState);
const date = video.created_at.toString().split('T')[0].split('-');
const handleImg = (event : React.SyntheticEvent<HTMLImageElement, Event>) => {
const target = event.target as HTMLImageElement;
target.style.display = 'none';
}
const handleOnclick = () => {
nav(`/summary/${video.video_id}?insight=${userName?.name === video.user}`);
}

return (
<Styled.VideoCard style={{width : '910px', height : '254px'}} onClick={handleOnclick}>
<div className="main" style={{width : '670px', height : '254px'}}>
<div className="user" style={{width : '114px', height : '20px'}}>
<span className="userName" style={{ height : '19px'}}>{video.user}</span>
<span className='contour' style={{width : '0px', height : '12px'}}></span>
<span className="userDate" style={{height :'19px'}}>
{`${date[0]}년 ${date[1]}월 ${date[2]}일`}
</span>
</div>
<div className="content" style={{width : '648px', height : '108px'}}>
<div className="title" style={{width : '648px', height : '26px'}} dangerouslySetInnerHTML={{__html : video.title}}></div>
<div className="subtitle" style={{width : '648px', height : '22px'}} dangerouslySetInnerHTML={{__html : video.description}}></div>
<div className="subcontent" style={{width : '648px' , height : '44px'}} dangerouslySetInnerHTML={{__html : video.content}}></div>
</div>
<div className='hashtag' style={{maxWidth : '648px',height : '31px'}}>
{video.tag.map((item, index) =>
<Styled.hashtagBox key = {index} style={{backgroundColor : tags.includes(`#${item.name}`) ? '#E9FF3F':''}}>{item.name}</Styled.hashtagBox>
)}
</div>
</div>
<div className="imgBox">
<img src={video.image} onError={(event) => handleImg(event)}></img>
</div>
</Styled.VideoCard>
);
}
const SearchResultBox: React.FC<SearchResultProp> = ({ video, tags }) => {
const nav = useNavigate();
const userName = useRecoilValue(userInfoState);
const date = video.created_at.toString().split('T')[0].split('-');
const handleImg = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
const target = event.target as HTMLImageElement;
target.style.display = 'none';
};
const handleOnclick = () => {
nav(`/summary/${video.video_id}?insight=${userName?.name === video.user}`);
};

return (
<Styled.VideoCard
style={{ width: '910px', height: '254px' }}
onClick={handleOnclick}
>
<div className="main" style={{ width: '670px', height: '254px' }}>
<div className="user" style={{ width: '114px', height: '20px' }}>
<span className="userName" style={{ height: '19px' }}>
{video.user}
</span>
<span
className="contour"
style={{ width: '0px', height: '12px' }}
></span>
<span className="userDate" style={{ height: '19px' }}>
{`${date[0]}년 ${date[1]}월 ${date[2]}일`}
</span>
</div>
<div className="content" style={{ width: '648px', height: '108px' }}>
<div
className="title"
style={{ width: '648px', height: '26px' }}
dangerouslySetInnerHTML={{ __html: video.title }}
></div>
<div
className="subtitle"
style={{ width: '648px', height: '22px' }}
dangerouslySetInnerHTML={{ __html: video.description }}
></div>
<div
className="subcontent"
style={{ width: '648px', height: '44px' }}
dangerouslySetInnerHTML={{ __html: video.content }}
></div>
</div>
<div className="hashtag" style={{ maxWidth: '648px', height: '31px' }}>
{video.tag.map((item, index) => (
<Styled.hashtagBox
key={index}
style={{
backgroundColor: tags.includes(`#${item.name}`)
? '#E9FF3F'
: '',
}}
>
# {item.name}
</Styled.hashtagBox>
))}
</div>
</div>
<div className="imgBox">
<img src={video.image} onError={(event) => handleImg(event)}></img>
</div>
</Styled.VideoCard>
);
};

export default SearchResultBox;
export default SearchResultBox;
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@ import { userTokenState } from '@/stores/user';
import { CategoryDropdown } from './CategoryDropdown';

type Props = {
size?: 'SMALL' | 'LARGE';
disabled?: boolean;
selectedCategoryId?: number;
startSelect?: boolean;
setStartSelect?: React.Dispatch<React.SetStateAction<boolean>>;
onSelect: (categoryId: number, categoryName?: string) => void;
};

const CategorySelectBox = ({
size,
disabled,
selectedCategoryId,
startSelect,
setStartSelect,
onSelect,
}: Props) => {
const userToken = useRecoilValue(userTokenState);
Expand Down Expand Up @@ -59,17 +57,11 @@ const CategorySelectBox = ({

const handleSelect = (categoryId: number) => {
setSelectedId(categoryId);
setStartSelect && setStartSelect(true);
setIsOpen(false);
};

const handleClick = () => {
if (
!selectedCategory ||
selectedId === selectedCategoryId ||
disabled ||
!startSelect
)
if (!selectedCategory || selectedId === selectedCategoryId || disabled)
return;

onSelect(selectedCategory.categoryId, selectedCategory.name);
Expand All @@ -92,7 +84,9 @@ const CategorySelectBox = ({
{userToken
? selectedCategory
? selectedCategory.name
: '어떤 카테고리에 넣을까요?'
: size === 'SMALL'
? '카테고리 선택'
: '어떤 카테고리에 넣을까요?'
: '로그인하고 요약한 영상을 아카이빙해요!'}
</span>

Expand All @@ -105,9 +99,9 @@ const CategorySelectBox = ({
</div>

<span
className={`icon-button ${startSelect && 'start-select'} ${
(!userToken || disabled) && 'disabled'
} ${selectedCategoryId !== selectedId ? 'changed' : ''}`}
className={`icon-button ${(!userToken || disabled) && 'disabled'} ${
selectedCategoryId !== selectedId ? 'changed' : ''
}`}
onClick={handleClick}
>
<OpenFileIcon width={28} height={28} />
Expand Down
12 changes: 8 additions & 4 deletions src/components/SummaryPage/SummaryDetailBox/SummaryDetailBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {
}
};

useEffect(() => {
return () => {
setSummaryVideoTime(0);
setPlaySubHeadingId(-1);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (player.current) return;

Expand All @@ -98,10 +106,6 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {

window.onmessage = handleMessage;

return () => {
setSummaryVideoTime(0);
setPlaySubHeadingId(-1);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [summaryVideo]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const ScriptViewer = ({ keyword }: Props) => {
return (
<div className="script-container">
{scriptList.map((script) => (
<div key={script.id}>
<div key={script.id} className="script-box">
<div
style={{
display: 'flex',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ const SummaryScriptBox = ({ onRefresh }: Props) => {
<ScriptBox style={{ width }}>
<ToolBox onRefresh={onRefresh} onChangeKeyword={handleChangeKeyword} />

<div ref={ref} style={{ height: 'calc(100% - 78px)', overflowY: 'auto' }}>
<div
ref={ref}
id="script-box"
style={{ height: 'calc(100% - 78px)', overflowY: 'auto' }}
>
{isEditingView ? <ScriptEditor /> : <ScriptViewer keyword={keyword} />}
</div>

Expand Down
Loading
Loading