{{-- The customer's own settings. ## Four attempts, and what was wrong with each 1. One column 768px wide in a 1240px shell, everything in it, two thousand pixels deep. 2. Four tabs — better — but cards of different heights in a grid, which on the contract tab read as a staircase. 3. Panels and rows: right idea, wrong proportions. Full-width slabs stacked down the page, each with its title INSIDE it, so the page was a column of long boxes and nothing said where one topic ended. ## What it is now The shape serious settings pages actually use: a section list on the left, a measured content column on the right, and the heading OUTSIDE the card it belongs to. - The nav is the structure. It is sticky, so the sections stay reachable however far down a form goes, and it says which one you are in without making you read a row of tabs. - 820px is the content column. Nobody types a phone number into a field 1100px wide; a settings page that lets them looks like a spreadsheet. - A section is a heading, a sentence, and then a card of rows. Putting the heading inside the card gave every group two frames — the title bar and the border — and that is what made them read as boxes rather than as topics. - What cannot be undone lives at the end, in a card that says so with its border. Below `lg` the nav becomes a scrolling strip of chips above the content, and the rows stack, because on a telephone a label belongs above its field. --}} @php $sections = [ 'profile' => 'users', 'security' => 'shield-check', 'branding' => 'pen', 'contract' => 'receipt', ]; @endphp

{{ __('settings.eyebrow') }}

{{ __('settings.title') }}

{{ __('settings.subtitle') }}

{{-- ── The section list ──────────────────────────────────────────── Sticky on a wide screen: a long form must not scroll its own navigation away. A strip of chips below `lg`, because a vertical list on a telephone is four rows of nothing. --}} {{-- ── The content column ─────────────────────────────────────────── 820px, not the whole shell. Nobody types a postcode into a field a thousand pixels wide. --}}
{{-- ══ Ihre Daten ═══════════════════════════════════════════════ --}} @if ($tab === 'profile')

{{ __('settings.company_title') }}

{{ __('settings.company_sub') }}

{{-- Field by field, not a paragraph: what landed in the textarea was whatever somebody typed — a postcode on the street line, a town with no postcode, no country at all — and an invoice has to name its recipient precisely enough to be a document. --}}
{{ __('settings.save') }}
{{-- A FACT for a record that has one. It decides the fourteen-day right of withdrawal: a business able to set itself to "Privatperson" here is a business able to withdraw from a contract it may not withdraw from. Registration asks; this page reports. The lock is in Settings::saveProfile, not here — a form that only hides a control has never stopped anybody who can post to /livewire/update. --}}

{{ __('settings.customer_type') }}

{{ $customer?->customer_type ? __('settings.customer_type_locked') : __('settings.customer_type_once') }}

@if ($customer?->customer_type)

{{ __('settings.customer_type_'.$customer->customer_type) }}

@else
@foreach ($customerTypes as $type) @endforeach
@error('customerType')

{{ $message }}

@enderror @endif
@endif {{-- ══ Sicherheit ═══════════════════════════════════════════════ --}} @if ($tab === 'security')
{{-- Own password. There was no way to change one at all — Fortify's updatePasswords feature was switched off. --}}

{{ __('admin_settings.password_title') }}

{{ __('admin_settings.password_sub') }}

{{ __('admin_settings.password_save') }}
{{-- Two-factor. Every action is re-checked server-side against a recent password confirmation — hiding the buttons stops nobody who can post to /livewire/update. --}}

{{ __('settings.twofa_title') }}

{{ $twoFactorOn ? __('settings.twofa_state_on') : __('settings.twofa_state_off') }}

{{ __('settings.twofa_sub') }}

@if (! $passwordConfirmed) {{-- The gate. A signed-in session is not enough to change how the account is protected — the risk is an unlocked machine. --}}
{{ __('settings.twofa_confirm_button') }}
@elseif ($twoFactorOn)
{{ __('settings.twofa_new_codes') }} {{ __('settings.twofa_disable') }}
@elseif ($twoFactorPending)
{!! $twoFactorQr !!}
{{ __('settings.twofa_activate') }}
@else {{ __('settings.twofa_enable') }} @endif @if ($recoveryCodes) {{-- Shown once, on purpose: nobody writes down what they were never shown, and these are the way back in when the phone is gone. --}}
    @foreach ($recoveryCodes as $code)
  • {{ $code }}
  • @endforeach
@endif
{{-- The devices. It answers the same question two-factor does — who can get into this account. --}}
@livewire('sessions')
@endif {{-- ══ Erscheinungsbild ═════════════════════════════════════════ --}} @if ($tab === 'branding')

{{ __('settings.branding_title') }}

{{ __('settings.branding_sub') }}

@error('brandPrimary')

{{ $message }}

@enderror
@error('brandAccent')

{{ $message }}

@enderror
@if ($logo) @elseif ($logoUrl) @else {{ __('settings.brand_default') }} @endif
@if ($logoUrl) @endif @error('logo')

{{ $message }}

@enderror
@if ($branding['is_default'] ?? false)

{{ __('settings.brand_using_default') }}

@endif {{ __('settings.save') }}
@endif {{-- ══ Vertrag ══════════════════════════════════════════════════ --}} @if ($tab === 'contract')

{{ __('settings.package_title') }}

{{ __('settings.contract_sub') }}

@if ($cancellationScheduled) {{ __('settings.cancel_scheduled_body', ['date' => $instance?->service_ends_at?->local()->isoFormat('LL')]) }} @elseif ($hasActivePackage) {{ __('settings.package_active', ['plan' => $instance ? __('billing.plan.'.$instance->plan) : '—']) }} @else {{ __('settings.no_package') }} @endif

@if ($hasActivePackage && ! $cancellationScheduled) {{ __('settings.cancel_cta') }} @elseif (! $hasActivePackage && ! $cancellationScheduled) {{ __('settings.to_packages') }} @endif
{{-- ── Das Widerrufsrecht ──────────────────────── Shown to every CONSUMER with a contract, open or not. It used to render only while the window was open, so once the fourteen days expired the block vanished — indistinguishable from a feature nobody built. A business never sees it, and Settings::withdraw() refuses them again on the server: a card that is not rendered has never stopped anybody who can post to /livewire/update. Not a variant of the cancellation above it: that one ends a contract validly concluded and keeps the term already paid for; this one unwinds the contract, ends the service the same day and sends the whole amount back. --}} @if ($withdrawal->applies)

@if ($withdrawal->open) {{ __('withdrawal.card_sub', [ 'date' => $withdrawal->endsAt->local()->isoFormat('LL'), 'days' => $withdrawal->daysLeft(), ]) }} @else {{ $withdrawal->refusal }} @endif

@if ($withdrawal->open) {{ __('withdrawal.cta') }} @endif
@endif
{{-- ── AV-Vertrag & TOM ────────────────────────────────── Art. 28 DSGVO wants a contract wherever personal data is processed on somebody else's behalf. It is concluded WITH the terms at checkout (see the AGB), so this is not a second signing ceremony: the document has to be available, current and retrievable. The extra confirmation is offered because a practice or a firm that gets audited often wants one on file. Nothing renders until an operator has published a version. --}} @if ($dpa !== null)

{{ __('dpa.title') }}

{{ __('dpa.version', ['version' => $dpa->version]) }}

{{ __('dpa.sub') }}

{{ __('dpa.open') }} {{ __('dpa.download') }}
@if ($dpa->measures_path)
{{ __('dpa.open') }} {{ __('dpa.download') }}
@endif @if ($dpaAcceptance) {{-- R19: stored in UTC, read on the wall clock. --}}

{{ __('dpa.accepted_on', [ 'version' => $dpa->version, 'when' => $dpaAcceptance->accepted_at->local()->isoFormat('LL, LT'), ]) }}

@else

{{ __('dpa.in_force_note') }}

{{ __('dpa.accept_cta') }}
@endif
@endif {{-- ── What ends an account ────────────────────────────── The deadlines and the button that closes it, together and last, in a card whose border says what kind of thing this is. Everything irreversible on this page lives here. The deadlines come from the commands that enforce them, so the page cannot drift from what actually happens. --}}

{{ __('settings.close_account_title') }}

{{ __('settings.close_account_sub') }}

  • {{ __('settings.lifecycle_unverified', ['days' => App\Console\Commands\PruneUnverifiedAccounts::AFTER_DAYS]) }}
  • {{ __('settings.lifecycle_dormant', ['warn' => App\Console\Commands\PruneDormantAccounts::WARN_DAYS_BEFORE]) }}
  • {{ __('settings.lifecycle_kept') }}
{{ __('settings.lifecycle_terms') }}
{{ __('settings.close_cta') }}
@endif