Skip to content
Snippets Groups Projects
Commit 227b80e7 authored by Matthias Feyll's avatar Matthias Feyll :cookie:
Browse files

(ui): remove sidebar

parent 4dae015f
No related branches found
No related tags found
4 merge requests!1196[renovate] Update module golang.org/x/net to v0.32.0,!1195UI: implement add device functionality,!1167Ui refactor style,!1161Ui refactor style
......@@ -16,7 +16,7 @@ const DeviceView = () => {
<Container fluid>
<Row>
<Col lg={5} sm={12}>
<Container className='bg-white rounded c-box'>
<Container className='bg-white c-box'>
<Row>
<Col sm={12} className='mt-4'><h3 className='text-black-50'>{t('device.title')}</h3></Col>
</Row>
......@@ -40,7 +40,7 @@ const DeviceView = () => {
</Container>
</Col>
<Col xs={12} lg={7} className='mt-5 mt-lg-0'>
<Container className='bg-white rounded c-box'>
<Container className='bg-white c-box'>
<Row>
<Col xs={12} className='mt-4'>
<Nav className='justify-content-around'>
......
import { BasicLayout } from "@layout/basic.layout";
import { ProtectedLayout } from "@layout/protected.layout/protected.layout";
import DelayedRender, { SplashScreen } from "@utils/loading-fallback";
import { lazy, Suspense } from 'react';
import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router-dom";
......@@ -10,17 +11,16 @@ export const LOGIN_URL = '/login';
const DeviceView = lazy(() => import('./components/devices/view/device.view'));
const LoginLayout = lazy(() => import('./components/login/layouts/login.layout'));
// Loading fallback component
const LoadingFallback = () => <div>Loading...</div>;
export const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<BasicLayout />}>
<Route
path={LOGIN_URL}
element={
<Suspense fallback={<LoadingFallback />}>
<LoginLayout />
<Suspense fallback={null}>
<DelayedRender>
<LoginLayout />
</DelayedRender>
</Suspense>
}
/>
......@@ -28,9 +28,16 @@ export const router = createBrowserRouter(
<Route
path={DEVICE_URL}
element={
<Suspense fallback={<LoadingFallback />}>
<DeviceView />
</Suspense>
<DelayedRender
loading={{
minimumLoadingTime: 1000,
component: SplashScreen
}}
>
<Suspense fallback={null}>
<DeviceView />
</Suspense>
</DelayedRender>
}
/>
<Route
......@@ -38,6 +45,6 @@ export const router = createBrowserRouter(
element={<Navigate to={DEVICE_URL} replace={true} />}
/>
</Route>
</Route>
</Route >
)
);
\ No newline at end of file
@import "/src/shared/style/colors.scss";
$sidebar-width: 4.5em;
.head-links {
text-decoration: none;
color: map-get($theme-colors, dark);
......@@ -19,11 +17,46 @@ $sidebar-width: 4.5em;
}
}
.sidebar {
width: $sidebar-width;
height: 100vh;
}
// Add these styles to your protected.layout.scss
nav {
border-radius: 0 0 $border-radius $border-radius;
box-shadow:
0px 4px 8px mix(map-get($theme-colors, "primary"), map-get($theme-colors, "dark"), 35%),
0px 2px 4px mix(map-get($theme-colors, "primary"), map-get($theme-colors, "dark"), 20%);
.head-links {
text-decoration: none;
color: map-get($theme-colors, "dark");
padding: 8px 16px;
margin: 0 4px;
border-radius: 12px;
transition: all 0.2s ease;
.main-content {
margin-left: $sidebar-width;
&:hover {
background-color: map-get($theme-colors, "bg-primary");
}
&.active {
color: map-get($theme-colors, "primary");
background-color: map-get($theme-colors, "primary::hover");
}
}
.dropdown-menu {
border-radius: $border-radius;
box-shadow:
0px 4px 8px mix(map-get($theme-colors, "primary"), map-get($theme-colors, "dark"), 35%),
0px 2px 4px mix(map-get($theme-colors, "primary"), map-get($theme-colors, "dark"), 20%);
border: none;
padding: 8px;
.dropdown-item {
border-radius: 8px;
padding: 8px 16px;
&:hover {
background-color: map-get($theme-colors, "bg-primary");
}
}
}
}
......@@ -69,14 +69,6 @@ export const ProtectedLayout = () => {
}
);
const VerticalSidebar = () => {
return (
<div className="d-flex fixed-top flex-column flex-shrink-0 bg-white sidebar justify-content-end border-end border-dark py-3 z-2">
<FontAwesomeIcon className="clickable icon" icon={faRightFromBracket} onClick={logout} size="2x" />
</div>
)
}
const HorizontalNavbar = () => {
return (
<nav className="bg-white border-bottom border-dark py-2 d-flex align-items-center z-3 position-relative">
......@@ -87,15 +79,18 @@ export const ProtectedLayout = () => {
<Dropdown className="ms-auto px-3">
<Dropdown.Toggle as={UserIconToggle}>
<FontAwesomeIcon icon={faCircleUser} className="icon clickable" />
<FontAwesomeIcon icon={faCircleUser} className="clickable" size="2x" />
</Dropdown.Toggle>
<Dropdown.Menu as={UserIconMenu}>
<Dropdown.Item eventKey="1">{user?.name}</Dropdown.Item>
<hr />
<Dropdown.Item eventKey="1">
<Dropdown.Item eventKey="2">
<Link className="text-decoration-none text-reset" to="/">{t('protected.link.settings')}</Link>
</Dropdown.Item>
<Dropdown.Item eventKey="3" onClick={logout}>
<Link className="text-decoration-none text-reset" to="/"><FontAwesomeIcon className="clickable" icon={faRightFromBracket} />{t('protected.link.settings')}</Link>
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</nav>
......@@ -106,10 +101,7 @@ export const ProtectedLayout = () => {
<div>
<MenuProvider>
{HorizontalNavbar()}
{VerticalSidebar()}
<div className='main-content'>
<Outlet />
</div>
<Outlet />
</MenuProvider>
</div>
)
......
@import './colors.scss';
@import "./colors.scss";
$box-padding: 10px;
$border-radius: 20px;
$border-width: 2px;
.c-box {
padding: $box-padding;
background-color: white;
box-shadow: 0px 4px 4px rgba(0,0,0, .35);
position: relative;
border-radius: $border-radius;
background:
linear-gradient(white, white) padding-box,
linear-gradient(
180deg,
rgba(map-get($theme-colors, "primary"), 0.3) 0%,
rgba(map-get($theme-colors, "primary"), 0.1) 100%
)
border-box;
border: $border-width solid transparent;
box-shadow: 0px 1px 2px rgba(map-get($theme-colors, "dark"), 0.12);
}
.abstract-box {
padding: 16px $box-padding;
font-size: .90em;
font-size: 0.9em;
border-radius: calc($border-radius / 2);
}
// @each $color, $value in $theme-colors {
// .#{$color}-box {
// @extend .abstract-box;
// background-color: $value !important;
// }
// }
$theme-colors: (
'primary': #b350e0,
'primary::hover': #ddaff3af,
'bg-primary': #E1E1E1,
'danger': #ffdcdc,
'warning': #dbd116,
'dark': #595959,
'black': #000000,
"primary": #b350e0,
"primary::hover": #ddaff3af,
"bg-primary": #ededed,
"danger": #ffdcdc,
"warning": #dbd116,
"dark": #595959,
"black": #000000
);
@import '/node_modules/bootstrap/scss/bootstrap';
@import "/node_modules/bootstrap/scss/bootstrap";
......@@ -7,7 +7,3 @@
cursor: pointer;
}
}
.icon {
font-size: 1.75em;
}
import React, { useEffect, useState } from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import logo from '/public/logo.png';
interface DelayedRenderProps {
children: React.ReactNode;
loading?: {
minimumLoadingTime: number;
component: () => JSX.Element
}
}
export const SplashScreen = () => {
const [dots, setDots] = useState('');
useEffect(() => {
const dotsInterval = setInterval(() => {
setDots(prev => prev.length >= 3 ? '' : prev + '.');
}, 500);
return () => clearInterval(dotsInterval);
}, []);
return (
<div className="splash-screen-overlay">
<Container fluid className="h-100 d-flex align-items-center justify-content-center bg-bg-primary">
<Row>
<Col className="text-center">
<div className="loading-bounce mb-4">
<img
src={logo}
alt="Logo"
className="img-fluid"
style={{ width: '120px', height: '120px', objectFit: 'contain' }}
/>
</div>
<div className="loading-text">
<span className="h4 text-secondary">Loading</span>
<span className="h4 text-secondary dots-width">{dots}</span>
</div>
</Col>
</Row>
</Container>
<style>
{`
.splash-screen-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #f8f9fa;
z-index: 0;
display: flex;
align-items: center;
justify-content: center;
}
.loading-bounce {
animation: bounce 1s infinite;
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
}
.loading-text {
display: flex;
justify-content: center;
align-items: center;
}
.dots-width {
min-width: 24px;
text-align: left;
margin-left: 2px;
}
`}
</style>
</div>
);
};
export const DelayedRender: React.FC<DelayedRenderProps> = ({
children,
loading
}) => {
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
if (!loading) {
setShouldRender(true);
return;
}
const timer = setTimeout(() => {
setShouldRender(true);
}, loading.minimumLoadingTime);
return () => clearTimeout(timer);
}, [loading]);
if (!shouldRender && loading) {
const LoadingComponent = loading.component;
return <LoadingComponent />;
}
return <>{children}</>;
};
export default DelayedRender;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment