Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(shared): 바텀 네비게이션 바와 헤더에 유저 인증 필요한 경우 모달창 띄우는 기능 추가 #264

Merged
merged 4 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions packages/shared/components/AlertModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
} from '@chakra-ui/react';

export type AlertModalProps = {
modalTitle: string;
modalContent: string;
modalTitle?: string;
modalContent?: string;
btnTitle: string;
onClick?: VoidFunction;
} & Omit<ModalProps, 'children'>;
Expand All @@ -33,17 +33,24 @@ export default function AlertModal({
{modalTitle}
</ModalHeader>
<ModalCloseButton />
<ModalBody>{modalContent}</ModalBody>

<ModalBody whiteSpace="pre-wrap">{modalContent}</ModalBody>
<ModalFooter>
<Button colorScheme="gray" mr={3} onClick={onClose}>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
_active={{ bg: undefined }}
_hover={{ bg: undefined }}
>
취소하기
</Button>
<Button
variant="ghost"
bgColor="orange.400"
color="white"
onClick={onClick}
_active={{ bg: undefined }}
_hover={{ bg: undefined }}
>
{btnTitle}
</Button>
Expand Down
98 changes: 58 additions & 40 deletions packages/shared/layout/BottomNavBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Flex } from '@chakra-ui/react';
import { Flex, useDisclosure } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom';

import AnimalsSelectedIcon from '../../assets/bottomNavBar/icon_animals_selected.svg';
Expand All @@ -9,63 +9,81 @@ import MyPageSeletedIcon from '../../assets/bottomNavBar/icon_mypage_selected.sv
import MyPageUnselectedIcon from '../../assets/bottomNavBar/icon_mypage_unselected.svg';
import VolunteersSelectedIcon from '../../assets/bottomNavBar/icon_volunteers_selected.svg';
import VolunteersUnselectedIcon from '../../assets/bottomNavBar/icon_volunteers_unselected.svg';
import AlertModal from '../../components/AlertModal';
import PAGE_TYPE from '../../constants/pageType';
import { usePageType } from '../../hooks/usePageType';
import useAuthStore from '../../store/authStore';
import NavBarButton from './NavBarButton';
import { useBottomNavBar } from './useBottomNavBar';

export default function BottomNavBar() {
const { pageType } = usePageType();
const { isBottomNavBarVisible } = useBottomNavBar(pageType);
const { user } = useAuthStore();
const { isOpen, onOpen, onClose } = useDisclosure();

const navigate = useNavigate();

const goVolunteers = () => navigate('/volunteers');
const goAnimals = () => navigate('/animals');
const goChattings = () => navigate('/chattings');
const goMyPage = () => navigate('/mypage');
const goMyPage = () => (user ? navigate('/mypage') : onOpen());
const goLoginPage = () => {
navigate('/signin');
onClose();
};

return (
isBottomNavBarVisible && (
<Flex
bgColor="white"
w="100%"
h="50px"
px={4}
justifyContent="space-between"
borderTop="1px solid"
borderColor="gray.200"
align="center"
bottom={0}
pos="absolute"
zIndex={10}
as="nav"
>
<NavBarButton
selected={pageType === PAGE_TYPE.VOLUNTEERS}
onClick={goVolunteers}
buttonImageSrc={[VolunteersUnselectedIcon, VolunteersSelectedIcon]}
buttonText="봉사"
<>
<Flex
bgColor="white"
w="100%"
h="50px"
px={4}
justifyContent="space-between"
borderTop="1px solid"
borderColor="gray.200"
align="center"
bottom={0}
pos="absolute"
zIndex={10}
as="nav"
>
<NavBarButton
selected={pageType === PAGE_TYPE.VOLUNTEERS}
onClick={goVolunteers}
buttonImageSrc={[VolunteersUnselectedIcon, VolunteersSelectedIcon]}
buttonText="봉사"
/>
<NavBarButton
selected={pageType === PAGE_TYPE.ANIMALS}
onClick={goAnimals}
buttonImageSrc={[AnimalsUnselectedIcon, AnimalsSelectedIcon]}
buttonText="입양"
/>
<NavBarButton
selected={pageType === PAGE_TYPE.CHATTINGS}
onClick={goChattings}
buttonImageSrc={[ChattingsUnselectedIcon, ChattingsSelectedIcon]}
buttonText="채팅"
/>
<NavBarButton
selected={pageType === PAGE_TYPE.MYPAGE}
onClick={goMyPage}
buttonImageSrc={[MyPageUnselectedIcon, MyPageSeletedIcon]}
buttonText="마이"
/>
</Flex>
<AlertModal
isOpen={isOpen}
onClose={onClose}
modalTitle="로그인 페이지로 이동하기"
modalContent={`로그인이 필요한 서비스입니다.\n로그인 페이지로 이동하시겠습니까?`}
btnTitle="로그인하기"
onClick={goLoginPage}
/>
<NavBarButton
selected={pageType === PAGE_TYPE.ANIMALS}
onClick={goAnimals}
buttonImageSrc={[AnimalsUnselectedIcon, AnimalsSelectedIcon]}
buttonText="입양"
/>
<NavBarButton
selected={pageType === PAGE_TYPE.CHATTINGS}
onClick={goChattings}
buttonImageSrc={[ChattingsUnselectedIcon, ChattingsSelectedIcon]}
buttonText="채팅"
/>
<NavBarButton
selected={pageType === PAGE_TYPE.MYPAGE}
onClick={goMyPage}
buttonImageSrc={[MyPageUnselectedIcon, MyPageSeletedIcon]}
buttonText="마이"
/>
</Flex>
</>
)
);
}
99 changes: 62 additions & 37 deletions packages/shared/layout/Header/DefaultHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,82 @@
import { Box, ButtonGroup, Flex, Image, Text } from '@chakra-ui/react';
import {
Box,
ButtonGroup,
Flex,
Image,
Text,
useDisclosure,
} from '@chakra-ui/react';
import { useLocation, useNavigate } from 'react-router-dom';

import NotificationsIcon from '../../../assets/icon_notifications.svg';
import SearchIcon from '../../../assets/icon_search.svg';
import SettingsIcon from '../../../assets/icon_settings.svg';
import AlertModal from '../../../components/AlertModal';
import useAuthStore from '../../../store/authStore';
import { HeaderProps } from '../index';
import { useDefaultHeader } from './useDefaultHeader';

export default function DefaultHeader({ appType }: HeaderProps) {
const navigate = useNavigate();
const { pathname } = useLocation();
const { title, iconVisibility } = useDefaultHeader(appType);
const { user } = useAuthStore();
const { isOpen, onOpen, onClose } = useDisclosure();

const { searchIcon, settingsIcon, notificationsIcon } = iconVisibility;

const goSearch = () => navigate(`${pathname}/search`);
const goSettings = () => navigate('/settings');
const goNotifications = () => navigate('/notifications');
const goSettings = () => (user ? navigate('/settings') : onOpen());
const goNotifications = () => (user ? navigate('/notifications') : onOpen());
const goLoginPage = () => {
navigate('/signin');
onClose();
};

return (
<Flex
bgColor="orange.400"
color="white"
lineHeight={6}
pos="sticky"
zIndex={10}
w="100%"
py={2.5}
justify="center"
align="center"
top={0}
as="header"
>
<Text fontSize="md" fontWeight="medium" h={6}>
{title}
</Text>
<ButtonGroup pos="absolute" right="1rem">
{searchIcon && (
<Box onClick={goSearch} as="button">
<Image src={SearchIcon} alt="Search Icon" />
</Box>
)}
{settingsIcon && (
<Box onClick={goSettings} as="button">
<Image src={SettingsIcon} alt="Settings Icon" />
</Box>
)}
{notificationsIcon && (
<Box onClick={goNotifications} as="button">
<Image src={NotificationsIcon} alt="Notifications Icon" />
</Box>
)}
</ButtonGroup>
</Flex>
<>
<Flex
bgColor="orange.400"
color="white"
lineHeight={6}
pos="sticky"
zIndex={10}
w="100%"
py={2.5}
justify="center"
align="center"
top={0}
as="header"
>
<Text fontSize="md" fontWeight="medium" h={6}>
{title}
</Text>
<ButtonGroup pos="absolute" right="1rem">
{searchIcon && (
<Box onClick={goSearch} as="button">
<Image src={SearchIcon} alt="Search Icon" />
</Box>
)}
{settingsIcon && (
<Box onClick={goSettings} as="button">
<Image src={SettingsIcon} alt="Settings Icon" />
</Box>
)}
{notificationsIcon && (
<Box onClick={goNotifications} as="button">
<Image src={NotificationsIcon} alt="Notifications Icon" />
</Box>
)}
</ButtonGroup>
</Flex>
<AlertModal
isOpen={isOpen}
onClose={onClose}
modalTitle="로그인 페이지로 이동하기"
modalContent={`로그인이 필요한 서비스입니다.\n로그인 페이지로 이동하시겠습니까?`}
btnTitle="로그인하기"
onClick={goLoginPage}
/>
</>
);
}