자 저번까지는 Main section 까지 만들었고 이제는 교회 소개를 만들어보자
아무래도 교회소개부분은 설명할게 별로없어 그냥 css고 tailwindcss를 적용했다? 정도 빼고는 말할게 없을 것 같아
그래서 간단했냐?? 아니 진짜 너무 어렵더라 구조잡고 그 구조를 컨트롤하는게 생각보다 많이어려워...
백문이불여일견 일단 어떻게 했는지 결과부터봐
이게 일단 대충 만들어논 Main화면 교회 소개 파트이고
앞으로 저 Card요소에는 db에서 값을 불러와서 최신글 5개정도만 보여지도록 구성하려고 현재는 저 영역의 코드가 전부 하나로 되어있는데 만들고 나서 보니까 영역을 component로 구분해야 겠더라
이유는!
현재 클라이언트에서 이벤트가 없는 화면은 전부 SSR로 처리하고 있는데 나중에 Prisma를 통해서 값을 API로 가져올것인데 (사실 아직 어케될지 모름) 그때 CSR로할지 SSR로 할지 아직 못정했다... 근데 만약 CSR로 해야된다면 하나의 화면에 모든 코드를 구성한 파일은 전부 CSR이 될 것이 자명하다
이건 좀 아랫부분의 파트여서 빈 html을 반환하고 resource가 전부 다운받아 진 이후 가져와도 관계가 없을것 같긴한데 우선 파트를 분리해서 생각해보려고 저 부분만 CSR로 되면 더 깔끔하잖아
그래서 생각한 것은
이렇게 교회소개 파트에서도 컴포넌트를 3개로 분리하는거야
빨간색 : 전체 영역과 소개글 초록색 : 소개 카테고리 노란색 : 최근 교회소식
초록색은 굳이 분리할 필요는 없는데 차후 저런 컴포넌트를 재활용 할 수 있다라는 가정을 가지고 분리해서 사용해볼게~
자 모든게 합쳐진 기존 코드 나가신다~
app/MainNews.js
import { Church , NotebookPen , UserRoundPlus } from "lucide-react" ;
export default function MainNews () {
// 여기에 나중에 db연결해서 값 가져올것
const title = [
{
eng : "News" ,
kor : "교회소식" ,
contents1 : "새 성도가 찾아왔어요" ,
contents2 : "교회에 새로운 차량을 구매했어요" ,
contents3 : "교회를 이전했어요" ,
},
{
eng : "Weekly Bulletin" ,
kor : "주보보기" ,
contents1 : "2025-03-05 주보" ,
contents2 : "2025-02-28 주보" ,
contents3 : "2025-02-21 주보" ,
},
];
return (
< div >
< div className = "flex justify-center bg-gray-900 py-12" >
< div className = "max-w-[1400px] w-full mx-auto px-4 relative" >
< div className = "flex justify-between gap-6" >
< div className = "p-6 rounded-3xl shadow-md w-[650px] relative z-10" >
< p className = "text-lg mb-1 text-gray-200" >
예수 그리스도 안에서 행복한 새에덴교회
</ p >
< p className = "text-lg mb-1 text-gray-200 mb-4" >
공동체에 오신 것을 환영합니다!
</ p >
< h1 className = "text-4xl font-bold mb-6 text-gray-200" >
거룩하신 하나님의 뜻을 잘 분별하고 잘 따르는 교회
</ h1 >
< p className = "text-lg mb-4 text-gray-200" >
새에덴 교회 공동체는 예수 그리스도의 가르침을 따라 먼저 하나님을
사랑하고 이웃을 내몸같이 사랑하는 가르침을 실천하고 있습니다.
</ p >
< p className = "text-lg text-gray-200" >
새에덴 교회 공통체는 살아있는 예배를 하나님께 드리며, 성도가
서로 사랑하고, 지역 이웃들과 함께 행복한 교회가 되어가고
있습니다.
</ p >
</ div >
< div className = "w-[500px] h-[650px] bg-gray-100 rounded-[50px] absolute top-0 right-0 p-8" >
< div className = "grid grid-rows-2 gap-4 h-full" >
{ title . map (( item , index ) => (
< div key = { index } className = "relative pl-6" >
< span className = "absolute left-0 top-0 h-13 w-1 bg-blue-500 rounded-full" ></ span >
< h2 className = "font-bold text-black-200" > { item . eng } </ h2 >
< h2 className = "text-2xl font-bold text-black-200" >
{ item . kor }
</ h2 >
< div className = "mt-4" >
< h2 className = "text-black-200" > { item . contents1 } </ h2 >
< h2 className = "text-black-200 mt-2" > { item . contents2 } </ h2 >
< h2 className = "text-black-200 mt-2" > { item . contents3 } </ h2 >
</ div >
</ div >
)) }
</ div >
</ div >
</ div >
</ div >
</ div >
< div className = "flex w-[1200px] relative flex-row-reverse mt-15 mb-15 gap-14 justify-center" >
< div className = "bg-gray-100 border border-gray-200 w-36 h-36 rounded-full p-6 flex flex-col items-center justify-center" >
< Church size = { 62 } strokeWidth = { 1.5 } />
< h1 className = "text-lg font-semibold text-center mt-3" > 교회소개 </ h1 >
</ div >
< div className = "bg-gray-100 border border-gray-200 w-36 h-36 rounded-full p-6 flex flex-col items-center justify-center" >
< UserRoundPlus size = { 62 } strokeWidth = { 1.5 } />
< h1 className = "text-lg font-semibold text-center mt-3" > 선교소식 </ h1 >
</ div >
< div className = "bg-gray-100 border border-gray-200 w-36 h-36 rounded-full p-6 flex flex-col items-center justify-center" >
< NotebookPen size = { 62 } strokeWidth = { 1.5 } />
< h1 className = "text-lg font-semibold text-center mt-3" > 말씀교육 </ h1 >
</ div >
</ div >
</ div >
);
}
코드 부시기 On
우선 파일명이 MainNews인 것을 노란색 영역에 있는 카드로 바꿀꺼고 초록색 영역은 CircleButton으로 분리 나머지 전체영역은 MainContents로 만들겠다.
1. app/MainContents.js
import { Church , NotebookPen , UserRoundPlus } from "lucide-react" ;
import CircleButton from "@/components/CircleButton" ;
import MainNews from "./MainNews" ;
export default function MainContents () {
return (
< div >
< div className = "flex justify-center bg-gray-900 py-12" >
< div className = "max-w-[1400px] w-full mx-auto px-4 relative" >
< div className = "flex justify-between gap-6" >
< div className = "p-6 rounded-3xl shadow-md w-[650px] relative z-10" >
< p className = "text-lg mb-1 text-gray-200" >
예수 그리스도 안에서 행복한 새에덴교회
</ p >
< p className = "text-lg mb-1 text-gray-200 mb-4" >
공동체에 오신 것을 환영합니다!
</ p >
< h1 className = "text-4xl font-bold mb-6 text-gray-200" >
거룩하신 하나님의 뜻을 잘 분별하고 잘 따르는 교회
</ h1 >
< p className = "text-lg mb-4 text-gray-200" >
새에덴 교회 공동체는 예수 그리스도의 가르침을 따라 먼저 하나님을
사랑하고 이웃을 내몸같이 사랑하는 가르침을 실천하고 있습니다.
</ p >
< p className = "text-lg text-gray-200" >
새에덴 교회 공통체는 살아있는 예배를 하나님께 드리며, 성도가
서로 사랑하고, 지역 이웃들과 함께 행복한 교회가 되어가고
있습니다.
</ p >
</ div >
< MainNews />
</ div >
</ div >
</ div >
< div className = "flex w-[1200px] relative flex-row-reverse mt-15 mb-15 gap-14 justify-center" >
< CircleButton icon = { Church } text = "교회소개" />
< CircleButton icon = { UserRoundPlus } text = "선교소식" />
< CircleButton icon = { NotebookPen } text = "말씀교육" />
</ div >
</ div >
);
}
2. app/MainNews.js
export default function MainNews () {
// 여기에 나중에 db연결해서 값 가져올것
const title = [
{
eng : "News" ,
kor : "교회소식" ,
contents1 : "새 성도가 찾아왔어요" ,
contents2 : "교회에 새로운 차량을 구매했어요" ,
contents3 : "교회를 이전했어요" ,
},
{
eng : "Weekly Bulletin" ,
kor : "주보보기" ,
contents1 : "2025-03-05 주보" ,
contents2 : "2025-02-28 주보" ,
contents3 : "2025-02-21 주보" ,
},
];
return (
< div className = "w-[500px] h-[650px] bg-gray-100 rounded-[50px] absolute top-0 right-0 p-8" >
< div className = "grid grid-rows-2 gap-4 h-full" >
{ title . map (( item , index ) => (
< div key = { index } className = "relative pl-6" >
< span className = "absolute left-0 top-0 h-13 w-1 bg-blue-500 rounded-full" ></ span >
< h2 className = "font-bold text-black-200" > { item . eng } </ h2 >
< h2 className = "text-2xl font-bold text-black-200" > { item . kor } </ h2 >
< div className = "mt-4" >
< h2 className = "text-black-200" > { item . contents1 } </ h2 >
< h2 className = "text-black-200 mt-2" > { item . contents2 } </ h2 >
< h2 className = "text-black-200 mt-2" > { item . contents3 } </ h2 >
</ div >
</ div >
)) }
</ div >
</ div >
);
}
3. components/CircleButton.js
function CircleButton ({ icon : Icon , text }) {
return (
< div className = "bg-gray-100 border border-gray-200 w-36 h-36 rounded-full p-6 flex flex-col items-center justify-center" >
< a href = "#" >
< Icon size = { 62 } strokeWidth = { 1.5 } />
< h1 className = "text-lg font-semibold text-center mt-3" > { text } </ h1 >
</ a >
</ div >
);
}
export default CircleButton ;
이렇게 3개로 분리하여 작업을 했고 차후에 MainNews.js는 API 호출을 위하여 "use client"를 적용해서 CSR 로 변경하는 작업을 해야할 것 같군요~
오늘은 이만 마무리