diff --git a/src/index.css b/src/index.css
index 16601d1..192b341 100644
--- a/src/index.css
+++ b/src/index.css
@@ -48,6 +48,31 @@ textarea::placeholder {
--color-desc: #8c90a3;
}
+:root {
+ /* App shell — keep Header / Sidebar / AppLayout in sync */
+ --layout-frame: 1rem;
+ --layout-sidebar-width: 240px;
+ --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/pages/auth/CompleteProfile.tsx b/src/pages/auth/CompleteProfile.tsx
index 9ebc1a0..b744b46 100644
--- a/src/pages/auth/CompleteProfile.tsx
+++ b/src/pages/auth/CompleteProfile.tsx
@@ -1,27 +1,12 @@
import { type FC } from 'react'
-import LogoImage from '../../assets/images/logo.svg'
-import LogoSmallImage from '../../assets/images/logo-small.svg'
import CompleteProfileForm from './components/CompleteProfileForm'
+import AuthLayout from '@/shared/AuthLayout'
const CompleteProfile: FC = () => {
return (
-
-
-
-
-
-

-

-
-
-
-
-
-
-

-
-
-
+
+
+
)
}
diff --git a/src/pages/auth/Login.tsx b/src/pages/auth/Login.tsx
index 88445cc..13fc802 100644
--- a/src/pages/auth/Login.tsx
+++ b/src/pages/auth/Login.tsx
@@ -1,44 +1,25 @@
import { type FC } from 'react'
-import LogoImage from '../../assets/images/logo.svg'
-import LogoSmallImage from '../../assets/images/logo-small.svg'
import { useAuthStore } from './store/AuthStore'
import LoginStep1 from './components/LoginStep1'
import LoginStep2 from './components/LoginStep2'
+import AuthLayout from '@/shared/AuthLayout'
const Login: FC = () => {
const { stepLogin, phone } = useAuthStore()
-
return (
-
-
-
-
-
-
-

-

- {
- stepLogin === 1 ?
-
- :
- stepLogin === 2 && !!phone ?
-
- : null
- }
-
-
-
-
-
-
-
-

-
-
-
+
+ {
+ stepLogin === 1 ?
+
+ :
+ stepLogin === 2 && !!phone ?
+
+ : null
+ }
+
)
}
-export default Login
\ No newline at end of file
+export default Login
diff --git a/src/router/MainRouter.tsx b/src/router/MainRouter.tsx
index 88c5c3f..dce9ac4 100644
--- a/src/router/MainRouter.tsx
+++ b/src/router/MainRouter.tsx
@@ -1,8 +1,7 @@
import { type FC } from 'react'
import { Route, Routes } 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 MyRequests from '@/pages/request/MyRequests'
import ProformaInvoice from '@/pages/invoice/ProformaInvoice'
@@ -23,38 +22,29 @@ import PayInvoice from '@/pages/payment/PayInvoice'
const MainRouter: FC = () => {
return (
-
-
-
-
-
-
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
-
-
-
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
)
}
-export default MainRouter
\ No newline at end of file
+export default MainRouter
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 (
+
+ )
+}
+
+export default AppLayout
diff --git a/src/shared/AuthLayout.tsx b/src/shared/AuthLayout.tsx
new file mode 100644
index 0000000..a3e8c17
--- /dev/null
+++ b/src/shared/AuthLayout.tsx
@@ -0,0 +1,33 @@
+import { type FC, type ReactNode } from 'react'
+import LogoImage from '@/assets/images/logo.svg'
+import LogoSmallImage from '@/assets/images/logo-small.svg'
+
+type AuthLayoutProps = {
+ children: ReactNode
+}
+
+const AuthLayout: FC = ({ children }) => {
+ return (
+
+
+
+
+

+

+ {children}
+
+
+
+
+

+
+
+
+ )
+}
+
+export default AuthLayout
diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx
index 8d0b6a4..8561e8d 100644
--- a/src/shared/Header.tsx
+++ b/src/shared/Header.tsx
@@ -17,7 +17,7 @@ const Header: FC = () => {
const initials = `${String(data?.firstName ?? '').charAt(0)}${String(data?.lastName ?? '').charAt(0)}`
return (
-
+
{
}
-
+
-

+
-
+
{t('sidebar.menu')}
@@ -133,4 +133,4 @@ const SideBar: FC = () => {
)
}
-export default SideBar
\ No newline at end of file
+export default SideBar