Skip to content

Commit

Permalink
Merge branch 'dev' into feature-031
Browse files Browse the repository at this point in the history
  • Loading branch information
jina4066 committed Feb 14, 2024
2 parents b1c78d3 + a8478c1 commit beba1d9
Show file tree
Hide file tree
Showing 27 changed files with 496 additions and 281 deletions.
21 changes: 19 additions & 2 deletions src/apis/videos.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIResponse } from '@/models/config/axios';
import { IVideo, VideoVersionType } from '@/models/video';
import { APIBaseResponse, APIResponse } from '@/models/config/axios';
import { IVideo, UpdateVideoRequest, VideoVersionType } from '@/models/video';

import axios from './config/instance';
import axiosInstance from './config/instance';
Expand Down Expand Up @@ -34,3 +34,20 @@ export const getVideoById = async (
const response = await axiosInstance.get(`/videos/${videoId}`);
return response.data;
};

export const updateVideoAPI = (
videoId: string | number,
data: UpdateVideoRequest,
) => {
return axios.patch<APIResponse<IVideo>>(PREFIX + `/${videoId}`, data);
};

export const createVideoSummaryAPI = (videoId: number, content: string[]) => {
return axios.post<APIBaseResponse>(PREFIX + `/${videoId}/newSummary`, {
content,
});
};

export const deleteVideoSummaryAPI = (summaryId: number) => {
return axios.delete<APIBaseResponse>(PREFIX + `/${summaryId}/deleteSummary`);
};
Binary file added src/assets/kakao-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 18 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, useEffect, useCallback, useRef } from 'react';
import { InsightVideosContainer } from '@/styles/HomepageStyle';
import Card from '../category/Card';
import { IVideoProps } from 'types/videos';
import { CardContainer } from '@/styles/category/Card.style';
import successImg from '@/assets/success.png';

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

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

const timerId = useRef<NodeJS.Timeout | null>(null);
Expand Down Expand Up @@ -63,11 +69,18 @@ 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}
key={video.category_id}
/>
))}
</CardContainer>
</div>
{isEndOfPage &&
<div className='end-message'>
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 key={video.category_id} mode="default" video={video} />
))}
</CardContainer>
)}
</div>
</RecentVideosContainer>
);
Expand Down
29 changes: 24 additions & 5 deletions src/components/ProfilePage/Account/Account.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { AxiosError } from 'axios';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useRecoilState } from 'recoil';

import { getMyInfoAPI, updateMyInfoAPI } from '@/apis/user';

import NaverIconImage from '@/assets/naver-icon.png';
import KakaoIconImage from '@/assets/kakao-icon.png';

import { Tooltip } from '@/components/common';

import { GENDER_TYPE_LIST } from '@/constants/user';

import useFocus from '@/hooks/useFocus';

import { APIBaseResponse } from '@/models/config/axios';

import { userInfoState } from '@/stores/user';

import theme from '@/styles/theme';
Expand Down Expand Up @@ -46,7 +50,7 @@ const Account = () => {

const nicknameInputStyle = {
border: `1.5px solid ${
isErrorNickname
isErrorNickname || isDuplicateNickname
? theme.color.red
: isNicknameFocus
? theme.color.gray500
Expand Down Expand Up @@ -98,8 +102,14 @@ const Account = () => {
showTooltip();
refreshMyInfo();
}
} catch (e) {
console.error(e);
} catch (error) {
if (error instanceof AxiosError) {
const { code } = error.response?.data as APIBaseResponse;

if (code === 'DUPLICATE_NICKNAME') {
setIsDuplicateNickname(true);
}
}
}
};

Expand Down Expand Up @@ -227,7 +237,9 @@ const Account = () => {
<div className="account-group">
<span className="group-title">전화번호</span>

<div className="input-box disabled">{userInfo?.phone_number}</div>
<div className="input-box disabled">
{userInfo?.phone_number || '-'}
</div>
</div>

{isSocialAccount && (
Expand All @@ -238,7 +250,14 @@ const Account = () => {
className="input-box disabled"
style={{ display: 'flex', alignItems: 'center', gap: 10 }}
>
<img src={NaverIconImage} width={40} />
<img
src={
userInfo.platform === 'kakao'
? KakaoIconImage
: NaverIconImage
}
width={40}
/>

<span>{userInfo?.email}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import { useRecoilValue } from 'recoil';

import { Dropdown } from '@/styles/SummaryPage';

import DropdownItem from './DropdownItem';
import { useRecoilValue } from 'recoil';
import { categoryState } from '@/stores/category';
import React from 'react';
import { ISelectedCategoryProps } from 'types/category';

interface ICategoryDropdownProp {
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
handleSelectCategory: ({ name, categoryId }: ISelectedCategoryProps) => void;
}
import DropdownItem from './DropdownItem';

type Props = {
onSelect: (categoryId: number) => void;
};

const CategoryDropdown = ({
setIsOpen,
handleSelectCategory,
}: ICategoryDropdownProp) => {
const CategoryDropdown = ({ onSelect }: Props) => {
const categories = useRecoilValue(categoryState);

return (
<Dropdown onClick={(e) => e.stopPropagation()}>
<ul>
{categories.map((category) => (
<DropdownItem
key={category.categoryId}
category={category}
setIsOpen={setIsOpen}
handleSelectCategory={handleSelectCategory}
onSelect={onSelect}
/>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import { useState } from 'react';
import { IFolderProps } from 'types/category';

import DownIcon from '@/assets/icons/down.svg?react';
import { IFolderProps, ISelectedCategoryProps } from 'types/category';

import { DropdownTopCategoryName } from '@/styles/SummaryPage';

interface ICategoryDropdownProp {
type Props = {
category: IFolderProps;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
handleSelectCategory: ({ name, categoryId }: ISelectedCategoryProps) => void;
}

interface IItemClickProps {
name: string;
categoryId: number;
}
onSelect: (categoryId: number) => void;
};

const DropdownItem = ({
category,
setIsOpen,
handleSelectCategory,
}: ICategoryDropdownProp) => {
const DropdownItem = ({ category, onSelect }: Props) => {
const [isShow, setIsShow] = useState(false);

const dynamicStyles = {
Expand All @@ -31,11 +22,6 @@ const DropdownItem = ({
},
};

const handleItemClick = async ({ name, categoryId }: IItemClickProps) => {
handleSelectCategory({ name, categoryId });
setIsOpen(false);
};

return (
<>
<li>
Expand All @@ -45,14 +31,8 @@ const DropdownItem = ({
style={dynamicStyles.icon}
onClick={() => setIsShow(!isShow)}
/>
<DropdownTopCategoryName
onClick={() =>
handleItemClick({
name: category.name,
categoryId: category.categoryId,
})
}
>

<DropdownTopCategoryName onClick={() => onSelect(category.categoryId)}>
{category.name}
</DropdownTopCategoryName>
</li>
Expand All @@ -61,12 +41,7 @@ const DropdownItem = ({
{category.subFolders.map((subFolder) => (
<li
key={subFolder.categoryId}
onClick={() =>
handleItemClick({
name: subFolder.name,
categoryId: subFolder.categoryId,
})
}
onClick={() => onSelect(subFolder.categoryId)}
>
{subFolder.name}
</li>
Expand Down
Loading

0 comments on commit beba1d9

Please sign in to comment.