이전까지 메인 페이지는 단순히 컴포넌트만 배치된 구조였다.
하지만 이제는 실제 데이터를 불러오고,
Figma 기반의 UI 기획을 바탕으로 구성도 훨씬 풍부해졌다.
이번 포스트에서는 그 변화의 흐름과 고민했던 부분,
그리고 구조적으로 어떻게 구성했는지를 정리해본다.
메인 배너: react-slick을 이용한 자동 슬라이딩 배너
이벤트 버튼: 클릭 유도형 이벤트 배너
월드 선택 영역: 서버에서 받아온 월드 데이터를 동적으로 아이콘으로 렌더링
하단 배너: 고정 안내 영역 구성
전체 페이지: 모바일 중심의 비율 (vh/vw) 사용
<Slider {...settings}>
<Box>
<BannerContainer imageKey={MainBannerImage.BANNER_1} height="35vh"/>
</Box>
<Box>
<BannerContainer imageKey={MainBannerImage.BANNER_2} height="35vh"/>
</Box>
</Slider>
react-slick으로 배너 슬라이드를 구현
BannerContainer로 이미지 출력 → 이미지 높이는 height="35vh"로 지정해 반응형 대응
autoplay, dots 등 옵션으로 UX 향상
💡 height를 props로 넘길 수 있게 리팩터링해서, 다양한 배너에 재활용할 수 있도록 설계했다.
const BannerContainer: React.FC<BannerContainerProps> = ({ imageKey, height }) => {
return (
<Image src={imageKey} alt="Banner" height={height} />
);
};
const Image = styled.img<{ height: string }>`
width: 100%;
height: ${({ height }) => height}; // 전달된 height 값을 사용
max-height: 100%;
object-fit: cover;
display: block;
`;
<Button>
<BannerContainer imageKey={EventBannerImage.BANNER_1} height="9vh"/>
</Button>
배너를 버튼 형태로 감싸 클릭 유도를 시도
background-color는 UI 톤에 맞게 #f1e7dc로 지정
향후 클릭 시 이벤트 페이지로 라우팅 기능 확장 가능
useEffect(() => {
const worldWing = GetWorldWing(MAPLEGAMEID, {});
const response = await shootingStar.launch<{ items: WorldData[] }>(worldWing);
setWorlds(response.data.items);
}, []);
<WorldIconsContainer>
{worlds.map((world) => (
<WorldIconWrapper key={world.id} onClick={handleIconClick}>
<WorldIcon
src={`https://32df21a4fa5888078cd8b4ba3dbcd246.burumarket.shop/v1/resource/images/${world.foreign_ids.logo_id}`}
alt={world.title}
/>
<WorldName>{world.title}</WorldName>
</WorldIconWrapper>
))}
</WorldIconsContainer>
서버에서 월드 정보를 받아옴 (Swagger → GetWorldWing)
받은 데이터를 map()으로 돌며 아이콘과 이름을 렌더링
월드 아이콘처럼 서버에서 단순히 이미지 ID만 주고,
URL 규칙이 명확할 땐 API 호출 없이 바로 URL로 접근하는 게 더 효율적이다.
<WorldIcon src={`.../${world.foreign_ids.logo_id}`} />
<WorldName>{world.title}</WorldName>
클릭 시 /trade 페이지로 이동
💡 처음부터 dummy 데이터 없이 실데이터 기반으로 설계해
유지보수성과 확장성이 뛰어난 구조가 됐다
<BannerContainer imageKey={BottomBannerImage.BANNER_1} height="9vh"/>
메인 하단 영역 고정 배너
홍보, 공지, 정책 안내 등 다양한 용도로 사용 가능
<MainBanner />
<EventButton />
<WorldSelectButton />
<BottomBanner />
레이아웃은 단순하지만, 각 컴포넌트 내부에서 의미 있는 기능 처리
페이지 전체가 모바일 비율 (vh, vw) 기준으로 설계되어 작은 화면에서도 안정적인 표현
이번 개편에서는 단순히 보이는 UI를 넘어서
실제 데이터를 어떻게 받아오고, 화면에 바인딩할 것인가에 대한 고민이 많았다.
특히, 월드 아이콘처럼 서버에 등록된 이미지 ID를 불러와 URL로 조합하는 방식은
백엔드와 프론트 간의 협업에서 유연하게 동작하도록 설계되었다.