홈화면 배너 처리

This commit is contained in:
focp212@naver.com
2025-09-22 16:33:18 +09:00
parent 0480108942
commit 55424b11fb
13 changed files with 87 additions and 34 deletions

View File

@@ -8,8 +8,12 @@ export const DEFAULT_PAGE_PARAM = {
}; };
export const FilterMotionVariants = { export const FilterMotionVariants = {
hidden: {x: '100%'}, hidden: {
visible: {x: '0%'}, x: '100%'
},
visible: {
x: '0%'
},
}; };
export const FilterMotionDuration = { export const FilterMotionDuration = {
duration: 0.3 duration: 0.3
@@ -20,8 +24,12 @@ export const FilterMotionStyle = {
}; };
export const BottomSheetMotionVaiants = { export const BottomSheetMotionVaiants = {
hidden: { y: '100%' }, hidden: {
visible: { y: '0%' }, y: '100%'
},
visible: {
y: '0%'
},
}; };
export const BottomSheetMotionDuration = { export const BottomSheetMotionDuration = {
duration: 0.3 duration: 0.3

View File

@@ -0,0 +1,26 @@
import { lens } from '@dhmk/zustand-lens';
import { SetStateAction } from 'react';
import { BannerInfo } from './types';
export interface BannerInfoState {
bannerInfo: BannerInfo;
setBannerInfo: (update: SetStateAction<Partial<BannerInfo>>) => void;
};
const initialState = {
bannerInfo: {} as BannerInfo,
} as BannerInfoState;
export const createBannerInfoStore = lens<BannerInfoState>((set, get) => ({
...initialState,
setBannerInfo: (update) => {
set((state: BannerInfoState) => {
const newBannerInfo = typeof update === 'function' ? update(state.bannerInfo) : update;
return {
...state,
bannerInfo: { ...state.bannerInfo, ...newBannerInfo },
};
});
},
}));

View File

@@ -190,4 +190,7 @@ export interface EmptyTokenAddSendCodeResponse {
export interface SectionArrowProps { export interface SectionArrowProps {
isOpen?: boolean; isOpen?: boolean;
}; };
export interface BannerInfo {
HomneBottomBanner: boolean;
};

View File

@@ -2,6 +2,7 @@ import { IMAGE_ROOT } from '@/shared/constants/common';
import { AuthRegisterProps } from '../model/types'; import { AuthRegisterProps } from '../model/types';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useAppBridge } from '@/hooks/useAppBridge'; import { useAppBridge } from '@/hooks/useAppBridge';
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant';
export const AuthRegister = ({ export const AuthRegister = ({
setAuthRegisterOn, setAuthRegisterOn,
@@ -18,11 +19,6 @@ export const AuthRegister = ({
setAuthRegisterOn(false); setAuthRegisterOn(false);
}; };
const variants = {
hidden: { y: '100%' },
visible: { y: '0%' },
};
return ( return (
<> <>
{ (authRegisterOn) && { (authRegisterOn) &&
@@ -32,8 +28,8 @@ export const AuthRegister = ({
className="bottomsheet" className="bottomsheet"
initial="hidden" initial="hidden"
animate={ (authRegisterOn)? 'visible': 'hidden' } animate={ (authRegisterOn)? 'visible': 'hidden' }
variants={ variants } variants={ BottomSheetMotionVaiants }
transition={{ duration: 0.5 }} transition={ BottomSheetMotionDuration }
> >
<div className="bottomsheet-header"> <div className="bottomsheet-header">
<div className="bottomsheet-title"> <div className="bottomsheet-title">

View File

@@ -1,20 +1,27 @@
import moment from 'moment'; import moment from 'moment';
import { motion } from 'framer-motion';
import { IMAGE_ROOT } from '@/shared/constants/common'; import { IMAGE_ROOT } from '@/shared/constants/common';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { StorageKeys } from '@/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
import { setLocalStorage } from '@/shared/lib/web-view-bridge'; import { setLocalStorage } from '@/shared/lib/web-view-bridge';
import { HomeBottomBannerProps } from '../model/types'; import { HomeBottomBannerProps } from '../model/types';
import { motion } from 'framer-motion'; import { useStore } from '@/shared/model/store';
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant';
import { useEffect, useState } from 'react';
export const HomeBottomBanner = ({ export const HomeBottomBanner = ({
setBottomBannerOn, setBottomBannerOn,
bottomBannerOn bottomBannerOn
}: HomeBottomBannerProps) => { }: HomeBottomBannerProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [isFirstOpen, setIsFirstOpen] = useState<boolean>(false);
const onClickToClose = () => { const onClickToClose = () => {
// close
setBottomBannerOn(false); setBottomBannerOn(false);
useStore.getState().BannerStore.setBannerInfo({
HomneBottomBanner: true
});
}; };
const onClickToCloseDay = () => { const onClickToCloseDay = () => {
// 오늘 날짜 기록 // 오늘 날짜 기록
@@ -23,22 +30,28 @@ export const HomeBottomBanner = ({
onClickToClose(); onClickToClose();
}; };
const variants = { useEffect(() => {
hidden: { y: '100%' }, let bannerInfo = useStore.getState().BannerStore.bannerInfo;
visible: { y: '0%' }, if(!!bannerInfo.HomneBottomBanner){
}; setIsFirstOpen(false);
}
else{
setIsFirstOpen(true);
}
}, [bottomBannerOn]);
return ( return (
<> <>
{bottomBannerOn && {bottomBannerOn && isFirstOpen &&
<div className="bg-dim"></div> <div className="bg-dim"></div>
} }
<motion.div <motion.div
className="bottomsheet banner" className="bottomsheet banner"
initial="hidden" initial="hidden"
animate={ (bottomBannerOn)? 'visible': 'hidden' } animate={ (bottomBannerOn && isFirstOpen)? 'visible': 'hidden' }
variants={ variants } variants={ BottomSheetMotionVaiants }
transition={{ duration: 0.5 }} transition={ BottomSheetMotionDuration }
> >
<div className="bottomsheet-content"> <div className="bottomsheet-content">
<img <img

View File

@@ -1,26 +1,26 @@
import { lens } from '@dhmk/zustand-lens'; import { lens } from '@dhmk/zustand-lens';
import { SetStateAction } from 'react'; import { SetStateAction } from 'react';
import { UserInfo } from '@/entities/user/model/types'; import { UserInfo } from './types';
import { StorageKeys } from '~/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
export interface UserInfoState { export interface UserInfoState {
UserInfo: UserInfo; userInfo: UserInfo;
setUserInfo: (update: SetStateAction<Partial<UserInfo>>) => void; setUserInfo: (update: SetStateAction<Partial<UserInfo>>) => void;
resetUserInfo: () => void; resetUserInfo: () => void;
} };
const initialState = { const initialState = {
UserInfo: {} as UserInfo, userInfo: {} as UserInfo,
} as UserInfoState; } as UserInfoState;
export const createUserInfoStore = lens<UserInfoState>((set, get) => ({ export const createUserInfoStore = lens<UserInfoState>((set, get) => ({
...initialState, ...initialState,
setUserInfo: (update) => { setUserInfo: (update) => {
set((state: UserInfoState) => { set((state: UserInfoState) => {
const newUserInfo = typeof update === 'function' ? update(state.UserInfo) : update; const newUserInfo = typeof update === 'function' ? update(state.userInfo) : update;
return { return {
...state, ...state,
UserInfo: { ...state.UserInfo, ...newUserInfo }, userInfo: { ...state.userInfo, ...newUserInfo },
}; };
}); });
}, },

View File

@@ -21,7 +21,7 @@ export interface LoginResponse {
available2FAMethod?: Array<string>; available2FAMethod?: Array<string>;
requires2FA?: boolean; requires2FA?: boolean;
}; };
export interface UserInfo extends LoginResponse{ export interface UserInfo extends LoginResponse {
} }
export interface UserParams { export interface UserParams {

View File

@@ -10,7 +10,6 @@ import { useStore } from '@/shared/model/store';
import { StorageKeys } from '@/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
import { setLocalStorage, getLocalStorage } from '@/shared/lib/web-view-bridge'; import { setLocalStorage, getLocalStorage } from '@/shared/lib/web-view-bridge';
import { useAppBridge } from '@/hooks/useAppBridge'; import { useAppBridge } from '@/hooks/useAppBridge';
import { HeaderType } from '@/entities/common/model/types'; import { HeaderType } from '@/entities/common/model/types';
import { import {
useSetHeaderTitle, useSetHeaderTitle,
@@ -156,6 +155,8 @@ export const HomePage = () => {
checkBottomBannerOpen(); checkBottomBannerOpen();
checkAuthRegisterOpen(); checkAuthRegisterOpen();
}, []); }, []);
const setBottomBannerEffect = (mode: boolean) => { const setBottomBannerEffect = (mode: boolean) => {

View File

@@ -22,7 +22,7 @@ import {
export const BillingListPage = () => { export const BillingListPage = () => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const userInfo = useStore((state) => state.UserStore.UserInfo); const userInfo = useStore((state) => state.UserStore.userInfo);
const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New); const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New);
const [listItems, setListItems] = useState({}); const [listItems, setListItems] = useState({});

View File

@@ -22,7 +22,7 @@ import {
export const EscrowListPage = () => { export const EscrowListPage = () => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const userInfo = useStore((state) => state.UserStore.UserInfo); const userInfo = useStore((state) => state.UserStore.userInfo);
const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New); const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New);
const [listItems, setListItems] = useState({}); const [listItems, setListItems] = useState({});

View File

@@ -3,10 +3,12 @@ import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware'; import { devtools, persist } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer'; import { immer } from 'zustand/middleware/immer';
import { createUserInfoStore, UserInfoState } from '@/entities/user/model/store'; import { createUserInfoStore, UserInfoState } from '@/entities/user/model/store';
import { createBannerInfoStore, BannerInfoState } from '@/entities/common/model/store';
import { StorageKeys } from '@/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
export type RootStore = { export type RootStore = {
UserStore: UserInfoState; UserStore: UserInfoState;
BannerStore: BannerInfoState;
}; };
export const useStore = create<RootStore>()( export const useStore = create<RootStore>()(
devtools( devtools(
@@ -14,6 +16,7 @@ export const useStore = create<RootStore>()(
immer( immer(
withLenses(() => ({ withLenses(() => ({
UserStore: createUserInfoStore, UserStore: createUserInfoStore,
BannerStore: createBannerInfoStore,
})), })),
), ),
{ {

View File

@@ -75,3 +75,6 @@ main {
.tab-pane.sub { .tab-pane.sub {
padding-bottom: unset !important; padding-bottom: unset !important;
} }
.notice-box {
margin-top: 1rem;
}

View File

@@ -15,7 +15,7 @@ export const Menu = ({
setMenuOn setMenuOn
}: MenuProps) => { }: MenuProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const userInfo = useStore((state) => state.UserStore.UserInfo); const userInfo = useStore((state) => state.UserStore.userInfo);
const onClickToNavigate = (path: string) => { const onClickToNavigate = (path: string) => {
onClickToMenuClose(); onClickToMenuClose();