diff --git a/package-lock.json b/package-lock.json index f9f6bcc688..0a083186af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", + "react-helmet-async": "^2.0.4", "react-query": "^3.39.3", "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", @@ -9301,6 +9302,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", @@ -14615,6 +14624,20 @@ "react": ">=16.3.0" } }, + "node_modules/react-helmet-async": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", + "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index dcaeafb6b7..317a29e4cd 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", + "react-helmet-async": "^2.0.4", "react-query": "^3.39.3", "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", diff --git a/src/Main.js b/src/Main.js index f3b211d01a..12b2aca3bd 100644 --- a/src/Main.js +++ b/src/Main.js @@ -1,6 +1,6 @@ import Layout from './pages/Layout'; -import Shared from './pages/Shared'; -import Folder from './pages/Folder'; +import SharedPage from './pages/SharedPage'; +import FolderPage from './pages/FolderPage'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; function Main() { @@ -8,8 +8,8 @@ function Main() { }> - } /> - } /> + } /> + } /> diff --git a/src/components/CardListItem.js b/src/components/CardListItem.js index 7e62c0c665..1abcab8725 100644 --- a/src/components/CardListItem.js +++ b/src/components/CardListItem.js @@ -3,6 +3,31 @@ import noCardImg from '../images/no-image.svg'; import { Link } from 'react-router-dom'; // import loadingImg from '../images/loading-spinner.svg'; +const Card = ({ + imageSource, + title, + timePassed, + description, + formattedDate, + handleImageError, +}) => { + return ( +
+ {title} +
+ {timePassed} +

{description}

+

{formattedDate}

+
+
+ ); +}; + function CardListItem() { const data = useFetchCardsData(); const handleImageError = (e) => { @@ -22,19 +47,14 @@ function CardListItem() { formattedDate, }) => ( -
- {title} -

- {timePassed} -

{description}

-

{formattedDate}

-

-
+ ) )} diff --git a/src/components/Folder/Card.js b/src/components/Folder/Card.js index c0261a898a..108cd468d5 100644 --- a/src/components/Folder/Card.js +++ b/src/components/Folder/Card.js @@ -1,57 +1,36 @@ import React from 'react'; -import defaultImg from '../../images/non_image.svg'; +import defaultImg from '../../images/no-image.svg'; import starImg from '../../images/star.svg'; import kebabImg from '../../images/kebab.svg'; import { updateStatus } from './cardUpdate'; -import { Link } from 'react-router-dom'; -export default function Card({ - imageSource, - createdAt, - description, - url, - folder, -}) { +export default function Card({ imageSource, createdAt, description, folder }) { const date = new Date(createdAt).toLocaleDateString(); const dataStatus = updateStatus(createdAt); return (
- -
-
- card - {folder && ( - star - )} -
-
-
-

- {createdAt ? dataStatus : null} -

- {folder && ( - star - )} -
-

{description}

-

{date}

-
-
- + card + {folder && ( + star + )} +
+ {createdAt ? dataStatus : null} +

{description}

+

{date}

+ {folder && star} +
); } diff --git a/src/components/Folder/FolderCards.js b/src/components/Folder/FolderCards.js index 49e043a5d1..182650006b 100644 --- a/src/components/Folder/FolderCards.js +++ b/src/components/Folder/FolderCards.js @@ -1,25 +1,26 @@ import React from 'react'; import Card from './Card'; import { NonLink } from '../../style/styledComponents'; +import { Link } from 'react-router-dom'; export const FolderCards = ({ folder }) => { + const isExistFolder = folder && folder.length > 0; return ( <> -
- {folder && folder.length >= 1 ? ( - folder.map( - (folderData, index) => - index !== 0 && ( - - ) - ) +
+ {isExistFolder ? ( + folder.map(({ id, image_source, created_at, description, url }) => ( + + + + )) ) : ( 저장된 링크가 없습니다 )} diff --git a/src/components/Folder/FolderCategory.js b/src/components/Folder/FolderCategory.js index 3580f79312..0368dce8b3 100644 --- a/src/components/Folder/FolderCategory.js +++ b/src/components/Folder/FolderCategory.js @@ -10,29 +10,27 @@ import { function FolderCategory({ category, currentCategory, handleCategoryButton }) { return ( - <> - - - {category && - category.map((categoryData) => ( - - {categoryData.name} - - ))} - + + + {category && + category.map(({ id, name }) => ( + + {name} + + ))} + - - 폴더 추가 - - - - + + 폴더 추가 + + + ); } diff --git a/src/components/Folder/FolderContent.js b/src/components/Folder/FolderContent.js index 8e55378216..34f33da5cf 100644 --- a/src/components/Folder/FolderContent.js +++ b/src/components/Folder/FolderContent.js @@ -7,14 +7,17 @@ import { FolderTitle } from './FolderTitle'; import { FolderCards } from './FolderCards'; function FolderContent() { - const folderCategory = useFetchFolderCategoryData(); + const [currentCategory, setCurrentCategory] = useState('전체'); - const folderCards = useFetchFolderCardsData(0); + const [folderId, setFolderId] = useState(0); - const [currentCategory, setCurrentCategory] = useState('전체'); + const folderCategory = useFetchFolderCategoryData(); + + const folderCards = useFetchFolderCardsData(folderId); const handleCategoryButton = (e) => { setCurrentCategory(e.target.innerText); + setFolderId(e.target.id); }; return ( @@ -23,7 +26,7 @@ function FolderContent() { {folderCategory ? ( <> diff --git a/src/hooks/useFetchFolderCardsData.js b/src/hooks/useFetchFolderCardsData.js index 5614e29c0c..5f364de725 100644 --- a/src/hooks/useFetchFolderCardsData.js +++ b/src/hooks/useFetchFolderCardsData.js @@ -1,31 +1,44 @@ +import { useState, useEffect } from 'react'; + const BASE_URL = 'https://bootcamp-api.codeit.kr/api'; -const fetchFolderCardsData = async (folderId) => { - if (folderId === '0') { - try { - const response = await fetch(`${BASE_URL}/users/4/links`); - if (!response.ok) { - throw new Error('response 전달 실패'); - } - return response.data.json(); - } catch (error) { - console.error('에러 발생:', error); - return null; - } - } else { - try { - const response = await fetch( - `${BASE_URL}/users/4/links?folderId=${folderId}` - ); - if (!response.ok) { - throw new Error('response 전달 실패'); +function useFetchFolderCardsData(folderId) { + const [cardsData, setCardsData] = useState([]); + + useEffect(() => { + const fetchData = async () => { + if (folderId === 0) { + try { + const response = await fetch(`${BASE_URL}/users/11/links`); + if (!response.ok) { + throw new Error('response 전달 실패'); + } + const data = await response.json(); + setCardsData(data.data); + } catch (error) { + console.error('Fetch FolderCardsData에서 에러 발생:', error); + return null; + } + } else { + try { + const response = await fetch( + `${BASE_URL}/users/11/links?folderId=${folderId}` + ); + if (!response.ok) { + throw new Error('response 전달 실패'); + } + const data = await response.json(); + setCardsData(data.data); + } catch (error) { + console.error('에러 발생:', error); + return null; + } } - return response.data.json(); - } catch (error) { - console.error('에러 발생:', error); - return null; - } - } -}; + }; + fetchData(); + }, [folderId]); + + return cardsData; +} -export default fetchFolderCardsData; +export default useFetchFolderCardsData; diff --git a/src/hooks/useFetchFolderCategoryData.js b/src/hooks/useFetchFolderCategoryData.js index ac5829c1d4..4354d36a9b 100644 --- a/src/hooks/useFetchFolderCategoryData.js +++ b/src/hooks/useFetchFolderCategoryData.js @@ -7,7 +7,7 @@ function useFetchFolderCategoryData() { const fetchData = async () => { try { const response = await fetch( - 'https://bootcamp-api.codeit.kr/api/users/4/folders' + 'https://bootcamp-api.codeit.kr/api/users/11/folders' ); if (!response.ok) { throw new Error('response 전달 실패'); diff --git a/src/images/non_image.svg b/src/images/non_image.svg deleted file mode 100644 index 1dc759407e..0000000000 --- a/src/images/non_image.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/pages/Folder.js b/src/pages/FolderPage.js similarity index 63% rename from src/pages/Folder.js rename to src/pages/FolderPage.js index 3ce3adb317..c6da19bd5f 100644 --- a/src/pages/Folder.js +++ b/src/pages/FolderPage.js @@ -1,17 +1,17 @@ -import { Helmet } from 'react-helmet'; +import { Helmet, HelmetProvider } from 'react-helmet-async'; import FolderHeader from '../components/Folder/FolderHeader'; import FolderContent from '../components/Folder/FolderContent'; -function Folder() { +function FolderPage() { return ( - <> + Linkbrary - Folder - + ); } -export default Folder; +export default FolderPage; diff --git a/src/pages/Shared.js b/src/pages/SharedPage.js similarity index 61% rename from src/pages/Shared.js rename to src/pages/SharedPage.js index a57d25d740..32a6c5babe 100644 --- a/src/pages/Shared.js +++ b/src/pages/SharedPage.js @@ -1,17 +1,17 @@ -import { Helmet } from 'react-helmet'; +import { Helmet, HelmetProvider } from 'react-helmet-async'; import SharedHeader from '../components/Shared/SharedHeader'; import CardList from '../components/CardList'; -function Shared() { +function SharedPage() { return ( - <> + Linkbrary - Shared - + ); } -export default Shared; +export default SharedPage;