Skip to content

Commit

Permalink
Merge pull request #182 from Moaguide-develop/feat/testpage
Browse files Browse the repository at this point in the history
feat: 학습하기 페이지 리뉴얼 작업
  • Loading branch information
jiohjung98 authored Dec 19, 2024
2 parents 575ff81 + 76ce790 commit 6b7e4ae
Show file tree
Hide file tree
Showing 27 changed files with 1,058 additions and 77 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"scroll-lock": "^2.1.5",
"sharp": "^0.33.5",
"slick-carousel": "^1.8.1",
"swiper": "^11.1.8",
"swiper": "^11.1.15",
"uuidv4": "^6.2.13",
"zustand": "^4.5.4"
},
Expand Down
8 changes: 8 additions & 0 deletions public/images/learning/bottom_arrow_button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/learning/learning_background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/learning/learning_home.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/images/learning/learning_img.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 27 additions & 3 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}

.mySwiper .swiper-pagination {
padding-top: 100px;
/* padding-top: 100px; */
bottom: 0px;
/* 하단에 위치 */
position: absolute;
Expand Down Expand Up @@ -84,7 +84,7 @@
}

.mySwiper2 .swiper-pagination {
padding-top: 100px;
padding-top: 16px;
bottom: 0px;
position: absolute;
width: 100%;
Expand Down Expand Up @@ -129,4 +129,28 @@
.max-md\:custom-blur {
backdrop-filter: blur(2px);
}
}
}

.mySwiper2 .swiper-pagination {
position: static !important;
margin-top: 16px;
display: flex;
justify-content: center;
}

.mySwiper2 .swiper-pagination-bullet {
background-color: #888;
opacity: 1;
}

.mySwiper2 .swiper-pagination-bullet-active {
background-color: #000;
}
.custom-swiper-pagination .swiper-pagination {
position: static;
margin-top: 16px;
display: flex;
justify-content: center;
z-index: 10;
}

23 changes: 23 additions & 0 deletions src/app/learning/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Navbar from '@/components/common/Navbar';
import LearningPageClient from '@/components/learning/LearningPageClient';

const LearningPage = async () => {

const response = await fetch('http://43.200.90.72/contents/overview', { cache: 'no-store' });

if (!response.ok) {
console.error('Failed to fetch Overview API');
return <div>데이터를 가져오지 못했습니다.</div>;
}

const initialData = await response.json();

return (
<div>
<Navbar />
<LearningPageClient initialData={initialData} />
</div>
);
};

export default LearningPage;
2 changes: 1 addition & 1 deletion src/app/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useRouter } from 'next/navigation';
import React, { useCallback, useEffect, useState } from 'react';
import MypageHeader from '@/components/mypage/MypageHeader';
import MypageMenu from '@/components/mypage/MypageMenu';
import { logout, refreshAccessToken } from '@/service/auth';
import { logout } from '@/service/auth';
import { useAuthStore } from '@/store/userAuth.store';
import { getCookie, removeCookie } from '@/utils/cookie';
import { axiosInstance } from '@/service/axiosInstance';
Expand Down
1 change: 1 addition & 0 deletions src/app/product/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Navbar from '@/components/common/Navbar';
import Product from '@/components/product/Product';
import { IProductCommon, IReport, ISummaryData } from '@/types/Diviend';
import { cookies } from 'next/headers';

const ProductPage = async ({
searchParams
}: {
Expand Down
22 changes: 8 additions & 14 deletions src/components/common/Gnb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePathname, useRouter } from 'next/navigation';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useAuthStore } from '@/store/userAuth.store';
import { getCookie } from '@/utils/cookie';
import { refreshAccessToken } from '@/service/auth';
import { refreshAccessToken } from '@/service/axiosInstance';

const Gnb = () => {
const pathname = usePathname();
Expand All @@ -14,20 +14,15 @@ const Gnb = () => {
const router = useRouter();
const intervalId = useRef<NodeJS.Timeout | null>(null);

// access_token 갱신
const checkAndRefreshToken = useCallback(async () => {
const handleTokenRefresh = useCallback(async () => {
try {
const newAccessToken = await refreshAccessToken();
setIsLoggedIn(!!newAccessToken);
} catch (error) {
console.error('리프레시 토큰 갱신 실패:', error);
alert('로그인이 만료되었습니다. 다시 로그인해주세요.');
setIsLoggedIn(false);

// 요청 실패 시 interval 정지
if (intervalId.current) {
clearInterval(intervalId.current);
intervalId.current = null;
}
if (intervalId.current) clearInterval(intervalId.current);
}
}, [setIsLoggedIn]);

Expand All @@ -36,9 +31,7 @@ const Gnb = () => {
if (accessToken) {
setIsLoggedIn(true);
setIsLoading(false);

// 29분마다 토큰 갱신 시도
intervalId.current = setInterval(checkAndRefreshToken, 29 * 60 * 1000);
intervalId.current = setInterval(handleTokenRefresh, 29 * 60 * 1000);
} else {
setIsLoggedIn(false);
setIsLoading(false);
Expand All @@ -47,7 +40,8 @@ const Gnb = () => {
return () => {
if (intervalId.current) clearInterval(intervalId.current);
};
}, [checkAndRefreshToken, setIsLoggedIn]);
}, [handleTokenRefresh, setIsLoggedIn]);

if (pathname.includes('detail') && isLoading) return null;

return (
Expand Down Expand Up @@ -100,4 +94,4 @@ const Gnb = () => {
);
};

export default Gnb;
export default Gnb;
88 changes: 88 additions & 0 deletions src/components/learning/FilteredContents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Image from 'next/image';
import defaultImage from '../../../public/images/learning/learning_img.svg';

interface FilteredContentsProps {
contents: any[];
total: number;
page: number;
size: number;
onPageChange: (newPage: number) => void;
}

const FilteredContents = ({
contents,
total,
page,
size,
onPageChange,
}: FilteredContentsProps) => {
const totalPages = Math.ceil(total / size);

const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toISOString().split('T')[0];
};

return (
<div className='mt-10'>
<div className="space-y-10">
{contents.length > 0 ? (
contents.map((item) => (
<div key={item.contentId} className="flex items-center gap-4">
<div className="w-64 h-40 flex-shrink-0 overflow-hidden rounded-md">
<Image
src={item.img_link || defaultImage}
alt={item.title}
width={128}
height={80}
className="object-cover w-full h-full"
/>
</div>
<div className="h-full flex-1">
<h3 className="text-lg font-bold text-gray-800 mb-4 line-clamp-1">
{item.title}
</h3>
<p className="text-sm text-gray-600 line-clamp-2">
{item.description}
</p>
<div className="justify-end text-xs text-gray-500 mt-4 flex items-center gap-4">
<span>{formatDate(item.date)}</span>
<span>{item.likes}</span>
<span>👁 {item.views}</span>
</div>
</div>
</div>
))
) : (
<div className="text-center text-gray-500">데이터가 없습니다.</div>
)}
</div>

{/* 페이지네이션 */}
{totalPages > 1 && (
<div className="flex justify-center mt-8">
<ul className="flex items-center space-x-1">
{Array.from({ length: totalPages }, (_, i) => i + 1).map(
(pageNum) => (
<li key={pageNum}>
<button
onClick={() => onPageChange(pageNum)}
className={`w-8 h-8 flex items-center justify-center border rounded ${
page === pageNum
? 'bg-purple-600 text-white'
: 'bg-white text-gray-800 border-gray-300 hover:bg-gray-100'
}`}
>
{pageNum}
</button>
</li>
)
)}
</ul>
</div>
)}
</div>
);
};

export default FilteredContents;
Loading

0 comments on commit 6b7e4ae

Please sign in to comment.