Files
2026-07-21 14:41:46 +07:00

221 lines
8.5 KiB
Plaintext

@using Indotalent.ConfigBackEnd.Extensions
@using Indotalent.ConfigBackEnd.Interfaces
@using Indotalent.Infrastructure.Authentication
@using Indotalent.Infrastructure.Authorization.Identity
@using Indotalent.Shared.Consts
@using Microsoft.AspNetCore.Components.Authorization
@inherits LayoutComponentBase
@inject NavigationManager NavigationManager
@inject ICurrentUserService CurrentUserService
<MudThemeProvider />
<MudDialogProvider />
<MudSnackbarProvider />
<MudPopoverProvider />
<MudLayout>
<AuthorizeView>
<MudAppBar Elevation="1">
<MudSpacer />
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" Dense="true"
ActivationEvent="@MouseEvent.LeftClick" AnchorOrigin="Origin.BottomCenter" TransformOrigin="Origin.TopCenter">
<MudMenuItem OnClick="GoToProfile">Profile</MudMenuItem>
<MudMenuItem OnClick="Logout" Color="Color.Error">Logout</MudMenuItem>
</MudMenu>
</MudAppBar>
<MudDrawer @bind-Open="_drawerOpen"
Elevation="0"
Variant="@DrawerVariant.Mini"
OpenMiniOnHover="false"
MiniWidth="80px"
Width="280px"
Class="v6-drawer">
<MudIconButton Icon="@(_drawerOpen? Icons.Material.Rounded.ChevronLeft : Icons.Material.Rounded.ChevronRight)"
OnClick="@DrawerToggle"
Class="v6-toggle-btn"
Size="Size.Small" />
<MudDrawerHeader Class="pa-6 mb-2">
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.Apps" Size="Size.Medium" Color="Color.Primary" />
@if (_drawerOpen)
{
<MudText Typo="Typo.h5" Class="ml-3" Style="font-weight:900">@GlobalConsts.AppInitial</MudText>
}
</div>
</MudDrawerHeader>
<MudNavMenu Class="v6-nav">
<AuthorizeView Roles="@($"{ApplicationRoles.Admin},{ApplicationRoles.Member}")" Context="commonAuth">
<Authorized>
<MudNavLink Href="/home" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">@(_drawerOpen ? "Home" : "")</MudNavLink>
<MudNavLink Href="/profile" Icon="@Icons.Material.Filled.AccountCircle">@(_drawerOpen ? "Profile" : "")</MudNavLink>
<MudNavLink Href="/thirdparty" Icon="@Icons.Material.Filled.Groups">@(_drawerOpen ? "Third Party" : "")</MudNavLink>
<MudNavLink Href="/sales" Icon="@Icons.Material.Filled.MonetizationOn">@(_drawerOpen ? "Sales" : "")</MudNavLink>
<MudNavLink Href="/purchase" Icon="@Icons.Material.Filled.ShoppingCart">@(_drawerOpen ? "Purchase" : "")</MudNavLink>
<MudNavLink Href="/inventory" Icon="@Icons.Material.Filled.Inventory2">@(_drawerOpen ? "Inventory" : "")</MudNavLink>
<MudNavLink Href="/utilities" Icon="@Icons.Material.Filled.Build">@(_drawerOpen ? "Utilities" : "")</MudNavLink>
</Authorized>
</AuthorizeView>
<AuthorizeView Roles="@ApplicationRoles.Admin" Context="adminAuth">
<Authorized>
<MudNavLink Href="/serilogs" Icon="@Icons.Material.Filled.HistoryEdu">@(_drawerOpen ? "System Logs" : "")</MudNavLink>
<MudNavLink Href="/setting" Icon="@Icons.Material.Filled.Settings">@(_drawerOpen ? "App Settings" : "")</MudNavLink>
<MudNavLink Href="/appsettings/json" Icon="@Icons.Material.Filled.SettingsEthernet">@(_drawerOpen ? "System Settings" : "")</MudNavLink>
</Authorized>
</AuthorizeView>
</MudNavMenu>
<div class="v6-footer d-flex align-center @(_drawerOpen ? "" : "justify-center")">
<MudBadge Color="Color.Success" Overlap="true" Dot="true" Bordered="true" Placement="Placement.BottomRight">
<MudAvatar Color="Color.Warning" Size="Size.Medium">@CurrentUserService.FullName.ToInitial()</MudAvatar>
</MudBadge>
@if (_drawerOpen)
{
<div class="ml-3">
<MudText Typo="Typo.caption" Style="font-weight:700; display: block; color: #1e293b;">@CurrentUserService.FullName</MudText>
<MudText Typo="Typo.caption" Style="color: #64748b; font-size: 10px;">Online</MudText>
</div>
}
</div>
</MudDrawer>
</AuthorizeView>
<MudMainContent Style="background-color: #f1f5f9;">
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pa-3 md-pa-6 lg-pa-8 pt-3 pb-12">
@Body
</MudContainer>
</MudMainContent>
</MudLayout>
<script>
function downloadFile(fileName, contentType, base64String) {
const link = document.createElement('a');
link.download = fileName;
link.href = `data:${contentType};base64,${base64String}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
</script>
@code {
private bool _drawerOpen = true;
private void DrawerToggle() => _drawerOpen = !_drawerOpen;
private void GoToProfile() => NavigationManager.NavigateTo("/profile");
private void Logout() => NavigationManager.NavigateTo("/account/logout");
}
<style>
.mud-input-control:has(.mud-input-adornment-start) {
margin-top: 0 !important;
height: 35px !important;
}
.mud-input-control:has(.mud-input-adornment-start) .mud-input-outlined-border {
height: 35px !important;
}
.mud-input-control:has(.mud-input-adornment-start) input {
padding-top: 0px !important;
padding-bottom: 0px !important;
height: 30px !important;
font-size: 13px !important;
}
.mud-input-control:has(.mud-input-adornment-start) .mud-input-adornment {
margin-top: 0 !important;
margin-bottom: 0 !important;
height: 35px !important;
}
div:has(> .mud-input-control:has(.mud-input-adornment-start)) > .mud-button-root {
height: 35px !important;
box-shadow: none !important;
}
</style>
<style>
.mud-input-outlined-border {
border-radius: 4px !important;
}
.custom-select-dense .mud-input-control {
margin-top: 0 !important;
}
.custom-select-dense .mud-input-slot {
padding-top: 4px !important;
padding-bottom: 4px !important;
padding-left: 8px !important;
font-size: 12px !important;
}
</style>
<style>
.mud-drawer.v6-drawer {
overflow: visible !important;
z-index: 1350 !important;
background-color: #f8fafc !important;
border-right: 1px solid var(--mud-palette-divider) !important;
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.v6-drawer .mud-drawer-content {
overflow-y: auto !important;
overflow-x: hidden !important;
display: flex;
flex-direction: column;
height: 100%;
}
.v6-toggle-btn {
position: absolute !important;
right: -16px !important;
top: 18px !important;
z-index: 1400 !important;
background-color: white !important;
border: 1px solid var(--mud-palette-divider) !important;
width: 32px !important;
height: 32px !important;
min-width: 32px !important;
border-radius: 50% !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.1) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.v6-nav .mud-nav-link {
border-radius: 12px;
margin: 4px 12px;
color: #64748b;
}
.v6-nav .mud-nav-link.active {
background-color: white !important;
color: var(--mud-palette-primary) !important;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
font-weight: 600;
}
.v6-nav .mud-nav-link.active .mud-nav-link-icon {
color: var(--mud-palette-primary) !important;
}
.v6-footer {
margin-top: auto;
padding: 16px;
border-top: 1px solid #FFEDD5;
background-color: #FFF7ED;
flex-shrink: 0;
}
.mud-badge-dot {
border: 2px solid white !important;
}
</style>