re-add theme as ptrs broken fixed ipad theme
This commit is contained in:
@@ -2439,3 +2439,86 @@ html:not(.dark) .hd-priority-legend > div { color:#475467 !important; }
|
||||
|
||||
/* Safari 12 does not support inset shorthand. */
|
||||
.ios12 .hd-sidebar-backdrop { top:72px; right:0; bottom:0; left:0; }
|
||||
|
||||
/* ============================================================
|
||||
Stable account/settings UI for legacy WebKit and modern browsers.
|
||||
These controls deliberately avoid Flux layout primitives so Safari 12
|
||||
receives the same usable profile/settings experience.
|
||||
============================================================ */
|
||||
.hd-settings-heading { margin:0 0 26px; padding:0 0 20px; border-bottom:1px solid #303845; }
|
||||
.hd-settings-heading h1 { margin:0; color:#f8fafc; font-size:1.9rem; line-height:1.15; font-weight:800; }
|
||||
.hd-settings-heading p { margin:7px 0 0; color:#9ca3af; font-size:.95rem; }
|
||||
.hd-account-settings { display:-webkit-flex; display:flex; -webkit-align-items:flex-start; align-items:flex-start; width:100%; max-width:980px; }
|
||||
.hd-settings-nav { width:190px; min-width:190px; margin-right:34px; padding:5px; border:1px solid #303845; border-radius:12px; background:#151a22; }
|
||||
.hd-settings-nav a { display:block; min-height:42px; box-sizing:border-box; padding:11px 12px; border-radius:8px; color:#aeb7c5; font-size:.88rem; font-weight:650; text-decoration:none; }
|
||||
.hd-settings-nav a:hover { background:#202732; color:#fff; }
|
||||
.hd-settings-nav a.is-active { background:#263244; color:#fff; box-shadow:inset 3px 0 #3b82f6; }
|
||||
.hd-settings-panel { -webkit-flex:1 1 auto; flex:1 1 auto; min-width:0; max-width:620px; }
|
||||
.hd-settings-panel-header { margin-bottom:22px; }
|
||||
.hd-settings-panel-header h2 { margin:0; color:#f8fafc; font-size:1.2rem; font-weight:750; }
|
||||
.hd-settings-panel-header p { margin:5px 0 0; color:#9ca3af; font-size:.84rem; }
|
||||
.hd-settings-form { display:block; width:100%; }
|
||||
.hd-settings-field { display:block; margin:0 0 18px; color:#dce2ea; }
|
||||
.hd-settings-field > span { display:block; margin-bottom:7px; font-size:.78rem; font-weight:700; }
|
||||
.hd-settings-field input { box-sizing:border-box; width:100%; height:44px; padding:0 12px; border:1px solid #424a56; border-radius:9px; background:#252a31; color:#f3f4f6; font:inherit; font-size:16px; -webkit-appearance:none; appearance:none; }
|
||||
.hd-settings-field input:focus { border-color:#3b82f6; outline:none; box-shadow:0 0 0 3px rgba(59,130,246,.16); }
|
||||
.hd-settings-error { display:block; margin-top:6px; color:#fca5a5; font-size:.72rem; }
|
||||
.hd-settings-note { margin:0 0 18px; color:#9ca3af; font-size:.8rem; }
|
||||
.hd-settings-link { padding:0; border:0; background:none; color:#93c5fd; font:inherit; cursor:pointer; text-decoration:underline; }
|
||||
.hd-settings-actions { display:-webkit-flex; display:flex; -webkit-align-items:center; align-items:center; gap:10px; margin-top:10px; }
|
||||
.hd-settings-button { box-sizing:border-box; min-height:40px; padding:9px 15px; border:1px solid #48515e; border-radius:9px; background:#252b34; color:#e5e7eb; font:inherit; font-size:.82rem; font-weight:700; line-height:1.2; cursor:pointer; text-decoration:none; -webkit-appearance:none; appearance:none; }
|
||||
.hd-settings-button-primary { border-color:#3b82f6; background:#2563eb; color:#fff; }
|
||||
.hd-settings-button-danger { border-color:#dc2626; background:#dc2626; color:#fff; }
|
||||
.hd-native-appearance { display:-webkit-flex; display:flex; width:100%; margin-top:6px; }
|
||||
.hd-native-appearance button { -webkit-flex:1 1 0; flex:1 1 0; min-width:0; height:86px; margin-right:10px; border:1px solid #3a4350; border-radius:11px; background:#1a2029; color:#cbd5e1; font:inherit; font-weight:700; cursor:pointer; -webkit-appearance:none; appearance:none; }
|
||||
.hd-native-appearance button:last-child { margin-right:0; }
|
||||
.hd-native-appearance button svg { display:block; width:24px !important; height:24px !important; margin:0 auto 8px; fill:currentColor; }
|
||||
.hd-native-appearance button.is-active { border-color:#3b82f6; background:#1d355b; color:#bfdbfe; box-shadow:inset 0 0 0 1px #3b82f6; }
|
||||
.hd-delete-account { margin-top:36px; padding-top:25px; border-top:1px solid #303845; }
|
||||
.hd-delete-account h3,.hd-delete-confirm h4 { margin:0; color:#f8fafc; font-size:1rem; }
|
||||
.hd-delete-account p,.hd-delete-confirm p { margin:5px 0 16px; color:#9ca3af; font-size:.8rem; line-height:1.5; }
|
||||
.hd-delete-details > summary { display:inline-block; list-style:none; }
|
||||
.hd-delete-details > summary::-webkit-details-marker { display:none; }
|
||||
.hd-delete-confirm { margin-top:14px; padding:18px; border:1px solid #4b3135; border-radius:11px; background:#23181a; }
|
||||
|
||||
html:not(.dark) .hd-settings-heading { border-bottom-color:#d8dee7; }
|
||||
html:not(.dark) .hd-settings-heading h1,
|
||||
html:not(.dark) .hd-settings-panel-header h2,
|
||||
html:not(.dark) .hd-delete-account h3,
|
||||
html:not(.dark) .hd-delete-confirm h4 { color:#111827; }
|
||||
html:not(.dark) .hd-settings-heading p,
|
||||
html:not(.dark) .hd-settings-panel-header p,
|
||||
html:not(.dark) .hd-settings-note,
|
||||
html:not(.dark) .hd-delete-account p,
|
||||
html:not(.dark) .hd-delete-confirm p { color:#667085; }
|
||||
html:not(.dark) .hd-settings-nav { border-color:#d8dee7; background:#fff; }
|
||||
html:not(.dark) .hd-settings-nav a { color:#475467; }
|
||||
html:not(.dark) .hd-settings-nav a:hover { background:#eef2f7; color:#111827; }
|
||||
html:not(.dark) .hd-settings-nav a.is-active { background:#e9f0fb; color:#1d4ed8; }
|
||||
html:not(.dark) .hd-settings-field { color:#344054; }
|
||||
html:not(.dark) .hd-settings-field input { border-color:#c9d1dc; background:#fff; color:#1f2937; }
|
||||
html:not(.dark) .hd-settings-button { border-color:#c9d1dc; background:#fff; color:#344054; }
|
||||
html:not(.dark) .hd-settings-button-primary { border-color:#2563eb; background:#2563eb; color:#fff; }
|
||||
html:not(.dark) .hd-settings-button-danger { border-color:#dc2626; background:#dc2626; color:#fff; }
|
||||
html:not(.dark) .hd-native-appearance button { border-color:#c9d1dc; background:#fff; color:#475467; }
|
||||
html:not(.dark) .hd-native-appearance button.is-active { border-color:#2563eb; background:#eff6ff; color:#1d4ed8; }
|
||||
html:not(.dark) .hd-delete-account { border-top-color:#d8dee7; }
|
||||
html:not(.dark) .hd-delete-confirm { border-color:#fecaca; background:#fff7f7; }
|
||||
|
||||
/* iOS 12 account dropdown: anchor to the viewport so it cannot be displaced
|
||||
by the old flex implementation in the top bar. */
|
||||
.ios12 .hd-topbar-main .hd-account-menu { margin-left:auto; position:static; }
|
||||
.ios12 .hd-topbar-main .hd-account-dropdown { position:fixed; top:66px; right:14px; left:auto; width:300px; max-width:calc(100vw - 28px); }
|
||||
.ios12 .hd-account-button { min-width:150px; -webkit-justify-content:flex-end; justify-content:flex-end; }
|
||||
.ios12 .hd-account-dropdown-copy { display:block; }
|
||||
.ios12 .hd-account-dropdown-copy strong,
|
||||
.ios12 .hd-account-dropdown-copy span,
|
||||
.ios12 .hd-account-dropdown-copy small { display:block; }
|
||||
|
||||
@media(max-width:760px) {
|
||||
.hd-account-settings { display:block; }
|
||||
.hd-settings-nav { width:100%; min-width:0; margin:0 0 22px; box-sizing:border-box; }
|
||||
.hd-settings-panel { max-width:none; }
|
||||
.hd-native-appearance { display:block; }
|
||||
.hd-native-appearance button { width:100%; margin:0 0 10px; }
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
<div class="hd-account-settings flex items-start max-md:flex-col">
|
||||
<div class="me-10 w-full pb-4 md:w-[220px]">
|
||||
<flux:navlist aria-label="{{ __('Settings') }}">
|
||||
<flux:navlist.item :href="route('profile.edit')" wire:navigate>{{ __('Profile') }}</flux:navlist.item>
|
||||
<flux:navlist.item :href="route('security.edit')" wire:navigate>{{ __('Security') }}</flux:navlist.item>
|
||||
<flux:navlist.item :href="route('appearance.edit')" wire:navigate>{{ __('Appearance') }}</flux:navlist.item>
|
||||
</flux:navlist>
|
||||
</div>
|
||||
<div class="hd-account-settings">
|
||||
<aside class="hd-settings-nav" aria-label="{{ __('Settings') }}">
|
||||
<a class="{{ request()->routeIs('profile.edit') ? 'is-active' : '' }}" href="{{ route('profile.edit') }}" wire:navigate>{{ __('Profile') }}</a>
|
||||
<a class="{{ request()->routeIs('security.edit') ? 'is-active' : '' }}" href="{{ route('security.edit') }}" wire:navigate>{{ __('Security') }}</a>
|
||||
<a class="{{ request()->routeIs('appearance.edit') ? 'is-active' : '' }}" href="{{ route('appearance.edit') }}" wire:navigate>{{ __('Appearance') }}</a>
|
||||
</aside>
|
||||
|
||||
<flux:separator class="md:hidden" />
|
||||
|
||||
<div class="flex-1 self-stretch max-md:pt-6">
|
||||
<flux:heading>{{ $heading ?? '' }}</flux:heading>
|
||||
<flux:subheading>{{ $subheading ?? '' }}</flux:subheading>
|
||||
|
||||
<div class="mt-5 w-full max-w-lg">
|
||||
<section class="hd-settings-panel">
|
||||
<header class="hd-settings-panel-header">
|
||||
<h2>{{ $heading ?? '' }}</h2>
|
||||
<p>{{ $subheading ?? '' }}</p>
|
||||
</header>
|
||||
<div class="hd-settings-content">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
<section class="w-full">
|
||||
@include('partials.settings-heading')
|
||||
|
||||
<flux:heading class="sr-only">{{ __('Appearance settings') }}</flux:heading>
|
||||
|
||||
<x-settings.layout :heading="__('Appearance')" :subheading=" __('Update the appearance settings for your account')">
|
||||
<flux:radio.group x-data variant="segmented" x-model="$flux.appearance" class="hd-appearance-group">
|
||||
<flux:radio value="light" icon="sun">{{ __('Light') }}</flux:radio>
|
||||
<flux:radio value="dark" icon="moon">{{ __('Dark') }}</flux:radio>
|
||||
<flux:radio value="system" icon="computer-desktop">{{ __('System') }}</flux:radio>
|
||||
</flux:radio.group>
|
||||
<x-settings.layout :heading="__('Appearance')" :subheading="__('Update the appearance settings for your account')">
|
||||
<div class="hd-native-appearance" data-hd-appearance>
|
||||
<button type="button" data-hd-appearance-value="light" onclick="window.HDTheme && window.HDTheme.set('light')" aria-pressed="false">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10zm0-5h1v3h-2V2h1zm0 17h1v3h-2v-3h1zM2 11h3v2H2v-2zm17 0h3v2h-3v-2zM4.2 5.6l1.4-1.4 2.1 2.1-1.4 1.4-2.1-2.1zm12.1 12.1 1.4-1.4 2.1 2.1-1.4 1.4-2.1-2.1zM4.2 18.4l2.1-2.1 1.4 1.4-2.1 2.1-1.4-1.4zM16.3 6.3l2.1-2.1 1.4 1.4-2.1 2.1-1.4-1.4z"/></svg>
|
||||
<span>{{ __('Light') }}</span>
|
||||
</button>
|
||||
<button type="button" data-hd-appearance-value="dark" onclick="window.HDTheme && window.HDTheme.set('dark')" aria-pressed="false">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20.2 15.2A8 8 0 0 1 8.8 3.8 9 9 0 1 0 20.2 15.2z"/></svg>
|
||||
<span>{{ __('Dark') }}</span>
|
||||
</button>
|
||||
<button type="button" data-hd-appearance-value="system" onclick="window.HDTheme && window.HDTheme.set('system')" aria-pressed="false">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4h18v13H3V4zm2 2v9h14V6H5zm4 13h6v2H9v-2z"/></svg>
|
||||
<span>{{ __('System') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</x-settings.layout>
|
||||
</section>
|
||||
|
||||
@@ -1,34 +1,23 @@
|
||||
<section class="mt-10 space-y-6">
|
||||
<div class="relative mb-5">
|
||||
<flux:heading>{{ __('Delete account') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Delete your account and all of its resources') }}</flux:subheading>
|
||||
<section class="hd-delete-account">
|
||||
<div>
|
||||
<h3>{{ __('Delete account') }}</h3>
|
||||
<p>{{ __('Delete your account and all of its resources') }}</p>
|
||||
</div>
|
||||
|
||||
<flux:modal.trigger name="confirm-user-deletion">
|
||||
<flux:button variant="danger" x-data="" x-on:click.prevent="$dispatch('open-modal', 'confirm-user-deletion')">
|
||||
{{ __('Delete account') }}
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
|
||||
<flux:modal name="confirm-user-deletion" :show="$errors->isNotEmpty()" focusable class="max-w-lg">
|
||||
<form method="POST" wire:submit="deleteUser" class="space-y-6">
|
||||
<div>
|
||||
<flux:heading size="lg">{{ __('Are you sure you want to delete your account?') }}</flux:heading>
|
||||
|
||||
<flux:subheading>
|
||||
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
|
||||
</flux:subheading>
|
||||
</div>
|
||||
|
||||
<flux:input wire:model="password" :label="__('Password')" type="password" viewable />
|
||||
|
||||
<div class="flex justify-end space-x-2 rtl:space-x-reverse">
|
||||
<flux:modal.close>
|
||||
<flux:button variant="filled">{{ __('Cancel') }}</flux:button>
|
||||
</flux:modal.close>
|
||||
|
||||
<flux:button variant="danger" type="submit">{{ __('Delete account') }}</flux:button>
|
||||
<details class="hd-delete-details" {{ $errors->isNotEmpty() ? 'open' : '' }}>
|
||||
<summary class="hd-settings-button hd-settings-button-danger">{{ __('Delete account') }}</summary>
|
||||
<form method="POST" wire:submit="deleteUser" class="hd-delete-confirm">
|
||||
<h4>{{ __('Are you sure you want to delete your account?') }}</h4>
|
||||
<p>{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm.') }}</p>
|
||||
<label class="hd-settings-field">
|
||||
<span>{{ __('Password') }}</span>
|
||||
<input wire:model="password" type="password" autocomplete="current-password">
|
||||
@error('password') <small class="hd-settings-error">{{ $message }}</small> @enderror
|
||||
</label>
|
||||
<div class="hd-settings-actions">
|
||||
<button type="button" class="hd-settings-button" onclick="this.closest('details').removeAttribute('open')">{{ __('Cancel') }}</button>
|
||||
<button class="hd-settings-button hd-settings-button-danger" type="submit">{{ __('Delete account') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:modal>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
<section class="w-full">
|
||||
@include('partials.settings-heading')
|
||||
|
||||
<flux:heading class="sr-only">{{ __('Profile settings') }}</flux:heading>
|
||||
|
||||
<x-settings.layout :heading="__('Profile')" :subheading="__('Update your name and email address')">
|
||||
<form wire:submit="updateProfileInformation" class="my-6 w-full space-y-6">
|
||||
<flux:input wire:model="name" :label="__('Name')" type="text" required autofocus autocomplete="name" />
|
||||
<form wire:submit="updateProfileInformation" class="hd-settings-form">
|
||||
<label class="hd-settings-field">
|
||||
<span>{{ __('Name') }}</span>
|
||||
<input wire:model="name" type="text" required autofocus autocomplete="name">
|
||||
@error('name') <small class="hd-settings-error">{{ $message }}</small> @enderror
|
||||
</label>
|
||||
|
||||
<div>
|
||||
<flux:input wire:model="email" :label="__('Email')" type="email" required autocomplete="email" />
|
||||
<label class="hd-settings-field">
|
||||
<span>{{ __('Email') }}</span>
|
||||
<input wire:model="email" type="email" required autocomplete="email">
|
||||
@error('email') <small class="hd-settings-error">{{ $message }}</small> @enderror
|
||||
</label>
|
||||
|
||||
@if ($this->hasUnverifiedEmail)
|
||||
<div>
|
||||
<flux:text class="mt-4">
|
||||
{{ __('Your email address is unverified.') }}
|
||||
@if ($this->hasUnverifiedEmail)
|
||||
<p class="hd-settings-note">
|
||||
{{ __('Your email address is unverified.') }}
|
||||
<button type="button" class="hd-settings-link" wire:click.prevent="resendVerificationNotification">{{ __('Click here to re-send the verification email.') }}</button>
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<flux:link class="text-sm cursor-pointer" wire:click.prevent="resendVerificationNotification">
|
||||
{{ __('Click here to re-send the verification email.') }}
|
||||
</flux:link>
|
||||
</flux:text>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<flux:button variant="primary" type="submit">{{ __('Save') }}</flux:button>
|
||||
<div class="hd-settings-actions">
|
||||
<button class="hd-settings-button hd-settings-button-primary" type="submit">{{ __('Save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -66,4 +66,55 @@
|
||||
$viteAssets = array_values(array_unique($viteAssets));
|
||||
@endphp
|
||||
@vite($viteAssets)
|
||||
@fluxAppearance
|
||||
@fluxAppearance
|
||||
<script>
|
||||
(function () {
|
||||
var root = document.documentElement;
|
||||
var key = 'hd.appearance';
|
||||
var media = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
|
||||
|
||||
function stored() {
|
||||
try { return localStorage.getItem(key) || 'system'; } catch (e) { return 'system'; }
|
||||
}
|
||||
|
||||
function isDark(mode) {
|
||||
return mode === 'dark' || (mode === 'system' && media && media.matches);
|
||||
}
|
||||
|
||||
function syncButtons(mode) {
|
||||
var buttons = document.querySelectorAll('[data-hd-appearance-value]');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var active = buttons[i].getAttribute('data-hd-appearance-value') === mode;
|
||||
buttons[i].setAttribute('aria-pressed', active ? 'true' : 'false');
|
||||
if (active) buttons[i].classList.add('is-active');
|
||||
else buttons[i].classList.remove('is-active');
|
||||
}
|
||||
}
|
||||
|
||||
function apply(mode) {
|
||||
if (isDark(mode)) root.classList.add('dark');
|
||||
else root.classList.remove('dark');
|
||||
root.setAttribute('data-hd-appearance', mode);
|
||||
syncButtons(mode);
|
||||
}
|
||||
|
||||
window.HDTheme = {
|
||||
get: stored,
|
||||
set: function (mode) {
|
||||
if (mode !== 'light' && mode !== 'dark' && mode !== 'system') return;
|
||||
try { localStorage.setItem(key, mode); } catch (e) {}
|
||||
apply(mode);
|
||||
},
|
||||
apply: function () { apply(stored()); }
|
||||
};
|
||||
|
||||
apply(stored());
|
||||
if (media) {
|
||||
var onChange = function () { if (stored() === 'system') apply('system'); };
|
||||
if (media.addListener) media.addListener(onChange);
|
||||
else if (media.addEventListener) media.addEventListener('change', onChange);
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', function () { apply(stored()); });
|
||||
document.addEventListener('livewire:navigated', function () { apply(stored()); });
|
||||
}());
|
||||
</script>
|
||||
@@ -1,5 +1,4 @@
|
||||
<div class="relative mb-6 w-full">
|
||||
<flux:heading size="xl" level="1">{{ __('Settings') }}</flux:heading>
|
||||
<flux:subheading size="lg" class="mb-6">{{ __('Manage your profile and account settings') }}</flux:subheading>
|
||||
<flux:separator variant="subtle" />
|
||||
</div>
|
||||
<header class="hd-settings-heading">
|
||||
<h1>{{ __('Settings') }}</h1>
|
||||
<p>{{ __('Manage your profile and account settings') }}</p>
|
||||
</header>
|
||||
|
||||
Reference in New Issue
Block a user