Refactored main layout and nav

This commit is contained in:
2026-07-09 09:11:13 +02:00
parent f82f3f147b
commit e7defebed4
3 changed files with 163 additions and 112 deletions
@@ -1,17 +1,78 @@
@inherits LayoutComponentBase
<div class="flex flex-col sm:flex-row relative min-h-screen">
<!-- Updated the gradient here to use deep blue and navy -->
<div class="bg-gradient-to-b from-[#052767] to-[#020f26] sm:w-[250px] sm:h-screen sm:sticky sm:top-0 shadow-xl">
<div class="flex flex-col sm:flex-row relative min-h-screen bg-gray-50/50">
<!-- Sidebar -->
<div class="bg-gradient-to-b from-[#052767] to-[#020f26] sm:w-[250px] sm:h-screen sm:sticky sm:top-0 shadow-xl z-20">
<NavMenu />
</div>
<!-- Main Content -->
<main class="flex-1 flex flex-col">
<div class="bg-[#f7f7f7] border-b border-[#d6d5d5] flex items-center justify-between sm:justify-end h-14 sm:sticky sm:top-0 z-10 px-4 sm:px-8">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank" class="whitespace-nowrap sm:ml-6 no-underline hover:underline overflow-hidden text-ellipsis text-gray-700">About</a>
</div>
<!-- Top Bar -->
<header class="bg-white border-b border-gray-200 flex items-center justify-between h-16 sm:sticky sm:top-0 z-10 px-4 sm:px-6 shadow-sm">
<article class="px-4 sm:px-8 py-4">
<!-- Left: Forex Rates -->
<div class="hidden lg:flex items-center gap-6 text-xs font-semibold tracking-wide bg-gray-50 px-4 py-2 rounded-full border border-gray-100">
<div class="flex items-center gap-2">
<span class="text-gray-400">USD/ZAR</span>
<span class="text-green-600 flex items-center gap-0.5">R16.37</span>
</div>
<div class="w-px h-3 bg-gray-300"></div>
<div class="flex items-center gap-2">
<span class="text-gray-400">EUR/ZAR</span>
<span class="text-green-600 flex items-center gap-0.5">R18.72</span>
</div>
<div class="w-px h-3 bg-gray-300"></div>
<div class="flex items-center gap-2">
<span class="text-gray-400">GBP/ZAR</span>
<span class="text-green-600 flex items-center gap-0.5">R21.97</span>
</div>
</div>
<!-- Right: Action Menu & Profile -->
<div class="flex items-center gap-2 sm:gap-4 ml-auto">
<!-- Trip Reports -->
<button class="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-full transition-colors group relative" title="Trip Reports">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
</svg>
</button>
<!-- GDS Sync -->
<button class="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-full transition-colors group relative" title="GDS Sync">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
</button>
<!-- Mobile -->
<button class="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-full transition-colors group relative" title="Mobile">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 006 3.75v16.5a2.25 2.25 0 002.25 2.25h7.5A2.25 2.25 0 0018 20.25V3.75a2.25 2.25 0 00-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />
</svg>
</button>
<!-- Settings -->
<button class="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-full transition-colors group relative" title="Settings">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</button>
<div class="h-6 w-px bg-gray-300 mx-1 sm:mx-2"></div>
<!-- Profile -->
<button class="flex items-center gap-3 pl-2 pr-1 py-1 rounded-full hover:bg-gray-100 transition-colors">
<span class="hidden sm:block text-sm font-medium text-gray-700">J. Mokoena</span>
<div class="w-8 h-8 rounded-full bg-blue-600 text-white flex items-center justify-center font-bold text-sm shadow-inner">
A
</div>
</button>
</div>
</header>
<article class="px-4 sm:px-8 py-6">
@Body
</article>
</main>
@@ -66,14 +66,6 @@
Booking
</NavLink>
<!-- Trip Reports -->
<NavLink class="group flex items-center px-3 py-2.5 text-sm font-medium rounded-lg text-gray-300 hover:text-white hover:bg-white/10 transition-all duration-200 border-l-2 border-transparent [&.active]:bg-blue-500/20 [&.active]:text-white [&.active]:border-blue-400" href="trip-reports">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-3 flex-shrink-0 text-gray-400 group-hover:text-white group-[.active]:text-blue-400 transition-colors">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
</svg>
Trip Reports
</NavLink>
<!-- Financial -->
<NavLink class="group flex items-center px-3 py-2.5 text-sm font-medium rounded-lg text-gray-300 hover:text-white hover:bg-white/10 transition-all duration-200 border-l-2 border-transparent [&.active]:bg-blue-500/20 [&.active]:text-white [&.active]:border-blue-400" href="financial">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-3 flex-shrink-0 text-gray-400 group-hover:text-white group-[.active]:text-blue-400 transition-colors">
@@ -98,14 +90,6 @@
Visa
</NavLink>
<!-- Mobile -->
<NavLink class="group flex items-center px-3 py-2.5 text-sm font-medium rounded-lg text-gray-300 hover:text-white hover:bg-white/10 transition-all duration-200 border-l-2 border-transparent [&.active]:bg-blue-500/20 [&.active]:text-white [&.active]:border-blue-400" href="mobile">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-3 flex-shrink-0 text-gray-400 group-hover:text-white group-[.active]:text-blue-400 transition-colors">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 006 3.75v16.5a2.25 2.25 0 002.25 2.25h7.5A2.25 2.25 0 0018 20.25V3.75a2.25 2.25 0 00-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />
</svg>
Mobile
</NavLink>
<!-- Compliance -->
<NavLink class="group flex items-center px-3 py-2.5 text-sm font-medium rounded-lg text-gray-300 hover:text-white hover:bg-white/10 transition-all duration-200 border-l-2 border-transparent [&.active]:bg-blue-500/20 [&.active]:text-white [&.active]:border-blue-400" href="compliance">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-3 flex-shrink-0 text-gray-400 group-hover:text-white group-[.active]:text-blue-400 transition-colors">
@@ -122,13 +106,5 @@
VAS
</NavLink>
<!-- GDS Sync -->
<NavLink class="group flex items-center px-3 py-2.5 text-sm font-medium rounded-lg text-gray-300 hover:text-white hover:bg-white/10 transition-all duration-200 border-l-2 border-transparent [&.active]:bg-blue-500/20 [&.active]:text-white [&.active]:border-blue-400" href="gds-sync">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-3 flex-shrink-0 text-gray-400 group-hover:text-white group-[.active]:text-blue-400 transition-colors">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
GDS Sync
</NavLink>
</nav>
</div>
+95 -81
View File
@@ -8,6 +8,8 @@
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
--color-red-600: oklch(57.7% 0.245 27.325);
--color-green-600: oklch(62.7% 0.194 149.214);
--color-blue-50: oklch(97% 0.014 254.604);
--color-blue-100: oklch(93.2% 0.032 255.585);
--color-blue-200: oklch(88.2% 0.059 254.128);
--color-blue-300: oklch(80.9% 0.105 251.813);
@@ -26,6 +28,8 @@
--color-black: #000;
--color-white: #fff;
--spacing: 0.25rem;
--text-xs: 0.75rem;
--text-xs--line-height: calc(1 / 0.75);
--text-sm: 0.875rem;
--text-sm--line-height: calc(1.25 / 0.875);
--text-lg: 1.125rem;
@@ -245,6 +249,9 @@
.m-0 {
margin: 0;
}
.mx-1 {
margin-inline: var(--spacing);
}
.mx-auto {
margin-inline: auto;
}
@@ -269,12 +276,18 @@
.mb-6 {
margin-bottom: calc(var(--spacing) * 6);
}
.ml-auto {
margin-left: auto;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-3 {
height: calc(var(--spacing) * 3);
}
.h-5 {
height: calc(var(--spacing) * 5);
}
@@ -287,18 +300,12 @@
.h-10 {
height: calc(var(--spacing) * 10);
}
.h-12 {
height: calc(var(--spacing) * 12);
}
.h-14 {
height: calc(var(--spacing) * 14);
.h-16 {
height: calc(var(--spacing) * 16);
}
.h-20 {
height: calc(var(--spacing) * 20);
}
.min-h-\[3\.5rem\] {
min-height: 3.5rem;
}
.min-h-\[4\.5rem\] {
min-height: 4.5rem;
}
@@ -308,9 +315,6 @@
.w-5 {
width: calc(var(--spacing) * 5);
}
.w-6 {
width: calc(var(--spacing) * 6);
}
.w-8 {
width: calc(var(--spacing) * 8);
}
@@ -326,6 +330,9 @@
.w-full {
width: 100%;
}
.w-px {
width: 1px;
}
.min-w-full {
min-width: 100%;
}
@@ -359,6 +366,12 @@
.justify-between {
justify-content: space-between;
}
.justify-center {
justify-content: center;
}
.gap-0\.5 {
gap: calc(var(--spacing) * 0.5);
}
.gap-2 {
gap: calc(var(--spacing) * 2);
}
@@ -368,6 +381,9 @@
.gap-4 {
gap: calc(var(--spacing) * 4);
}
.gap-6 {
gap: calc(var(--spacing) * 6);
}
.space-y-1 {
:where(& > :not(:last-child)) {
--tw-space-y-reverse: 0;
@@ -389,9 +405,6 @@
border-color: var(--color-gray-200);
}
}
.overflow-hidden {
overflow: hidden;
}
.overflow-x-auto {
overflow-x: auto;
}
@@ -427,8 +440,11 @@
.border-\[\#0087ff\] {
border-color: #0087ff;
}
.border-\[\#d6d5d5\] {
border-color: #d6d5d5;
.border-gray-100 {
border-color: var(--color-gray-100);
}
.border-gray-200 {
border-color: var(--color-gray-200);
}
.border-gray-300 {
border-color: var(--color-gray-300);
@@ -445,9 +461,6 @@
.bg-\[\#6b9ed2\] {
background-color: #6b9ed2;
}
.bg-\[\#f7f7f7\] {
background-color: #f7f7f7;
}
.bg-\[\#ffffe0\] {
background-color: #ffffe0;
}
@@ -457,21 +470,24 @@
background-color: color-mix(in oklab, var(--color-black) 20%, transparent);
}
}
.bg-black\/40 {
background-color: color-mix(in srgb, #000 40%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 40%, transparent);
}
}
.bg-blue-600 {
background-color: var(--color-blue-600);
}
.bg-gray-50 {
background-color: var(--color-gray-50);
}
.bg-gray-50\/50 {
background-color: color-mix(in srgb, oklch(98.5% 0.002 247.839) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-gray-50) 50%, transparent);
}
}
.bg-gray-100 {
background-color: var(--color-gray-100);
}
.bg-gray-300 {
background-color: var(--color-gray-300);
}
.bg-white {
background-color: var(--color-white);
}
@@ -494,10 +510,6 @@
--tw-gradient-from: var(--color-blue-100);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-\[\#3a0647\] {
--tw-gradient-to: #3a0647;
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-\[\#020f26\] {
--tw-gradient-to: #020f26;
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
@@ -518,6 +530,9 @@
.bg-no-repeat {
background-repeat: no-repeat;
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
.p-3 {
padding: calc(var(--spacing) * 3);
}
@@ -557,14 +572,14 @@
.py-5 {
padding-block: calc(var(--spacing) * 5);
}
.pt-4 {
padding-top: calc(var(--spacing) * 4);
.py-6 {
padding-block: calc(var(--spacing) * 6);
}
.pb-2 {
padding-bottom: calc(var(--spacing) * 2);
.pr-1 {
padding-right: var(--spacing);
}
.pb-4 {
padding-bottom: calc(var(--spacing) * 4);
.pl-2 {
padding-left: calc(var(--spacing) * 2);
}
.text-center {
text-align: center;
@@ -588,18 +603,13 @@
font-size: var(--text-xl);
line-height: var(--tw-leading, var(--text-xl--line-height));
}
.text-\[0\.9rem\] {
font-size: 0.9rem;
.text-xs {
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
}
.text-\[0\.65rem\] {
font-size: 0.65rem;
}
.text-\[1\.1rem\] {
font-size: 1.1rem;
}
.text-\[1\.15rem\] {
font-size: 1.15rem;
}
.font-bold {
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
@@ -632,15 +642,9 @@
--tw-tracking: var(--tracking-wider);
letter-spacing: var(--tracking-wider);
}
.text-ellipsis {
text-overflow: ellipsis;
}
.whitespace-nowrap {
white-space: nowrap;
}
.text-\[\#d7d7d7\] {
color: #d7d7d7;
}
.text-blue-300 {
color: var(--color-blue-300);
}
@@ -671,6 +675,9 @@
.text-gray-900 {
color: var(--color-gray-900);
}
.text-green-600 {
color: var(--color-green-600);
}
.text-red-600 {
color: var(--color-red-600);
}
@@ -699,6 +706,10 @@
--tw-shadow: 0 -1px 2px var(--tw-shadow-color, rgba(0,0,0,0.2));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.shadow-inner {
--tw-shadow: inset 0 2px 4px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.shadow-lg {
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -817,14 +828,6 @@
}
}
}
.checked\:bg-white\/50 {
&:checked {
background-color: color-mix(in srgb, #fff 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 50%, transparent);
}
}
}
.hover\:bg-\[\#3b6ea2\] {
&:hover {
@media (hover: hover) {
@@ -832,6 +835,13 @@
}
}
}
.hover\:bg-blue-50 {
&:hover {
@media (hover: hover) {
background-color: var(--color-blue-50);
}
}
}
.hover\:bg-blue-700 {
&:hover {
@media (hover: hover) {
@@ -846,6 +856,13 @@
}
}
}
.hover\:bg-gray-100 {
&:hover {
@media (hover: hover) {
background-color: var(--color-gray-100);
}
}
}
.hover\:bg-white\/10 {
&:hover {
@media (hover: hover) {
@@ -856,6 +873,13 @@
}
}
}
.hover\:text-blue-600 {
&:hover {
@media (hover: hover) {
color: var(--color-blue-600);
}
}
}
.hover\:text-white {
&:hover {
@media (hover: hover) {
@@ -863,13 +887,6 @@
}
}
}
.hover\:underline {
&:hover {
@media (hover: hover) {
text-decoration-line: underline;
}
}
}
.active\:bg-\[\#6b9ed2\] {
&:active {
background-color: #6b9ed2;
@@ -885,9 +902,9 @@
top: 0;
}
}
.sm\:ml-6 {
.sm\:mx-2 {
@media (width >= 40rem) {
margin-left: calc(var(--spacing) * 6);
margin-inline: calc(var(--spacing) * 2);
}
}
.sm\:block {
@@ -900,11 +917,6 @@
display: none;
}
}
.sm\:h-\[calc\(100vh-3\.5rem\)\] {
@media (width >= 40rem) {
height: calc(100vh - 3.5rem);
}
}
.sm\:h-\[calc\(100vh-4\.5rem\)\] {
@media (width >= 40rem) {
height: calc(100vh - 4.5rem);
@@ -925,9 +937,9 @@
flex-direction: row;
}
}
.sm\:justify-end {
.sm\:gap-4 {
@media (width >= 40rem) {
justify-content: flex-end;
gap: calc(var(--spacing) * 4);
}
}
.sm\:overflow-y-auto {
@@ -935,11 +947,21 @@
overflow-y: auto;
}
}
.sm\:px-6 {
@media (width >= 40rem) {
padding-inline: calc(var(--spacing) * 6);
}
}
.sm\:px-8 {
@media (width >= 40rem) {
padding-inline: calc(var(--spacing) * 8);
}
}
.lg\:flex {
@media (width >= 64rem) {
display: flex;
}
}
.\[\&\.active\]\:border-blue-400 {
&.active {
border-color: var(--color-blue-400);
@@ -953,14 +975,6 @@
}
}
}
.\[\&\.active\]\:bg-white\/\[0\.37\] {
&.active {
background-color: color-mix(in srgb, #fff 37%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 37%, transparent);
}
}
}
.\[\&\.active\]\:text-white {
&.active {
color: var(--color-white);