mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-23 04:19:48 +00:00
Add sidebar component
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + React + TS</title>
|
<title>Hotel Management</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -1,9 +1,24 @@
|
|||||||
import Header from './ui/Header';
|
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
|
||||||
|
import AppLayout from './ui/AppLayout';
|
||||||
|
import User from './pages/User';
|
||||||
|
import Dashboard from './pages/Dashboard';
|
||||||
|
import Room from './pages/Room';
|
||||||
|
import NotFound from './pages/NotFound';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<BrowserRouter>
|
||||||
|
<Routes>
|
||||||
|
<Route element={<AppLayout />}>
|
||||||
|
<Route index element={<Navigate replace to="user" />} />
|
||||||
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
|
<Route path="user" element={<User />} />
|
||||||
|
<Route path="room" element={<Room />} />
|
||||||
|
</Route>
|
||||||
|
<Route path="*" element={<NotFound />} />
|
||||||
|
</Routes>
|
||||||
|
</BrowserRouter>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledDashboard = styled.main`
|
||||||
|
padding: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Dashboard = () => {
|
||||||
|
return (
|
||||||
|
<StyledDashboard>
|
||||||
|
<p>This page currently still develop. Please try again later!</p>
|
||||||
|
</StyledDashboard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledNotFound = styled.div`
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 30px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Heading = styled.h1`
|
||||||
|
font-size: 40px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Button = styled.button`
|
||||||
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: var(--light-text);
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const useMoveBack = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return () => navigate(-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NotFound = () => {
|
||||||
|
const onBack = useMoveBack();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledNotFound>
|
||||||
|
<Heading>The page not found!</Heading>
|
||||||
|
<Button onClick={onBack}>Go back!</Button>
|
||||||
|
</StyledNotFound>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NotFound;
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledRoom = styled.main`
|
||||||
|
padding: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Room = () => {
|
||||||
|
return (
|
||||||
|
<StyledRoom>
|
||||||
|
<p>Room page</p>
|
||||||
|
</StyledRoom>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Room;
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledUser = styled.main`
|
||||||
|
padding: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const User = () => {
|
||||||
|
return (
|
||||||
|
<StyledUser>
|
||||||
|
<p>User page</p>
|
||||||
|
</StyledUser>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default User;
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
:root {
|
:root {
|
||||||
|
--primary-color: #0010ba;
|
||||||
--border-color: #8c8c8c;
|
--border-color: #8c8c8c;
|
||||||
--radius-sm: 10px;
|
--radius-sm: 10px;
|
||||||
|
--hover-background-color: #f3f4f6;
|
||||||
|
--light-text: #fff;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,8 @@ button:has(svg) {
|
|||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import Header from './Header';
|
||||||
|
import Sidebar from './Sidebar';
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
const StyledAppLayout = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 300px 1fr;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
height: 100vh;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Main = styled.main`
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const AppLayout = () => {
|
||||||
|
return (
|
||||||
|
<StyledAppLayout>
|
||||||
|
<Header />
|
||||||
|
<Sidebar />
|
||||||
|
<Main>
|
||||||
|
<Outlet />
|
||||||
|
</Main>
|
||||||
|
</StyledAppLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppLayout;
|
||||||
@@ -8,7 +8,7 @@ const ButtonIcon = styled.button`
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #f3f4f6;
|
background-color: var(--hover-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
& svg {
|
& svg {
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { NavLink } from 'react-router-dom';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { MdSpaceDashboard } from 'react-icons/md';
|
||||||
|
import { HiUsers } from 'react-icons/hi2';
|
||||||
|
import { BsHouseDoorFill } from 'react-icons/bs';
|
||||||
|
|
||||||
|
const StyledNav = styled.div`
|
||||||
|
margin-top: 70px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledNavLink = styled(NavLink)`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.active {
|
||||||
|
background-color: var(--hover-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover svg,
|
||||||
|
&.active svg {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Nav = () => {
|
||||||
|
return (
|
||||||
|
<StyledNav>
|
||||||
|
<StyledNavLink to={'/dashboard'}>
|
||||||
|
<MdSpaceDashboard />
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</StyledNavLink>
|
||||||
|
<StyledNavLink to={'/user'}>
|
||||||
|
<HiUsers />
|
||||||
|
<span>User</span>
|
||||||
|
</StyledNavLink>
|
||||||
|
<StyledNavLink to={'/room'}>
|
||||||
|
<BsHouseDoorFill />
|
||||||
|
<span>Room</span>
|
||||||
|
</StyledNavLink>
|
||||||
|
</StyledNav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Nav;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import Nav from './Nav';
|
||||||
|
|
||||||
|
const StyledSidebar = styled.aside`
|
||||||
|
padding: 50px 20px;
|
||||||
|
|
||||||
|
grid-row: 1 / 3;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Heading = styled.h1`
|
||||||
|
font-size: 30px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--primary-color);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Sidebar = () => {
|
||||||
|
return (
|
||||||
|
<StyledSidebar>
|
||||||
|
<Heading>Hotel Management</Heading>
|
||||||
|
<Nav />
|
||||||
|
</StyledSidebar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sidebar;
|
||||||
Reference in New Issue
Block a user