Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const nextConfig = {
'308b-203-249-127-39.ngrok-free.app',
'4870-203-249-127-39.ngrok-free.app',
'308b-203-249-127-39.ngrok-free.app',
'opgg-com-image.akamaized.net',
],
remotePatterns: [
{
Expand Down
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"react-paginate": "^8.2.0",
"react-slick": "^0.30.2",
"react-syntax-highlighter": "^15.6.1",
"react-toastify": "^11.0.0",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0",
"sharp": "^0.33.5",
Expand Down
Binary file added public/images/4581_7415.jpeg
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/posts/003542.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/posts/AD.36584394.1.jpg
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/posts/img (1).jpg
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/posts/img.jpg
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/posts/long_short_img_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/sosuke.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/app/(route)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { Metadata } from 'next';
import localFont from 'next/font/local';
import { ToastContainer } from 'react-toastify';
import Header from '../components/common/layout/Header';
import Rum from '../components/common/layout/Rum';
import UserProvider from '../components/common/layout/useProvider';
import 'react-toastify/dist/ReactToastify.css';
import '../styles/globals.css';

export const metadata: Metadata = {
Expand Down Expand Up @@ -31,6 +33,17 @@ export default function RootLayout({
<UserProvider>
<Header />
{children}
<ToastContainer
position="top-right" // 알림 위치
autoClose={3000} // 3초 후 자동 닫힘
hideProgressBar={false}
newestOnTop
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</UserProvider>
</Rum>
</body>
Expand Down
6 changes: 4 additions & 2 deletions src/app/api/blog/search/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ export async function GET(req: Request) {
const { searchParams } = new URL(req.url);

const query = searchParams.get('query') || ''; // 검색어
const page = searchParams.get('page') || '1'; // 페이지 번호
const page = parseInt(searchParams.get('page') || '0', 10); // 페이지 번호를 정수로 변환

const data = await getSearchPost(req, query);
console.log('Parsed Page:', page); // 디버깅용 로그

const data = await getSearchPost(req, page, query);

return NextResponse.json(data);
}
66 changes: 52 additions & 14 deletions src/app/components/analyze/AnalyzeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Icons from '../common/Icons';
const AnalyzeContainer = () => {
const fadeInVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
visible: { opacity: 1, y: 0, transition: { duration: 1 } },
};

const [nickname, setNickname] = useState<string>('');
Expand Down Expand Up @@ -96,18 +96,27 @@ const AnalyzeContainer = () => {
className="px-[6%] w-full h-auto flex-col flex gap-3"
>
<div className="w-full px-3 pt-3 pb-1.5 bg-white border-b border-main-1 justify-between items-end flex">
<div className="text-center text-black text-2xl font-bold font-['Plus Jakarta Sans'] leading-9">
<div className="text-center text-black text-2xl font-bold leading-9">
{ANALYZE_RESULT_TITLE[0]}
</div>
<div className="text-center text-gray-1 text-xs flex items-center gap-1 tracking-wide">
<Icons name={infoIcon} />
<p>{ANALYZE_RESULT_GUIDE[0]}</p>
</div>
</div>
<div className="pl-10 leading-9">
<p>위험도: {analysisData.investmentStyle.riskLevel}</p>
<p>거래 패턴: {analysisData.investmentStyle.tradingPattern}</p>
<p>분석: {analysisData.investmentStyle.analysis}</p>
<div className="pl-10 leading-9 tracking-wide">
<p>
<span className="font-bold">위험도 :</span>{' '}
{analysisData.investmentStyle.riskLevel}
</p>
<p>
<span className="font-bold">거래 패턴 :</span>{' '}
{analysisData.investmentStyle.tradingPattern}
</p>
<p>
<span className="font-bold">분석 :</span>{' '}
{analysisData.investmentStyle.analysis}
</p>
</div>
</motion.div>

Expand All @@ -117,27 +126,56 @@ const AnalyzeContainer = () => {
className="px-[6%] w-full h-auto flex-col flex gap-3"
>
<div className="w-full px-3 pt-3 pb-1.5 bg-white border-b border-main-1 justify-between items-end flex">
<div className="text-center text-black text-2xl font-bold font-['Plus Jakarta Sans'] leading-9">
<div className="text-center text-black text-2xl font-bold leading-9">
{ANALYZE_RESULT_TITLE[1]}
</div>
<div className="text-center text-gray-1 text-xs flex items-center gap-1 tracking-wide">
<Icons name={infoIcon} />
<p>{ANALYZE_RESULT_GUIDE[1]}</p>
</div>
</div>
<div className="pl-10 leading-9">
<p>추천 전략: {analysisData.investmentStrategy.recommendation}</p>
<div className="pl-10 leading-9 tracking-wide">
<p>
<span className="font-bold">추천 전략 :</span>{' '}
{analysisData.investmentStrategy.recommendation}
</p>
<p>
리스크 관리: {analysisData.investmentStrategy.riskManagement}
<span className="font-bold">리스크 관리 :</span>{' '}
{analysisData.investmentStrategy.riskManagement}
</p>
<p>
<span className="font-bold">분석 :</span>{' '}
{analysisData.investmentStrategy.analysis}
</p>
<p>분석: {analysisData.investmentStrategy.analysis}</p>
</div>
</motion.div>
</>
) : (
<p className="text-center mt-10 text-gray-500">
분석 데이터를 불러오는 중...
</p>
<div>
<motion.div
className="font-bold flex items-center justify-center mt-[100px] tracking-wide text-[20px]"
variants={fadeInVariants}
>
📈 {nickname}님의 제테크 타입을 분석중입니다...
</motion.div>
<div className="flex gap-3 justify-center items-center mt-[70px]">
{[0, 1, 2].map((index) => (
<motion.div
key={index}
className="w-4 h-4 bg-main-1 rounded-full"
animate={{
y: [0, -10, 0],
opacity: [1, 0.5, 1],
}}
transition={{
duration: 1.5,
repeat: Infinity,
delay: index * 0.2,
}}
/>
))}
</div>
</div>
)}
</motion.div>
);
Expand Down
90 changes: 61 additions & 29 deletions src/app/components/blog/detail/BlogDetailContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ const BlogDetailContainer = ({ postId }: PostDetailProps) => {
const currentUserId = user?.result?.nickname;
const router = useRouter();

const { scrollYProgress } = useScroll();
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001,
});

// Scroll to top before the component is painted
useLayoutEffect(() => {
window.scrollTo(0, 0);
Expand Down Expand Up @@ -59,7 +52,25 @@ const BlogDetailContainer = ({ postId }: PostDetailProps) => {

if (!blogData) {
console.log(blogData);
return <div>Loading...</div>;
return (
<div className="flex gap-3 justify-center items-center mt-7">
{[0, 1, 2].map((index) => (
<motion.div
key={index}
className="w-4 h-4 bg-main-1 rounded-full"
animate={{
y: [0, -10, 0],
opacity: [1, 0.5, 1],
}}
transition={{
duration: 1.5,
repeat: Infinity,
delay: index * 0.2,
}}
/>
))}
</div>
);
}

const handleNicknameClick = () => {
Expand All @@ -68,36 +79,57 @@ const BlogDetailContainer = ({ postId }: PostDetailProps) => {

return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
initial={{ opacity: 0, scale: 0.95, y: 50 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: -50 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
className="relative"
>
{/* 스크롤 진행바 */}
<motion.div
style={{ scaleX }}
className="fixed top-0 left-0 right-0 h-2 bg-main-1 origin-left z-50"
/>

{/* 콘텐츠 */}
<div>
className="container mx-auto p-4"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
delay: 0.3,
duration: 0.6,
ease: 'easeOut',
}}
>
<BlogHeader
tags={blogData.tags}
likeStatus={blogData.likeStatus}
likeCount={blogData.likeCount}
postId={blogData.id}
/>
<BlogTitle
title={blogData.title}
nickname={blogData.nickname}
createdAt={blogData.createdAt}
userId={blogData.userId}
onNicknameClick={handleNicknameClick}
following={blogData.following}
/>
<BlogContent content={blogData.content} />
<BlogComment postId={blogData.id} currentUserId={currentUserId} />
</div>
<motion.div
initial={{ opacity: 0, x: -30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
<BlogTitle
title={blogData.title}
nickname={blogData.nickname}
createdAt={blogData.createdAt}
userId={blogData.userId}
onNicknameClick={handleNicknameClick}
following={blogData.following}
/>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4, duration: 0.6, ease: 'easeOut' }}
>
<BlogContent content={blogData.content} />
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5, duration: 0.6, ease: 'easeOut' }}
>
<BlogComment postId={blogData.id} currentUserId={currentUserId} />
</motion.div>
</motion.div>
</motion.div>
);
};
Expand Down
20 changes: 19 additions & 1 deletion src/app/components/blog/main/all/BlogPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,25 @@ const BlogPost = ({ post }: BlogPostProps) => {
? post.tags.split(',').map((tag: string) => `#${tag}`)
: [];

const textContent = post.content.replace(/!\[.*?\]\(.*?\)/g, '').trim();
const removeHtmlTags = (content: string) => {
return content.replace(/<[^>]*>?/gm, '');
};

const removeMarkdownTags = (content: string) => {
return content
.replace(/[#*~`>+-]/g, '') // Markdown 기호 제거
.replace(/\n/g, ' ') // 줄바꿈을 공백으로 변경
.trim(); // 앞뒤 공백 제거
};

const removeImageTags = (content: string) => {
return content.replace(/!\[.*?\]\(.*?\)/g, ''); // 이미지 태그 제거
};

// 결과 출력 시 처리
const textContent = post.content
? removeImageTags(removeHtmlTags(removeMarkdownTags(post.content))).trim()
: '';

return (
<Link
Expand Down
Loading
Loading