reddit-clone-app\client\src\pages\index.tsx
파일을 아래와 같이 수정한다.
import type { NextPage } from 'next'
import Link from 'next/link'
const Home: NextPage = () => {
return (
<div className='flex max-w-5xl px-4 pt-5 mx-auth'>
{/* 포스트 리스트 */}
<div className='w-full md:mr-3 md:w-8/12'></div>
{/* 사이드바 */}
<div className='hidden w-4/12 ml-3 md:block'>
<div className='bg-white border rounded'>
<div className='p-4 border-b'>
<p className='text-lg font-semibold text-center'>상위 커뮤니티</p>
</div>
{/* 커뮤니티 리스트 */}
<div></div>
<div className='w-full py-6 text-center'>
<Link href="/subs/create">
<a className='w-full p-2 text-center text-white bg-gray-400 rounded'>
커뮤니티 만들기
</a>
</Link>
</div>
</div>
</div>
</div>
)
}
export default Home
서버 요청 시 axios 대신 swr 모듈을 사용할 예정이다.
swr이 무엇인지는 이후 설명으로 대신하고 아래 명령어를 사용해 swr을 설치한다.
reddit-clone-app/client
경로의 터미널에서 아래 명령어를 사용해 설치한다.
npm install swr --save
reddit-clone-app\client\src\pages\index.tsx
파일에 아래 내용을 추가한다.
import axios from 'axios';
import type { NextPage } from 'next';
import Link from 'next/link';
import useSWR from 'swr';
import { Sub } from '../types';
const Home: NextPage = () => {
const fetcher = async (url: string) => {
return await axios.get(url).then(res => res.data);
}
const address = "http://localhost:5000/api/subs/sub/topSubs";
const { data: topSubs } = useSWR<Sub[]>(address, fetcher)
...생략
reddit-clone-app\server\src\routes\subs.ts
파일에 아래 내용을 추가한다.
...생략
const topSubs = async (_:Request, res:Response) => {
try {
const imageUrlExp = `COALESCE(s."imageUrn", 'http://www.gravatar.com/avatar?d=mp&f=y')`;
// 쿼리 빌더를 통해 subs 결과를 가져온다
const subs = await AppDataSource
.createQueryBuilder()
.select(`s.title, s.name, ${imageUrlExp} as "imageUrl", count(p.id) as "postCount"`)
.from(Sub, "s")
.leftJoin(Post, "p", `s.name = p."subName"`)
.groupBy('s.titlem, s.name, "imageUrl"')
.orderBy(`"postCount"`, "DESC")
.limit(5)
.execute();
return res.json(subs);
} catch (error) {
console.log(error);
return res.status(500).json({ error: "문제가 발생했습니다." });
}
}
const router = Router();
router.post('/', userMiddleware, authMiddleware, createSub);
router.get('/sub/topSubs', topSubs);
export default router;
reddit-clone-app\client\src\pages\index.tsx
파일에 아래 내용을 추가한다.
... 생략
const Home: NextPage = () => {
const { authenticated } = useAuthState();
... 생략
{/* 커뮤니티 리스트 */}
<div>
{topSubs?.map((sub) => (
<div
key={sub.name}
className='flex items-center px-4 py-2 text-xs border-b'
>
<Link href={`/r/${sub.name}`}>
<a>
<Image
src={sub.imageUrl}
className="rounded-full cursor-pointer"
alt="Sub"
width={24}
height={24}
/>
</a>
</Link>
<Link href={`/r/${sub.name}`}>
<a className='ml-2 font-bold hover:cursor-pointer'>
/r/{sub.name}
</a>
</Link>
<p className='ml-auth font-medium'>{sub.postCount}</p>
</div>
))}
// 커뮤니티 만들기 버튼은 로그인 세션이 존재할 때만 출력
</div>
{authenticated &&
<div className='w-full py-6 text-center'>
<Link href="/subs/create">
<a className='w-full p-2 text-center text-white bg-gray-400 rounded'>
커뮤니티 만들기
</a>
</Link>
</div>
}
... 생략
해당 에러는 Default imagaUrl인 http://www.gravatar.com/avatar?d=mp&f=y
를 통해 외부 이미지URL 호출을 차단하기 때문이다.
이를 허용하는 Next.js 설정파일 수정이 필요하다.
reddit-clone-app\client\next.config.js
파일을 아래의 내용으로 수정한다.
수정 내용을 적용하기 위해 Next.js Client App을 재시작한다.
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
// 추가된 내용
images:{
domains: ["www.gravatar.com"]
}
}
module.exports = nextConfig
[커뮤니티 리스트 출력]