Files
blazor-hrm/Features/Account/AuthenticationLayout.razor
T
2026-07-21 14:08:10 +07:00

420 lines
12 KiB
Plaintext

@using Indotalent.Shared.Consts
@inherits LayoutComponentBase
@inject NavigationManager Navigation
<MudThemeProvider @bind-IsDarkMode="isDarkMode" Theme="_theme" />
<style>
/* ===== RESET & BASE ===== */
.auth *,
.auth *::before,
.auth *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.auth {
font-family: "Poppins", sans-serif;
background: #ffffff;
}
/* ===== SPLIT CONTAINER ===== */
.auth-split-container {
display: flex;
min-height: 100vh;
background: #f8fafc;
}
/* ===== LEFT PANEL - GRADIENT BRANDING ===== */
.auth-left-panel {
display: none;
position: relative;
overflow: hidden;
}
@@media (min-width: 1024px) {
.auth-left-panel {
display: flex;
width: 50%;
background: linear-gradient(135deg, #594AE2 0%, #7B6EF0 50%, #4A3DC8 100%);
align-items: center;
justify-content: center;
padding: 3rem;
}
}
@@media (min-width: 1280px) {
.auth-left-panel {
padding: 5rem;
}
}
.auth-left-panel::before {
content: '';
position: absolute;
top: -150px;
right: -150px;
width: 400px;
height: 400px;
background: rgba(255, 255, 255, 0.05);
border-radius: 50%;
pointer-events: none;
}
.auth-left-panel::after {
content: '';
position: absolute;
bottom: -100px;
left: -100px;
width: 300px;
height: 300px;
background: rgba(255, 255, 255, 0.04);
border-radius: 50%;
pointer-events: none;
}
.auth-left-content {
max-width: 28rem;
z-index: 1;
position: relative;
}
/* Brand row */
.auth-brand-row {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 2rem;
}
.auth-brand-icon {
width: 3.5rem;
height: 3.5rem;
background: rgba(255, 255, 255, 0.2);
border-radius: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(4px);
flex-shrink: 0;
cursor: pointer;
transition: background 0.2s;
}
.auth-brand-icon:hover {
background: rgba(255, 255, 255, 0.3);
}
.auth-brand-name {
font-size: 1.5rem;
font-weight: 700;
color: #ffffff;
line-height: 1.2;
}
.auth-brand-sub {
font-size: 0.8125rem;
color: rgba(255, 255, 255, 0.55);
line-height: 1.2;
}
/* Welcome */
.auth-welcome-title {
font-size: 1.875rem;
font-weight: 700;
line-height: 1.25;
color: #ffffff;
margin-bottom: 1rem;
}
.auth-welcome-desc {
color: rgba(255, 255, 255, 0.7);
line-height: 1.625;
margin-bottom: 2rem;
font-size: 0.9375rem;
}
/* Feature list */
.auth-feature-list {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 2.5rem;
}
.auth-feature-item {
display: flex;
align-items: flex-start;
gap: 0.75rem;
}
.auth-feature-check {
width: 1.25rem;
height: 1.25rem;
border-radius: 0.25rem;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 0.125rem;
}
.auth-feature-check svg {
width: 0.75rem;
height: 0.75rem;
color: #ffffff;
}
.auth-feature-title {
font-weight: 600;
color: #ffffff;
font-size: 0.875rem;
}
.auth-feature-desc {
font-size: 0.75rem;
color: rgba(255, 255, 255, 0.55);
margin-top: 0.125rem;
}
/* Support card */
.auth-support-card {
padding: 1rem;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(4px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 0.75rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.auth-support-avatar {
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.auth-support-avatar svg {
width: 1.25rem;
height: 1.25rem;
color: #ffffff;
}
.auth-support-title {
font-size: 0.875rem;
font-weight: 600;
color: #ffffff;
}
.auth-support-desc {
font-size: 0.75rem;
color: rgba(255, 255, 255, 0.55);
}
/* ===== RIGHT PANEL ===== */
.auth-right-panel {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
}
@@media (min-width: 640px) {
.auth-right-panel {
padding: 2.5rem;
}
}
@@media (min-width: 1024px) {
.auth-right-panel {
width: 50%;
padding: 4rem;
}
}
@@media (min-width: 1280px) {
.auth-right-panel {
padding: 5rem;
}
}
.auth-form-wrapper {
width: 100%;
max-width: 28rem;
}
/* ===== MOBILE BRAND STRIP ===== */
.auth-mobile-brand {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
margin-bottom: 1.5rem;
padding: 1rem;
background: linear-gradient(135deg, #594AE2 0%, #7B6EF0 100%);
border-radius: 0.75rem;
}
@@media (min-width: 1024px) {
.auth-mobile-brand {
display: none;
}
}
.auth-mobile-brand-icon {
width: 2rem;
height: 2rem;
background: rgba(255, 255, 255, 0.2);
border-radius: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
}
.auth-mobile-brand-icon svg {
width: 1.25rem;
height: 1.25rem;
color: #ffffff;
}
.auth-mobile-brand-name {
font-weight: 700;
color: #ffffff;
font-size: 0.9375rem;
}
/* ===== CARD ===== */
.auth-card {
width: 100%;
border-radius: 1rem !important;
border: 1px solid #e2e8f0 !important;
background: #ffffff !important;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 4px rgba(0, 0, 0, 0.04) !important;
}
/* ===== FOOTER ===== */
.auth-card-footer {
text-align: center;
margin-top: 1.5rem;
color: #94a3b8;
font-size: 0.75rem;
}
</style>
<MudDialogProvider />
<MudSnackbarProvider />
<MudPopoverProvider />
<div class="auth">
<div class="auth-split-container">
<!-- LEFT PANEL: Gradient Branding -->
<div class="auth-left-panel">
<div class="auth-left-content">
<div class="auth-brand-row">
<div class="auth-brand-icon" @onclick="NavigateToHome">
<MudIcon Icon="@Icons.Material.Filled.Groups" Style="font-size: 2rem; color: #ffffff;" />
</div>
<div>
<div class="auth-brand-name">@GlobalConsts.AppInitial</div>
<div class="auth-brand-sub">Enterprise Application Platform</div>
</div>
</div>
<h2 class="auth-welcome-title">Your People,<br />One Platform</h2>
<p class="auth-welcome-desc">A complete Human Resource Management system built with .NET 10 & Blazor — ready to run, beautiful by default.</p>
<div class="auth-feature-list">
<div class="auth-feature-item">
<div class="auth-feature-check">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
</div>
<div>
<div class="auth-feature-title">Employee Profiles & Organization</div>
<div class="auth-feature-desc">Personal info, branches, departments & designations</div>
</div>
</div>
<div class="auth-feature-item">
<div class="auth-feature-check">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
</div>
<div>
<div class="auth-feature-title">Leave & Performance</div>
<div class="auth-feature-desc">Leave requests, evaluations, appraisal & promotion</div>
</div>
</div>
<div class="auth-feature-item">
<div class="auth-feature-check">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
</div>
<div>
<div class="auth-feature-title">Payroll Processing</div>
<div class="auth-feature-desc">Salary grades, income, deductions & reporting</div>
</div>
</div>
</div>
<div class="auth-support-card">
<div class="auth-support-avatar">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
</div>
<div>
<div class="auth-support-title">Production-Ready Source Code</div>
<div class="auth-support-desc">Guaranteed to compile. Built with VSA, CQRS & MediatR</div>
</div>
</div>
</div>
</div>
<!-- RIGHT PANEL: Form Area -->
<div class="auth-right-panel">
<div class="auth-form-wrapper">
<!-- Mobile Brand Strip -->
<div class="auth-mobile-brand">
<div class="auth-mobile-brand-icon">
<MudIcon Icon="@Icons.Material.Filled.Groups" Style="font-size: 1.25rem; color: #ffffff;" />
</div>
<span class="auth-mobile-brand-name">@GlobalConsts.AppInitial</span>
</div>
<MudCard Elevation="0" Class="auth-card">
<MudCardContent Class="pa-5 pa-sm-6">
@Body
</MudCardContent>
</MudCard>
<div class="auth-card-footer">
&copy; @DateTime.Now.Year @GlobalConsts.AppInitial. ALL RIGHTS RESERVED.
</div>
</div>
</div>
</div>
</div>
@code {
private bool isDarkMode;
private MudTheme _theme = new()
{
PaletteLight = new PaletteLight()
{
Primary = "#594AE2",
Secondary = "#7B6EF0",
AppbarBackground = "#594AE2"
}
};
private void NavigateToHome()
{
Navigation.NavigateTo("/", forceLoad: true);
}
}