diff --git a/src/assets/images/chat_icon.svg b/src/assets/images/chat_icon.svg new file mode 100644 index 0000000..79c2249 --- /dev/null +++ b/src/assets/images/chat_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/chat_icon_clicked.svg b/src/assets/images/chat_icon_clicked.svg new file mode 100644 index 0000000..a96c815 --- /dev/null +++ b/src/assets/images/chat_icon_clicked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/home_icon.svg b/src/assets/images/home_icon.svg new file mode 100644 index 0000000..05f1ee1 --- /dev/null +++ b/src/assets/images/home_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/home_icon_clicked.svg b/src/assets/images/home_icon_clicked.svg new file mode 100644 index 0000000..2474f94 --- /dev/null +++ b/src/assets/images/home_icon_clicked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/mypage_icon.svg b/src/assets/images/mypage_icon.svg new file mode 100644 index 0000000..39bbb28 --- /dev/null +++ b/src/assets/images/mypage_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/mypage_icon_clicked.svg b/src/assets/images/mypage_icon_clicked.svg new file mode 100644 index 0000000..8bdf3bd --- /dev/null +++ b/src/assets/images/mypage_icon_clicked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/qspace_icon.svg b/src/assets/images/qspace_icon.svg new file mode 100644 index 0000000..738fd78 --- /dev/null +++ b/src/assets/images/qspace_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/qspace_icon_clicked.svg b/src/assets/images/qspace_icon_clicked.svg new file mode 100644 index 0000000..deaf9b8 --- /dev/null +++ b/src/assets/images/qspace_icon_clicked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx index d62b37e..1c8effa 100644 --- a/src/components/common/Footer.tsx +++ b/src/components/common/Footer.tsx @@ -1,5 +1,170 @@ -const Footer = () => { - return
Footer
; +import { useState } from 'react'; +import styled from '@emotion/styled'; +import { + BottomNavigation, + BottomNavigationItem, + BottomNavigationIcon, + BottomNavigationLabel, +} from 'chakra-ui-bottom-navigation'; + +import HomeIcon from '@/assets/images/home_icon.svg'; +import HomeIconClicked from '@/assets/images/home_icon_clicked.svg'; +import GroupIcon from '@/assets/images/qspace_icon.svg'; +import GroupIconClicked from '@/assets/images/qspace_icon_clicked.svg'; +import ChatIcon from '@/assets/images/chat_icon.svg'; +import ChatIconClicked from '@/assets/images/chat_icon_clicked.svg'; +import MyPageIcon from '@/assets/images/mypage_icon.svg'; +import MyPageIconClicked from '@/assets/images/mypage_icon_clicked.svg'; + +import theme from '@/styles/theme'; +import { useNavigate } from 'react-router-dom'; + +interface FooterProps { + maxWidth?: string; +} +const Footer = ({ maxWidth = '425px' }: FooterProps) => { + const navigate = useNavigate(); + const [value, setValue] = useState('/'); + const [hoveredPath, setHoveredPath] = useState(null); + + const handleNavigation = (newValue: string) => { + setValue(newValue); + navigate(newValue); + }; + + const menuItems = [ + { + path: '/', + label: '홈', + icon: HomeIcon, + activeIcon: HomeIconClicked + }, + { + path: '/qspace', + label: '큐스페이스', + icon: GroupIcon, + activeIcon: GroupIconClicked + }, + { + path: '/chat', + label: '채팅', + icon: ChatIcon, + activeIcon: ChatIconClicked + }, + { + path: '/mypage', + label: '마이', + icon: MyPageIcon, + activeIcon: MyPageIconClicked + }, + ]; + + return ( + + + + {menuItems.map((item) => ( + setHoveredPath(item.path)} + onMouseLeave={() => setHoveredPath(null)}> + ( + + {item.label} + + )} /> + + {item.label} + + + ))} + + + + ); }; -export default Footer; +const FooterWrapper = styled.div` + position: fixed; + bottom: 0; + left: 0; + right: 0; + width: 100%; + display: flex; + justify-content: center; + height : 5.25rem; //84px + padding : 0; + margin : 0; +`; + +const Container = styled.div<{ maxWidth: string }>` + width: 100%; + max-width: ${props => props.maxWidth}; + background-color: ${theme.colors.white}; + overflow: hidden; + position: relative; + height: 100%; + padding: 0; + margin: 0; +`; + +const StyledNavigationItem = styled(BottomNavigationItem)` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width : 100%; + height: 100%; + cursor: pointer; + transition: all 0.2s ease-in-out; +`; + +const IconWrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + height: 1.5rem; //24px +`; + +const StyledLabel = styled(BottomNavigationLabel)<{ isActive: boolean }>` + font-family: ${theme.typography.fontFamily}; + font-size: ${theme.typography.body2.size}; + font-weight: ${theme.typography.body2.weight}; + color: ${props => props.isActive ? theme.colors.primary : theme.colors.gray[300]}; + margin-top: 4px; + text-align: center; + transition: color 0.2s ease-in-out; +`; + +const StyledBottomNavigation = styled(BottomNavigation)` + width: 100%; + height: 5.25rem; //84px + max-width: inherit; + position: relative; + left: 0; + bottom : 0; + right: 0; + display: flex; + align-items: center; + justify-content: space-around; + box-shadow: none; + padding: 10px; + margin: 0; + + && { + box-shadow: none; + } +`; + +export default Footer; \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 3654030..1782bbc 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,12 +1,13 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { RouterProvider } from 'react-router-dom'; -import { ChakraProvider } from '@chakra-ui/react'; +import { ChakraProvider, extendTheme } from '@chakra-ui/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import router from '@/router'; import { ThemeProvider } from '@emotion/react'; import { GlobalStyles } from '@/styles/GlobalStyles'; import theme from '@/styles/theme'; +import { BottomNavigationStyleConfig as BottomNavigation } from 'chakra-ui-bottom-navigation'; const queryClient = new QueryClient({ defaultOptions: { @@ -20,11 +21,17 @@ const queryClient = new QueryClient({ }, }); +const chakraTheme = extendTheme({ + components: { + BottomNavigation, + }, +}); + ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - + diff --git a/src/pages/ChatList/ChatList.tsx b/src/pages/ChatList/ChatList.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/ChatList/index.tsx b/src/pages/ChatList/index.tsx new file mode 100644 index 0000000..a45d501 --- /dev/null +++ b/src/pages/ChatList/index.tsx @@ -0,0 +1,3 @@ +export default function ChatList() { + return
ai code review test
; +} diff --git a/src/pages/MyPage/index.tsx b/src/pages/MyPage/index.tsx new file mode 100644 index 0000000..037df86 --- /dev/null +++ b/src/pages/MyPage/index.tsx @@ -0,0 +1,3 @@ +export default function MyPage() { + return
ai code review test
; +} diff --git a/src/router/index.tsx b/src/router/index.tsx index 861c25a..5e5050f 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -1,6 +1,8 @@ import RootLayout from '@/components/RootLayout'; import Login from '@/pages/Login'; +import ChatList from '@/pages/ChatList'; import Main from '@/pages/Main'; +import MyPage from '@/pages/MyPage'; import QSpaceMainPage from '@/pages/QSpaceMain'; import { createBrowserRouter } from 'react-router-dom'; @@ -13,6 +15,14 @@ const router = createBrowserRouter([ path: '/', element:
, }, + { + path: 'chat', // 채팅 목록 + element: , + }, + { + path: '/mypage', // 마이페이지 + element: , + }, { path: '/qspace', // 홈 페이지 element: ,