하단 배너

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

View File

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

View File

@@ -8,14 +8,19 @@ import { HomeBottomBannerProps } from '../model/types';
import { useStore } from '@/shared/model/store'; import { useStore } from '@/shared/model/store';
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant'; import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import { Autoplay, Pagination } from 'swiper/modules';
export const HomeBottomBanner = ({ export const HomeBottomBanner = ({
setBottomBannerOn, setBottomBannerOn,
bottomBannerOn bottomBannerOn,
bannerList
}: HomeBottomBannerProps) => { }: HomeBottomBannerProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [isFirstOpen, setIsFirstOpen] = useState<boolean>(false); const [isFirstOpen, setIsFirstOpen] = useState<boolean>(false);
const [currentSlide, setCurrentSlide] = useState<number>(1);
const onClickToClose = () => { const onClickToClose = () => {
setBottomBannerOn(false); setBottomBannerOn(false);
@@ -30,6 +35,13 @@ export const HomeBottomBanner = ({
onClickToClose(); onClickToClose();
}; };
const swiperPagination = {
type: 'fraction',
currentClass: 'current',
totalClass: 'total',
el: '.banner-page'
};
useEffect(() => { useEffect(() => {
let bannerInfo = useStore.getState().BannerStore.bannerInfo; let bannerInfo = useStore.getState().BannerStore.bannerInfo;
if(!!bannerInfo.HomneBottomBanner){ if(!!bannerInfo.HomneBottomBanner){
@@ -54,14 +66,46 @@ export const HomeBottomBanner = ({
transition={ BottomSheetMotionDuration } transition={ BottomSheetMotionDuration }
> >
<div className="bottomsheet-content"> <div className="bottomsheet-content">
<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 <img
src={ IMAGE_ROOT + '/sample_banner.png' } src={ value.imageUrl }
alt="배너" alt={ value.title }
style={{
objectFit: 'contain',
width: '100%',
height: '100%'
}}
/> />
<div className="banner-page"> </SwiperSlide>
<span className="current">1</span> ))
}
</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> </div>
<div className="bottom-btn"> <div className="bottom-btn">

View File

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

View File

@@ -17,6 +17,9 @@ import {
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
import { useStore } from '@/shared/model/store'; import { useStore } from '@/shared/model/store';
import { UserFavorite } from '@/entities/user/model/types'; 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 let homeReloadKey = 1;
export const setHomeReloadKey = () => { export const setHomeReloadKey = () => {
@@ -25,6 +28,7 @@ export const setHomeReloadKey = () => {
export const HomePage = () => { export const HomePage = () => {
const { openBiometricRegistrationPopup } = useAppBridge(); const { openBiometricRegistrationPopup } = useAppBridge();
const { mutateAsync: homeBannerList } = useHomeBannerListMutation();
useSetHeaderTitle(''); useSetHeaderTitle('');
useSetHeaderType(HeaderType.Home); useSetHeaderType(HeaderType.Home);
@@ -37,6 +41,34 @@ export const HomePage = () => {
const [bottomBannerOn, setBottomBannerOn] = useState<boolean>(false); const [bottomBannerOn, setBottomBannerOn] = useState<boolean>(false);
const [authRegisterOn, setAuthRegisterOn] = useState<boolean>(false); const [authRegisterOn, setAuthRegisterOn] = useState<boolean>(false);
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]); 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 = () => { const checkBottomBannerOpen = () => {
if(!!bannerToday){ if(!!bannerToday){
@@ -74,6 +106,7 @@ export const HomePage = () => {
let userFavorite = useStore.getState().UserStore.userFavorite; let userFavorite = useStore.getState().UserStore.userFavorite;
setFavoriteItems(userFavorite); setFavoriteItems(userFavorite);
callHomeBannerList();
}, []); }, []);
@@ -103,10 +136,13 @@ export const HomePage = () => {
</div> </div>
</div> </div>
</main> </main>
{ !!bannerList && bannerList.length > 0 &&
<HomeBottomBanner <HomeBottomBanner
setBottomBannerOn={ setBottomBannerEffect } setBottomBannerOn={ setBottomBannerEffect }
bottomBannerOn={ bottomBannerOn } bottomBannerOn={ bottomBannerOn }
bannerList={ bannerList }
></HomeBottomBanner> ></HomeBottomBanner>
}
{ (!bottomBannerOn) && { (!bottomBannerOn) &&
<AuthRegister <AuthRegister
setAuthRegisterOn={ setAuthRegisterOn } 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>
</>
);
};