Skip to content

Commit

Permalink
Merge pull request #67 from teamViNO/feature-064
Browse files Browse the repository at this point in the history
feature-064: 카드 컴포넌트 공통 컴포넌트로 구현
  • Loading branch information
whistleJs authored Feb 13, 2024
2 parents 8241e80 + 0d910bb commit 8b4bc62
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 159 deletions.
22 changes: 17 additions & 5 deletions src/components/Home/InsightVideos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { InsightVideosContainer } from '@/styles/HomepageStyle';
import Card from '../category/Card';
import { IVideoProps } from 'types/videos';
import { CardContainer } from '@/styles/category/Card.style';

interface InsightVideosProps {
username: string;
Expand All @@ -16,6 +17,11 @@ const InsightVideos: React.FC<InsightVideosProps> = ({
const [categoryItems] = useState<IVideoProps[]>([]);
const [checkedItems, setCheckedItems] = useState<number[]>([]);

const onFileClick = (e: React.MouseEvent<HTMLSpanElement>) => {
e.stopPropagation();
// 비디오 카테고리로 저장 API 호출 후 이런 인사이트는 어때요 API 재호출로 최신화하기
};

return (
<InsightVideosContainer>
<div className="insight-container">
Expand All @@ -27,11 +33,17 @@ const InsightVideos: React.FC<InsightVideosProps> = ({
</h4>
</div>
<div className="insight-videos">
<Card
videos={categoryItems}
checkedVideos={checkedItems}
setCheckedVideos={setCheckedItems}
/>
<CardContainer>
{categoryItems.map((video) => (
<Card
mode="recommend"
video={video}
checkedVideos={checkedItems}
setCheckedVideos={setCheckedItems}
onFileClick={onFileClick}
/>
))}
</CardContainer>
</div>
</div>
</InsightVideosContainer>
Expand Down
55 changes: 35 additions & 20 deletions src/components/Home/RecentVideos.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
import React from 'react'
import { RecentVideosContainer, VideoButton, VideosSubtitle, VideosTitle } from '@/styles/HomepageStyle';
// import Card from '../category/Card';
import {
RecentVideosContainer,
VideoButton,
VideosSubtitle,
VideosTitle,
} from '@/styles/HomepageStyle';
import CardImage from '@/assets/empty-video.png';
const RecentVideos: React.FC = () => {
import { CardContainer } from '@/styles/category/Card.style';
import Card from '../category/Card';
import { IVideoProps } from 'types/videos';

interface IRecentVideosProp {
videos: IVideoProps[];
}

const RecentVideos = ({ videos }: IRecentVideosProp) => {
return (
<RecentVideosContainer>
<div className="container">
<VideosTitle>최근 읽은 영상</VideosTitle>

{/* 영상 개수 0개일 때 */}
<>
<div className="empty-video">
<img src={CardImage} alt="비어있는 비디오 이미지" />
</div>
<VideosSubtitle>
처음 방문하셨나요? <br /> 아직 정리해본 영상이 없어요!
</VideosSubtitle>
<VideoButton>
<h2 className="button-text">영상 정리해보기</h2>
</VideoButton>
</>

{/* 영상 개수 3개 이하일 때 */}

{/* 영상 개수 4개 이상일 때 '더보기 버튼' 활성화 & 전체 카드 모두 보여짐 */}
{videos.length === 0 && (
<>
<div className="empty-video">
<img src={CardImage} alt="비어있는 비디오 이미지" />
</div>
<VideosSubtitle>
처음 방문하셨나요? <br /> 아직 정리해본 영상이 없어요!
</VideosSubtitle>
<VideoButton>
<h2 className="button-text">영상 정리해보기</h2>
</VideoButton>
</>
)}
{videos.length > 0 && (
<CardContainer>
{videos.map((video) => (
<Card mode="default" video={video} />
))}
</CardContainer>
)}
</div>
</RecentVideosContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { ISelectedCategoryProps } from 'types/category';
interface ICategorySelectBoxProps {
selectedCategory: ISelectedCategoryProps;
handleSelectCategory: ({ name, categoryId }: ISelectedCategoryProps) => void;
onFileClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;
}

const CategorySelectBox = ({
selectedCategory,
handleSelectCategory,
onFileClick,
}: ICategorySelectBoxProps) => {
const [isLogin] = useState(true);
const [isOpen, setIsOpen] = useState(false);
Expand Down Expand Up @@ -57,6 +59,7 @@ const CategorySelectBox = ({
className={`icon-button ${!isLogin && 'disabled'} ${
selectedCategory.name ? 'selected' : 'not-selected'
}`}
onClick={onFileClick}
>
<OpenFileIcon width={28} height={28} />
</span>
Expand Down
117 changes: 69 additions & 48 deletions src/components/category/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,89 @@
import React, { useEffect } from 'react';
import React, { useState } from 'react';
import * as CardStyles from '@/styles/category/Card.style';
import VideoTag from '../common/videoTag';
import { IVideoProps } from 'types/videos';
import { CategorySelectBox } from '../SummaryPage/SummaryDetailBox/CategorySelectBox';
import { ISelectedCategoryProps } from 'types/category';
import { useRecoilValue } from 'recoil';
import { categoryState } from '@/stores/category';

interface ICardProps {
videos: IVideoProps[];
checkedVideos: number[];
setCheckedVideos: (value: number[]) => void;
mode: 'default' | 'category' | 'recommend';
video: IVideoProps;
checkedVideos?: number[];
setCheckedVideos?: (value: number[]) => void;
onFileClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;
}

const Card: React.FC<ICardProps> = ({
videos,
mode = 'default',
video,
checkedVideos,
setCheckedVideos,
onFileClick,
}) => {
useEffect(() => {}, [checkedVideos]);
const [isOpen, setIsOpen] = useState(false);
const category = useRecoilValue(categoryState);
const [selectedCategory, setSelectedCategory] =
useState<ISelectedCategoryProps>({
name: category[0].name,
categoryId: category[0].categoryId,
});

const handleSelectCategory = ({
name,
categoryId,
}: ISelectedCategoryProps) => {
setSelectedCategory({
name,
categoryId,
});
};

const handleCheckBox = (videoId: number) => {
if (checkedVideos.includes(videoId)) {
setCheckedVideos(checkedVideos.filter((id) => id !== videoId));
if (checkedVideos!.includes(videoId)) {
setCheckedVideos!(checkedVideos!.filter((id) => id !== videoId));
} else {
setCheckedVideos([...checkedVideos, videoId]);
setCheckedVideos!([...checkedVideos!, videoId]);
}
};
return (
<CardStyles.Container>
{videos.map((video) => (
<CardStyles.Wrap key={`${video.title}-wrap`}>
<CardStyles.Image source={video.image}>
<CardStyles.CheckBoxWrap
className={checkedVideos.length > 0 ? 'activated' : ''}
>
<CardStyles.CheckBox
type="checkbox"
checked={checkedVideos.includes(video.video_id)}
onChange={() => handleCheckBox(video.video_id)}
/>
</CardStyles.CheckBoxWrap>
</CardStyles.Image>

<CardStyles.Content
to={`/summary/${video.video_id}`}
key={`${video.title}-card-content`}
<CardStyles.Wrap
onMouseEnter={() => setIsOpen(true)}
onMouseLeave={() => setIsOpen(false)}
>
<CardStyles.Image source={video.image}>
{mode === 'category' && (
<CardStyles.CheckBoxWrap
className={checkedVideos!.length > 0 ? 'activated' : ''}
>
<CardStyles.Title key={`${video.title}`}>
{video.title}
</CardStyles.Title>
<CardStyles.Summary key={`${video.description}`}>
{video.description}
</CardStyles.Summary>
<CardStyles.ChipWrap key={`${video.title}-chip-wrap`}>
{video.tag.map((tag) => (
<VideoTag
content={`# ${tag.name}`}
color={'gray400'}
typography="Caption1"
key={`${video.title}-${tag.name}`}
/>
))}
</CardStyles.ChipWrap>
</CardStyles.Content>
</CardStyles.Wrap>
))}
</CardStyles.Container>
<CardStyles.CheckBox
type="checkbox"
checked={checkedVideos!.includes(video.video_id)}
onChange={() => handleCheckBox(video.video_id)}
/>
</CardStyles.CheckBoxWrap>
)}
</CardStyles.Image>

<CardStyles.Content to={`/summary/${video.video_id}`}>
<CardStyles.Title>{video.title}</CardStyles.Title>
<CardStyles.Summary>{video.description}</CardStyles.Summary>
<CardStyles.ChipWrap>
{video.tag.map((tag) => (
<CardStyles.Chip key={tag.name}>{`# ${tag.name}`}</CardStyles.Chip>
))}
</CardStyles.ChipWrap>
</CardStyles.Content>
{isOpen && mode === 'recommend' && (
<CardStyles.DropdownWrap>
<CategorySelectBox
selectedCategory={selectedCategory}
handleSelectCategory={handleSelectCategory}
onFileClick={onFileClick}
/>
</CardStyles.DropdownWrap>
)}
</CardStyles.Wrap>
);
};

Expand Down
17 changes: 0 additions & 17 deletions src/components/common/videoTag/VideoTag.style.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/components/common/videoTag/index.tsx

This file was deleted.

17 changes: 12 additions & 5 deletions src/pages/CategoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import EmptyCard from '@/components/category/EmptyCard';
import { deleteVideos, getRecentVideos, getVideoById } from '@/apis/videos';
import { IVideoProps } from 'types/videos';
import { sortVideos } from '@/utils/sortVideos';
import { CardContainer } from '@/styles/category/Card.style';

const CategoryPage = () => {
const params = useParams();
Expand Down Expand Up @@ -151,11 +152,17 @@ const CategoryPage = () => {
<EmptyCard />
)}
{sortedVideos.length > 0 && (
<Card
videos={sortedVideos}
checkedVideos={checkedVideos}
setCheckedVideos={setCheckedVideos}
/>
<CardContainer>
{sortedVideos.map((video) => (
<Card
mode="category"
video={video}
checkedVideos={checkedVideos}
setCheckedVideos={setCheckedVideos}
key={video.category_id}
/>
))}
</CardContainer>
)}
</CategoryPageStyles.Container>
);
Expand Down
15 changes: 8 additions & 7 deletions src/pages/GuestPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import SearchYoutube from '@/components/Home/SearchYoutube';
import {
HomePageContainer
} from '@/styles/HomepageStyle';
import { HomePageContainer } from '@/styles/HomepageStyle';
import RecentVideos from '@/components/Home/RecentVideos';
import InsightVideos from '@/components/Home/InsightVideos';

Expand All @@ -11,7 +9,7 @@ export interface Video {
title: string;
subtitle: string;
hashtags: string[];
thumbnailUrl: string;
thumbnailUrl: string;
}

const GuestPage: React.FC = () => {
Expand All @@ -22,10 +20,13 @@ const GuestPage: React.FC = () => {
return (
<HomePageContainer>
<SearchYoutube onSearch={handleSearch} />
<InsightVideos username="여울" popularHashtags={['디자인', '진로', '브랜딩']} />
<RecentVideos />
<InsightVideos
username="여울"
popularHashtags={['디자인', '진로', '브랜딩']}
/>
<RecentVideos videos={[]} />
</HomePageContainer>
);
};

export default GuestPage;
export default GuestPage;
Loading

0 comments on commit 8b4bc62

Please sign in to comment.