Project 중 Prisma의 실습이 필요해서 우선 DB에 값이 들어간 User 테이블가지고 테스트를 해볼까해
그런데 문제는 아직 cloud storage를 안만들어놔서 프로필 사진까지는 연동이 힘들다 이말이야
그리고 또 한가지는 내가 시간이 없어서 퍼블리싱을 일일히 하기가 어려워서 AI의 도움을 받다보니 state같은 관리를 AI가 만들어줘 버렸어... 나중에는 한번 만들어볼게 이번엔 간단하게 원리만 집고가보자
이번에 해야할 것은
우리교회 드랍박스에 있는 섬기는 사람들 목록조회야
구조는 Tab별로 전체 ~ 직분별로 나누어 교회 있는 사람들을 조회할 수 있는 페이지를 만드는것이고 현재 이것으로 진행한 이유는 DB에 값이 USER 밖에 없어서 그래
자 실습을 해보자
component에 우선 profile을 만들었고, 그것을 참조하는 leadership/page.js 를 만들어서 사용할 거야
1. /component/profile.js
"use client" ;
import { useState } from "react" ;
export default function Profile ( {tabs , staffMembers }) {
const [ activeTab , setActiveTab ] = useState ( "전체" );
return (
< div className = "max-w-6xl mx-auto p-6" >
{ /* Tabs */ }
< div className = "flex flex-wrap mb-8 border-b" >
{ tabs . map (( tab ) => (
< button
key = { tab }
className = { `px-6 py-3 text-lg font-medium transition-colors duration-200
${
activeTab === tab
? "text-blue-600 border-b-2 border-blue-600"
: "text-gray-600 hover:text-blue-500"
} ` }
onClick = { () => setActiveTab ( tab ) }
>
{ tab }
</ button >
)) }
</ div >
{ /* Content Section */ }
< div className = "mb-8" >
{ /* Section Title */ }
< div className = "flex items-center mb-6" >
< div className = "w-2 h-6 bg-blue-600 mr-3" ></ div >
< h2 className = "text-xl font-bold text-blue-600" > { activeTab } </ h2 >
</ div >
{ /* Staff Grid */ }
< div className = "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6" >
{ staffMembers [ activeTab ]?. map (( member , index ) => (
< div key = { index } className = "flex flex-col items-center" >
< div className = "w-40 h-48 overflow-hidden mb-3 border border-gray-200 rounded shadow-sm" >
< img
src = { member . image }
alt = { member . name }
className = "w-full h-full object-cover"
/>
</ div >
< h3 className = "text-lg font-bold" > { member . name } </ h3 >
< p className = "text-gray-600" > { member . position } </ p >
</ div >
)) }
</ div >
</ div >
</ div >
);
}
우선 tabs, staffMembers 를 props로 받아와서 탭과 활성화된 탭에 해당하는 profile을 조회해야겠지? 그럼 state는 당연히 탭의 활성화 유무를 알 수 있어야겟네? 그래서 activeTab을 usestate로 만들었어
첫번째 헷갈릴 수 있는 문법 설명
< div className = "flex flex-wrap mb-8 border-b" >
{ tabs . map (( tab ) => (
< button
key = { tab }
className = { `px-6 py-3 text-lg font-medium transition-colors duration-200
${
activeTab === tab
? "text-blue-600 border-b-2 border-blue-600"
: "text-gray-600 hover:text-blue-500"
} ` }
onClick = { () => setActiveTab ( tab ) }
>
{ tab }
</ button >
)) }
</ div >
${}는 템플릿 리터럴에서 사용되는 문법 이고, 템플릿 리터럴은 ``(백틱)으로 둘러쌓인 문자열로, 안에 javscript표션식을 삽입할 수 있어 여기서 사용한건 탭이 활성화된 탭과 같은 tab을 찾아 그 탭은 blue로 표현하고 아닌탭은 gray로 표시하는거야
두번째로 헷갈릴 수 있는 문법
< div className = "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6" >
{ staffMembers [ activeTab ]?. map (( member , index ) => (
< div key = { index } className = "flex flex-col items-center" >
< div className = "w-40 h-48 overflow-hidden mb-3 border border-gray-200 rounded shadow-sm" >
< img
src = { member . image }
alt = { member . name }
className = "w-full h-full object-cover"
/>
</ div >
< h3 className = "text-lg font-bold" > { member . name } </ h3 >
< p className = "text-gray-600" > { member . position } </ p >
</ div >
)) }
</ div >
?. 은 옵셔널 체이닝 연산자 로써 Javascript에서 객체의 속성이나 메서드에 안전하게 접근을 해줄수 있어 자 무슨뜻이냐면 위의 staffMembers[activeTab] 이것이 만약 undefined나 null일 수 있잖아 그럴때 ?.를 사용하면 오류를 발생시키지 않고 그냥 undefined를 반환해 이걸 사용하지않으면 그대로 오류가 발생하게 되어 버렷
끝이다~ 오늘은 간단하게 이정도만 하고 Prisma로 page에서 값을 가져와 props로 넘겨주는것은 다음시간에 계속 이어갈게~