From 533a9b56d3e7e272913a34222aa8a96485252b4c Mon Sep 17 00:00:00 2001 From: gs0428 Date: Sat, 17 Feb 2024 23:30:15 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feature-073:=20=EC=82=AC=EC=9D=B4=EB=93=9C?= =?UTF-8?q?=20=EB=B0=94=20=EC=B5=9C=EC=86=8C=20=EB=86=92=EC=9D=B4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/layout/sideBar/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/layout/sideBar/index.ts b/src/styles/layout/sideBar/index.ts index 9a6ffcf..b9781cd 100644 --- a/src/styles/layout/sideBar/index.ts +++ b/src/styles/layout/sideBar/index.ts @@ -8,6 +8,7 @@ export const Container = styled.div` box-shadow: 4px 0px 10px rgba(0, 0, 0, 0.05); z-index: 2; background-color: ${theme.color.white}; + min-height: 964px; `; export const StickySection = styled.div` From 3b103614105106785718ea82ca2ddd45e7f42083 Mon Sep 17 00:00:00 2001 From: gs0428 Date: Sat, 17 Feb 2024 23:34:56 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feature-073:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20API=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 9 +-------- src/apis/videos.ts | 8 -------- src/models/video.ts | 4 ---- src/utils/getTokenInCookie.ts | 7 ------- 4 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 src/utils/getTokenInCookie.ts diff --git a/src/App.tsx b/src/App.tsx index e7ae2cf..1cce95e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -41,19 +41,12 @@ import useUpdateCategories from '@/hooks/useUpdateCategories'; // Store import { userTokenState } from '@/stores/user'; -import { getTempToken } from './apis/videos'; const App = () => { const userToken = useRecoilValue(userTokenState); const { updateCategories } = useUpdateCategories(); - useEffect(() => { - (async () => { - const response = await getTempToken(); - document.cookie = `tempToken=${response.result.tempToken}`; - })(); - userToken && updateCategories(); - }, [updateCategories, userToken]); + useEffect(() => {}, [updateCategories, userToken]); return ( diff --git a/src/apis/videos.ts b/src/apis/videos.ts index 9bdf070..53ea7c2 100644 --- a/src/apis/videos.ts +++ b/src/apis/videos.ts @@ -1,6 +1,5 @@ import { APIBaseResponse, APIResponse } from '@/models/config/axios'; import { - ITempTokenResponse, IVideo, UpdateVideoCategoryRequest, UpdateVideoRequest, @@ -93,13 +92,6 @@ export const createDummyVideoToMine = async ( return response.data; }; -export const getTempToken = async (): Promise< - APIResponse -> => { - const response = await axiosInstance.get('/'); - return response.data; -}; - export const getVideoModeling = async (url: string) => { const response = await axiosInstance.get(`/video/?v=${url}`); console.log(response); diff --git a/src/models/video.ts b/src/models/video.ts index 565e8a6..cceca7e 100644 --- a/src/models/video.ts +++ b/src/models/video.ts @@ -52,7 +52,3 @@ export interface UpdateVideoRequest { export interface UpdateVideoCategoryRequest { video_id: (string | number)[]; } - -export interface ITempTokenResponse { - tempToken: string; -} diff --git a/src/utils/getTokenInCookie.ts b/src/utils/getTokenInCookie.ts deleted file mode 100644 index 851f853..0000000 --- a/src/utils/getTokenInCookie.ts +++ /dev/null @@ -1,7 +0,0 @@ -const getTokenInCookie = () => - document.cookie - .split(';') - .find((cookie) => cookie.includes('tempToken')) - ?.split('=')[1]; - -export default getTokenInCookie; From 495fe564ff80194968f3d4844319b3e8a1456036 Mon Sep 17 00:00:00 2001 From: gs0428 Date: Sun, 18 Feb 2024 00:03:58 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feature-073:=20=EC=97=94=ED=84=B0=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95=20API=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 4 +- src/components/category/EditCategoryName.tsx | 62 +++++++++++++++++++ src/components/layout/sideBar/SubCategory.tsx | 35 +++-------- src/components/layout/sideBar/TopCategory.tsx | 37 +++-------- src/styles/category/EditCategoryName.style.ts | 31 ++++++++++ .../layout/sideBar/SubCategory.style.ts | 20 ------ .../layout/sideBar/TopCategory.style.ts | 21 ------- 7 files changed, 114 insertions(+), 96 deletions(-) create mode 100644 src/components/category/EditCategoryName.tsx create mode 100644 src/styles/category/EditCategoryName.style.ts diff --git a/src/App.tsx b/src/App.tsx index 1cce95e..94a209b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -46,7 +46,9 @@ const App = () => { const userToken = useRecoilValue(userTokenState); const { updateCategories } = useUpdateCategories(); - useEffect(() => {}, [updateCategories, userToken]); + useEffect(() => { + userToken && updateCategories(); + }, [updateCategories, userToken]); return ( diff --git a/src/components/category/EditCategoryName.tsx b/src/components/category/EditCategoryName.tsx new file mode 100644 index 0000000..c33e9e2 --- /dev/null +++ b/src/components/category/EditCategoryName.tsx @@ -0,0 +1,62 @@ +import useOutsideClick from '@/hooks/useOutsideClick'; +import * as EditCategoryNameStyles from '@/styles/category/EditCategoryName.style'; +import handleEdit from '@/utils/handleEdit'; +import { useState } from 'react'; + +interface IEditCategoryNameProps { + mode: 'top' | 'sub'; + beforeEdit: string; + categoryId: number; + edit: string; + setEdit: React.Dispatch>; + setIsEditing: React.Dispatch>; +} + +const EditCategoryName = ({ + mode, + categoryId, + beforeEdit, + edit, + setEdit, + setIsEditing, +}: IEditCategoryNameProps) => { + const { editText, finishEdit } = handleEdit(); + const [nameRegex, setNameRegex] = useState(true); + + const handleFinish = () => + finishEdit( + edit, + setEdit, + beforeEdit, + setIsEditing, + nameRegex, + setNameRegex, + categoryId, + ); + + const onKeydown = (e: React.KeyboardEvent) => { + if (e.code === 'Enter') handleFinish(); + }; + + const [editNameRef] = useOutsideClick(handleFinish); + + const handleInput = (e: React.ChangeEvent) => + editText(e, setEdit, setNameRegex); + return ( + + + + ); +}; + +export default EditCategoryName; diff --git a/src/components/layout/sideBar/SubCategory.tsx b/src/components/layout/sideBar/SubCategory.tsx index bb9568c..0a1d891 100644 --- a/src/components/layout/sideBar/SubCategory.tsx +++ b/src/components/layout/sideBar/SubCategory.tsx @@ -3,9 +3,9 @@ import useOutsideClick from '@/hooks/useOutsideClick'; import { useState } from 'react'; import * as SubCategoryStyles from '@/styles/layout/sideBar/SubCategory.style'; import Option from './Option'; -import handleEdit from '@/utils/handleEdit'; import handleDrag from '@/utils/handleDrag'; import { ISubFolderProps } from 'types/category'; +import EditCategoryName from '@/components/category/EditCategoryName'; interface ISubCategoryProps { topId: number; @@ -33,19 +33,6 @@ const SubCategory = ({ const [isEditing, setIsEditing] = useState(false); const [edit, setEdit] = useState(name); const [beforeEdit, setBeforeEdit] = useState(edit); - const { editText, finishEdit } = handleEdit(); - const [editNameRef] = useOutsideClick(() => - finishEdit( - edit, - setEdit, - beforeEdit, - setIsEditing, - nameRegex, - setNameRegex, - categoryId, - ), - ); - const [nameRegex, setNameRegex] = useState(true); const [subFolderOptionModalRef] = useOutsideClick(() => setSubFolderOptionModalOpen(false), @@ -76,9 +63,6 @@ const SubCategory = ({ setSubFolderOptionModalOpen(true); }; - const handleInput = (e: React.ChangeEvent) => - editText(e, setEdit, setNameRegex); - const handleDragStart = () => (grabedCategory.current = { categoryId: categoryId, @@ -96,15 +80,14 @@ const SubCategory = ({ onDragEnd={putCategoryFolder} > {isEditing ? ( - - - + ) : (
diff --git a/src/components/layout/sideBar/TopCategory.tsx b/src/components/layout/sideBar/TopCategory.tsx index 1d7ee45..798cca9 100644 --- a/src/components/layout/sideBar/TopCategory.tsx +++ b/src/components/layout/sideBar/TopCategory.tsx @@ -6,9 +6,9 @@ import React, { useState } from 'react'; import useOutsideClick from '@/hooks/useOutsideClick'; import SubCategory from './SubCategory'; import Option from './Option'; -import handleEdit from '@/utils/handleEdit'; import handleDrag from '@/utils/handleDrag'; import { ISubFolderProps } from 'types/category'; +import EditCategoryName from '@/components/category/EditCategoryName'; interface ITopCategoryProps { topId: number; @@ -47,23 +47,8 @@ const TopCategory = ({ const [isEditing, setIsEditing] = useState(false); const [edit, setEdit] = useState(name); const [beforeEdit, setBeforeEdit] = useState(edit); - const { editText, finishEdit } = handleEdit(); - - const [nameRegex, setNameRegex] = useState(true); const options = ['추가', '수정', '삭제', '이동']; - const [editNameRef] = useOutsideClick(() => - finishEdit( - edit, - setEdit, - beforeEdit, - setIsEditing, - nameRegex, - setNameRegex, - categoryId, - ), - ); - const handleOptionClick = (e: React.MouseEvent, option: string) => { e.stopPropagation(); if (option === '추가') { @@ -84,8 +69,6 @@ const TopCategory = ({ setFolderOptionModalOpen(true); }; - const handleInput = (e: React.ChangeEvent) => - editText(e, setEdit, setNameRegex); const handleDragStart = () => (grabedCategory.current = { categoryId: categoryId, @@ -124,16 +107,14 @@ const TopCategory = ({ selected={topId === categoryId && !subId} > {isEditing ? ( - - - - + ) : ( <> diff --git a/src/styles/category/EditCategoryName.style.ts b/src/styles/category/EditCategoryName.style.ts new file mode 100644 index 0000000..283133e --- /dev/null +++ b/src/styles/category/EditCategoryName.style.ts @@ -0,0 +1,31 @@ +import styled from 'styled-components'; +import theme from '../theme'; + +export const EditNameInputWrap = styled.div` + display: flex; + padding: 10px 20px; + border: 1px solid ${theme.color.gray200}; + width: 100%; + border-radius: 100px; + &.warning { + border: 1px solid ${theme.color.red}; + } + + &.sub-category { + padding: 10px 0 10px 60px; + } +`; + +export const EditNameInput = styled.input` + outline: none; + border: 0; + background-color: rgba(0, 0, 0, 0); + margin-left: 10px; + ${theme.typography.Body1} + + &.sub-category { + padding: 0; + margin: 0px 0px 4px -1px; + ${theme.typography.Body3} + } +`; diff --git a/src/styles/layout/sideBar/SubCategory.style.ts b/src/styles/layout/sideBar/SubCategory.style.ts index 75ee617..a81ff0b 100644 --- a/src/styles/layout/sideBar/SubCategory.style.ts +++ b/src/styles/layout/sideBar/SubCategory.style.ts @@ -7,26 +7,6 @@ export const Container = styled.div` width: 100%; `; -export const EditNameInputWrap = styled.div` - display: flex; - padding: 10px 0 10px 60px; - border: 1px solid ${theme.color.gray200}; - width: 100%; - border-radius: 100px; - &.warning { - border: 1px solid ${theme.color.red}; - } -`; - -export const EditNameInput = styled.input` - outline: none; - border: 0; - padding: 0; - background-color: rgba(0, 0, 0, 0); - margin: 0px 0px 4px -1px; - ${theme.typography.Body3} -`; - export const SubFolderWrap = styled.div` width: 100%; display: flex; diff --git a/src/styles/layout/sideBar/TopCategory.style.ts b/src/styles/layout/sideBar/TopCategory.style.ts index 2ca8d1c..3629045 100644 --- a/src/styles/layout/sideBar/TopCategory.style.ts +++ b/src/styles/layout/sideBar/TopCategory.style.ts @@ -33,27 +33,6 @@ export const Container = styled.div<{ selected: boolean }>` } `; -export const EditNameInputWrap = styled.div` - display: flex; - padding: 10px 20px; - border: 1px solid ${theme.color.gray200}; - width: 100%; - background-color: ${theme.color.white}; - border-radius: 100px; - &.warning { - border: 1px solid ${theme.color.red}; - } -`; - -export const EditNameInput = styled.input` - width: 100%; - margin-left: 10px; - outline: none; - border: 0; - background-color: rgba(0, 0, 0, 0); - ${theme.typography.Body1} -`; - export const FolderButton = styled(CommonButtonStyle)` width: 100%; `; From 679c282337b41cbc2330c3a8d507e70695ff9b47 Mon Sep 17 00:00:00 2001 From: gs0428 Date: Sun, 18 Feb 2024 00:05:40 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feature-073:=20=EB=B9=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=8B=9C=20=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4=20?= =?UTF-8?q?=EC=95=88=20=EB=B3=B4=EC=9D=B4=EA=B2=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Home/InsightVideos.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Home/InsightVideos.tsx b/src/components/Home/InsightVideos.tsx index 3ce5388..0db8cbe 100644 --- a/src/components/Home/InsightVideos.tsx +++ b/src/components/Home/InsightVideos.tsx @@ -71,7 +71,7 @@ const InsightVideos: React.FC = ({ {dummyVideos.map((video) => ( Date: Sun, 18 Feb 2024 00:43:46 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feature-073:=20=ED=86=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=8C=9D=EC=97=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Home/InsightVideos.tsx | 17 ++++++--------- src/components/category/Card.tsx | 10 ++++++--- src/pages/HomePage.tsx | 30 +++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/components/Home/InsightVideos.tsx b/src/components/Home/InsightVideos.tsx index 0db8cbe..ec9a34a 100644 --- a/src/components/Home/InsightVideos.tsx +++ b/src/components/Home/InsightVideos.tsx @@ -4,32 +4,27 @@ import Card from '../category/Card'; import { IVideoProps } from 'types/videos'; import { CardContainer } from '@/styles/category/Card.style'; import successImg from '@/assets/success.png'; -import { createDummyVideoToMine, getUnReadDummyVideos } from '@/apis/videos'; interface InsightVideosProps { userToken: string | null; dummyVideos: IVideoProps[]; - setDummyVideos: React.Dispatch>; + onFileClick: ( + videoId: number, + categoryId: number, + categoryName?: string, + ) => void; } const InsightVideos: React.FC = ({ userToken, dummyVideos, - setDummyVideos, + onFileClick, }) => { const [checkedItems, setCheckedItems] = useState([]); const [showEndMessage, setShowEndMessage] = useState(false); const endBox = useRef(null); - const onFileClick = async (videoId: number, categoryId: number) => { - const res = await createDummyVideoToMine(videoId, categoryId); - if (res.isSuccess) - await getUnReadDummyVideos().then((res) => - setDummyVideos(res.result.videos), - ); - }; - useEffect(() => { const handleIntersect = (entries: IntersectionObserverEntry[]) => { entries.forEach((entry) => { diff --git a/src/components/category/Card.tsx b/src/components/category/Card.tsx index 667793e..3cc084f 100644 --- a/src/components/category/Card.tsx +++ b/src/components/category/Card.tsx @@ -14,7 +14,11 @@ interface ICardProps { video: IVideoProps; checkedVideos?: number[]; setCheckedVideos?: (value: number[]) => void; - onFileClick?: (videoId: number, categoryId: number) => void; + onFileClick?: ( + videoId: number, + categoryId: number, + categoryName?: string, + ) => void; } const Card: React.FC = ({ @@ -30,9 +34,9 @@ const Card: React.FC = ({ category.length ? category[0].categoryId : -1, ); - const onFileClickWithProps = (categoryId: number) => { + const onFileClickWithProps = (categoryId: number, categoryName?: string) => { setSelectedCategoryId(categoryId); - onFileClick && onFileClick(video.video_id, categoryId); + onFileClick && onFileClick(video.video_id, categoryId, categoryName); }; const handleCheckBox = (videoId: number) => { diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index d7a6387..ec05701 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -3,16 +3,18 @@ import SearchYoutube from '@/components/Home/SearchYoutube'; import { HomePageContainer } from '@/styles/HomepageStyle'; import RecentVideos from '@/components/Home/RecentVideos'; import InsightVideos from '@/components/Home/InsightVideos'; -import { useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import { recommendationModalState } from '@/stores/modal'; import RecommendationModal from '@/components/modals/RecommendationModal'; import { getUnReadDummyVideos, getRecentVideos, getAllDummyVideos, + createDummyVideoToMine, } from '@/apis/videos'; import { userTokenState } from '@/stores/user'; import { IVideoProps } from 'types/videos'; +import { toastListState } from '@/stores/toast'; export interface Video { id: string; @@ -26,9 +28,29 @@ const HomePage: React.FC = () => { const userToken = useRecoilValue(userTokenState); const [recentVideos, setRecentVideos] = useState([]); const [dummyVideos, setDummyVideos] = useState([]); + const [toastList, setToastList] = useRecoilState(toastListState); + + const createToast = (content: string) => { + setToastList([...toastList, { id: Date.now(), content }]); + }; const handleSearch = (value: string) => { console.log(value); }; + + const onFileClick = async ( + videoId: number, + categoryId: number, + categoryName?: string, + ) => { + const res = await createDummyVideoToMine(videoId, categoryId); + if (res.isSuccess) { + createToast(`[${categoryName}] 폴더에 저장되었어요`); + + await getUnReadDummyVideos().then((res) => + setDummyVideos(res.result.videos.slice(0, 9)), + ); + } + }; const searchRef = useRef(null); const isModalOpen = useRecoilValue(recommendationModalState); @@ -38,7 +60,7 @@ const HomePage: React.FC = () => { Promise.all([getRecentVideos(), getUnReadDummyVideos()]).then((res) => { const [recentVideosResponse, dummyVideosResponse] = res; setRecentVideos(recentVideosResponse.result.videos); - setDummyVideos(dummyVideosResponse.result.videos); + setDummyVideos(dummyVideosResponse.result.videos.slice(0, 9)); }); !userToken && @@ -58,7 +80,7 @@ const HomePage: React.FC = () => { )} @@ -67,7 +89,7 @@ const HomePage: React.FC = () => { From 2f30254857ad7c7b18e5420301526a7376e2eb7a Mon Sep 17 00:00:00 2001 From: gs0428 Date: Sun, 18 Feb 2024 01:02:33 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feature-073:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/category/Card.style.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/category/Card.style.ts b/src/styles/category/Card.style.ts index 1b2f722..6082d10 100644 --- a/src/styles/category/Card.style.ts +++ b/src/styles/category/Card.style.ts @@ -95,7 +95,7 @@ export const CheckBox = styled.input` export const CardContainer = styled.div` display: grid; - grid-template-columns: repeat(3, auto); + grid-template-columns: repeat(3, 290px); column-gap: 20px; row-gap: 40px; `; @@ -162,4 +162,4 @@ export const Image = styled.img` border-radius: 16px 16px 0 0; width: 290px; height: 163px; -`; \ No newline at end of file +`;