diff --git a/client/public/index.html b/client/public/index.html index c242e9d02229ab18ea8595314c9f4694c7b15f1e..f3cdd31fc9d9f6e576c0da7fb067f4a66310d79f 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -16,6 +16,7 @@ <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> + <link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet"> <title>ryoko | plan your projects like a journey</title> </head> diff --git a/client/src/App.tsx b/client/src/App.tsx index 429313ae1af999aa9d4e6de2d20b7afe3cb05b18..38ea359fb60fce8f888b6dae8dfcccc2ed6f4e68 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,24 +1,27 @@ import { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; -import { isLoggedIn } from 'adapters/api'; +import ProtectedRoute from 'components/helpers/Rerouters/ProtectedRoute'; +import LoginRoute from 'components/helpers/Rerouters/LoginRoute'; const Home = lazy(() => import('pages/Home')); const Login = lazy(() => import('pages/Login')); const Register = lazy(() => import('pages/Register')); const Tasks = lazy(() => import('pages/Tasks')); -const Navigation = lazy(() => import('components/ui/Navigation')); +const Projects = lazy(() => import('pages/Projects')); +const Stats = lazy(() => import('pages/Stats')); export default function App() { return ( <Router> <Suspense fallback={false}> - {isLoggedIn() && <Navigation />} <Switch> - {!isLoggedIn() && <Route path="/register" component={Register} />} - {!isLoggedIn() && <Route exact path="/" component={Home} />} - {!isLoggedIn() && <Route path="/" component={Login} />} - <Route path="/" component={Tasks} /> + <ProtectedRoute path="/tasks" component={<Tasks />} /> + <ProtectedRoute path="/projects" component={<Projects />} /> + <ProtectedRoute path="/stats" component={<Stats />} /> + <LoginRoute path="/login" component={Login} /> + <LoginRoute path="/register" component={Register} /> + <Route path="/" component={Home} /> </Switch> </Suspense> </Router> diff --git a/client/src/adapters/api.ts b/client/src/adapters/api.ts index 929c441a0d606cc634e5f0e8a308b5ebbc788afe..28227040739216551352419a16fb0f27020e02e7 100644 --- a/client/src/adapters/api.ts +++ b/client/src/adapters/api.ts @@ -1 +1 @@ -export const isLoggedIn = (): boolean => false; +export const isLoggedIn = (): boolean => true; diff --git a/client/src/components/helpers/Rerouters/LoginRoute.tsx b/client/src/components/helpers/Rerouters/LoginRoute.tsx new file mode 100644 index 0000000000000000000000000000000000000000..56de5692595ad31d6bddc743d29bb81fa2c073e0 --- /dev/null +++ b/client/src/components/helpers/Rerouters/LoginRoute.tsx @@ -0,0 +1,19 @@ +import { ComponentType } from 'react'; +import { Redirect, Route } from 'react-router-dom'; +import { isLoggedIn } from 'adapters/api'; + +interface Props { + path: string, + exact?: boolean, + component: ComponentType<any> +} +export default function ProtectedRoute({ path, exact, component }: Props) { + if (!isLoggedIn()) { + return ( + <Route path={path} exact={exact} component={component} /> + ); + } + return ( + <Redirect to="/tasks"/> + ); +} \ No newline at end of file diff --git a/client/src/components/helpers/Rerouters/ProtectedRoute.tsx b/client/src/components/helpers/Rerouters/ProtectedRoute.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c3f3daeb8e0d5f5cabaab8ac164a46f8526fed88 --- /dev/null +++ b/client/src/components/helpers/Rerouters/ProtectedRoute.tsx @@ -0,0 +1,32 @@ + +import { Redirect, Route } from 'react-router-dom'; +import { isLoggedIn } from 'adapters/api'; +import Navigation from 'components/ui/Navigation'; +import Header from 'components/ui/Header'; + +interface Props { + path: string, + exact?: boolean, + component: JSX.Element +} + + +export default function ProtectedRoute({ path, exact, component }: Props) { + console.log(component); + + + if (isLoggedIn()) { + return ( + <Route path={path} exact={exact} render={() => + <> + <Header /> + <Navigation /> + { component } + </> + } /> + ); + } + return ( + <Redirect to="/login" /> + ); +} \ No newline at end of file diff --git a/client/src/components/ui/Header/header.scss b/client/src/components/ui/Header/header.scss new file mode 100644 index 0000000000000000000000000000000000000000..4d137387d1c6b19dd9d52d0998bbef6d5e25bc06 --- /dev/null +++ b/client/src/components/ui/Header/header.scss @@ -0,0 +1,7 @@ +.site-header { + display: flex; + justify-content: space-between; + img { + padding: 35px; + } +} \ No newline at end of file diff --git a/client/src/components/ui/Header/index.tsx b/client/src/components/ui/Header/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..22257f96381524142f394bbab0ee8e299d48e709 --- /dev/null +++ b/client/src/components/ui/Header/index.tsx @@ -0,0 +1,12 @@ +import './header.scss'; +import hamburger from 'images/svg/hamburger.svg'; +import profile from 'images/svg/profile.svg'; + +export default function Header() { + return ( + <header className="site-header"> + <img src={hamburger} alt="Navigation"/> + <img src={profile} alt="Profile"/> + </header> + ); +} \ No newline at end of file diff --git a/client/src/components/ui/Navigation/index.tsx b/client/src/components/ui/Navigation/index.tsx index d1c633fd764b3745af27a745c0adaf1928d084b8..4a019f25a2382ee193855389775eea4aa0001a05 100644 --- a/client/src/components/ui/Navigation/index.tsx +++ b/client/src/components/ui/Navigation/index.tsx @@ -1,9 +1,31 @@ +import { NavLink } from 'react-router-dom'; + import './navigation.scss'; +import background from 'images/svg/nav-bg.svg'; + export default function Navigation() { return ( - <main> - <h1>Navigation</h1> - </main> + <nav className="site-nav"> + <NavLink to="/tasks" activeClassName="active" className="nav-link"> + <span className="icon material-icons-outlined"> + home + </span> + <span className="label">Home</span> + </NavLink> + <NavLink to="/projects" activeClassName="active" className="nav-link"> + <span className="icon material-icons-outlined"> + public + </span> + <span className="label">Projects</span> + </NavLink> + <NavLink to="/stats" activeClassName="active" className="nav-link"> + <span className="icon material-icons-outlined"> + public + </span> + <span className="label">Stats</span> + </NavLink> + <img src={background} alt="Background" className="background" /> + </nav> ); } \ No newline at end of file diff --git a/client/src/components/ui/Navigation/navigation.scss b/client/src/components/ui/Navigation/navigation.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5d192c40213dbd3ad8f0ab6d3994748567a1ceb9 100644 --- a/client/src/components/ui/Navigation/navigation.scss +++ b/client/src/components/ui/Navigation/navigation.scss @@ -0,0 +1,54 @@ +@use 'styles/settings.scss'as s; + +.site-nav { + position: fixed; + width: 100%; + bottom: 0; + left: 0; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + + .background { + position: absolute; + bottom: 0; + left: 0; + max-width: 100%; + height: auto; + z-index: -1; + } + + .nav-link { + color: s.$body-color; + position: relative; + padding: 10px 30px; + display: flex; + + .icon { + font-size: 24px; + line-height: 1; + } + + .label { + position: absolute; + opacity: 0; + font-size: 12px; + top: 50%; + left: 60px; + transform: translateY(-50%); + z-index: -1; + } + + &.active { + padding-right: 60px; + .icon { + font-family: 'Material Icons'; + } + + .label { + opacity: 1; + } + } + } +} \ No newline at end of file diff --git a/client/src/images/svg/hamburger.svg b/client/src/images/svg/hamburger.svg new file mode 100644 index 0000000000000000000000000000000000000000..b370555eb1a10f494e4d81dec8ff5ccd16421568 --- /dev/null +++ b/client/src/images/svg/hamburger.svg @@ -0,0 +1,5 @@ +<svg width="31" height="24" viewBox="0 0 31 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="31" height="4" rx="2" fill="#3A5255"/> +<rect y="10" width="24" height="4" rx="2" fill="#3A5255"/> +<rect y="20" width="12" height="4" rx="2" fill="#3A5255"/> +</svg> diff --git a/client/src/images/svg/nav-bg.svg b/client/src/images/svg/nav-bg.svg new file mode 100644 index 0000000000000000000000000000000000000000..f9b758d1d2d4fd62709122e286017fd8b99984c5 --- /dev/null +++ b/client/src/images/svg/nav-bg.svg @@ -0,0 +1,5 @@ +<svg width="411" height="78" viewBox="0 0 411 78" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g filter="url(#filter0_b)"> +<path d="M208.5 1.00001C35.5 -4.4826 -0.5 25.5 -0.5 25.5V77.5H411V27C411 27 381.5 6.48262 208.5 1.00001Z" fill="white"/> +</g> +</svg> diff --git a/client/src/images/svg/profile.svg b/client/src/images/svg/profile.svg new file mode 100644 index 0000000000000000000000000000000000000000..c4a4f4ee334d48fadf34dfcffa551aa5f8162b2e --- /dev/null +++ b/client/src/images/svg/profile.svg @@ -0,0 +1,4 @@ +<svg width="21" height="25" viewBox="0 0 21 25" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect x="3" width="15" height="15" rx="7.5" fill="#3A5255"/> +<rect y="18" width="21" height="7" rx="3.5" fill="#3A5255"/> +</svg> diff --git a/client/src/index.scss b/client/src/index.scss index 526bfefb7f908d5789fc1a139c8fc00ae6155db4..46b3eb5ab99157beba7219048888796cfca70a7b 100644 --- a/client/src/index.scss +++ b/client/src/index.scss @@ -46,7 +46,7 @@ a { max-width: 1280px; width: 100%; margin: 0 auto; - padding: 20px; + padding: 30px; } h1, h2, h3, h4, h5, h6 { diff --git a/client/src/pages/Projects/index.tsx b/client/src/pages/Projects/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0ad04b0e0b9476e3e8fef1b0426c4d9b7d7f832a --- /dev/null +++ b/client/src/pages/Projects/index.tsx @@ -0,0 +1,14 @@ + +import Navigation from 'components/ui/Navigation'; +import './projects.scss'; + +export default function Tasks() { + return ( + <div className="projects-page"> + <Navigation /> + <main> + <h1>Projects</h1> + </main> + </div> + ); +} \ No newline at end of file diff --git a/client/src/pages/Projects/projects.scss b/client/src/pages/Projects/projects.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/client/src/pages/Register/register.scss b/client/src/pages/Register/register.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8b137891791fe96927ad78e64b0aad7bded08bdc 100644 --- a/client/src/pages/Register/register.scss +++ b/client/src/pages/Register/register.scss @@ -0,0 +1 @@ + diff --git a/client/src/pages/Stats/index.tsx b/client/src/pages/Stats/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7a368a472572f10d8f080aeba621090d9575ebcf --- /dev/null +++ b/client/src/pages/Stats/index.tsx @@ -0,0 +1,14 @@ + +import Navigation from 'components/ui/Navigation'; +import './stats.scss'; + +export default function Tasks() { + return ( + <div className="stats-page"> + <Navigation /> + <main> + <h1>Stats</h1> + </main> + </div> + ); +} \ No newline at end of file diff --git a/client/src/pages/Stats/stats.scss b/client/src/pages/Stats/stats.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/client/src/pages/Tasks/index.tsx b/client/src/pages/Tasks/index.tsx index 9978280ce48e8acc50cb8fbd858913143d108c66..6e12d538b58dc19f9ac96dc2076d4737cb7bb82b 100644 --- a/client/src/pages/Tasks/index.tsx +++ b/client/src/pages/Tasks/index.tsx @@ -2,8 +2,13 @@ import './tasks.scss'; export default function Tasks() { return ( - <main> - <h1>Tasks</h1> - </main> + <> + <div className="tasks-page page-container"> + <main className="content-container"> + <h1>Tasks</h1> + <p>Hey Daniel, you have <strong>10</strong> Tasks for today.</p> + </main> + </div> + </> ); } \ No newline at end of file