하단 배너

This commit is contained in:
focp212@naver.com
2025-10-29 14:28:47 +09:00
parent 88445ec607
commit c82f37fbb5
6 changed files with 167 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ import {
export interface HomeBottomBannerProps {
setBottomBannerOn: (bottomBannerOn: boolean) => void;
bottomBannerOn: boolean;
bannerList: Array<BannerList>;
};
export interface AuthRegisterProps {
setAuthRegisterOn: (authRegisterOn: boolean) => void;
@@ -79,14 +80,20 @@ export interface HomeGroupsParams {
export interface HomeGroupsResponse {
mids: Array<string>;
};
export interface HomeBannerListParams {};
export enum BannerType {
MAIN = 'MAIN',
BOTTOM = 'BOTTOM'
};
export interface HomeBannerListParams {
bannerType: BannerType;
};
export interface HomeBannerListResponse {
bannerList: Array<BannerList>
};
export interface BannerList {
bannerId: number;
title: string;
imageUrl: string;
linkUrl: string;
priority: number;
title?: string;
imageUrl?: string;
linkUrl?: string;
order?: number;
};

View File

@@ -7,6 +7,7 @@ import { IMAGE_ROOT } from '@/shared/constants/common';
import { useHomeBannerListMutation } from '../api/use-home-banner-list-mutation';
import {
BannerList,
BannerType,
HomeBannerListParams,
HomeBannerListResponse
} from '../model/types';
@@ -18,7 +19,9 @@ export const HomeBannerList = () => {
const [bannerList, setBannerList] = useState<Array<BannerList>>([]);
const callHomeBannerList = () => {
let params: HomeBannerListParams = {};
let params: HomeBannerListParams = {
bannerType: BannerType.MAIN
};
homeBannerList(params).then((rs: HomeBannerListResponse) => {
console.log(rs);

View File

@@ -8,14 +8,19 @@ import { HomeBottomBannerProps } from '../model/types';
import { useStore } from '@/shared/model/store';
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant';
import { useEffect, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import { Autoplay, Pagination } from 'swiper/modules';
export const HomeBottomBanner = ({
setBottomBannerOn,
bottomBannerOn
bottomBannerOn,
bannerList
}: HomeBottomBannerProps) => {
const { navigate } = useNavigate();
const [isFirstOpen, setIsFirstOpen] = useState<boolean>(false);
const [currentSlide, setCurrentSlide] = useState<number>(1);
const onClickToClose = () => {
setBottomBannerOn(false);
@@ -30,6 +35,13 @@ export const HomeBottomBanner = ({
onClickToClose();
};
const swiperPagination = {
type: 'fraction',
currentClass: 'current',
totalClass: 'total',
el: '.banner-page'
};
useEffect(() => {
let bannerInfo = useStore.getState().BannerStore.bannerInfo;
if(!!bannerInfo.HomneBottomBanner){
@@ -43,7 +55,7 @@ export const HomeBottomBanner = ({
return (
<>
{bottomBannerOn && isFirstOpen &&
{ bottomBannerOn && isFirstOpen &&
<div className="bg-dim"></div>
}
<motion.div
@@ -54,14 +66,46 @@ export const HomeBottomBanner = ({
transition={ BottomSheetMotionDuration }
>
<div className="bottomsheet-content">
<img
src={ IMAGE_ROOT + '/sample_banner.png' }
alt="배너"
/>
<div className="banner-page">
<span className="current">1</span>
<Swiper
modules={[Pagination, Autoplay]}
slidesPerView={ 1 }
pagination={{
type: 'fraction',
currentClass: 'current',
totalClass: 'total',
el: '.banner-page'
}}
style={{ height: '300px' }}
>
{ bannerList.map((value, index) => (
<SwiperSlide key={ `favorite-slide-key-${index}` }>
<img
src={ value.imageUrl }
alt={ value.title }
style={{
objectFit: 'contain',
width: '100%',
height: '100%'
}}
/>
</SwiperSlide>
))
}
</Swiper>
<div
className="banner-page"
style={{
zIndex: 20,
bottom: 'unset',
top: '15px',
left: 'unset',
width: 'unset',
color: 'var(--color-999999)'
}}
>
<span className="current"></span>
/
<span className="total">3</span>
<span className="total"></span>
</div>
</div>
<div className="bottom-btn">

View File

@@ -125,6 +125,7 @@
"inquiryButton": "1:1 문의하기",
"categories": {
"all": "모두",
"00": "TOP 10",
"01": "계약",
"02": "취소",
"03": "정산/세금계산서",

View File

@@ -17,6 +17,9 @@ import {
} from '@/widgets/sub-layout/use-sub-layout';
import { useStore } from '@/shared/model/store';
import { UserFavorite } from '@/entities/user/model/types';
import { useHomeBannerListMutation } from '@/entities/home/api/use-home-banner-list-mutation';
import { BannerList, BannerType, HomeBannerListParams, HomeBannerListResponse } from '@/entities/home/model/types';
import { IMAGE_ROOT } from '@/shared/constants/common';
export let homeReloadKey = 1;
export const setHomeReloadKey = () => {
@@ -25,6 +28,7 @@ export const setHomeReloadKey = () => {
export const HomePage = () => {
const { openBiometricRegistrationPopup } = useAppBridge();
const { mutateAsync: homeBannerList } = useHomeBannerListMutation();
useSetHeaderTitle('');
useSetHeaderType(HeaderType.Home);
@@ -37,6 +41,34 @@ export const HomePage = () => {
const [bottomBannerOn, setBottomBannerOn] = useState<boolean>(false);
const [authRegisterOn, setAuthRegisterOn] = useState<boolean>(false);
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
const [bannerList, setBannerList] = useState<Array<BannerList>>([]);
const callHomeBannerList = () => {
let params: HomeBannerListParams = {
bannerType: BannerType.BOTTOM
};
homeBannerList(params).then((rs: HomeBannerListResponse) => {
console.log(rs);
if(rs.bannerList && rs.bannerList.length > 0){
setBannerList(rs.bannerList);
}
else{
setBannerList([]);
}
}).finally(() => {
/*
let items = [
{title: '배너 이미지1', imageUrl: IMAGE_ROOT + '/sample_banner_0.png', linkUrl: 'http://www.google.com', order: 3},
{title: '배너 이미지2', imageUrl: IMAGE_ROOT + '/home-banner01.png', linkUrl: 'http://www.naver.com', order: 1},
{title: '배너 이미지3', imageUrl: IMAGE_ROOT + '/home-banner01.png', linkUrl: 'http://www.daum.net', order: 2},
];
items.sort((a, b) => a.order - b.order);
setBannerList(items);
*/
});
};
const checkBottomBannerOpen = () => {
if(!!bannerToday){
@@ -74,6 +106,7 @@ export const HomePage = () => {
let userFavorite = useStore.getState().UserStore.userFavorite;
setFavoriteItems(userFavorite);
callHomeBannerList();
}, []);
@@ -103,10 +136,13 @@ export const HomePage = () => {
</div>
</div>
</main>
<HomeBottomBanner
setBottomBannerOn={ setBottomBannerEffect }
bottomBannerOn={ bottomBannerOn }
></HomeBottomBanner>
{ !!bannerList && bannerList.length > 0 &&
<HomeBottomBanner
setBottomBannerOn={ setBottomBannerEffect }
bottomBannerOn={ bottomBannerOn }
bannerList={ bannerList }
></HomeBottomBanner>
}
{ (!bottomBannerOn) &&
<AuthRegister
setAuthRegisterOn={ setAuthRegisterOn }

View File

@@ -0,0 +1,55 @@
import { useStore } from "@/shared/model/store";
import { ChangeEvent, useEffect, useState } from "react";
export interface FilterSelectMidProps {
title: string;
selectValue: string;
selectSetter: (value: any) => void;
};
export const FilterSelectMid = ({
title,
selectValue,
selectSetter,
}: FilterSelectMidProps) => {
const midOptions = useStore.getState().UserStore.selectOptionsMids;
const userMid = useStore.getState().UserStore.mid;
const [filterMid, setFilterMid] = useState<string>(userMid);
const getSelectMidOptions = () => {
let rs = [];
for(let i=0;i<midOptions.length;i++){
rs.push(
<option
key={ `key-filter-select-${i}` }
value={ midOptions[i]?.value }
>{ midOptions[i]?.name }</option>
);
}
return rs;
};
const onChangeMidSelect = (val: string) => {
setFilterMid(val);
};
useEffect(() => {
}, [filterMid]);
return (
<>
<div className="opt-field">
<div className="opt-label">{ title }</div>
<div className="opt-controls">
<select
className="flex-1"
value={ filterMid }
onChange={ (e: ChangeEvent<HTMLSelectElement>) => onChangeMidSelect(e.target.value)}
>
{ getSelectMidOptions() }
</select>
</div>
</div>
</>
);
};