하단 배너
This commit is contained in:
@@ -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;
|
|
||||||
};
|
};
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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){
|
||||||
@@ -43,7 +55,7 @@ export const HomeBottomBanner = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{bottomBannerOn && isFirstOpen &&
|
{ bottomBannerOn && isFirstOpen &&
|
||||||
<div className="bg-dim"></div>
|
<div className="bg-dim"></div>
|
||||||
}
|
}
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -54,14 +66,46 @@ export const HomeBottomBanner = ({
|
|||||||
transition={ BottomSheetMotionDuration }
|
transition={ BottomSheetMotionDuration }
|
||||||
>
|
>
|
||||||
<div className="bottomsheet-content">
|
<div className="bottomsheet-content">
|
||||||
<img
|
<Swiper
|
||||||
src={ IMAGE_ROOT + '/sample_banner.png' }
|
modules={[Pagination, Autoplay]}
|
||||||
alt="배너"
|
slidesPerView={ 1 }
|
||||||
/>
|
pagination={{
|
||||||
<div className="banner-page">
|
type: 'fraction',
|
||||||
<span className="current">1</span>
|
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>
|
</div>
|
||||||
<div className="bottom-btn">
|
<div className="bottom-btn">
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
"inquiryButton": "1:1 문의하기",
|
"inquiryButton": "1:1 문의하기",
|
||||||
"categories": {
|
"categories": {
|
||||||
"all": "모두",
|
"all": "모두",
|
||||||
|
"00": "TOP 10",
|
||||||
"01": "계약",
|
"01": "계약",
|
||||||
"02": "취소",
|
"02": "취소",
|
||||||
"03": "정산/세금계산서",
|
"03": "정산/세금계산서",
|
||||||
|
|||||||
@@ -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>
|
||||||
<HomeBottomBanner
|
{ !!bannerList && bannerList.length > 0 &&
|
||||||
setBottomBannerOn={ setBottomBannerEffect }
|
<HomeBottomBanner
|
||||||
bottomBannerOn={ bottomBannerOn }
|
setBottomBannerOn={ setBottomBannerEffect }
|
||||||
></HomeBottomBanner>
|
bottomBannerOn={ bottomBannerOn }
|
||||||
|
bannerList={ bannerList }
|
||||||
|
></HomeBottomBanner>
|
||||||
|
}
|
||||||
{ (!bottomBannerOn) &&
|
{ (!bottomBannerOn) &&
|
||||||
<AuthRegister
|
<AuthRegister
|
||||||
setAuthRegisterOn={ setAuthRegisterOn }
|
setAuthRegisterOn={ setAuthRegisterOn }
|
||||||
|
|||||||
55
src/shared/ui/filter/select-mid.tsx
Normal file
55
src/shared/ui/filter/select-mid.tsx
Normal 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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user