From 20caca174f6f9b578279efd7ee363362c9cb7e82 Mon Sep 17 00:00:00 2001 From: whistleJs Date: Thu, 15 Feb 2024 21:53:27 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feature-057:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4=20=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CategoryDropdown/CategoryDropdown.tsx | 4 ++- .../CategoryDropdown/DropdownItem.tsx | 6 ++-- .../CategorySelectBox/CategorySelectBox.tsx | 35 +++++++++++-------- src/components/category/Card.tsx | 22 ++---------- src/components/category/VideoSelectMenu.tsx | 25 +++---------- src/pages/CategoryPage.tsx | 8 ++--- src/styles/SummaryPage.ts | 15 ++++---- src/styles/category/Card.style.ts | 9 ++--- src/styles/category/index.style.ts | 8 +++-- 9 files changed, 54 insertions(+), 78 deletions(-) diff --git a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/CategoryDropdown.tsx b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/CategoryDropdown.tsx index 94b5429..4f120f5 100644 --- a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/CategoryDropdown.tsx +++ b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/CategoryDropdown.tsx @@ -7,10 +7,11 @@ import { categoryState } from '@/stores/category'; import DropdownItem from './DropdownItem'; type Props = { + selectedId?: number; onSelect: (categoryId: number) => void; }; -const CategoryDropdown = ({ onSelect }: Props) => { +const CategoryDropdown = ({ selectedId, onSelect }: Props) => { const categories = useRecoilValue(categoryState); return ( @@ -20,6 +21,7 @@ const CategoryDropdown = ({ onSelect }: Props) => { ))} diff --git a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/DropdownItem.tsx b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/DropdownItem.tsx index 2af58c7..5ca61d6 100644 --- a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/DropdownItem.tsx +++ b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategoryDropdown/DropdownItem.tsx @@ -7,10 +7,11 @@ import { DropdownTopCategoryName } from '@/styles/SummaryPage'; type Props = { category: IFolderProps; + selectedId?: number; onSelect: (categoryId: number) => void; }; -const DropdownItem = ({ category, onSelect }: Props) => { +const DropdownItem = ({ category, selectedId, onSelect }: Props) => { const [isShow, setIsShow] = useState(false); const dynamicStyles = { @@ -24,7 +25,7 @@ const DropdownItem = ({ category, onSelect }: Props) => { return ( <> -
  • +
  • {
      {category.subFolders.map((subFolder) => (
    • onSelect(subFolder.categoryId)} > diff --git a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategorySelectBox.tsx b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategorySelectBox.tsx index 36876d9..25309fd 100644 --- a/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategorySelectBox.tsx +++ b/src/components/SummaryPage/SummaryDetailBox/CategorySelectBox/CategorySelectBox.tsx @@ -14,21 +14,17 @@ import { CategoryDropdown } from './CategoryDropdown'; type Props = { selectedCategoryId?: number; onSelect: (categoryId: number) => void; - onFileClick?: (e: React.MouseEvent) => void; }; -const CategorySelectBox = ({ - selectedCategoryId, - onSelect, - onFileClick, -}: Props) => { +const CategorySelectBox = ({ selectedCategoryId, onSelect }: Props) => { const userToken = useRecoilValue(userTokenState); const categories = useRecoilValue(categoryState); const [isOpen, setIsOpen] = useState(false); + const [selectedId, setSelectedId] = useState(selectedCategoryId); const selectedCategory = - selectedCategoryId && + selectedId && categories .reduce( // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -39,7 +35,7 @@ const CategorySelectBox = ({ ], [], ) - .find((category) => category.categoryId === selectedCategoryId); + .find((category) => category.categoryId === selectedId); // 다른 영역 클릭 시 dropdown 안보여지게 하기 const [ref] = useOutsideClick(() => { @@ -53,13 +49,22 @@ const CategorySelectBox = ({ }; const handleSelect = (categoryId: number) => { - onSelect(categoryId); + setSelectedId(categoryId); setIsOpen(false); }; + const handleClick = () => { + if (!selectedId || selectedId === selectedCategoryId) return; + + onSelect(selectedId); + }; + return ( -
      -
      +
      +
      {userToken @@ -72,14 +77,16 @@ const CategorySelectBox = ({
      - {isOpen && } + {isOpen && ( + + )}
      diff --git a/src/components/category/Card.tsx b/src/components/category/Card.tsx index f72cccb..3baafa9 100644 --- a/src/components/category/Card.tsx +++ b/src/components/category/Card.tsx @@ -1,11 +1,8 @@ import React, { useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { IVideoProps } from 'types/videos'; import { CategorySelectBox } from '@/components/SummaryPage/SummaryDetailBox/CategorySelectBox'; -import { categoryState } from '@/stores/category'; - import * as CardStyles from '@/styles/category/Card.style'; import Chip from '../common/chip/Chip'; @@ -14,11 +11,7 @@ interface ICardProps { video: IVideoProps; checkedVideos?: number[]; setCheckedVideos?: (value: number[]) => void; - onFileClick?: ( - e: React.MouseEvent, - videoId: number, - categoryId: number, - ) => void; + onFileClick?: (videoId: number, categoryId: number) => void; } const Card: React.FC = ({ @@ -29,17 +22,9 @@ const Card: React.FC = ({ onFileClick, }) => { const [isOpen, setIsOpen] = useState(false); - const category = useRecoilValue(categoryState); - - const [selectedCategoryId, setSelectedCategoryId] = useState( - category.length ? category[0].categoryId : -1, - ); - - const onFileClickWithProps = (e: React.MouseEvent) => - onFileClick && onFileClick(e, video.video_id, selectedCategoryId); const handleSelectCategory = (categoryId: number) => { - setSelectedCategoryId(categoryId); + onFileClick && onFileClick(video.video_id, categoryId); }; const handleCheckBox = (videoId: number) => { @@ -82,9 +67,8 @@ const Card: React.FC = ({ {isOpen && mode === 'recommend' && ( )} diff --git a/src/components/category/VideoSelectMenu.tsx b/src/components/category/VideoSelectMenu.tsx index 615fc66..c14cae8 100644 --- a/src/components/category/VideoSelectMenu.tsx +++ b/src/components/category/VideoSelectMenu.tsx @@ -2,7 +2,6 @@ import * as CategoryPageStyles from '@/styles/category/index.style'; import GarbageSvg from '@/assets/icons/garbage.svg?react'; import CloseSvg from '@/assets/icons/close.svg?react'; import { CategorySelectBox } from '../SummaryPage/SummaryDetailBox/CategorySelectBox'; -import { useState } from 'react'; import { IFolderProps } from 'types/category'; interface IVideoSelectMenuProps { @@ -12,15 +11,10 @@ interface IVideoSelectMenuProps { setCheckedVideos: React.Dispatch>; handleDeleteVideos: () => void; allCheckBtnHandler: () => void; - onFileClick?: ( - e: React.MouseEvent, - videoId: number, - categoryId: number, - ) => void; + onFileClick?: (videoId: number, categoryId: number) => void; } const VideoSelectMenu = ({ - categories, totalVideoCount, checkedVideos, setCheckedVideos, @@ -28,16 +22,9 @@ const VideoSelectMenu = ({ allCheckBtnHandler, onFileClick, }: IVideoSelectMenuProps) => { - const [selectedCategoryId, setSelectedCategoryId] = useState( - categories.length ? categories[0].categoryId : -1, - ); - - const onSelect = (categoryId: number) => { - setSelectedCategoryId(categoryId); - }; + const onFileClickWithProps = (categoryId: number) => + onFileClick && onFileClick(checkedVideos[0], categoryId); - const onFileClickWithProps = (e: React.MouseEvent) => - onFileClick && onFileClick(e, checkedVideos[0], selectedCategoryId); return (
      @@ -50,11 +37,7 @@ const VideoSelectMenu = ({
      - + diff --git a/src/pages/CategoryPage.tsx b/src/pages/CategoryPage.tsx index 31a21b4..0ec508c 100644 --- a/src/pages/CategoryPage.tsx +++ b/src/pages/CategoryPage.tsx @@ -63,12 +63,8 @@ const CategoryPage = () => { setCheckedVideos(videos.map((video) => video.video_id)); } }; - const onFileClick = async ( - e: React.MouseEvent, - videoId: number, - categoryId: number, - ) => { - e.stopPropagation(); + + const onFileClick = async (videoId: number, categoryId: number) => { const res = await putVideoToOtherCategory(videoId, categoryId); if (res.isSuccess) { handleVideo( diff --git a/src/styles/SummaryPage.ts b/src/styles/SummaryPage.ts index 86bc0a8..0c9e379 100644 --- a/src/styles/SummaryPage.ts +++ b/src/styles/SummaryPage.ts @@ -50,14 +50,11 @@ export const DetailBox = styled.div` width: 40px; height: 40px; border-radius: 8px; - cursor: pointer; + background-color: ${(props) => props.theme.color.gray200}; - &.selected { + &.changed { background-color: ${(props) => props.theme.color.green400}; - } - - &.not-selected { - background-color: ${(props) => props.theme.color.gray200}; + cursor: pointer; } &.disabled svg { @@ -327,7 +324,11 @@ export const Dropdown = styled.div` color: ${(props) => props.theme.color.gray400}; transition: 0.1s; cursor: pointer; - ${(props) => props.theme.typography.Body3} + ${(props) => props.theme.typography.Body3}; + + &.active { + color: ${(props) => props.theme.color.gray500}; + } &:hover { background-color: ${(props) => props.theme.color.gray100}; diff --git a/src/styles/category/Card.style.ts b/src/styles/category/Card.style.ts index b25686f..f61dafe 100644 --- a/src/styles/category/Card.style.ts +++ b/src/styles/category/Card.style.ts @@ -131,14 +131,11 @@ export const DropdownWrap = styled.div` width: 40px; height: 40px; border-radius: 8px; - cursor: pointer; + background-color: ${(props) => props.theme.color.gray200}; - &.selected { + &.changed { background-color: ${(props) => props.theme.color.green400}; - } - - &.not-selected { - background-color: ${(props) => props.theme.color.gray200}; + cursor: pointer; } &.disabled svg { diff --git a/src/styles/category/index.style.ts b/src/styles/category/index.style.ts index 399d20f..7c2c029 100644 --- a/src/styles/category/index.style.ts +++ b/src/styles/category/index.style.ts @@ -124,7 +124,11 @@ export const DropdownWrap = styled.div` width: 40px; height: 40px; border-radius: 8px; - cursor: pointer; - background-color: ${theme.color.gray100}; + background-color: ${(props) => props.theme.color.gray200}; + + &.changed { + background-color: ${(props) => props.theme.color.green400}; + cursor: pointer; + } } `; From 735efaa1d84e2cd0f786e82f20de89c77ca6aa13 Mon Sep 17 00:00:00 2001 From: whistleJs Date: Thu, 15 Feb 2024 22:14:11 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feature-057:=20NoteBox=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SummaryDetailBox/NoteBox/NoteBox.tsx | 34 ++++++++++++++++--- .../SummaryDetailBox/NoteBox/NoteItem.tsx | 23 ++++++++++--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteBox.tsx b/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteBox.tsx index bb916c5..787485e 100644 --- a/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteBox.tsx +++ b/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteBox.tsx @@ -42,8 +42,6 @@ const NoteBox = ({ onRefresh }: Props) => { setDisableIndex(); } else { await updateVideoAPI(summaryVideo.video_id, { summary: [summary] }); - - handleActiveEditable(editableIndex + 1); } onRefresh(); @@ -64,6 +62,17 @@ const NoteBox = ({ onRefresh }: Props) => { } }; + const handleRemoveNote = async (summaryId: number) => { + try { + await deleteVideoSummaryAPI(summaryId); + + setDisableIndex(); + onRefresh(); + } catch (e) { + console.error(e); + } + }; + return (
      @@ -74,7 +83,15 @@ const NoteBox = ({ onRefresh }: Props) => { isEditable={editableIndex === index} onDisableEditable={setDisableIndex} onActiveEditable={() => handleActiveEditable(index)} - onEdit={(content) => handleUpdateNote({ id: summary.id, content })} + onEdit={(content) => { + handleUpdateNote({ id: summary.id, content }); + setDisableIndex(); + }} + onEditAndNext={(content) => { + handleUpdateNote({ id: summary.id, content }); + handleActiveEditable(index + 1); + }} + onRemove={() => handleRemoveNote(summary.id)} /> ))} @@ -84,7 +101,11 @@ const NoteBox = ({ onRefresh }: Props) => { summary={{ id: -1, content: '' }} isEditable={editableIndex === -1} onDisableEditable={setDisableIndex} - onEdit={handleCreateNote} + onEdit={(content) => { + handleCreateNote(content); + setDisableIndex(); + }} + onEditAndNext={handleCreateNote} /> )} @@ -92,7 +113,10 @@ const NoteBox = ({ onRefresh }: Props) => { {editableIndex === null && ( diff --git a/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteItem.tsx b/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteItem.tsx index bd36b28..f06de8a 100644 --- a/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteItem.tsx +++ b/src/components/SummaryPage/SummaryDetailBox/NoteBox/NoteItem.tsx @@ -2,6 +2,8 @@ import { useEffect, useRef, useState } from 'react'; import CloseIcon from '@/assets/icons/close.svg?react'; +import useOutsideClick from '@/hooks/useOutsideClick'; + import { IVideoSummary } from '@/models/video'; type Props = { @@ -10,6 +12,8 @@ type Props = { onDisableEditable: () => void; onActiveEditable?: () => void; onEdit: (content: string) => void; + onEditAndNext?: (content: string) => void; + onRemove?: () => void; }; const NoteItem = ({ @@ -18,10 +22,18 @@ const NoteItem = ({ onDisableEditable, onActiveEditable, onEdit, + onEditAndNext, + onRemove, }: Props) => { const textareaRef = useRef(null); const [noteText, setNoteText] = useState(summary.content); + const [outsideRef] = useOutsideClick(() => { + if (isEditable) { + onEdit(noteText); + } + }); + const handleKeyDown: React.KeyboardEventHandler = ( e, ) => { @@ -30,7 +42,7 @@ const NoteItem = ({ } else if (e.key === 'Enter') { e.preventDefault(); - onEdit(noteText); + onEditAndNext && onEditAndNext(noteText); // 이어서 생성할 수 있도록 if (summary.id === -1) { @@ -53,6 +65,7 @@ const NoteItem = ({ return (
      @@ -70,9 +83,11 @@ const NoteItem = ({ />
      - + {summary.id !== -1 && ( + + )}
      ) : ( {noteText} From a432f0481c4944d7fc4d657c0860618d5f37b217 Mon Sep 17 00:00:00 2001 From: whistleJs Date: Thu, 15 Feb 2024 22:19:03 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feature-057:=20API=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/config/instance.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apis/config/instance.ts b/src/apis/config/instance.ts index 1bdae5f..90abea4 100644 --- a/src/apis/config/instance.ts +++ b/src/apis/config/instance.ts @@ -8,8 +8,8 @@ const baseURL = const axiosInstance = axios.create({ baseURL }); axiosInstance.interceptors.request.use((config) => { - config.withCredentials = true; - config.headers['Access-Control-Allow-Origin'] = '*'; + // config.withCredentials = true; + // config.headers['Access-Control-Allow-Origin'] = '*'; if (localStorage.vino) { const storage = JSON.parse(localStorage.vino); From 70f51f67c80ddbd9c05c7b757192ed515b418f19 Mon Sep 17 00:00:00 2001 From: whistleJs Date: Thu, 15 Feb 2024 22:21:00 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feature-057:=20=EB=B9=8C=EB=93=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Home/InsightVideos.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/Home/InsightVideos.tsx b/src/components/Home/InsightVideos.tsx index 0ee0631..bef8355 100644 --- a/src/components/Home/InsightVideos.tsx +++ b/src/components/Home/InsightVideos.tsx @@ -22,12 +22,7 @@ const InsightVideos: React.FC = ({ const endBox = useRef(null); - const onFileClick = async ( - e: React.MouseEvent, - videoId: number, - categoryId: number, - ) => { - e.stopPropagation(); + const onFileClick = async (videoId: number, categoryId: number) => { const res = await createDummyVideoToMine(videoId, categoryId); if (res.isSuccess) await getUnReadDummyVideos().then((res) =>