performance updates

This commit is contained in:
Mark Gregory
2026-09-03 09:54:07 +01:00
parent 525607db99
commit df7561737c
3 changed files with 89 additions and 55 deletions
@@ -0,0 +1 @@
:root{color-scheme:light dark;font-family:Instrument Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:#f8fafc;color:#18181b}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:#f8fafc;color:#18181b;-webkit-font-smoothing:antialiased}.auth-main{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}.auth-wrap{width:100%;max-width:390px}.auth-brand{display:flex;justify-content:center;margin-bottom:20px}.auth-brand img{width:48px;height:48px}.auth-card{background:#fff;border:1px solid #e4e4e7;border-radius:16px;padding:30px;box-shadow:0 10px 30px rgba(15,23,42,.06)}h1{font-size:24px;line-height:1.2;margin:0 0 8px;text-align:center}p{margin:0}.auth-subtitle{text-align:center;color:#71717a;font-size:14px;margin-bottom:24px}.field{margin-bottom:18px}.field-row{display:flex;align-items:center;justify-content:space-between;gap:12px}label{display:block;font-size:14px;font-weight:600;margin-bottom:7px}input[type=email],input[type=password]{width:100%;height:44px;border:1px solid #d4d4d8;border-radius:9px;padding:0 12px;background:#fff;color:#18181b;font:inherit;outline:none}input:focus{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.14)}.remember{display:flex;align-items:center;gap:8px;font-size:14px;color:#52525b}.remember input{width:16px;height:16px}.btn{width:100%;min-height:44px;border:0;border-radius:9px;padding:10px 14px;font:inherit;font-weight:600;cursor:pointer}.btn-primary{background:#2563eb;color:#fff}.btn-primary:hover{background:#1d4ed8}.btn-passkey{background:#fff;color:#18181b;border:1px solid #d4d4d8;margin-bottom:18px}.divider{display:flex;align-items:center;gap:12px;color:#71717a;font-size:11px;text-transform:uppercase;margin:2px 0 20px}.divider:before,.divider:after{content:"";height:1px;background:#e4e4e7;flex:1}.link{color:#2563eb;text-decoration:none;font-size:14px}.link:hover{text-decoration:underline}.signup{text-align:center;color:#71717a;font-size:14px;margin-top:22px}.status{padding:10px 12px;border-radius:8px;background:#ecfdf5;color:#047857;font-size:14px;margin-bottom:18px}.error{color:#dc2626;font-size:13px;margin-top:6px}.passkey-error{text-align:center;margin:-8px 0 16px}[hidden]{display:none!important}@media(max-width:480px){.auth-main{padding:16px}.auth-card{padding:24px 20px;border-radius:13px}}@media(prefers-color-scheme:dark){:root{background:#09090b;color:#fafafa}body{background:#09090b;color:#fafafa}.auth-card{background:#18181b;border-color:#27272a;box-shadow:none}.auth-subtitle,.signup,.remember,.divider{color:#a1a1aa}input[type=email],input[type=password]{background:#09090b;border-color:#3f3f46;color:#fafafa}.btn-passkey{background:#18181b;border-color:#3f3f46;color:#fafafa}.divider:before,.divider:after{background:#3f3f46}.status{background:#052e24;color:#6ee7b7}}
+87 -55
View File
@@ -1,63 +1,95 @@
<x-layouts::auth :title="__('Log in')">
<div class="flex flex-col gap-6">
<x-auth-header :title="__('Log in to your account')" :description="__('Enter your email and password below to log in')" />
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Sign in to {{ config('app.name', 'Systems Helpdesk') }} to manage helpdesk tickets and support requests.">
<meta name="theme-color" content="#0b1220">
<title>{{ __('Log in') }} - {{ config('app.name', 'Systems Helpdesk') }}</title>
<link rel="icon" type="image/png" sizes="32x32" href="{{ asset('favicon-32x32.png') }}">
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('apple-touch-icon.png') }}">
@vite('resources/themes/backend/assets/css/auth.css')
</head>
<body>
<main class="auth-main">
<div class="auth-wrap">
<a class="auth-brand" href="{{ route('home') }}" aria-label="{{ config('app.name', 'Systems Helpdesk') }}">
<img src="{{ asset('favicon-96x96.png') }}" width="48" height="48" alt="">
</a>
<!-- Session Status -->
<x-auth-session-status class="text-center" :status="session('status')" />
<section class="auth-card" aria-labelledby="login-heading">
<h1 id="login-heading">{{ __('Log in to your account') }}</h1>
<p class="auth-subtitle">{{ __('Enter your email and password below to log in') }}</p>
<div class="hd-auth-passkey">
<x-passkey-verify />
</div>
@if (session('status'))
<div class="status" role="status">{{ session('status') }}</div>
@endif
<form method="POST" action="{{ route('login.store') }}" class="flex flex-col gap-6">
@csrf
<!-- Email Address -->
<flux:input
name="email"
:label="__('Email address')"
:value="old('email')"
type="email"
required
autofocus
autocomplete="email"
placeholder="email@example.com"
/>
<!-- Password -->
<div class="relative">
<flux:input
name="password"
:label="__('Password')"
type="password"
required
autocomplete="current-password"
:placeholder="__('Password')"
viewable
/>
@if (Route::has('password.request'))
<flux:link class="absolute top-0 text-sm end-0" :href="route('password.request')" wire:navigate>
{{ __('Forgot your password?') }}
</flux:link>
@endif
<div id="passkey-area" hidden>
<button id="passkey-button" class="btn btn-passkey" type="button">{{ __('Sign in with a passkey') }}</button>
<p id="passkey-error" class="error passkey-error" role="alert" hidden></p>
<div class="divider"><span>{{ __('Or continue with email') }}</span></div>
</div>
<!-- Remember Me -->
<div class="hd-auth-checkbox">
<flux:checkbox name="remember" :label="__('Remember me')" :checked="old('remember')" />
</div>
<form method="POST" action="{{ route('login.store') }}">
@csrf
<div class="field">
<label for="email">{{ __('Email address') }}</label>
<input id="email" name="email" value="{{ old('email') }}" type="email" required autofocus autocomplete="email" inputmode="email">
@error('email')<p class="error">{{ $message }}</p>@enderror
</div>
<div class="flex items-center justify-end">
<flux:button variant="primary" type="submit" class="hd-auth-primary w-full" data-test="login-button">
{{ __('Log in') }}
</flux:button>
</div>
</form>
<div class="field">
<div class="field-row">
<label for="password">{{ __('Password') }}</label>
@if (Route::has('password.request'))
<a class="link" href="{{ route('password.request') }}">{{ __('Forgot your password?') }}</a>
@endif
</div>
<input id="password" name="password" type="password" required autocomplete="current-password">
@error('password')<p class="error">{{ $message }}</p>@enderror
</div>
<div class="space-x-1 text-sm text-center rtl:space-x-reverse text-zinc-600 dark:text-zinc-400">
<span>{{ __('Don\'t have an account?') }}</span>
<flux:link :href="route('register')" wire:navigate>{{ __('Sign up') }}</flux:link>
</div>
<div class="field">
<label class="remember"><input name="remember" type="checkbox" value="1" @checked(old('remember'))> <span>{{ __('Remember me') }}</span></label>
</div>
<button class="btn btn-primary" type="submit" data-test="login-button">{{ __('Log in') }}</button>
</form>
@if (Route::has('register'))
<p class="signup">{{ __('Don\'t have an account?') }} <a class="link" href="{{ route('register') }}">{{ __('Sign up') }}</a></p>
@endif
</section>
</div>
</x-layouts::auth>
</main>
@vite('resources/themes/backend/assets/js/passkeys.js')
<script>
window.addEventListener('passkeys:ready', () => {
const area = document.getElementById('passkey-area');
const button = document.getElementById('passkey-button');
const error = document.getElementById('passkey-error');
if (!window.Passkeys?.isSupported?.()) return;
area.hidden = false;
button.addEventListener('click', async () => {
button.disabled = true;
button.textContent = @json(__('Authenticating...'));
error.hidden = true;
try {
const response = await window.Passkeys.verify({routes:{options:@json(route('passkey.login-options')),submit:@json(route('passkey.login'))}});
window.location.assign(response.redirect || @json(route('dashboard')));
} catch (e) {
if (e?.constructor?.name !== 'UserCancelledError') {
error.textContent = e?.message || @json(__('Passkey authentication failed.'));
error.hidden = false;
}
} finally {
button.disabled = false;
button.textContent = @json(__('Sign in with a passkey'));
}
});
});
</script>
</body>
</html>
+1
View File
@@ -32,6 +32,7 @@ export default defineConfig({
laravel({
input:[
backendCssEntry,
'resources/themes/backend/assets/css/auth.css',
'resources/themes/backend/assets/js/passkeys.js',
'resources/themes/backend/assets/js/layout.js',
...moduleInputs,