From dcb2c1326c1998c9811bf1462861dfe6255d8c8a Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Fri, 17 Jul 2026 19:02:39 +0330 Subject: [PATCH] refactor layout --- src/index.css | 26 ++++++++ src/router/MainRouter.tsx | 134 +++++++++++++++++--------------------- src/shared/AppLayout.tsx | 30 +++++++++ src/shared/Header.tsx | 2 +- src/shared/Sidebar.tsx | 8 +-- 5 files changed, 122 insertions(+), 78 deletions(-) create mode 100644 src/shared/AppLayout.tsx diff --git a/src/index.css b/src/index.css index 1c50f30..dc67c4c 100644 --- a/src/index.css +++ b/src/index.css @@ -48,6 +48,32 @@ textarea::placeholder { --color-desc: #8c90a3; } +:root { + /* App shell — keep Header / Sidebar / AppLayout in sync */ + --layout-frame: 1rem; + --layout-sidebar-width: 240px; + /* Sidebar width + frame gap (was 269px ≈ 29px gutter — felt too wide) */ + --layout-main-offset: calc(var(--layout-sidebar-width) + var(--layout-frame)); + --layout-header-height: 3rem; + --layout-header-height-xl: 4rem; + --layout-header-stack: calc(var(--layout-header-height) + 0.75rem); + --layout-header-stack-xl: calc(var(--layout-header-height-xl) + 1rem); + --layout-content-pad-x: 1rem; +} + +.app-main { + scrollbar-gutter: stable; +} + +.no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + tbody tr:nth-child(odd) { background-color: #f5f7fc; } diff --git a/src/router/MainRouter.tsx b/src/router/MainRouter.tsx index 4ec3d12..d99f85f 100644 --- a/src/router/MainRouter.tsx +++ b/src/router/MainRouter.tsx @@ -1,8 +1,7 @@ import { type FC } from "react"; import { Route, Routes, useLocation } from "react-router-dom"; import Home from "../pages/home/Home"; -import SideBar from "../shared/Sidebar"; -import Header from "../shared/Header"; +import AppLayout from "../shared/AppLayout"; import { Paths } from "@/config/Paths"; import ProformaInvoice from "@/pages/invoice/ProformaInvoice"; import CreateInvoice from "@/pages/invoice/Create"; @@ -72,88 +71,77 @@ const MainRouter: FC = () => { } return ( -
-
- -
-
-
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> + } /> + } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> + } /> + } /> + } /> - } /> - } /> - } /> + } /> + } /> + } /> - } /> - } /> - } /> + } /> + } /> + } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> + } /> + } /> - } /> - } /> - - } /> - } /> - } /> - -
-
-
-
+ } /> + } /> + } /> + + ); }; diff --git a/src/shared/AppLayout.tsx b/src/shared/AppLayout.tsx new file mode 100644 index 0000000..3a947e0 --- /dev/null +++ b/src/shared/AppLayout.tsx @@ -0,0 +1,30 @@ +import { type FC, type ReactNode } from 'react' +import Header from './Header' +import SideBar from './Sidebar' + +type AppLayoutProps = { + children: ReactNode +} + +/** + * Authenticated app shell: fixed header + sidebar, one scrollable main column. + * Horizontal padding on the scrollport keeps content clear of the RTL scrollbar. + */ +const AppLayout: FC = ({ children }) => { + return ( +
+
+ + +
+
+
+ {children} +
+
+
+
+ ) +} + +export default AppLayout diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index 5c58f16..99d0d35 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -28,7 +28,7 @@ const Header: FC = () => { }, [location.pathname]); return ( -
+
{ )}
-
+
-
+
{t('sidebar.menu')}