CluPilotCloud/resources/views/livewire/admin/roles.blade.php

88 lines
4.6 KiB
PHP

<div class="mx-auto max-w-[1120px] space-y-6">
<div class="animate-rise">
<h1 class="text-2xl font-bold tracking-tight text-ink">{{ __('roles.title') }}</h1>
<p class="mt-1 max-w-[70ch] text-sm text-muted">{{ __('roles.subtitle') }}</p>
</div>
{{-- Neue Rolle. Ein Feld, ein Knopf die Rechte bekommt sie danach in
ihrer eigenen Karte, weil eine leere Rolle noch nichts kaputtmachen
kann und die Matrix im selben Formular unlesbar würde. --}}
<div class="flex flex-wrap items-end gap-3 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise">
<div class="min-w-56 flex-1">
<x-ui.input name="newRole" wire:model="newRole"
:label="__('roles.new_label')" :hint="__('roles.new_hint')" />
</div>
<x-ui.button variant="primary" wire:click="create" wire:loading.attr="disabled" wire:target="create">
{{ __('roles.create') }}
</x-ui.button>
</div>
@foreach ($roles as $role)
@php $isProtected = $role->name === $protectedRole; @endphp
<div wire:key="role-{{ $role->id }}"
class="space-y-4 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise">
<div class="flex flex-wrap items-start justify-between gap-3">
<div class="min-w-0">
<h2 class="flex flex-wrap items-center gap-2 font-semibold text-ink">
{{ $role->name }}
@if ($isProtected)
<span class="rounded-pill border border-warning-border bg-warning-bg px-2.5 py-0.5 text-xs font-medium text-warning">
{{ __('roles.locked_badge') }}
</span>
@endif
@if (in_array($role->name, $ownRoles, true))
<span class="rounded-pill border border-info-border bg-info-bg px-2.5 py-0.5 text-xs font-medium text-info">
{{ __('roles.your_role') }}
</span>
@endif
</h2>
<p class="mt-0.5 text-xs text-muted">
{{ trans_choice('roles.holders', $role->users_count, ['count' => $role->users_count]) }}
</p>
</div>
@unless ($isProtected)
<div class="flex flex-wrap gap-2">
<x-ui.button variant="primary" wire:click="save({{ $role->id }})"
wire:loading.attr="disabled" wire:target="save({{ $role->id }})">
{{ __('common.save') }}
</x-ui.button>
@if ($role->users_count === 0)
<x-ui.button variant="ghost" wire:click="delete({{ $role->id }})"
wire:loading.attr="disabled" wire:target="delete({{ $role->id }})">
{{ __('roles.delete') }}
</x-ui.button>
@endif
</div>
@endunless
</div>
@error('granted.'.$role->id)<p class="text-xs text-danger">{{ $message }}</p>@enderror
@if ($isProtected)
<p class="text-sm text-muted">{{ __('roles.owner_locked') }}</p>
@endif
{{-- Die Matrix. Auch für Owner sichtbar, nur nicht änderbar: was
der Owner darf, ist die Antwort auf „was gibt es überhaupt",
und die soll man nachlesen können. --}}
<div class="grid grid-cols-1 gap-x-6 gap-y-2 sm:grid-cols-2 lg:grid-cols-3">
@foreach ($permissions as $permission)
<label class="flex items-start gap-2 text-sm text-body">
<input type="checkbox" value="{{ $permission }}"
wire:model="granted.{{ $role->id }}"
@disabled($isProtected)
class="mt-0.5 size-4 shrink-0 rounded border-line-strong accent-[var(--accent-active)] disabled:opacity-50">
<span class="min-w-0">
<span class="font-mono text-xs">{{ $permission }}</span>
<span class="block text-xs text-muted">{{ __('roles.can.'.$permission) }}</span>
</span>
</label>
@endforeach
</div>
</div>
@endforeach
@error('newRole')<p class="text-sm text-danger">{{ $message }}</p>@enderror
</div>