-
Badge는 무료배송, 인기, best 등을 표시하기 위해서 사용했다!
공통 컴포넌트로 유연성 있게 만들어 보았다.
뱃지 계산 로직
//utils/calculateBadge.ts import type { BadgeFields } from "@/types"; export const calculateBadge = ({ shipping_type, review_count, rating, }: BadgeFields) => { const badges: string[] = []; if (shipping_type === "무료배송") badges.push("무료배송"); const hasEnoughReviews = review_count && review_count >= 10; const hasHighRating = rating && rating >= 4; if (hasEnoughReviews && hasHighRating) badges.push("Best👍"); return badges; }; //badge color 설정 export const getBadgeColor = (badge: string) => { switch (badge) { case "무료배송": return "bg-purple"; case "Best👍": return "bg-orange"; default: return "bg-gray-500"; } };
`shipping_type` : 무료배송인지 아닌지 여부
`review_count` : 리뷰 수
`rating` : 별점 평균
const badges: string[] = [];
처음에는 빈 배열로 시작해서 조건에 따라 빈 배열에 넣어준다.
if (shipping_type === "무료배송") badges.push("무료배송"); const hasEnoughReviews = review_count && review_count >= 10; const hasHighRating = rating && rating >= 4; if (hasEnoughReviews && hasHighRating) badges.push("Best👍");
`shipping_type` 이 무료배송이면 배열에 무료배송을 넣어준다.
`Best` 조건은 리뷰평점이 4.5이상, 리뷰가 10개 이상으로 카운트 했다.
조건이 전부 충족하면, Best를 넣어준다.
//badge color 설정 export const getBadgeColor = (badge: string) => { switch (badge) { case "무료배송": return "bg-purple"; case "Best👍": return "bg-orange"; default: return "bg-gray-500"; } };
`switch` 문을 사용해서 조건에 따라 다른 배경색을 반환해준다.
//Badge.tsx import type { BadgeItemProps } from "@/types"; import { calculateBadge, getBadgeColor } from "@/utils/calculateBadge"; const Badge = ({ item }: BadgeItemProps) => { const [averageRating, setAverageRating] = useState(0); useEffect(() => { const fetchRating = async () => { try { const rating = await getAverageRating(item.id); setAverageRating(rating); } catch (error) { if (error instanceof Error) { console.log(`평점 조회에 실패했습니다 : ,${error.message}`); } } }; fetchRating(); }, [item.id]); const badges = calculateBadge({ ...item, rating: averageRating }); if (badges.length === 0) return null; return ( <div className="flex items-center gap-1 mt-4 mb-1"> {badges.map((badge) => ( <span key={badge} className={`text-xs px-2 py-1 rounded-md text-white ${getBadgeColor( badge )}`} > {badge} </span> ))} </div> ); }; export default Badge;
리뷰 평점은 review의 테이블이 별도로 있어서 review의 내용을 넘겨줘야 한다.
그래서 useEffect로 수파베이스에 있는 review의 테이블을 가져와서 평점 계산한 함수를 가져온 다음 state에 넣어준다.
const badges = calculateBadge({ ...item, rating: averageRating }); if (badges.length === 0) return null;
item안에 리뷰 평균을 계산한 rating도 같이 넘겨줘야 해서
스프레드 연산자로 item과 함께 rating을 같이 넣어준다.
담은 내용을 `calculateBadge` 함수에 담아서 넘겨주고, 뱃지가 없으면 렌더링 하지 않는다.
<span key={badge} className={`text-xs px-2 py-1 rounded-md text-white ${getBadgeColor( badge )}`} > {badge} </span>
`getBadgeColor`에 있는 조건에 따라 bg를 설정해준다.
적용 결과
평점이 4이상이고, 리뷰가 10개 이상이면 Best를,
무료배송이면 무료배송 뱃지가 잘 나온다.
아무것도 없으면 빈 공간으로 나온다😊
'✨ 기억보다 기록을 > 프로젝트' 카테고리의 다른 글
20241120(수) ▶️ 굿즈샵 select 클라이언트에서 sort 해결하기+메모이제이션 (0) 2024.11.20 20241119(화) ▶️ 굿즈샵페이지 스켈레톤 구현하기, Select 정렬하기 (0) 2024.11.19 20241118(월) ▶️ 굿즈샵페이지 데이터 불러오기, 리뷰 평점 평균값 계산, 할인율 계산하기 (0) 2024.11.18 20241117(일) ▶️ 메인페이지 앨범 리스트 불러오기, 음악 스트리밍 링크 동적으로 설정하기 (0) 2024.11.17 20241115(금) ▶️ 일반 이메일 회원가입, 로그인 구현하기 (0) 2024.11.15 댓글