Files
construprogress/app/Livewire/UserView.php
T

159 lines
5.6 KiB
PHP
Raw Normal View History

<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\Attributes\Layout;
use App\Models\User;
use App\Models\Project;
use App\Models\Inspection;
use App\Models\Issue;
use Illuminate\Support\Facades\Auth;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\PermissionRegistrar;
#[Layout('layouts.app')]
class UserView extends Component
{
public User $user;
public string $activeTab = 'ficha';
// Projects tab
public ?int $addProjectId = null;
public string $addProjectRole = '';
public $availableProjects;
// Notes tab
public string $notes = '';
public bool $editingNotes = false;
// Recent activity (loaded once)
public $recentInspections;
public $recentIssues;
public function mount(User $user): void
{
abort_unless(Auth::user()->can('view users'), 403);
$this->user = $user->load(['roles', 'company', 'projects.phases']);
$this->notes = $user->notes ?? '';
$this->loadAvailableProjects();
$this->loadActivity();
}
private function loadAvailableProjects(): void
{
$assignedIds = $this->user->projects->pluck('id');
$this->availableProjects = Project::whereNotIn('id', $assignedIds)
->orderBy('name')->get();
}
private function loadActivity(): void
{
$this->recentInspections = Inspection::where('user_id', $this->user->id)
->with(['feature.layer.phase.project', 'template'])
->latest()->take(8)->get();
$this->recentIssues = Issue::where('reported_by', $this->user->id)
->with(['feature', 'project'])
->latest()->take(8)->get();
}
// ── Tabs ─────────────────────────────────────────────────────────────────
public function setTab(string $tab): void
{
$this->activeTab = $tab;
}
// ── Projects ──────────────────────────────────────────────────────────────
public function assignProject(): void
{
$this->validate([
'addProjectId' => 'required|exists:projects,id',
'addProjectRole' => 'nullable|string|max:100',
], [], ['addProjectId' => 'proyecto', 'addProjectRole' => 'rol en proyecto']);
$this->user->projects()->attach($this->addProjectId, [
'role_in_project' => $this->addProjectRole ?: null,
]);
$this->user->load('projects.phases');
$this->addProjectId = null;
$this->addProjectRole = '';
$this->loadAvailableProjects();
$this->dispatch('notify', 'Proyecto asignado.');
}
public function removeProject(int $projectId): void
{
$this->user->projects()->detach($projectId);
$this->user->load('projects.phases');
$this->loadAvailableProjects();
$this->dispatch('notify', 'Proyecto desasignado.');
}
// ── Permissions (direct, per user) ─────────────────────────────────────────
public function togglePermission(string $name): void
{
if ($this->user->hasDirectPermission($name)) {
$this->user->revokePermissionTo($name);
} else {
$this->user->givePermissionTo($name);
}
app(PermissionRegistrar::class)->forgetCachedPermissions();
$this->user->load('roles', 'permissions');
$this->dispatch('notify', 'Permisos del usuario actualizados');
}
public function setUserGroup(string $group, bool $enabled): void
{
foreach (Permission::where('group', $group)->pluck('name') as $name) {
if ($enabled) {
if (! $this->user->hasPermissionTo($name)) {
$this->user->givePermissionTo($name);
}
} elseif ($this->user->hasDirectPermission($name)) {
$this->user->revokePermissionTo($name);
}
}
app(PermissionRegistrar::class)->forgetCachedPermissions();
$this->user->load('roles', 'permissions');
$this->dispatch('notify', $enabled ? 'Permisos del grupo concedidos' : 'Permisos directos del grupo quitados');
}
// ── Notes ─────────────────────────────────────────────────────────────────
public function saveNotes(): void
{
$this->validate(['notes' => 'nullable|string']);
$this->user->update(['notes' => $this->notes ?: null]);
$this->editingNotes = false;
$this->dispatch('notify', 'Notas guardadas.');
}
public function render()
{
$order = [
'Proyectos', 'Fases y progreso', 'Capas y elementos', 'Inspecciones',
'Incidencias', 'Empresas', 'Usuarios', 'Roles', 'Informes', 'Archivos', 'General',
];
$grouped = Permission::orderBy('name')->get()
->groupBy(fn ($perm) => $perm->group ?: 'General')
->sortBy(function ($perms, $section) use ($order) {
$i = array_search($section, $order, true);
return $i === false ? 999 : $i;
});
return view('livewire.user-view', [
'grouped' => $grouped,
'directPerms' => $this->user->getDirectPermissions()->pluck('name')->toArray(),
'rolePerms' => $this->user->getPermissionsViaRoles()->pluck('name')->toArray(),
]);
}
}