그날의 공부기록
Home
  • FrontEnd Archive (222)
    • ✨ 기억보다 기록을 (51)
      • 트러블슈팅 (9)
      • 프로젝트 (42)
    • 📚 이론정리 (132)
      • React & Next.js (71)
      • JS & TS (16)
      • CSS (28)
      • HTML (6)
      • 알고리즘 (11)
    • 🐶 etc (39)
      • Github (6)
      • 디자인 (1)
      • VSCode (3)
      • 2022기록 (29)
Home
  • FrontEnd Archive (222)
    • ✨ 기억보다 기록을 (51)
      • 트러블슈팅 (9)
      • 프로젝트 (42)
    • 📚 이론정리 (132)
      • React & Next.js (71)
      • JS & TS (16)
      • CSS (28)
      • HTML (6)
      • 알고리즘 (11)
    • 🐶 etc (39)
      • Github (6)
      • 디자인 (1)
      • VSCode (3)
      • 2022기록 (29)
블로그 내 검색

그날의 공부기록

seokachu's Front-End Archive 🙂

  • ✨ 기억보다 기록을/프로젝트

    20241118(월) ▶️ 굿즈샵페이지 Badge 공통 컴포넌트 만들기

    2024. 11. 19.

    by. 서카츄

     

    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

    댓글

    관련글

    • 20241120(수) ▶️ 굿즈샵 select 클라이언트에서 sort 해결하기+메모이제이션 2024.11.20
    • 20241119(화) ▶️ 굿즈샵페이지 스켈레톤 구현하기, Select 정렬하기 2024.11.19
    • 20241118(월) ▶️ 굿즈샵페이지 데이터 불러오기, 리뷰 평점 평균값 계산, 할인율 계산하기 2024.11.18
    • 20241117(일) ▶️ 메인페이지 앨범 리스트 불러오기, 음악 스트리밍 링크 동적으로 설정하기 2024.11.17
맨 위로
전체 글 보기
  • Github
Tistory 로그인
Tistory 로그아웃
로그아웃 글쓰기 관리

Today

Total

seokachu's 기록저장소

블로그 이미지
서카츄

티스토리툴바