From 7754ac6457131c4f3a88643bb750212e09ebdbda Mon Sep 17 00:00:00 2001 From: jiohjung98 Date: Wed, 2 Oct 2024 16:59:00 +0900 Subject: [PATCH 1/6] =?UTF-8?q?design:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=EB=B3=84=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EB=B0=8F=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/mypage/bookmark-white.svg | 3 ++ public/images/mypage/googleSocial.svg | 14 ++++++ public/images/mypage/kakaoSocial.svg | 2 + public/images/mypage/naverSocial.svg | 2 + src/app/mypage/edit/page.tsx | 10 +++-- src/components/mypage/MypageHeader.tsx | 22 +++------ src/components/mypage/MypageMenu.tsx | 48 -------------------- src/components/sign/SignLayout.tsx | 2 +- src/factory/ReportLists.ts | 2 +- src/service/auth.ts | 4 +- src/store/user.store.ts | 8 ++-- src/utils/checkEmail.ts | 59 ++++++++++++------------- 12 files changed, 71 insertions(+), 105 deletions(-) create mode 100644 public/images/mypage/bookmark-white.svg create mode 100644 public/images/mypage/googleSocial.svg create mode 100644 public/images/mypage/kakaoSocial.svg create mode 100644 public/images/mypage/naverSocial.svg diff --git a/public/images/mypage/bookmark-white.svg b/public/images/mypage/bookmark-white.svg new file mode 100644 index 0000000..c242024 --- /dev/null +++ b/public/images/mypage/bookmark-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/mypage/googleSocial.svg b/public/images/mypage/googleSocial.svg new file mode 100644 index 0000000..02b2ad2 --- /dev/null +++ b/public/images/mypage/googleSocial.svg @@ -0,0 +1,14 @@ + + + + google + + + + + + + + + + \ No newline at end of file diff --git a/public/images/mypage/kakaoSocial.svg b/public/images/mypage/kakaoSocial.svg new file mode 100644 index 0000000..41c1132 --- /dev/null +++ b/public/images/mypage/kakaoSocial.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/images/mypage/naverSocial.svg b/public/images/mypage/naverSocial.svg new file mode 100644 index 0000000..6a36296 --- /dev/null +++ b/public/images/mypage/naverSocial.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/app/mypage/edit/page.tsx b/src/app/mypage/edit/page.tsx index 9931e11..0e67193 100644 --- a/src/app/mypage/edit/page.tsx +++ b/src/app/mypage/edit/page.tsx @@ -1,12 +1,12 @@ 'use client'; import { useModalStore } from '@/store/modal.store'; import { useMemberStore } from '@/store/user.store'; -import { checkEmail } from '@/utils/checkEmail'; import { useRouter } from 'next/navigation'; import React, { ChangeEvent, useEffect, useState } from 'react'; import { disablePageScroll, enablePageScroll } from 'scroll-lock'; import { checkNicknameAvailability } from '@/service/auth'; import { updateNickname } from '@/service/change'; +import { getSocialInfo } from '@/utils/checkEmail'; const Editpage = () => { const router = useRouter(); @@ -17,6 +17,8 @@ const Editpage = () => { const [isNameComplete, setIsNameComplete] = useState(''); const { setModalType, setOpen, open } = useModalStore(); + const socialInfo = getSocialInfo(member.loginType, member.memberEmail); + const handleNameChange = (e: ChangeEvent) => { const regex = e.target.value.replace(/[^a-zA-Z0-9ㄱ-ㅎㅏ-ㅣ가-힣]/g, ''); setNameValue(regex); @@ -136,9 +138,9 @@ const Editpage = () => {
이메일
-
- -
{checkEmail(member?.memberEmail)} 가입
+
+ {socialInfo.imgSrc && socialLogo} +
{socialInfo.platform} 가입
diff --git a/src/components/mypage/MypageHeader.tsx b/src/components/mypage/MypageHeader.tsx index d94ce10..c1370a4 100644 --- a/src/components/mypage/MypageHeader.tsx +++ b/src/components/mypage/MypageHeader.tsx @@ -21,22 +21,14 @@ const MypageHeader = () => {
-
{member.subscribe} 이용 중
-
- +
+ +
관심종목
-
-
-
-
- -
-
관심종목
-
-
-
24개
-
- +
+
+
24개
+
diff --git a/src/components/mypage/MypageMenu.tsx b/src/components/mypage/MypageMenu.tsx index 01255ec..f72281a 100644 --- a/src/components/mypage/MypageMenu.tsx +++ b/src/components/mypage/MypageMenu.tsx @@ -3,22 +3,6 @@ import React from 'react'; const MypageMenu = () => { return (
- {/* 구독 관리 */} -
-
-
- 구독 -
-
구독 관리
-
-
- 구독 -
-
{/* 공지사항 */}
@@ -35,22 +19,6 @@ const MypageMenu = () => { />
- {/* 쿠폰 관리 */} -
-
-
- 쿠폰 -
-
쿠폰 관리
-
-
- 쿠폰 -
-
{/* 알림 설정 */}
@@ -67,22 +35,6 @@ const MypageMenu = () => { />
- {/* 결제 관리 */} -
-
-
- 결제 -
-
결제 관리
-
-
- 결제 -
-
{/* 카카로톡 1:1 문의 */}
diff --git a/src/components/sign/SignLayout.tsx b/src/components/sign/SignLayout.tsx index 1598af1..1d1f825 100644 --- a/src/components/sign/SignLayout.tsx +++ b/src/components/sign/SignLayout.tsx @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; import { login } from '@/service/auth'; import { useAuthStore } from '@/store/userAuth.store'; -import throttle from 'lodash/throttle'; // lodash에서 throttle 함수 import +import throttle from 'lodash/throttle'; const SignLayout = () => { const [email, setEmail] = useState(''); diff --git a/src/factory/ReportLists.ts b/src/factory/ReportLists.ts index 162d668..37d3ff1 100644 --- a/src/factory/ReportLists.ts +++ b/src/factory/ReportLists.ts @@ -2,7 +2,7 @@ import { useInfiniteQuery } from '@tanstack/react-query'; import axios from 'axios'; const fetchStudyGuides = async ({ pageParam = 1 }) => { - const { data } = await axios.get(`https://api.moaguide.com/study/guide?page=${pageParam}&size=3`); + const { data } = await axios.get(`https://api.moaguide.com/study/guide?page=${pageParam}&size=10`); return { content: data.roadmaps, nextPage: pageParam + 1, diff --git a/src/service/auth.ts b/src/service/auth.ts index 10c9f57..b13acf8 100644 --- a/src/service/auth.ts +++ b/src/service/auth.ts @@ -92,9 +92,11 @@ export const login = async (email: string, password: string) => { memberEmail: userInfo.email, memberNickName: userInfo.nickname, memberPhone: userInfo.phonenumber, - subscribe: '1개월 플랜', + loginType: userInfo.loginType, }); + console.log(userInfo); + return response.data; } catch (error) { console.error('로그인 오류:', error); diff --git a/src/store/user.store.ts b/src/store/user.store.ts index 8b0c461..e441801 100644 --- a/src/store/user.store.ts +++ b/src/store/user.store.ts @@ -7,7 +7,7 @@ interface IUserInfo { memberEmail: string; memberNickName: string; memberPhone: string; - subscribe: string; + loginType: string; } interface IMember { @@ -23,7 +23,7 @@ export const useMemberStore = create( memberEmail: '', memberNickName: '', memberPhone: '', - subscribe: '' + loginType: '', }, setMember: (userInfo: IUserInfo) => set({ member: userInfo }), clearMember: () => set({ @@ -31,7 +31,7 @@ export const useMemberStore = create( memberEmail: '', memberNickName: '', memberPhone: '', - subscribe: '' + loginType: '', } }), }), @@ -39,4 +39,4 @@ export const useMemberStore = create( name: 'userInfo' } ) -); +); \ No newline at end of file diff --git a/src/utils/checkEmail.ts b/src/utils/checkEmail.ts index 7e07b51..23b3a85 100644 --- a/src/utils/checkEmail.ts +++ b/src/utils/checkEmail.ts @@ -1,33 +1,30 @@ -/* -유저의 이메일을 받아와서 도메인에 맞는 주소를 출력하는 함수입니다 -e.g. input) test@gmail.com -> output) 구글 -*/ -export const checkEmail = (email: string): string | null => { - const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - - if (!emailPattern.test(email)) { - return null; - } - - const domainPattern = /@([^@.]+)\./; - const match = email.match(domainPattern); - - if (match && match[1] === 'naver') { - return '네이버'; - } else if (match && match[1] === 'kakao') { - return '카카오'; - } else if (match && match[1] === 'gmail') { - return '구글'; - } else if (match && match[1] === 'nate') { - return '네이트'; - } else if (match && match[1] === 'daum') { - return '다음'; - } else if (match && match[1] === 'hanmail') { - return '다음'; - } else if (match && match[1]) { - return match[1]; - } else { - return null; +export const getSocialInfo = (loginType: string, email: string) => { + switch (loginType) { + case 'kakao': + return { + platform: '카카오', + imgSrc: '/images/mypage/kakaoSocial.svg', + }; + case 'google': + return { + platform: '구글', + imgSrc: '/images/mypage/googleSocial.svg', + }; + case 'naver': + return { + platform: '네이버', + imgSrc: '/images/mypage/naverSocial.svg', + }; + case 'local': + return { + platform: '일반', + imgSrc: null, + }; + default: + return { + platform: '알 수 없음', + imgSrc: null, + }; } -}; +}; \ No newline at end of file From 959862636aaddc98c7611027c702ce9db2234292 Mon Sep 17 00:00:00 2001 From: jiohjung98 Date: Wed, 2 Oct 2024 17:37:24 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20api=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/report/left-button.svg | 3 + src/components/practice/CategoryPractice.tsx | 4 +- .../practice/CategoryPracticeItem.tsx | 69 ++++--------------- .../skeleton/CategoryPracticeItemSkeleton.tsx | 16 +---- src/factory/ReportLists.ts | 12 ++-- src/types/homeComponentsType.ts | 3 +- 6 files changed, 28 insertions(+), 79 deletions(-) create mode 100644 public/images/report/left-button.svg diff --git a/public/images/report/left-button.svg b/public/images/report/left-button.svg new file mode 100644 index 0000000..636ab85 --- /dev/null +++ b/public/images/report/left-button.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/practice/CategoryPractice.tsx b/src/components/practice/CategoryPractice.tsx index 1b906ee..28e6213 100644 --- a/src/components/practice/CategoryPractice.tsx +++ b/src/components/practice/CategoryPractice.tsx @@ -46,7 +46,7 @@ const CategoryPractice = () => {
{isLoading ? ( subCategory === 'guide' ? ( - Array.from({ length: 3 }).map((_, i) => ) + Array.from({ length: 10 }).map((_, i) => ) ) : ( Array.from({ length: 10 }).map((_, i) => ) ) @@ -57,7 +57,7 @@ const CategoryPractice = () => { totalCount={allPosts.length} data={allPosts} endReached={loadMore} - itemContent={(index, item) => ( + itemContent={(_index, item) => ( subCategory === 'guide' ? ( ) : ( diff --git a/src/components/practice/CategoryPracticeItem.tsx b/src/components/practice/CategoryPracticeItem.tsx index 2949513..391da0a 100644 --- a/src/components/practice/CategoryPracticeItem.tsx +++ b/src/components/practice/CategoryPracticeItem.tsx @@ -1,75 +1,32 @@ -import type { ReportListsItem, StudyGuidesItem, SubLoadmap } from '@/types/homeComponentsType'; -import { formatCategory } from '@/utils/formatCategory'; +import type { StudyGuidesItem, SubLoadmap } from '@/types/homeComponentsType'; import axios from 'axios'; -import { format, parseISO } from 'date-fns'; -import { useRouter } from 'next/navigation'; import React, { useState } from 'react'; -import SubLoadmapSkeleton from '../skeleton/SubLoadmapSkeleton'; -import CategorySubloadmapItem from './CategorySubloadmapItem'; +import { useRouter } from 'next/navigation'; -const CategoryPracticeItem = ({ id, difficulty, title, description }: StudyGuidesItem) => { - const [details, setDetails] = useState(null); - const [showDetails, setShowDetails] = useState(false); - const [loadingDetails, setLoadingDetails] = useState(false); - const [toggleImage, setToggleImage] = useState('/images/report/toggle_button.svg'); +const CategoryPracticeItem = ({ id, title, link }: StudyGuidesItem) => { + const router = useRouter(); - const fetchDetails = async (itemId: number) => { - if (!details && !loadingDetails) { - setLoadingDetails(true); - try { - const response = await axios.get(`https://api.moaguide.com/study/guide/${itemId}`); - setDetails(response.data); - setLoadingDetails(false); - } catch (error) { - console.error('Fetching details failed:', error); - setLoadingDetails(false); - } + const handleLink = () => { + console.log(link); + if (link) { + router.push(link); } }; - const handleToggle = () => { - setShowDetails(!showDetails); - if (!showDetails && !details) { - fetchDetails(id); - } - - setToggleImage(!showDetails ? '/images/report/toggle_button_close.svg' : '/images/report/toggle_button.svg'); - }; - return ( -
-
-
-
- {difficulty} -
+
+
+
{title}
-
{description}
+
더보기
Toggle Details
- {showDetails && ( - loadingDetails ? ( - Array.from({ length: 3 }).map((_, i) => ( - - )) - ) : ( - details?.map((detail, index) => ( - - )) - ) - )}
); diff --git a/src/components/skeleton/CategoryPracticeItemSkeleton.tsx b/src/components/skeleton/CategoryPracticeItemSkeleton.tsx index 230dc12..86ed860 100644 --- a/src/components/skeleton/CategoryPracticeItemSkeleton.tsx +++ b/src/components/skeleton/CategoryPracticeItemSkeleton.tsx @@ -2,21 +2,11 @@ import React from 'react'; const CategoryPracticeItemSkeleton = () => { return ( -
-
- {/* Category Skeleton */} -
- {/* Title Skeleton */} -
- {/* Date Skeleton */} -
-
+
{/* Image Skeleton */} -
-
-
+
); }; -export default CategoryPracticeItemSkeleton; +export default CategoryPracticeItemSkeleton; \ No newline at end of file diff --git a/src/factory/ReportLists.ts b/src/factory/ReportLists.ts index 37d3ff1..5b27aa5 100644 --- a/src/factory/ReportLists.ts +++ b/src/factory/ReportLists.ts @@ -4,12 +4,12 @@ import axios from 'axios'; const fetchStudyGuides = async ({ pageParam = 1 }) => { const { data } = await axios.get(`https://api.moaguide.com/study/guide?page=${pageParam}&size=10`); return { - content: data.roadmaps, + content: data.roadmap, nextPage: pageParam + 1, totalPages: data.total, - totalElements: data.roadmaps.length, + totalElements: data.roadmap.length, currentPage: data.page, - isLast: data.page + 1 >= data.total + isLast: data.page + 1 >= data.total, }; }; @@ -19,7 +19,7 @@ export const getStudyGuides = (category: string, subCategory: string, sort: stri const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage, isLoading } = useInfiniteQuery({ queryKey, - queryFn: fetchStudyGuides, + queryFn: fetchStudyGuides, getNextPageParam: (lastPage) => { return lastPage.isLast ? undefined : lastPage.nextPage; }, @@ -28,12 +28,12 @@ export const getStudyGuides = (category: string, subCategory: string, sort: stri }); return { - data: data?.pages.flatMap((page) => page.content) || [], + data: data?.pages.flatMap((page) => page.content) || [], fetchNextPage, hasNextPage, isFetching, isFetchingNextPage, - isLoading + isLoading, }; }; diff --git a/src/types/homeComponentsType.ts b/src/types/homeComponentsType.ts index b97251b..2900520 100644 --- a/src/types/homeComponentsType.ts +++ b/src/types/homeComponentsType.ts @@ -66,9 +66,8 @@ export interface SearchedItem { export interface StudyGuidesItem { id: number; - difficulty: string; title: string; - description: string; + link: string; } export interface SubLoadmap { From 97192dc324d1aecd2d7d3d83ec63c7b555f18279 Mon Sep 17 00:00:00 2001 From: jiohjung98 Date: Wed, 2 Oct 2024 17:39:39 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=EC=9E=AC=ED=85=8C=ED=81=AC=20api?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20url=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 2 +- src/components/practice/CategoryPractice.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 90b170b..c729b6f 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -4,7 +4,7 @@ const nextConfig = { reactStrictMode: true, images: { - domains: ['www.kobis.or.kr', 'd2qf2amuam62ps.cloudfront.net'] + domains: ['www.kobis.or.kr', 'd2qf2amuam62ps.cloudfront.net', 'scs-phinf.pstatic.net'] }, swcMinify: true, compiler: { diff --git a/src/components/practice/CategoryPractice.tsx b/src/components/practice/CategoryPractice.tsx index 28e6213..ab72bc6 100644 --- a/src/components/practice/CategoryPractice.tsx +++ b/src/components/practice/CategoryPractice.tsx @@ -33,13 +33,13 @@ const CategoryPractice = () => { onClick={() => setSubCategory('guide')} className={`pb-5 cursor-pointer ${subCategory === 'guide' ? ' text-gray700 border-b-2 border-normal ' : 'text-gray300'}`} > - 투자 가이드 + 조각투자 가이드
setSubCategory('article')} className={`pb-5 cursor-pointer ${subCategory === 'article' ? ' text-gray700 border-b-2 border-normal ' : 'text-gray300'}`} > - 아티클 + 재테크 가이드
From 8aea19263f7c8d589a1c7c2abb5f30cfda694f9b Mon Sep 17 00:00:00 2001 From: jiohjung98 Date: Wed, 2 Oct 2024 18:40:58 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EC=9E=AC=ED=85=8C=ED=81=AC=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20=ED=83=AD=20=ED=95=9C=20=EC=A4=84?= =?UTF-8?q?=EC=97=90=202=EA=B0=9C=EC=94=A9=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EB=B0=8F=20=EC=8A=A4=EC=BC=88=EB=A0=88=ED=86=A4=20ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 17 +++-- src/components/practice/CategoryPractice.tsx | 75 ++++++++++++++++--- .../CategorySubloadmapBottomArticle.tsx | 20 ++--- .../SubLoadmapBottomArticleSkeleton.tsx | 39 +++++++--- src/types/homeComponentsType.ts | 11 +-- 5 files changed, 115 insertions(+), 47 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index c729b6f..8db54e5 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -4,15 +4,20 @@ const nextConfig = { reactStrictMode: true, images: { - domains: ['www.kobis.or.kr', 'd2qf2amuam62ps.cloudfront.net', 'scs-phinf.pstatic.net'] + domains: [ + 'www.kobis.or.kr', + 'd2qf2amuam62ps.cloudfront.net', + 'scs-phinf.pstatic.net', + 'api.moaguide.com', + ], }, + swcMinify: true, + compiler: { - styledComponents: true - }, - images: { - domains: ['api.moaguide.com'], + styledComponents: true, }, + webpack: (config, { isServer }) => { if (isServer) { if (Array.isArray(config.resolve.alias)) @@ -24,7 +29,7 @@ const nextConfig = { else config.resolve.alias['msw/node'] = false; } return config; - } + }, }; export default nextConfig; \ No newline at end of file diff --git a/src/components/practice/CategoryPractice.tsx b/src/components/practice/CategoryPractice.tsx index ab72bc6..8b80acc 100644 --- a/src/components/practice/CategoryPractice.tsx +++ b/src/components/practice/CategoryPractice.tsx @@ -1,14 +1,17 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useState, useEffect } from 'react'; import { useReportStore } from '@/store/report.store'; import { Virtuoso } from 'react-virtuoso'; import { getStudyGuides, getArticles } from '@/factory/ReportLists'; import CategoryPracticeItem from './CategoryPracticeItem'; import CategoryPracticeItemSkeleton from '../skeleton/CategoryPracticeItemSkeleton'; import SubLoadmapBottomArticleSkeleton from '../skeleton/SubLoadmapBottomArticleSkeleton'; -import CategorySubloadmapBottomArticle from './CategorySubloadmapBottomArticle'; +import CategorySubloadmapBottomArticle from './CategorySubloadmapBottomArticle'; const CategoryPractice = () => { const { currentCategory, subCategory, sort, setSubCategory } = useReportStore(); + const [showSkeleton, setShowSkeleton] = useState(true); + const [guideLoaded, setGuideLoaded] = useState(false); + const [articleLoaded, setArticleLoaded] = useState(false); const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage, isLoading @@ -16,6 +19,28 @@ const CategoryPractice = () => { ? getStudyGuides(currentCategory, subCategory, sort) : getArticles(); + useEffect(() => { + if (subCategory === 'guide' && !guideLoaded) { + setShowSkeleton(true); + const timer = setTimeout(() => { + setShowSkeleton(false); + setGuideLoaded(true); + }, 1000); + return () => clearTimeout(timer); + } + + if (subCategory === 'article' && !articleLoaded) { + setShowSkeleton(true); + const timer = setTimeout(() => { + setShowSkeleton(false); + setArticleLoaded(true); + }, 1000); + return () => clearTimeout(timer); + } + + setShowSkeleton(false); + }, [subCategory, guideLoaded, articleLoaded]); + const loadMore = useCallback(() => { if (hasNextPage && !isFetching && !isFetchingNextPage && !isLoading) { setTimeout(() => { @@ -44,7 +69,7 @@ const CategoryPractice = () => {
- {isLoading ? ( + {showSkeleton || isLoading ? ( subCategory === 'guide' ? ( Array.from({ length: 10 }).map((_, i) => ) ) : ( @@ -54,16 +79,44 @@ const CategoryPractice = () => { ( - subCategory === 'guide' ? ( - - ) : ( - - ) - )} + itemContent={(index, item) => { + if (subCategory === 'guide') { + return ; + } else { + const firstItem = allPosts[index * 2]; + const secondItem = allPosts[index * 2 + 1]; + + return ( +
+ {firstItem && ( + + )} + {secondItem && ( + + )} +
+ ); + } + }} /> )}
diff --git a/src/components/practice/CategorySubloadmapBottomArticle.tsx b/src/components/practice/CategorySubloadmapBottomArticle.tsx index def1d66..157b61b 100644 --- a/src/components/practice/CategorySubloadmapBottomArticle.tsx +++ b/src/components/practice/CategorySubloadmapBottomArticle.tsx @@ -1,29 +1,29 @@ import React from 'react'; -import { SubLoadmapBottomArticleItemsProps } from '@/types/homeComponentsType'; +import { InvestmentGuideProps } from '@/types/homeComponentsType'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; -const CategorySubloadmapBottomArticle: React.FC = ({ data }) => { +const CategorySubloadmapBottomArticle: React.FC = ({ id, title, description, date, imageLink, link }) => { const router = useRouter(); const handleClick = () => { - console.log(data.id); - router.push(`/practice/${data.id}`); + console.log(link); + router.push(link); }; return ( -
+
{/* 48% 너비로 한 줄에 두 개씩 */}
{data.title}
-
{data.title}
-
{data.description}
+
{title}
+
{description}ㆍ{date}
diff --git a/src/components/skeleton/SubLoadmapBottomArticleSkeleton.tsx b/src/components/skeleton/SubLoadmapBottomArticleSkeleton.tsx index 3bc6288..97de13e 100644 --- a/src/components/skeleton/SubLoadmapBottomArticleSkeleton.tsx +++ b/src/components/skeleton/SubLoadmapBottomArticleSkeleton.tsx @@ -2,19 +2,36 @@ import React from 'react'; const SubLoadmapBottomArticleSkeleton = () => { return ( -
-
-
-
+
+ {/* 첫 번째 스켈레톤 */} +
+
+
+
+
+
+ {/* Title Skeleton */} +
+ {/* Description Skeleton */} +
+
+
-
- {/* Number and Title Skeleton */} -
- {/* Description Skeleton */} -
+ + {/* 두 번째 스켈레톤 */} +
+
+
+
+
+
+ {/* Title Skeleton */} +
+ {/* Description Skeleton */} +
+
+
- {/* Image Skeleton */} -
); }; diff --git a/src/types/homeComponentsType.ts b/src/types/homeComponentsType.ts index 2900520..51e17b9 100644 --- a/src/types/homeComponentsType.ts +++ b/src/types/homeComponentsType.ts @@ -88,23 +88,16 @@ export interface CategorySubloadmapSkeletonItemProps { isBottom: boolean; } -export interface SubLoadmapBottomArticle { +export interface InvestmentGuideProps { id: number; title: string; description: string; imageLink: string; date: string; - content: string; - pdfLink: string; + link: string; } -export interface SubLoadmapBottomArticleItemsProps { - data: SubLoadmapBottomArticle; - isTop: boolean; - isBottom: boolean; -} - export interface ArticleItem { id: number; title: string; From eec5bcd9ecee7c5d6ac5cc8a8d96241d495ed357 Mon Sep 17 00:00:00 2001 From: jiohjung98 Date: Wed, 2 Oct 2024 18:43:39 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=ED=95=99=EC=8A=B5=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=ED=83=AD=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C,=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=ED=83=AD=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/practice/CategoryPracticeItem.tsx | 11 ++++------- .../practice/CategorySubloadmapBottomArticle.tsx | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/practice/CategoryPracticeItem.tsx b/src/components/practice/CategoryPracticeItem.tsx index 391da0a..5a489d2 100644 --- a/src/components/practice/CategoryPracticeItem.tsx +++ b/src/components/practice/CategoryPracticeItem.tsx @@ -1,21 +1,18 @@ import type { StudyGuidesItem, SubLoadmap } from '@/types/homeComponentsType'; -import axios from 'axios'; -import React, { useState } from 'react'; +import React from 'react'; import { useRouter } from 'next/navigation'; const CategoryPracticeItem = ({ id, title, link }: StudyGuidesItem) => { const router = useRouter(); - const handleLink = () => { + const handleClick = () => { console.log(link); - if (link) { - router.push(link); - } + window.open(link, '_blank'); }; return (
-
+
{title}
diff --git a/src/components/practice/CategorySubloadmapBottomArticle.tsx b/src/components/practice/CategorySubloadmapBottomArticle.tsx index 157b61b..fa4f348 100644 --- a/src/components/practice/CategorySubloadmapBottomArticle.tsx +++ b/src/components/practice/CategorySubloadmapBottomArticle.tsx @@ -1,18 +1,16 @@ import React from 'react'; import { InvestmentGuideProps } from '@/types/homeComponentsType'; import Image from 'next/image'; -import { useRouter } from 'next/navigation'; const CategorySubloadmapBottomArticle: React.FC = ({ id, title, description, date, imageLink, link }) => { - const router = useRouter(); const handleClick = () => { console.log(link); - router.push(link); + window.open(link, '_blank'); }; return ( -
{/* 48% 너비로 한 줄에 두 개씩 */} +
Date: Wed, 2 Oct 2024 18:52:53 +0900 Subject: [PATCH 6/6] =?UTF-8?q?remove:=20=EC=84=9C=EB=B8=8C=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=EB=A7=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practice/CategorySubloadmapItem.tsx | 59 ------------------- 1 file changed, 59 deletions(-) delete mode 100644 src/components/practice/CategorySubloadmapItem.tsx diff --git a/src/components/practice/CategorySubloadmapItem.tsx b/src/components/practice/CategorySubloadmapItem.tsx deleted file mode 100644 index be27d72..0000000 --- a/src/components/practice/CategorySubloadmapItem.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { CategorySubloadmapItemProps, SubLoadmapBottomArticle } from '@/types/homeComponentsType'; -import axios from 'axios'; -import React, { useState } from 'react'; -import CategorySubloadmapBottomArticle from './CategorySubloadmapBottomArticle'; -import SubLoadmapBottomArticleSkeleton from '../skeleton/SubLoadmapBottomArticleSkeleton'; - -const CategorySubloadmapItem: React.FC = ({ data, isTop, isBottom }) => { - - const [details, setDetails] = useState(null); - const [showDetails, setShowDetails] = useState(false); - const [loadingDetails, setLoadingDetails] = useState(false); - const [toggleImage, setToggleImage] = useState('/images/report/toggle_button.svg'); - - const fetchDetails = async () => { - if (!details) { // 데이터가 로드되지 않았을 때만 API 호출 - setLoadingDetails(true); - try { - const response = await axios.get(`https://api.moaguide.com/study/guide/article?subcategory=${data.id}`); - setTimeout(() => { - setDetails(response.data); - setLoadingDetails(false); - }, 500); - } catch (error) { - console.error('Fetching details failed:', error); - setLoadingDetails(false); - } - } - setShowDetails(!showDetails); - setToggleImage(showDetails ? '/images/report/toggle_button.svg' : '/images/report/toggle_button_close.svg'); - }; - - return ( -
-
-
-
{`${data.number}. ${data.title}`}
-
{data.description}
-
- Toggle Details -
- - {showDetails && ( -
- {loadingDetails ? ( - Array.from({ length: 2 }).map((_, i) => ( - - )) - ) : ( - details?.map((detail, index) => ( - - )) - )} -
- )} -
- ); -}; - -export default CategorySubloadmapItem; \ No newline at end of file